Index: /trunk/CrossPare/.classpath
===================================================================
--- /trunk/CrossPare/.classpath	(revision 102)
+++ /trunk/CrossPare/.classpath	(revision 103)
@@ -15,16 +15,20 @@
 	<classpathentry kind="lib" path="lib/org.eclipse.ocl.ecore_3.3.0.v20130520-1222.jar"/>
 	<classpathentry kind="lib" path="lib/commons-math3-3.5.jar"/>
+	<classpathentry kind="lib" path="lib/probabilisticSignificanceAE-1.0.2.jar"/>
+	<classpathentry kind="lib" path="lib/alternatingDecisionTrees.jar"/>
+	<classpathentry kind="lib" path="lib/elki-bundle-0.7.1.jar"/>
+	<classpathentry kind="lib" path="lib/guava-19.0.jar"/>
 	<classpathentry kind="lib" path="lib/ojalgo-37.1.jar"/>
-	<classpathentry kind="lib" path="lib/elki-bundle-0.7.1.jar"/>
-	<classpathentry kind="lib" path="lib/alternatingDecisionTrees.jar"/>
-	<classpathentry kind="lib" path="lib/guava-19.0.jar"/>
+	<classpathentry kind="lib" path="lib/jmetal-algorithm-5.0-jar-with-dependencies.jar"/>
 	<classpathentry kind="lib" path="lib/mysql-connector-java-5.1.38-bin.jar"/>
-	<classpathentry kind="lib" path="lib/jmetal-algorithm-5.0-jar-with-dependencies.jar"/>
+	<classpathentry kind="lib" path="lib/jmetal-exec-5.0-jar-with-dependencies.jar"/>
 	<classpathentry kind="lib" path="lib/jmetal-core-5.0-jar-with-dependencies.jar"/>
-	<classpathentry kind="lib" path="lib/jmetal-exec-5.0-jar-with-dependencies.jar"/>
-	<classpathentry kind="lib" path="lib/probabilisticSignificanceAE-1.0.2.jar"/>
 	<classpathentry kind="lib" path="lib/jgap.jar"/>
 	<classpathentry kind="lib" path="lib/commons-lang3-3.4.jar"/>
-	<classpathentry kind="lib" path="lib/commons-dbcp2-2.1.1.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-1.2-api-2.5.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-core-2.5.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-iostreams-2.5.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-api-2.5.jar"/>
+	<classpathentry kind="lib" path="lib/commons-lang-2.6.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: /trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java
===================================================================
--- /trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java	(revision 102)
+++ /trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java	(revision 103)
@@ -1,3 +1,5 @@
 package de.ugoe.cs.cpdp.training;
+
+import java.util.List;
 
 import org.apache.commons.collections4.list.SetUniqueList;
@@ -8,5 +10,5 @@
 import weka.core.Instances;
 import org.apache.commons.lang3.ArrayUtils;
-
+import org.jgap.Configuration;
 import org.jgap.InvalidConfigurationException;
 import org.jgap.gp.CommandGene;
@@ -34,4 +36,6 @@
 import org.jgap.util.ICloneable;
 
+import de.ugoe.cs.cpdp.util.WekaUtils;
+
 import org.jgap.gp.impl.ProgramChromosome;
 import org.jgap.util.CloneException;
@@ -43,5 +47,5 @@
 public class GPTraining implements ISetWiseTrainingStrategy, IWekaCompatibleTrainer  {
     
-    private final GPClassifier classifier = new GPClassifier();
+    private GPVClassifier classifier = new GPVClassifier();
     
     private int populationSize = 1000;
@@ -52,16 +56,15 @@
     @Override
     public void setParameter(String parameters) {
-        System.out.println("setParameters");
+        // todo, which type of classifier? GPV, GPVV?
+        // more config population size, etc.
+        // todo: voting for gpvv only 3 votes necessary?
     }
 
     @Override
     public void apply(SetUniqueList<Instances> traindataSet) {
-        System.out.println("apply");
-        for (Instances traindata : traindataSet) {
-            try {
-                classifier.buildClassifier(traindata);
-            }catch(Exception e) {
-                throw new RuntimeException(e);
-            }
+        try {
+            classifier.buildClassifier(traindataSet);
+        }catch(Exception e) {
+            throw new RuntimeException(e);
         }
     }
@@ -69,5 +72,4 @@
     @Override
     public String getName() {
-        System.out.println("getName");
         return "GPTraining";
     }
@@ -75,5 +77,4 @@
     @Override
     public Classifier getClassifier() {
-        System.out.println("getClassifier");
         return this.classifier;
     }
@@ -85,13 +86,11 @@
         public InstanceData(Instances instances) {
             this.instances_x = new double[instances.numInstances()][instances.numAttributes()-1];
-
+            this.instances_y = new boolean[instances.numInstances()];
+            
             Instance current;
             for(int i=0; i < this.instances_x.length; i++) {
                 current = instances.get(i);
-                for(int j=0; j < this.instances_x[0].length; j++) {
-                    this.instances_x[i][j] = current.value(j);
-                }
-                
-                this.instances_y[i] = current.stringValue(instances.classIndex()).equals("Y");
+                this.instances_x[i] = WekaUtils.instanceValues(current);
+                this.instances_y[i] = 1.0 == current.classValue();
             }
         }
@@ -105,7 +104,7 @@
     }
     
-    public class GPClassifier extends AbstractClassifier {
-
-        private static final long serialVersionUID = 3708714057579101522L;
+    // one gprun, we want several for voting
+    public class GPRun extends AbstractClassifier {
+        private static final long serialVersionUID = -4250422550107888789L;
 
         private int populationSize = 1000;
@@ -126,39 +125,16 @@
         }
         
-        @Override
-        public void buildClassifier(Instances instances) throws Exception {
-            // load instances into double[][] and boolean[]
-            InstanceData train = new InstanceData(instances);
-            this.problem = new CrossPareGP(train.getX(), train.getY(), this.populationSize, this.initMinDepth, this.initMaxDepth, this.tournamentSize);
-            
-            this.gp = problem.create();
-            this.gp.evolve(this.maxGenerations);
-        }
-        
-        @Override
-        public double classifyInstance(Instance instance) {
-            Variable[] vars = ((CrossPareGP)this.problem).getVariables();
-            
-            double[][] x = new double[1][instance.numAttributes()-1];
-            boolean[] y = new boolean[1];
-            
-            for(int i = 0; i < instance.numAttributes()-1; i++) {
-                x[0][i] = instance.value(i);
-            }
-            y[0] = instance.stringValue(instance.classIndex()).equals("Y");
-            
-            CrossPareFitness test = new CrossPareFitness(vars, x, y);
-            IGPProgram fitest = gp.getAllTimeBest();
-            
-            double sfitness = test.evaluate(fitest);
-            
-            // korrekt sind wir wenn wir geringe fitness haben?
-            if(sfitness < 0.5) {
-                return 1.0;
-            }
-            return 0;
-            
-        }
-
+        public GPGenotype getGp() {
+            return this.gp;
+        }
+        
+        public Variable[] getVariables() {
+            return ((CrossPareGP)this.problem).getVariables();
+        }
+        
+        public void setEvaldata(Instances testdata) {
+            
+        }
+        
         /**
          * GPProblem implementation
@@ -166,5 +142,5 @@
         class CrossPareGP extends GPProblem {
             
-            private static final long serialVersionUID = 7526472295622776147L;
+            //private static final long serialVersionUID = 7526472295622776147L;
 
             private double[][] instances;
@@ -175,12 +151,15 @@
             public CrossPareGP(double[][] instances, boolean[] output, int populationSize, int minInitDept, int maxInitDepth, int tournamentSize) throws InvalidConfigurationException {
                 super(new GPConfiguration());
-
+                
                 this.instances = instances;
                 this.output = output;
 
+                Configuration.reset();
                 GPConfiguration config = this.getGPConfiguration();
-
+                //config.reset();
+                
                 this.x = new Variable[this.instances[0].length];
 
+               
                 for(int j=0; j < this.x.length; j++) {
                     this.x[j] = Variable.create(config, "X"+j, CommandGene.DoubleClass);    
@@ -227,5 +206,5 @@
                 Class[][] argTypes = { {} };
 
-                // variables + functions
+                // variables + functions, we set the variables with the values of the instances here
                 CommandGene[] vars = new CommandGene[this.instances[0].length];
                 for(int j=0; j < this.instances[0].length; j++) {
@@ -256,4 +235,5 @@
             }
         }
+
         
         /**
@@ -317,6 +297,6 @@
                     }
 
-                    // value gives us a double, if > 0.5 we set this instance as faulty
-                    value = program.execute_double(0, NO_ARGS);
+                    // value gives us a double, if < 0.5 we set this instance as faulty
+                    value = program.execute_double(0, NO_ARGS);  // todo: test with this.x
 
                     if(value < 0.5) {
@@ -337,5 +317,7 @@
 
                 // number of nodes in the programm, if lower then 10 we assign sFitness of 10
+                // we can set metadata with setProgramData to save this
                 if(program.getChromosome(0).getSize(0) < 10) {
+                    program.setApplicationData(10.0f);
                     this.sfitness = 10.0f;
                     //System.out.println("wenige nodes: "+program.getChromosome(0).getSize(0));
@@ -346,4 +328,209 @@
 
                 return pfitness;
+            }
+        }
+
+        @Override
+        public void buildClassifier(Instances traindata) throws Exception {
+            InstanceData train = new InstanceData(traindata);            
+            this.problem = new CrossPareGP(train.getX(), train.getY(), this.populationSize, this.initMinDepth, this.initMaxDepth, this.tournamentSize);
+            this.gp = problem.create();
+            this.gp.evolve(this.maxGenerations);
+        }
+    }
+    
+    /**
+     * GP Multiple Data Sets Validation-Voting Classifier
+     *
+     *
+     */
+    public class GPVVClassifier extends GPVClassifier {
+        
+        private List<Classifier> classifiers = null;
+        
+        @Override
+        public void buildClassifier(Instances arg0) throws Exception {
+            // TODO Auto-generated method stub
+            
+        }
+        
+        public void buildClassifier(SetUniqueList<Instances> traindataSet) throws Exception {
+
+            // each classifier is trained with one project from the set
+            // then is evaluated on the rest
+            for(int i=0; i < traindataSet.size(); i++) {
+                Classifier classifier = new GPRun();
+                
+                // one project is training data
+                classifier.buildClassifier(traindataSet.get(i));
+                
+                double[] errors;
+                
+                // rest of the set is evaluation data, we evaluate now
+                for(int j=0; j < traindataSet.size(); j++) {
+                    if(j != i) {
+                        // if type1 and type2 errors are < 0.5 we allow the model in the final voting
+                        errors = this.evaluate((GPRun)classifier, traindataSet.get(j));
+                        if((errors[0] / traindataSet.get(j).numInstances()) < 0.5 && (errors[0] / traindataSet.get(j).numInstances()) < 0.5) {
+                            classifiers.add(classifier);                            
+                        }
+                    }
+                }
+            }
+        }
+        
+        /**
+         * Use the remaining classifiers for our voting
+         */
+        @Override
+        public double classifyInstance(Instance instance) {
+            
+            int vote_positive = 0;
+            int vote_negative = 0;
+            
+            for (int i = 0; i < classifiers.size(); i++) {
+                Classifier classifier = classifiers.get(i);
+                
+                GPGenotype gp = ((GPRun)classifier).getGp();
+                Variable[] vars = ((GPRun)classifier).getVariables();
+                
+                IGPProgram fitest = gp.getAllTimeBest();  // all time fitest
+                for(int j = 0; j < instance.numAttributes()-1; j++) {
+                   vars[j].set(instance.value(j));
+                }
+                
+                if(fitest.execute_double(0, vars) < 0.5) {
+                    vote_positive += 1;
+                }else {
+                    vote_negative += 1;
+                }
+            }
+            
+            if(vote_positive >= 3) {
+                return 1.0;
+            }else {
+                return 0.0;
+            }
+        }
+    }
+    
+    /**
+     * GP Multiple Data Sets Validation Classifier
+     * 
+     *
+     * for one test data set:
+     *   for one in 6 possible training data sets:
+     *     For 200 GP Runs:
+     *       train one Classifier with this training data
+     *       then evaluate the classifier with the remaining project
+     *       if the candidate model performs bad (error type1 or type2 > 50%) discard it
+     * for the remaining model candidates the best one is used
+     *
+     */
+    public class GPVClassifier extends AbstractClassifier {
+        
+        private Classifier best = null;
+        
+        private static final long serialVersionUID = 3708714057579101522L;
+
+
+        /** Build the GP Multiple Data Sets Validation Classifier
+         * 
+         * - Traindata one of the Instances of the Set (which one? The firsT? as it is a list?)
+         * - Testdata one other Instances of the Set (the next one? chose randomly?)
+         * - Evaluation the rest of the instances
+         * 
+         * @param traindataSet
+         * @throws Exception
+         */
+        public void buildClassifier(SetUniqueList<Instances> traindataSet) throws Exception {
+
+            // each classifier is trained with one project from the set
+            // then is evaluated on the rest
+            for(int i=0; i < traindataSet.size(); i++) {
+                Classifier classifier = new GPRun();
+                
+                // one project is training data
+                classifier.buildClassifier(traindataSet.get(i));
+                
+                // rest of the set is evaluation data, we evaluate now
+                double smallest_error_count = Double.MAX_VALUE;
+                double[] errors;
+                for(int j=0; j < traindataSet.size(); j++) {
+                    if(j != i) {
+                        errors = this.evaluate((GPRun)classifier, traindataSet.get(j));
+                        if(errors[0]+errors[1] < smallest_error_count) {
+                            this.best = classifier;
+                        }
+                    }
+                }
+            }
+        }
+        
+        @Override
+        public void buildClassifier(Instances traindata) throws Exception {
+            final Classifier classifier = new GPRun();
+            classifier.buildClassifier(traindata);
+            best = classifier;
+        }
+        
+        public double[] evaluate(GPRun classifier, Instances evalData) {
+            GPGenotype gp = classifier.getGp();
+            Variable[] vars = classifier.getVariables();
+            
+            IGPProgram fitest = gp.getAllTimeBest();  // selects the fitest of all not just the last generation
+            
+            double classification;
+            int error_type1 = 0;
+            int error_type2 = 0;
+            int number_instances = evalData.numInstances();
+            
+            for(Instance instance: evalData) {
+                
+                for(int i = 0; i < instance.numAttributes()-1; i++) {
+                    vars[i].set(instance.value(i));
+                }
+                
+                classification = fitest.execute_double(0, vars);
+                
+                // classification < 0.5 we say defective
+                if(classification < 0.5) {
+                    if(instance.classValue() != 1.0) {
+                        error_type1 += 1;
+                    }
+                }else {
+                    if(instance.classValue() == 1.0) {
+                        error_type2 += 1;
+                    }
+                }
+            }
+            
+            double et1_per = error_type1 / number_instances;
+            double et2_per = error_type2 / number_instances; 
+            
+            // return some kind of fehlerquote?
+            //return (error_type1 + error_type2) / number_instances;
+            return new double[]{error_type1, error_type2};
+        }
+        
+        /**
+         * Use only the best classifier from our evaluation phase
+         */
+        @Override
+        public double classifyInstance(Instance instance) {
+            GPGenotype gp = ((GPRun)best).getGp();
+            Variable[] vars = ((GPRun)best).getVariables();
+            
+            IGPProgram fitest = gp.getAllTimeBest();  // all time fitest
+            for(int i = 0; i < instance.numAttributes()-1; i++) {
+               vars[i].set(instance.value(i));
+            }
+            
+            double classification = fitest.execute_double(0, vars);
+            
+            if(classification < 0.5) {
+                return 1.0;
+            }else {
+                return 0.0;
             }
         }
