From 220c8e529c986c062dcd188ce1dff1121e04bff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Thu, 22 Aug 2024 10:14:20 +0200 Subject: [PATCH] Added ClassIterator to Classification --- .../inria/moex/classapp/Classification.java | 102 +++++++++++++++--- 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/src/fr/inria/moex/classapp/Classification.java b/src/fr/inria/moex/classapp/Classification.java index 4d53a36..4b767f2 100644 --- a/src/fr/inria/moex/classapp/Classification.java +++ b/src/fr/inria/moex/classapp/Classification.java @@ -45,12 +45,13 @@ import java.util.Random; import java.lang.ProcessBuilder; import java.lang.Process; +import java.lang.Iterable; import java.util.BitSet; // Used for classification guess mask! import java.util.Vector; import java.util.Arrays; -import java.util.Hashtable; import java.util.Enumeration; +import java.util.Iterator; import java.io.PrintStream; import java.io.BufferedOutputStream; @@ -64,7 +65,7 @@ import org.slf4j.LoggerFactory; * Structure of the Classication board */ -public class Classification { +public class Classification implements Iterable<Classification> { final static Logger logger = LoggerFactory.getLogger( Classification.class ); static int NBFEATURES = Feature.NBFEATURES; @@ -79,6 +80,9 @@ public class Classification { // The feature on which this node is split public Feature feature = null; + // JE: pattern should be set for all classes... + public int[] pattern; + // The bitset corresponding to the class (or cards belonging there?) // This is actually the ClassPattern of the class... is it? // May be a CardSet... or not... but should be... @@ -89,9 +93,12 @@ public class Classification { static Random generator = new Random(); + // JE2024: Empty top class public Classification() { + // pattern = new int[] = {-1, -1, -1, -1}; } + // JE2024: Empty top class divided by features public Classification ( Feature f ) { feature = f; if ( f != null ) { @@ -99,6 +106,7 @@ public class Classification { } } + // JE2024: Taken can be replaced by pattern public Classification( int level, int forks, boolean[] taken, boolean exact ) { if ( forks != 0) { // draw spliting feature @@ -150,6 +158,26 @@ public class Classification { return new Classification( levels, nbforks, new boolean[NBFEATURES], exact ); } + public boolean eqClass( Classification cl ) throws Exception { + if ( this == cl ) return true; + // I must find the meaning of the classification: + // could use cards, but must be filled + for( int i = 0; i < NBFEATURES; i++ ) { + if ( this.pattern[i] != cl.pattern[i] ) return false; + } + return true; + } + + // JE2024: Taken can be replaced by pattern + public int[] classPattern( int color, int shape, int filling, int number ) { + pattern = new int[4]; + pattern[0] = color; + pattern[1] = shape; + pattern[2] = filling; + pattern[3] = number; + return pattern; + } + /** * Make leave traversing an iterator!! */ @@ -159,6 +187,8 @@ public class Classification { */ private void fillLeaves() { fillLeaves( -1, -1, -1, -1 ); } private void fillLeaves( int color, int shape, int filling, int number ) { + // JE2024: fill patterns + pattern = classPattern( color, shape, filling, number); if ( subTree == null ) { cards = new CardSet(); // Fill it @@ -205,17 +235,6 @@ public class Classification { public CardSet getClass( int number, int filling, int shape, int color ) { return getClassification( number, filling, shape, color ).cards; - /*if ( feature == null ) { - return cards; - } else { - switch ( feature ) { - case COLOR: return subTree[color].getClass( number, filling, shape, color ); - case SHAPE: return subTree[shape].getClass( number, filling, shape, color ); - case FILLING: return subTree[filling].getClass( number, filling, shape, color ); - case NUMBER: return subTree[number].getClass( number, filling, shape, color ); - default: return null; // or throws Exception? (should never happen) - } - }*/ } public Classification getClassification( int number, int filling, int shape, int color ) { @@ -689,15 +708,70 @@ public class Classification { } } } + + public Iterator<Classification> iterator() { + return new ClassIterator( this ); + } + +} + +class ClassIterator implements Iterator<Classification> { + + // Classification piles + private Classification classif; + + static int NBFEATURES = Feature.NBFEATURES; + static int NBVALUES = Card.NBVALUES; + + // We need to record the pile of super classes and where we are + private Classification[] prevClasses; + private int[] prevRank; + private int current; + + ClassIterator( Classification cl ){ + classif = cl; + prevClasses = new Classification[NBFEATURES]; + prevRank = new int[NBFEATURES]; + int current = -1; + } + public boolean hasNext(){ + return ( classif != null ); + } + public Classification next() { + Classification result = classif; + // compute the next one + if ( classif.subTree != null ) { // or feature: PUSH + current++; + prevClasses[current] = classif; + prevRank[current] = 0; + classif = prevClasses[current].subTree[prevRank[current]]; + } else { // we are in a leave: POP + while ( current != -1 && prevRank[current] == NBVALUES-1 ) current--; + //System.err.println( "C: "+current+"prevRank[current] : "+prevRank[current] ); + if ( prevRank[current] != NBVALUES-1 && prevClasses[current] != null ) { // NEXT + prevRank[current] = prevRank[current] + 1; + classif = prevClasses[current].subTree[prevRank[current]]; + } else { + classif = null; + } + } + // return the other + return result; + } } + /** * TODO * the idea is that it returns classifications which are leaves... * We are not far! **/ +/** + * TODO + * We want also iterate on all classes... + **/ /* -class LeaveIterator implements Iterator<Classificationn> { +class LeaveIterator implements Iterator<Classification> { //private int currentIndex = 0; private Classification classif; -- GitLab