void RecurseMining(Itemset head, List <int> tail, int support, int minLength, int maxLength, MineResults mineResult, int maxLayerDiff) { if (head.Count >= maxLength) { return; } List <Candidate> candidates = new List <Candidate>(); // Find the layer with the minimal number of items int minLayerSize = head.layersItemsSum[0]; for (int loopLayer = 1; loopLayer < head.layersItemsSum.Length; loopLayer++) { minLayerSize = Math.Min(minLayerSize, head.layersItemsSum[loopLayer]); } for (int loopTail = 0; loopTail < tail.Count; loopTail++) { int i = tail[loopTail]; // TODO : Calculation of the support should be according to the items from the // lower and upper layers. FastSparseBitArray bitArray = null; for (int loop = 0; loop < head.Count; loop++) { int headItem = head.GetItem(loop); if (_itemsLayers[headItem] < _itemsLayers[i]) { if (bitArray == null) { bitArray = _dualComp.GetItemset(headItem, i).GetTransactions(); } else { bitArray = bitArray.And(_dualComp.GetItemset(headItem, i).GetTransactions()); } } else if (_itemsLayers[headItem] > _itemsLayers[i]) { if (bitArray == null) { bitArray = _dualComp.GetItemset(i, headItem).GetTransactions(); } else { bitArray = bitArray.And(_dualComp.GetItemset(i, headItem).GetTransactions()); } } } if (head.GetTransactions() != null) { if (bitArray == null) { bitArray = head.GetTransactions(); } else { bitArray = bitArray.And(head.GetTransactions()); } } int currentSupport = Int32.MaxValue; if (bitArray != null) { currentSupport = bitArray.CountElements(); } /* * FastSparseBitArray bitArray = dualComp.GetItemset(head.GetLastItem(), i).GetTransactions(); * * if (head.Count > 1) * bitArray = bitArray.And(head.GetTransactions()); * * int currentSupport = bitArray.CountElements(); */ if (currentSupport >= support) { Candidate cand = new Candidate(); cand.item = i; cand.support = currentSupport; // If the new tail creates and itemset with unbalanced layers // set support to infinity so the itemset will not be traversed if (head.layersItemsSum[_itemsLayers[i]] + 1 > minLayerSize + maxLayerDiff) { cand.support = Int32.MaxValue; } cand.bitArray = bitArray; candidates.Add(cand); } } // Dynamic Reordering candidates.Sort(); // Rebuild tail List <int> newTail = new List <int>(); for (int loop = 0; loop < candidates.Count; loop++) { newTail.Add(candidates[loop].item); } Itemset newHead; for (int loopTail = 0; loopTail < candidates.Count; loopTail++) { // Stop recursing when all the tail left are MaxInt (e.g. from the same layer) if (candidates[loopTail].support == Int32.MaxValue) { break; } int i = newTail[0]; newTail.RemoveAt(0); newHead = new Itemset(head); newHead.AddItem(i); newHead.layersItemsSum[_itemsLayers[i]]++; FastSparseBitArray bitArray = candidates[loopTail].bitArray; newHead.SetTransactions(bitArray); newHead.support = candidates[loopTail].support; RecurseMining(newHead, newTail, support, minLength, maxLength, mineResult, maxLayerDiff); if (newHead.Count >= minLength) { mineResult.Add(newHead); } newHead.SetTransactions(null); } }
void RecurseMining(Itemset head, List <int> tail, int support, int minLength, int maxLength, MineResults mineResult) { Itemset newHead; List <int> newTail; if (head.Count >= maxLength) { return; } for (int loopTail = 0; loopTail < tail.Count; loopTail++) { int i = tail[loopTail]; if (head.Count == 0) { newTail = new List <int>(tail); newTail.RemoveAt(loopTail); newHead = new Itemset(); newHead.AddItem(i); RecurseMining(newHead, newTail, support, minLength, maxLength, mineResult); } else { for (int loopHead = 0; loopHead < head.Count; loopHead++) { for (int loopReverseOrder = 0; loopReverseOrder < 1; loopReverseOrder++) { FastSparseBitArray bitArray; if (loopReverseOrder == 0) { if (head.outDegree[loopHead] >= MAX_OUT_RANK) { break; } bitArray = _dualComp.GetItemset(head.GetItem(loopHead), i).GetTransactions(); } else { if (head.inDegree[loopHead] >= MAX_IN_RANK) { break; } bitArray = _dualComp.GetItemset(i, head.GetItem(loopHead)).GetTransactions(); } if (head.Count > 1) { bitArray = bitArray.And(head.GetTransactions()); } if (bitArray.CountElements() >= support) { newTail = new List <int>(tail); newTail.RemoveAt(loopTail); newHead = new Itemset(head); newHead.AddItem(i); newHead.SetTransactions(bitArray); newHead.support = bitArray.CountElements(); if (loopReverseOrder == 0) { newHead.inDegree[newHead.Count - 1] = 1; newHead.outDegree[loopHead]++; newHead.customStringDisplay += "" + head.GetItem(loopHead) + "=>" + i + "; "; } else { newHead.inDegree[loopHead]++; newHead.outDegree[newHead.Count - 1] = 1; newHead.customStringDisplay += "" + i + "=>" + head.GetItem(loopHead) + "; "; } RecurseMining(newHead, newTail, support, minLength, maxLength, mineResult); if (newHead.Count >= minLength) { mineResult.Add(newHead); /* * System.IO.FileStream fs = new System.IO.FileStream("res.txt", * System.IO.FileMode.Append); * System.IO.StreamWriter tw = new System.IO.StreamWriter(fs); * tw.WriteLine(newHead.ToString()); * tw.Close(); * fs.Close();*/ } newHead.SetTransactions(null); } } } } } }
void RecurseMining(Itemset head, List <int> tail, int support, int minLength, int maxLength, int maxGroupLength, MineResults mineResult) { Itemset newHead; List <int> newTail; if (head.Count >= maxLength) { return; } for (int loopTail = 0; loopTail < tail.Count; loopTail++) { int i = tail[loopTail]; if (head.Count == 0) { newTail = new List <int>(tail); newTail.RemoveAt(loopTail); newHead = new Itemset(); newHead.AddItem(i); newHead.itemGroup[newHead.Count - 1] = 1; newHead.groupLength = 1; RecurseMining(newHead, newTail, support, minLength, maxLength, maxGroupLength, mineResult); } else { int currentItemGroup = head.itemGroup[head.Count - 1]; for (int loopGroups = 0; loopGroups < 2; loopGroups++) { // Don't try to add the same item to the same group twice if ((loopGroups == 0) && (i < head.GetItem(head.Count - 1))) { continue; } // Don't create too long group if ((loopGroups == 0) && (head.groupLength >= maxGroupLength)) { continue; } // Add 0 / 1 depends on the loop int newItemGroup = currentItemGroup + loopGroups; FastSparseBitArray bitArray = null; // Perform AND with all previous group members - calc support for (int loopHead = 0; loopHead < head.Count; loopHead++) { if (head.itemGroup[loopHead] == newItemGroup - 1) { if (bitArray == null) { bitArray = _dualComp.GetItemset(head.GetItem(loopHead), i).GetTransactions(); } else { bitArray = bitArray.And(_dualComp.GetItemset(head.GetItem(loopHead), i).GetTransactions()); } } } if (currentItemGroup > 1) { bitArray = bitArray.And(head.GetTransactions()); } bool validSupport = false; if (bitArray == null) { validSupport = true; } else if (bitArray.CountElements() >= support) { validSupport = true; } if (validSupport == false) { tail.RemoveAt(loopTail); loopTail--; break; } else //if (validSupport == true) { newTail = new List <int>(tail); newTail.RemoveAt(loopTail); newHead = new Itemset(head); newHead.AddItem(i); newHead.itemGroup[newHead.Count - 1] = newItemGroup; if (loopGroups == 0) { newHead.groupLength = head.groupLength + 1; } else { newHead.groupLength = 1; } newHead.SetTransactions(bitArray); if (bitArray != null) { newHead.support = bitArray.CountElements(); } RecurseMining(newHead, newTail, support, minLength, maxLength, maxGroupLength, mineResult); // Add the new item as 'found' itemset only if 1. it's above minSupport, 2. it contains more then the first group if ((newHead.Count >= minLength) && (newHead.Count > newHead.groupLength)) { mineResult.Add(newHead); } newHead.SetTransactions(null); } } } } }