Index: trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java
===================================================================
--- trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java	(revision 103)
+++ trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java	(revision 104)
@@ -1,4 +1,5 @@
 package de.ugoe.cs.cpdp.training;
 
+import java.util.LinkedList;
 import java.util.List;
 
@@ -47,5 +48,5 @@
 public class GPTraining implements ISetWiseTrainingStrategy, IWekaCompatibleTrainer  {
     
-    private GPVClassifier classifier = new GPVClassifier();
+    private GPVVClassifier classifier = new GPVVClassifier();
     
     private int populationSize = 1000;
@@ -342,5 +343,7 @@
     /**
      * GP Multiple Data Sets Validation-Voting Classifier
-     *
+     * 
+     * As the GP Multiple Data Sets Validation Classifier
+     * But here we do keep a model candidate for each training set which may later vote
      *
      */
@@ -360,21 +363,48 @@
             // 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));
-                
+                
+                // candidates we get out of evaluation
+                LinkedList<Classifier> candidates = new LinkedList<>();
+                
+                // 200 runs
+                
+                for(int k=0; k < 200; k++) {
+                    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) {
+                                candidates.add(classifier);                            
+                            }
+                        }
+                    }
+                }
+                
+                // now after the evaluation we do a model selection where only one model remains for the given training data
+                double smallest_error_count = Double.MAX_VALUE;
                 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);                            
+                Classifier best = null;
+                for(int ii=0; ii < candidates.size(); ii++) {
+                    for(int j=0; j < traindataSet.size(); j++) {
+                        if(j != i) {
+                            errors = this.evaluate((GPRun)candidates.get(ii), traindataSet.get(j));
+                            
+                            if(errors[0]+errors[1] < smallest_error_count) {
+                                best = candidates.get(ii);
+                            }
                         }
                     }
                 }
+                
+                // now we have the best classifier for this training data
+                classifiers.add(best);
+                
             }
         }
@@ -407,5 +437,5 @@
             }
             
-            if(vote_positive >= 3) {
+            if(vote_positive >= (classifiers.size()/2)) {
                 return 1.0;
             }else {
@@ -430,6 +460,7 @@
     public class GPVClassifier extends AbstractClassifier {
         
+        private List<Classifier> classifiers = null;
         private Classifier best = null;
-        
+
         private static final long serialVersionUID = 3708714057579101522L;
 
@@ -449,19 +480,66 @@
             // 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
+                
+                // candidates we get out of evaluation
+                LinkedList<Classifier> candidates = new LinkedList<>();
+                
+                // 200 runs
+                for(int k=0; k < 200; k++) {
+                    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) {
+                                candidates.add(classifier);                            
+                            }
+                        }
+                    }
+                }
+                
+                // now after the evaluation we do a model selection where only one model remains per training data set
+                // from that we chose the best model
+                
+                // now after the evaluation we do a model selection where only one model remains for the given training data
                 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;
+                Classifier best = null;
+                for(int ii=0; ii < candidates.size(); ii++) {
+                    for(int j=0; j < traindataSet.size(); j++) {
+                        if(j != i) {
+                            errors = this.evaluate((GPRun)candidates.get(ii), traindataSet.get(j));
+                            
+                            if(errors[0]+errors[1] < smallest_error_count) {
+                                best = candidates.get(ii);
+                            }
                         }
                     }
+                }
+                
+                // now we have the best classifier for this training data
+                classifiers.add(best);
+            }
+            
+            // now determine the best classifier for all training data
+            double smallest_error_count = Double.MAX_VALUE;
+            double error_count;
+            double errors[];
+            for(int j=0; j < classifiers.size(); j++) {
+                error_count = 0;
+                Classifier current = classifiers.get(j);
+                for(int i=0; i < traindataSet.size(); i++) {
+                    errors = this.evaluate((GPRun)current, traindataSet.get(i));
+                    error_count = errors[0] + errors[1];
+                }
+                
+                if(error_count < smallest_error_count) {
+                    best = current;
                 }
             }
@@ -472,5 +550,5 @@
             final Classifier classifier = new GPRun();
             classifier.buildClassifier(traindata);
-            best = classifier;
+            classifiers.add(classifier);
         }
         
