/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package ca.pfv.spmf.algorithms.sequentialpatterns.gsp_AGP.items; import java.util.List; import ca.pfv.spmf.algorithms.sequentialpatterns.gsp_AGP.items.abstractions.Abstraction_Generic; import ca.pfv.spmf.algorithms.sequentialpatterns.gsp_AGP.items.abstractions.ItemAbstractionPair; import ca.pfv.spmf.algorithms.sequentialpatterns.gsp_AGP.items.creators.AbstractionCreator; import ca.pfv.spmf.algorithms.sequentialpatterns.gsp_AGP.items.patterns.Pattern; /** * In this class a particular pattern is searched in a sequence. This class is a * tool of the class that implements the phase that check the support for a * candidate set. * * Copyright Antonio Gomariz PeƱalver 2013 * * This file is part of the SPMF DATA MINING SOFTWARE * (http://www.philippe-fournier-viger.com/spmf). * * SPMF is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * SPMF is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * SPMF. If not, see <http://www.gnu.org/licenses/>. * * @author agomariz */ public class CandidateInSequenceFinder { AbstractionCreator creator; /** * flag to indicate if a candidate is present in the sequence */ private boolean present = false; /** * Standard constructor. It only needs the abstraction creator. * * @param creator */ public CandidateInSequenceFinder(AbstractionCreator creator) { this.creator = creator; } /** * Recursive method to search for a candidate in a sequence. If the * candidate appears in the sequence, set the flag present to true * * @param candidate to find in the sequence * @param sequence the sequence where we will search for the candidate * @param k the level in which we are in the main loop of GSP, i.e. the * number of items of the candidate * @param length the current element with which we are dealing with. * @param position List of the positions of all of the elements of the * candidate in the sequence */ public void isCandidatePresentInTheSequence_qualitative(Pattern candidate, Sequence sequence, int k, int length, List<int[]> position) { //We get the current pair to deal with ItemAbstractionPair pair = candidate.getIthElement(length); //And we keep its item, Item itemPair = pair.getItem(); //its abstraction Abstraction_Generic abstractionPair = pair.getAbstraction(); // and the previous abstraction Abstraction_Generic previousAbstraction = length > 0 ? candidate.getIthElement(length - 1).getAbstraction() : null; //flag to know if we should cancel the search boolean cancelled = false; //Initialization of the position of the current item, itemPair, to search for int[] pos = null; //while the itemset index that correspond to the current item, itempair, is withing the sequence while (position.get(length)[0] < sequence.size()) { /*If we are dealing with the first element of the candidate, we * search for the item from the beginning of the sequence */ if (length == 0) { pos = sequence.searchForTheFirstAppearance(position.get(length)[0], position.get(length)[1], itemPair); } else { /* * Otherwise, we find that item depending on the temporal relation * between the current abstraction and the previous one */ pos = creator.findPositionOfItemInSequence(sequence, itemPair, abstractionPair, previousAbstraction, position.get(length)[0], position.get(length)[1], position.get(length - 1)[0], position.get(length - 1)[1]); } //If a duple <itemset index, item index> is found if (pos != null) { //We keep it in the current index of the position list position.set(length, pos); //If we are not in the last element of the candidate if (length + 1 < k) { //We establish as a new position the following one int[] newPos = increasePosition(sequence, position.get(length)); //and we keep it in the position of the following item of the candidate position.set(length + 1, newPos); //And we make a recursive call in order to deal with the next element of the candidate isCandidatePresentInTheSequence_qualitative(candidate, sequence, k, length + 1, position); //If the flag is activated, the process is over if (present) { return; } } else { /*If we are in the last element of the candidate, we * have checked that the candidate it appears in the sequence, and we set the corresponding flat to true */ present = true; return; } } else {//If we cannot find a position where the item appears //If we are not in the first element of the candidate if (length > 0) { //we increase the previous position and we update it int[] newPos = increaseItemset(position.get(length - 1)); position.set(length - 1, newPos); } /*We set the flag of cancel to true, in order to end this * execution and come back to the previous call, that to * referred to the previous element of the candidate */ cancelled = true; //And we break the loop break; } } /*if we exceeded the sequence limits we have to try modifying the * previous element position in order to test if we can find any * combination that contains the whole candidate */ if (length > 0 && !cancelled) { int[] newPos = increaseItemset(position.get(length - 1)); position.set(length - 1, newPos); } } /** * It answers if the candidate appears in the sequence * @return true if it appears otherwise flase */ public boolean isPresent() { return present; } /** * Setter of the "present" flag * @param present the present flag value */ public void setPresent(boolean present) { this.present = present; } /** * We move to the next item in the same itemset, returning < currentItemsetIndex, currentItemIndex + 1 >. * If the itemset is exceeded, we change to the next itemset, establishing the item index in 0 and so, in this case, our returning value is < currentItemsetIndex +1 , 0 >. * @param sequence sequence which we are dealing with * @param pos the current position * @return the incremented position */ private int[] increasePosition(Sequence sequence, int[] pos) { int[] newPos; if (pos[1] < sequence.get(pos[0]).size() - 1) { newPos = new int[]{pos[0], pos[1] + 1}; } else { newPos = new int[]{pos[0] + 1, 0}; } return newPos; } /** * It returns a new pair pointing out the beginning of the next itemset to the given current position * @param pos the current position * @return the position of beginning of the new itemset */ private int[] increaseItemset(int[] pos) { int newItemset = pos[0] + 1; int[] newPos = new int[]{newItemset, 0}; return newPos; } }