0

I have an algorithm to run and at one of the steps I have to find duplicate pairs in a list called (PairList), count them and eliminate the pairs that are smaller than a specific parameter (minSupp).This is my code for adding the pairs to PairList.

for (int i = sizes.get(sequence.getId())-maxError ; i <= sizes.get(sequence.getId())-1; i++){

             for(int j = i+1; j<sizes.get(sequence.getId()); j++){
                 //Get the first Item 
                int first = sequence.getItemsets().get(i);
                //gets the second Item
                int second =sequence.getItemsets().get(j);
                //Generate pattern as pair
                Pair pattern  = new Pair(first, second);

                sequenceID = sequence.getId();
                //Generate triples with sequence ID and pair
                Triples triples = new Triples(sequenceID, i, j);
                if (!pairList.contains(pattern)){
                    //adds if it doesn't exist
                    pairList.add(pattern);
                }

Now pairList contains some pairs like this: (3, 28) (3, 58) (3, 61) (3, 28) (5, 21) (3, 28) (5, 21) I want to know for instance how many times (3, 28) occurs in this List. and for a (minSupp=2) I want to remove the pairs that occurred less than 2 times So the output should be something like this:

   (3, 28) : 3 
   (3, 58) : 1 (this must be removed)
   (3, 61) : 1 remove
   (5, 21) : 2 

I worked on it and this is my code until now but it gives me an output far too much from what I want so please help!

  for(Pair pair : pairList){
                    int a = Collections.frequency(pairList, pair);

                    for (int i=0 ; i<pairList.size() ; i++){
                        for (int j =i+1 ; j<pairList.size()-1;j++){

                        if (pairList.get(i).getX()==pairList.get(j).getX() && pairList.get(i).getY()==pairList.get(j).getY() ){
                         a++;
                        System.out.println(pair + ": " + a);
                        } 
Hk148
  • 11
  • 4
  • Override `hashCode` and `equals` method of `Pair` class, and use `Collections.frequency()`. – pratZ Jul 27 '14 at 13:46

1 Answers1

0

Collections.frequency() is already enough to find the frequency of a pair in the list if you have implemented equals in your Pair-class. So your nested for-loops are redundant. Removal of the pairs can simply be done via .remove(). If you want each pair to be only printed once you can add the list into a Set and then iterate through that (you will also need to implement hashCode):

for (Pair pair : new HashSet<Pair>(pairList)) { // a set has no double entries
    int frequency = Collections.frequency(pairList, pair);
    System.out.print(pair + " : " + frequency); // print frequency of pair

    if (frequency < minSupp) { // if frequency is too low remove this pair
        while (pairList.remove(pair)); // remove all occurrences of this pair
        System.out.print(" remove");
    }

    System.out.println();
}

For more information on how to properly implement hashCode and equals have a look at this question: What issues should be considered when overriding equals and hashCode in Java?

Community
  • 1
  • 1
i_turo
  • 2,679
  • 1
  • 13
  • 15
  • I implemented equals in my Pair-class and when I try your code it gives me this output (3,28) :1 remove (3,28 ) :1 remove .... So it won't count the frequencies or it won't give me (3, 28) :3 because afterwards I have to use that number again. – Hk148 Jul 27 '14 at 14:12
  • Are you sure that you have implemented `equals` properly? The proposed code works for me. What I forgot is that for getting the *HashSet* to work properly, you also need to override `hashCode`. I have added a link to a pretty good explanation on how to properly override these two methods. – i_turo Jul 27 '14 at 14:53
  • For just quickly testing it I used: `return x + y; // could have collisions!` for `hashCode` and `Pair that = (Pair) y; return this.x == that.x && this.y == that.y;` for `equals`. (**Note**: You should only use that implementations for quick testing and follow the link I added for a proper implementation of these methods afterwards.) – i_turo Jul 27 '14 at 15:01
  • this is my equals from Pair-class . I don't know what is wrong with this? `public boolean equals(Pair pair){` `boolean status = false;` if(this.getX() != pair.getX()){ status = true; } if(this.getY() != pair.getY()){ status = true; } System.out.println(status); return status; } @Override public String toString(){ return "("+x+", "+y+")"; `}` – Hk148 Jul 27 '14 at 16:51
  • `equals` must have an `Object` as a parameter -> `public boolean equals(Object obj)`. You then have to cast the Object to a `Pair` before doing the attribute comparisons. See the link I have added to my answer for detailed information. – i_turo Jul 27 '14 at 17:23