package multinomad.tools.kmeansML;

import multinomad.algorithms.EFCL;
import multinomad.config.Configuration;
import multinomad.config.LoadProperties;
import multinomad.individuals.DoubleIndividual;
import multinomad.individuals.Population;
import net.sf.javaml.clustering.KMeans;
import net.sf.javaml.core.Dataset;
import net.sf.javaml.core.DefaultDataset;
import net.sf.javaml.core.DenseInstance;
import net.sf.javaml.core.Instance;

public class SimpleKmeansJavaML {
	
	/**
	 * This class uses java-ml version 0.1.7
	 * 
	 * @param pop - The population to cluster
	 * @param k - The number of centroids/clusters
	 * @param iterations - The number of iterations that kmeans performs. 100 should be sufficient
	 * @return A list with the centroids
	 */
	public static Centroids[] computeCentroidsKmeans(Population pop, int k, int iterations) {
		
		int noAttributes = 0;
		
		Centroids[] centroids = new Centroids[k];
		
		for(int i=0;i<k;i++) centroids[i] = new Centroids();
		
		Dataset dataset = new DefaultDataset();
		for(DoubleIndividual ind : pop) {
			noAttributes = ind.getChr().getLength();
			Instance inst = new DenseInstance(ind.getChr().asdouble());
			dataset.add(inst);
		}
		
		KMeans kmean = new KMeans(k,iterations);
		
		Dataset[] clusters = kmean.cluster(dataset);
		
		for(int i=0;i<clusters.length;i++) {
			double[] acluster = new double[noAttributes];
			for (int j=0;j<noAttributes;j++) acluster[j] = 0;

			for (Instance inst : clusters[i]) {
				int j = 0;	
				for(Double attribute : inst) {
					acluster[j] += attribute.doubleValue();
					j++;
				}
			}
			
			for(int j=0;j<noAttributes;j++) {
				acluster[j] /= clusters[i].size();
				centroids[i].addAttribute(new Double(acluster[j]));
			}
			
		}
		
		return centroids;
	}
	
	public static void main(String[] args) {
		LoadProperties lp = new LoadProperties(args,null);
		Configuration.setConfiguration(lp);
		EFCL efcl = new EFCL();
		Thread t1 =new Thread(efcl);  
		t1.start();		
		try {
			t1.join();
		} catch (InterruptedException e) {}
		
		Population solutions = efcl.getFilteredPop();
		
		Dataset dataset = new DefaultDataset();
		for(DoubleIndividual ind : solutions) {
			Instance inst = new DenseInstance(ind.getChr().asdouble());
			dataset.add(inst);
		}
		
		KMeans kmean = new KMeans(6,100);
		
		Dataset[] clusters = kmean.cluster(dataset);
		
		for(int i=0;i<clusters.length;i++) {
			for (Instance inst : clusters[i]) {
				System.out.print("Cluster "+i+": ");
				for(Double attribute : inst) {
					System.out.print(attribute.doubleValue()+" ");
				}
				System.out.println();
			}
		}
		
		
		
	}
}
