/** * Save a pattern of size 1 to the output file * * @param item the item * @param bitmap its bitmap * @throws IOException exception if error while writing to the file */ private void savePattern(Integer item, Bitmap bitmap) throws IOException { // First, we check if the pattern contains the desired items (optional) // We only do that if the user has specified some items that must appear in // patterns. if (mustAppearItems != null) { // if the pattern does not contains all required items, then return if (mustAppearItems.length > 1) { return; } if (item.equals(mustAppearItems[0]) == false) { return; } } patternCount++; // increase the pattern count StringBuilder r = new StringBuilder(""); r.append(item); r.append(" -1 "); r.append("#SUP: "); r.append(bitmap.getSupport()); // if the user wants the sequence IDs, we will show them if (outputSequenceIdentifiers) { r.append(" #SID: "); r.append(bitmap.getSIDs(sequencesSize)); } writer.write(r.toString()); writer.newLine(); }
/** * Create a new bitmap for the s-step by doing a AND between this bitmap and the bitmap of an * item. * * @param bitmapItem the bitmap of the item used for the S-Step * @param sequencesSize the sequence lengths * @param lastBitIndex the last bit index * @param maxGap * @return return the new bitmap */ Bitmap createNewBitmapSStep( Bitmap bitmapItem, List<Integer> sequencesSize, int lastBitIndex, int maxGap) { // INTERSECTION_COUNT++; // create a new bitset that will be use for the new bitmap BitSet newBitset = new BitSet(lastBitIndex); // create the new bitmap Bitmap newBitmap = new Bitmap(newBitset); // We do an AND with the bitmap of the item and this bitmap for (int bitK = bitmap.nextSetBit(0); bitK >= 0; bitK = bitmap.nextSetBit(bitK + 1)) { // find the sid of this bit int sid = bitToSID(bitK, sequencesSize); // get the last bit for this sid int lastBitOfSID = lastBitOfSID(sid, sequencesSize, lastBitIndex); boolean match = false; for (int bit = bitmapItem.bitmap.nextSetBit(bitK + 1); bit >= 0 && bit <= lastBitOfSID && (bit - bitK <= maxGap); bit = bitmapItem.bitmap.nextSetBit(bit + 1)) { // new int tid = bit - sequencesSize.get(sid); newBitmap.bitmap.set(bit); match = true; // System.out.println(); // System.out.println("bit " + bit); // System.out.println("sid " + sid); // System.out.println("seqSize " + sequencesSize.get(sid)); // System.out.println("tid " + tid); if (firstItemsetID == -1 || tid < firstItemsetID) { firstItemsetID = tid; } } if (match) { // update the support if (sid != newBitmap.lastSID) { newBitmap.support++; newBitmap.sidsum += sid; } newBitmap.lastSID = sid; } bitK = lastBitOfSID; // to skip the bit from the same sequence } // We return the resulting bitmap return newBitmap; }
/** * Save a pattern of size > 1 to the output file. * * @param prefix the prefix * @param bitmap its bitmap * @throws IOException exception if error while writing to the file */ private void savePattern(Prefix prefix, Bitmap bitmap) throws IOException { // First, we check if the pattern contains the desired items (optional) // We only do that if the user has specified some items that must appear in // patterns. if (mustAppearItems != null) { Set<Integer> itemsFound = new HashSet<Integer>(); // for each item in the pattern loop: for (Itemset itemset : prefix.getItemsets()) { for (Integer item : itemset.getItems()) { // if the user required that this item must appear in all patterns if (itemMustAppearInPatterns(item)) { // we note it itemsFound.add(item); if (itemsFound.size() == mustAppearItems.length) { break loop; } } } } // if the pattern does not contains all required items, then return if (itemsFound.size() != mustAppearItems.length) { return; } } patternCount++; StringBuilder r = new StringBuilder(""); for (Itemset itemset : prefix.getItemsets()) { // r.append('('); for (Integer item : itemset.getItems()) { String string = item.toString(); r.append(string); r.append(' '); } r.append("-1 "); } r.append("#SUP: "); r.append(bitmap.getSupport()); // if the user wants the sequence IDs, we will show them if (outputSequenceIdentifiers) { r.append(" #SID: "); r.append(bitmap.getSIDs(sequencesSize)); } writer.write(r.toString()); // System.out.println(r.toString()); writer.newLine(); }
/** * Create a new bitmap by performing the I-STEP with this bitmap and the bitmap of an item. * * @param bitmapItem the bitmap of the item * @param sequencesSize the sequence lengths * @param lastBitIndex the last bit index * @return the new bitmap */ Bitmap createNewBitmapIStep(Bitmap bitmapItem, List<Integer> sequencesSize, int lastBitIndex) { // INTERSECTION_COUNT++; // We create the new bitmap BitSet newBitset = new BitSet(lastBitIndex); // TODO: USE LAST SET BIT Bitmap newBitmap = new Bitmap(newBitset); // We do an AND with the bitmap of the item for (int bit = bitmap.nextSetBit(0); bit >= 0; bit = bitmap.nextSetBit(bit + 1)) { if (bitmapItem.bitmap.get(bit)) { // if both bits are TRUE // set the bit newBitmap.bitmap.set(bit); // update the support int sid = bitToSID(bit, sequencesSize); if (sid != newBitmap.lastSID) { newBitmap.sidsum += sid; newBitmap.support++; } newBitmap.lastSID = sid; // remember the last SID // new int tid = bit - sequencesSize.get(sid); if (firstItemsetID == -1 || tid < firstItemsetID) { firstItemsetID = tid; } // end new } } // Then do the AND newBitset.and(bitmapItem.bitmap); // We return the resulting bitmap return newBitmap; }
/** * Save a pattern of size > 1 to the output file. * * @param prefix the prefix * @param bitmap its bitmap * @throws IOException exception if error while writing to the file * @return true if pattern is subsumed */ private boolean savePatternMultipleItems(PrefixVMSP prefix, Bitmap bitmap, int length) throws IOException { // CHANGED ------ // System.out.println("prefix :" + prefix); // if(true == true) return false; // WE COMPARE WITH LARGER PATTERNS FOR SUPER-PATTERN CHECKING // ################# // IMPORTANT STRATEGY : FROM LARGER TO SMALLER...... // ################## for (int i = maxPatterns.size() - 1; i > length; i--) { for (PatternVMSP pPrime : maxPatterns.get(i)) { // System.out.println(pPrime.prefix.sumOfItems); // if the prefix pattern has a support higher or equal to the current pattern if (pPrime.prefix.sumOfOddItems + pPrime.prefix.sumOfEvenItems < prefix.sumOfOddItems + prefix.sumOfEvenItems) { break; } if (prefix.sumOfEvenItems <= pPrime.prefix.sumOfEvenItems && prefix.sumOfOddItems <= pPrime.prefix.sumOfOddItems && bitmap.getSupport() >= pPrime.support && strictlyContains(pPrime.prefix, prefix)) { return true; } } } // System.out.println(" ADD : " + prefix); // WE COMPARE WITH SMALLER PATTERNS FOR SUB-PATTERN CHECKING for (int i = 1; i < length && i < maxPatterns.size(); i++) { // for each pattern already found of size i // IMPORTANT : WE USE A DESCENDNIG ITERATOR... // HOWEVER' WE COULD USE THIS FOR PRUNING... Iterator<PatternVMSP> iter = maxPatterns.get(i).descendingIterator(); // DESCENDING ITERATOR !!!!!!!!!! while (iter.hasNext()) { PatternVMSP pPrime = iter.next(); // CAN DO THIS BECAUSE OF DESCENDING ORDER if (pPrime.prefix.sumOfOddItems + pPrime.prefix.sumOfEvenItems >= prefix.sumOfOddItems + prefix.sumOfEvenItems) { break; } if (prefix.sumOfEvenItems >= pPrime.prefix.sumOfEvenItems && prefix.sumOfOddItems >= pPrime.prefix.sumOfOddItems && bitmap.getSupport() <= pPrime.support && strictlyContains(prefix, pPrime.prefix)) { patternCount--; // DECREASE COUNT iter.remove(); } } } // OTHERWISE THE NEW PATTERN IS NOT SUBSUMMED while (maxPatterns.size() - 1 < length) { maxPatterns.add(new TreeSet<PatternVMSP>()); } TreeSet<PatternVMSP> patternsOfSizeM = maxPatterns.get(length); patternCount++; // INCREASE COUNT // Create the pattern PatternVMSP pattern = new PatternVMSP(prefix, bitmap.getSupport()); // If the user wants to see the sequence identifiers, we need to keep the bitmap which stores // them if (outputSequenceIdentifiers) { pattern.bitmap = bitmap; } // save the pattern patternsOfSizeM.add(pattern); // if(patternCount % 200 == 0) { // System.out.println(patternCount); // } return false; // not subsumed // StringBuilder r = new StringBuilder(""); // for (Itemset itemset : prefix.getItemsets()) { //// r.append('('); // for (Integer item : itemset.getItems()) { // String string = item.toString(); // r.append(string); // r.append(' '); // } // r.append("-1 "); // } // // r.append("SUP: "); // r.append(bitmap.getSupport()); // // writer.write(r.toString()); //// System.out.println(r.toString()); // writer.newLine(); // END CHANGED ------ }
/** * Save a pattern of size 1 to the output file * * @param item the item * @param bitmap its bitmap * @param itemIsEven * @throws IOException exception if error while writing to the file * @return true if is subsumed */ private boolean savePatternSingleItem(Integer item, Bitmap bitmap, boolean itemIsEven) throws IOException { // System.out.println("prefix :" + prefix); // FOR THE CASE OF SINGLE ITEM, WE DON'T NEED TO DO SUB-PATTERN CHECKING: // WE JUST NEED TO DO SUPER-PATTERN CHECKING // ################# // IMPORTANT STRATEGY : FROM LARGER TO SMALLER...... AND IN ASCENDING SUPPORT ORDER // ################## if (itemIsEven) { for (int i = maxPatterns.size() - 1; i > 1; i--) { for (PatternVMSP pPrime : maxPatterns.get(i)) { if (pPrime.prefix.sumOfOddItems + pPrime.prefix.sumOfEvenItems < item) { break; } // if the pattern already found contains the single item if (pPrime.prefix.sumOfEvenItems > item && bitmap.getSupport() >= pPrime.support) { if (pPrime.prefix.containsItem(item)) { return true; } } } } } else { for (int i = maxPatterns.size() - 1; i > 1; i--) { for (PatternVMSP pPrime : maxPatterns.get(i)) { if (pPrime.prefix.sumOfOddItems + pPrime.prefix.sumOfEvenItems < item) { break; } // if the pattern already found contains the single item if (pPrime.prefix.sumOfOddItems > item && bitmap.getSupport() >= pPrime.support) { if (pPrime.prefix.containsItem(item)) { return true; } } } } } // OTHERWISE THE NEW PATTERN IS NOT SUBSUMMED patternCount++; // INCREASE COUNT PrefixVMSP prefix = new PrefixVMSP(); prefix.addItemset(new Itemset(item)); if (itemIsEven) { prefix.sumOfEvenItems = item; prefix.sumOfOddItems = 0; } else { prefix.sumOfEvenItems = 0; prefix.sumOfOddItems = item; } PatternVMSP pattern = new PatternVMSP(prefix, bitmap.getSupport()); // If the user wants to see the sequence identifiers, we need to keep the bitmap which stores // them if (outputSequenceIdentifiers) { pattern.bitmap = bitmap; } // save the pattern // System.out.println(" ADD: " + item); maxPatterns.get(1).add(pattern); return false; // END CHANGED ------ }
/** * This is the dfsPruning method as described in the SPAM paper. * * @param prefix the current prefix * @param prefixBitmap the bitmap corresponding to the current prefix * @param sn a list of items to be considered for i-steps * @param in a list of items to be considered for s-steps * @param hasToBeGreaterThanForIStep * @param m size of the current prefix in terms of items * @param lastAppendedItem the last appended item to the prefix * @throws IOException if there is an error writing a pattern to the output file * @return TRUE IF A FREQUENT PATTERN WAS CREATED USING THE PREFIX. */ boolean dfsPruning( PrefixVMSP prefix, Bitmap prefixBitmap, List<Integer> sn, List<Integer> in, int hasToBeGreaterThanForIStep, int m, Integer lastAppendedItem) throws IOException { boolean atLeastOneFrequentExtension = false; // System.out.println(prefix.toString()); // ====== S-STEPS ====== // Temporary variables (as described in the paper) List<Integer> sTemp = new ArrayList<Integer>(); List<Bitmap> sTempBitmaps = new ArrayList<Bitmap>(); // for CMAP pruning, we will only check against the last appended item Map<Integer, Integer> mapSupportItemsAfter = coocMapAfter.get(lastAppendedItem); // for each item in sn loopi: for (Integer i : sn) { // LAST POSITION PRUNING /*if (useLastPositionPruning && lastItemPositionMap.get(i) < prefixBitmap.firstItemsetID) { // System.out.println("TEST"); continue loopi; }*/ // CMAP PRUNING // we only check with the last appended item if (useCMAPPruning) { if (mapSupportItemsAfter == null) { continue loopi; } Integer support = mapSupportItemsAfter.get(i); if (support == null || support < minsup) { // System.out.println("PRUNE"); continue loopi; } } // perform the S-STEP with that item to get a new bitmap Bitmap.INTERSECTION_COUNT++; Bitmap newBitmap = prefixBitmap.createNewBitmapSStep(verticalDB.get(i), sequencesSize, lastBitIndex, maxGap); // if the support is higher than minsup if (newBitmap.getSupportWithoutGapTotal() >= minsup) { // record that item and pattern in temporary variables sTemp.add(i); sTempBitmaps.add(newBitmap); } } // for each pattern recorded for the s-step for (int k = 0; k < sTemp.size(); k++) { // STRATEGY: NEWWW atLeastOneFrequentExtension = true; int item = sTemp.get(k); // create the new prefix PrefixVMSP prefixSStep = prefix.cloneSequence(); prefixSStep.addItemset(new Itemset(item)); if (item % 2 == 0) { prefixSStep.sumOfEvenItems = item + prefix.sumOfEvenItems; prefixSStep.sumOfOddItems = prefix.sumOfOddItems; } else { prefixSStep.sumOfEvenItems = prefix.sumOfEvenItems; prefixSStep.sumOfOddItems = item + prefix.sumOfOddItems; } // prefixSStep.sumOfItems = item + prefix.sumOfItems; // create the new bitmap Bitmap newBitmap = sTempBitmaps.get(k); // save the pattern to the file if (newBitmap.getSupport() >= minsup) { boolean hasFrequentExtension = false; // recursively try to extend that pattern if (maximumPatternLength > m) { hasFrequentExtension = dfsPruning(prefixSStep, newBitmap, sTemp, sTemp, item, m + 1, item); } if (hasFrequentExtension == false) { savePatternMultipleItems(prefixSStep, newBitmap, m); } } } Map<Integer, Integer> mapSupportItemsEquals = coocMapEquals.get(lastAppendedItem); // ======== I STEPS ======= // Temporary variables List<Integer> iTemp = new ArrayList<Integer>(); List<Bitmap> iTempBitmaps = new ArrayList<Bitmap>(); // for each item in in loop2: for (Integer i : in) { // the item has to be greater than the largest item // already in the last itemset of prefix. if (i > hasToBeGreaterThanForIStep) { // LAST POSITION PRUNING /*if (useLastPositionPruning && lastItemPositionMap.get(i) < prefixBitmap.firstItemsetID) { continue loop2; }*/ // CMAP PRUNING if (useCMAPPruning) { if (mapSupportItemsEquals == null) { continue loop2; } Integer support = mapSupportItemsEquals.get(i); if (support == null || support < minsup) { continue loop2; } } // Perform an i-step with this item and the current prefix. // This creates a new bitmap Bitmap.INTERSECTION_COUNT++; Bitmap newBitmap = prefixBitmap.createNewBitmapIStep(verticalDB.get(i), sequencesSize, lastBitIndex); // If the support is no less than minsup if (newBitmap.getSupport() >= minsup) { // record that item and pattern in temporary variables iTemp.add(i); iTempBitmaps.add(newBitmap); } } } // for each pattern recorded for the i-step for (int k = 0; k < iTemp.size(); k++) { // STRATEGY: NEWWW atLeastOneFrequentExtension = true; int item = iTemp.get(k); // create the new prefix PrefixVMSP prefixIStep = prefix.cloneSequence(); prefixIStep.getItemsets().get(prefixIStep.size() - 1).addItem(item); if (item % 2 == 0) { prefixIStep.sumOfEvenItems = item + prefix.sumOfEvenItems; prefixIStep.sumOfOddItems = prefix.sumOfOddItems; } else { prefixIStep.sumOfEvenItems = prefix.sumOfEvenItems; prefixIStep.sumOfOddItems = item + prefix.sumOfOddItems; } // create the new bitmap Bitmap newBitmap = iTempBitmaps.get(k); // recursively try to extend that pattern boolean hasFrequentExtension = false; if (maximumPatternLength > m) { hasFrequentExtension = dfsPruning(prefixIStep, newBitmap, sTemp, iTemp, item, m + 1, item); } if (hasFrequentExtension == false) { // save the pattern savePatternMultipleItems(prefixIStep, newBitmap, m); } } // check the memory usage MemoryLogger.getInstance().checkMemory(); return atLeastOneFrequentExtension || useStrategyForwardExtensionChecking == false; }
/** * This is the main method for the VMSP algorithm * * @param an input file * @param minsupRel the minimum support as a relative value * @throws IOException */ private void vmsp(String input, double minsupRel) throws IOException { // create maxPattern array maxPatterns = new ArrayList<TreeSet<PatternVMSP>>(20); maxPatterns.add(null); maxPatterns.add(new TreeSet<PatternVMSP>()); // the structure to store the vertical database // key: an item value : bitmap verticalDB = new HashMap<Integer, Bitmap>(); // structure to store the horizontal database List<int[]> inMemoryDB = new ArrayList<int[]>(); // STEP 0: SCAN THE DATABASE TO STORE THE FIRST BIT POSITION OF EACH SEQUENCE // AND CALCULATE THE TOTAL NUMBER OF BIT FOR EACH BITMAP sequencesSize = new ArrayList<Integer>(); lastBitIndex = 0; // variable to record the last bit position that we will use in bitmaps try { // read the file FileInputStream fin = new FileInputStream(new File(input)); BufferedReader reader = new BufferedReader(new InputStreamReader(fin)); String thisLine; int bitIndex = 0; // for each line (sequence) in the file until the end while ((thisLine = reader.readLine()) != null) { // if the line is a comment, is empty or is a // kind of metadata if (thisLine.isEmpty() == true || thisLine.charAt(0) == '#' || thisLine.charAt(0) == '%' || thisLine.charAt(0) == '@') { continue; } // record the length of the current sequence (for optimizations) sequencesSize.add(bitIndex); // split the sequence according to spaces into tokens String tokens[] = thisLine.split(" "); int[] transactionArray = new int[tokens.length]; inMemoryDB.add(transactionArray); for (int i = 0; i < tokens.length; i++) { int item = Integer.parseInt(tokens[i]); transactionArray[i] = item; // if it is not an itemset separator if (item == -1) { // indicate the end of an itemset // increase the number of bits that we will need for each bitmap bitIndex++; } } } // record the last bit position for the bitmaps lastBitIndex = bitIndex - 1; reader.close(); // close the input file } catch (Exception e) { e.printStackTrace(); } // Calculate the absolute minimum support // by multipling the percentage with the number of // sequences in this database // minsup = 163; minsup = (int) Math.ceil((minsupRel * sequencesSize.size())); if (minsup == 0) { minsup = 1; } // System.out.println("minsup : " + minsup); // STEP1: SCAN THE DATABASE TO CREATE THE BITMAP VERTICAL DATABASE REPRESENTATION try { FileInputStream fin = new FileInputStream(new File(input)); BufferedReader reader = new BufferedReader(new InputStreamReader(fin)); String thisLine; int sid = 0; // to know which sequence we are scanning int tid = 0; // to know which itemset we are scanning // for each line (sequence) from the input file while ((thisLine = reader.readLine()) != null) { // split the sequence according to spaces into tokens for (String token : thisLine.split(" ")) { if (token.equals("-1")) { // indicate the end of an itemset tid++; } else if (token.equals("-2")) { // indicate the end of a sequence // determineSection(bitindex - previousBitIndex); // register the sequence length // for the bitmap sid++; tid = 0; } else { // indicate an item // Get the bitmap for this item. If none, create one. Integer item = Integer.parseInt(token); Bitmap bitmapItem = verticalDB.get(item); if (bitmapItem == null) { bitmapItem = new Bitmap(lastBitIndex); verticalDB.put(item, bitmapItem); } // Register the bit in the bitmap for this item bitmapItem.registerBit(sid, tid, sequencesSize); } } } reader.close(); } catch (Exception e) { e.printStackTrace(); } // STEP2: REMOVE INFREQUENT ITEMS FROM THE DATABASE BECAUSE THEY WILL NOT APPEAR IN ANY FREQUENT // SEQUENTIAL PATTERNS List<Integer> frequentItems = new ArrayList<Integer>(); Iterator<Entry<Integer, Bitmap>> iter = verticalDB.entrySet().iterator(); // we iterate over items from the vertical database that we have in memory while (iter.hasNext()) { // we get the bitmap for this item Entry<Integer, Bitmap> entry = (Entry<Integer, Bitmap>) iter.next(); // if the cardinality of this bitmap is lower than minsup if (entry.getValue().getSupport() < minsup) { // we remove this item from the database. iter.remove(); } else { // otherwise, we save this item as a frequent // sequential pattern of size 1 // CHANGED // and we add this item to a list of frequent items // that we will use later. frequentItems.add(entry.getKey()); // END CHANGED } } // SET 2.1 SORT ITEMS BY DESCENDING SUPPORT Collections.sort( frequentItems, new Comparator<Integer>() { @Override public int compare(Integer arg0, Integer arg1) { return verticalDB.get(arg0).getSupport() - verticalDB.get(arg1).getSupport(); } }); // STEP 3.1 CREATE CMAP coocMapEquals = new HashMap<Integer, Map<Integer, Integer>>(frequentItems.size()); coocMapAfter = new HashMap<Integer, Map<Integer, Integer>>(frequentItems.size()); if (useLastPositionPruning) { lastItemPositionMap = new HashMap<Integer, Short>(frequentItems.size()); } for (int[] transaction : inMemoryDB) { short itemsetCount = 0; Set<Integer> alreadyProcessed = new HashSet<Integer>(); Map<Integer, Set<Integer>> equalProcessed = new HashMap<>(); loopI: for (int i = 0; i < transaction.length; i++) { Integer itemI = transaction[i]; Set<Integer> equalSet = equalProcessed.get(itemI); if (equalSet == null) { equalSet = new HashSet<Integer>(); equalProcessed.put(itemI, equalSet); } if (itemI < 0) { itemsetCount++; continue; } // System.out.println(itemsetCount); // update lastItemMap if (useLastPositionPruning) { Short last = lastItemPositionMap.get(itemI); if (last == null || last < itemsetCount) { lastItemPositionMap.put(itemI, itemsetCount); } } Bitmap bitmapOfItem = verticalDB.get(itemI); if (bitmapOfItem == null || bitmapOfItem.getSupport() < minsup) { continue; } Set<Integer> alreadyProcessedB = new HashSet<Integer>(); // NEW boolean sameItemset = true; for (int j = i + 1; j < transaction.length; j++) { Integer itemJ = transaction[j]; if (itemJ < 0) { sameItemset = false; continue; } Bitmap bitmapOfitemJ = verticalDB.get(itemJ); if (bitmapOfitemJ == null || bitmapOfitemJ.getSupport() < minsup) { continue; } // if (itemI != itemJ){ Map<Integer, Integer> map = null; if (sameItemset) { if (!equalSet.contains(itemJ)) { map = coocMapEquals.get(itemI); if (map == null) { map = new HashMap<Integer, Integer>(); coocMapEquals.put(itemI, map); } Integer support = map.get(itemJ); if (support == null) { map.put(itemJ, 1); } else { map.put(itemJ, ++support); } equalSet.add(itemJ); } } else if (!alreadyProcessedB.contains(itemJ)) { if (alreadyProcessed.contains(itemI)) { continue loopI; } map = coocMapAfter.get(itemI); if (map == null) { map = new HashMap<Integer, Integer>(); coocMapAfter.put(itemI, map); } Integer support = map.get(itemJ); if (support == null) { map.put(itemJ, 1); } else { map.put(itemJ, ++support); } alreadyProcessedB.add(itemJ); // NEW } } alreadyProcessed.add(itemI); } } // STEP3: WE PERFORM THE RECURSIVE DEPTH FIRST SEARCH // to find longer sequential patterns recursively if (maximumPatternLength == 1) { return; } // for each frequent item for (Entry<Integer, Bitmap> entry : verticalDB.entrySet()) { // We create a prefix with that item PrefixVMSP prefix = new PrefixVMSP(); prefix.addItemset(new Itemset(entry.getKey())); boolean itemIsEven = entry.getKey() % 2 == 0; if (itemIsEven) { prefix.sumOfEvenItems = (Integer) entry.getKey(); prefix.sumOfOddItems = 0; } else { prefix.sumOfEvenItems = 0; prefix.sumOfOddItems = (Integer) entry.getKey(); } boolean hasExtension = dfsPruning( prefix, entry.getValue(), frequentItems, frequentItems, entry.getKey(), 2, entry.getKey()); if (hasExtension == false) { savePatternSingleItem(entry.getKey(), entry.getValue(), itemIsEven); } // We call the depth first search method with that prefix // and the list of frequent items to try to find // larger sequential patterns by appending some of these // items. // if(!isSubsumedAndNonClosed) { // } } }