package medusa.georgios.ClusteringAlgorithms;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;

public class Kmeans_backup {

    public static final float MAXVAL = Float.MAX_VALUE;
    public static final float R = 0.999f;        // See Spaeth, p. 103
    private int distance_mode = 1;	// 1: eucileadian distance; 2: cosine similarity
    StringBuffer result;
    public Hashtable GiveNodeName_Get_Cluster = new Hashtable();
    float Threshold = 0.0001f;
    public int k = 2;
    int rows, columns;
    float distance[][];
    ArrayList labels;

    public Kmeans_backup(int k, float distance[][], int rows, int columns) {
        this.k = k;
        this.distance = distance;
        this.rows = rows;
        this.columns = columns;
    }

    public Kmeans_backup(int k, float distance[][], ArrayList labels_tmp) {
        this.k = k;
        this.labels = labels_tmp;
        this.distance = distance;
        this.rows = distance.length;
        this.columns = distance.length;
        this.distance_mode = 1;
    }

    public void setDistanceMode(int mode) {
        distance_mode = mode;
    }

    public String perform_and_get_results() {
        result = new StringBuffer("----------------- Cluster: 1 -----------------\n");
        GiveNodeName_Get_Cluster.clear();
        int[] cluster_result = this.performKmeans();
        int[] id = new int[cluster_result.length];
        int i, j;

        for (i = 0; i < cluster_result.length; i++) {
            id[i] = i;
        }
        for (i = 0; i < cluster_result.length - 1; i++) {
            for (j = i + 1; j < cluster_result.length; j++) {
                if (cluster_result[i] > cluster_result[j]) {
                    int temp = cluster_result[i];
                    cluster_result[i] = cluster_result[j];
                    cluster_result[j] = temp;
                    int temp2 = id[i];
                    id[i] = id[j];
                    id[j] = temp2;
                }
            }
        }
        for (i = 0; i < cluster_result.length; i++) {
            if (i > 0 && cluster_result[i] != cluster_result[i - 1]) {
                result.append("\n----------------- Cluster: " + cluster_result[i] + " -----------------\n");
            }
            result.append(labels.get(id[i]) + "\n");
        }

        for (i = 0; i < cluster_result.length; i++) {
            GiveNodeName_Get_Cluster.put(labels.get(id[i]), cluster_result[i] - 1);
        }

        String str = result.toString();
        //Save_To_File("Kmeans_clustering"+this.k+".txt",str);

        return str;
    }

    public String getReport() {
        return result.toString();
    }

    public void Save_To_File(String filename, String information) {
        try {
            BufferedWriter outp = new BufferedWriter(new FileWriter(filename));
            outp.append(information);
            outp.close();
        } catch (IOException e) {
        }

    }

    public int[] performKmeans() {
        //System.out.println("hello, start to do K-means clustering...");
        int n = rows;
        int m = columns;
        int assignment[] = new int[n];

        float temp1[] = new float[columns];
        float temp2[] = new float[columns];
        MatrixClustering centers = new MatrixClustering(k, columns, 0);
        MatrixClustering old_centers;
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < columns; j++) {
                centers.set(i, j, distance[i][j]);
            }
        }
        MatrixClustering I = new MatrixClustering(k, k, 0);
        for (int i = 0; i < k; i++) {
            I.set(i, i, 1);
        }
        int niters = 500;
        MatrixClustering tempDistance = new MatrixClustering(rows, k, 0);
        float ss_[] = new float[columns];
        float min_[] = new float[rows];
        int index_[] = new int[rows];
        MatrixClustering post = new MatrixClustering(rows, k, 0);
        int num_of_points[] = new int[k];
        int i;
        for (int count_ = 0; count_ < niters; count_++) {
            System.out.println("iteration " + count_);
            old_centers = centers.copy();


            for (int ii = 0; ii < rows; ii++) {
                for (int jj = 0; jj < k; jj++) {
                    for (int kk = 0; kk < columns; kk++) {
                        temp1[kk] = distance[ii][kk];
                        temp2[kk] = centers.get(jj, kk);
                    }
                    tempDistance.set(ii, jj, eDistance(temp1, temp2));
                }
            }
            //tempDistance.print(10, 5);
            for (int ii = 0; ii < rows; ii++) {
                min_[ii] = tempDistance.get(ii, 0);
                index_[ii] = 0;
                for (int jj = 1; jj < k; jj++) {
                    float temp_ = tempDistance.get(ii, jj);
                    if (temp_ < min_[ii]) {
                        min_[ii] = temp_;
                        index_[ii] = jj;
                    }
                }
            }
            //System.out.print("min_, and index_:");
			/*
            for (i = 0; i < rows; i ++)
            System.out.print(" " + min_[i]);
            for (i = 0; i < rows; i ++)
            System.out.print(" " + index_[i]);
             */

            for (i = 0; i < rows; i++) {
                for (int ii = 0; ii < k; ii++) {
                    post.set(i, ii, I.get(index_[i], ii));
                }
            }
            //post.print(10, 5);
            for (i = 0; i < k; i++) {
                int sum_ = 0;
                for (int ii = 0; ii < rows; ii++) {
                    sum_ += post.get(ii, i);
                }
                num_of_points[i] = (int) sum_;
            }
            /*
            System.out.print("\nnumber of points:");
            for (i = 0; i < k; i ++)
            System.out.print(" " + num_of_points[i]); */

            for (i = 0; i < k; i++) {		//for each center
                if (num_of_points[i] > 0) {	//cluster the points belonging to the center
                    for (int vv = 0; vv < columns; vv++) {
                        ss_[vv] = 0.0f;
                    }
                    for (int kk = 0; kk < rows; kk++) {
                        if (post.get(kk, i) == 1) {//sum this vector kk distance to center i;								
                            for (int mm = 0; mm < columns; mm++) {
                                ss_[mm] += distance[kk][mm];
                            }
                        }

                    }
                    for (int mm = 0; mm < columns; mm++) {
                        centers.set(i, mm, ss_[mm] / num_of_points[i]);
                    }
                }
            }
            //centers.print(10, 5);
            float maxDistance = 0;
            for (int ii = 0; ii < k; ii++) {
                for (int kk = 0; kk < columns; kk++) {
                    temp1[kk] = old_centers.get(ii, kk);
                    temp2[kk] = centers.get(ii, kk);
                }
                float temp = eDistance(temp1, temp2);
                if (maxDistance < temp) {
                    maxDistance = temp;
                }
            }
            if (maxDistance < Threshold) {
                count_ = niters + 1;
            }
        }
        int cluster_result[] = new int[rows];
        for (i = 0; i < rows; i++) {
            for (int ii = 0; ii < k; ii++) {
                if (post.get(i, ii) == 1.0) {
                    cluster_result[i] = ii + 1;
                }
            }
        }

        //for (int ii = 0; ii < rows; ii ++)
        //System.out.print(" " + cluster_result[ii]); 
        return cluster_result;

    }

    protected float eDistance(float vector1[], float vector2[]) {
        float d = 0;
        if (distance_mode == 1) { //Euclidean distance
            for (int i = 0; i < columns; i++) {
                d = d + 0.5f * (vector1[i] - vector2[i]) * (vector1[i] - vector2[i]);
            //return Math.sqrt(d);
            }
        }
        if (distance_mode == 2) { //cosine distance measurement
            float acc1 = 0, acc2 = 0, acc0 = 0;
            for (int i = 0; i < columns; i++) {
                acc0 += vector1[i] * vector2[i];
                acc1 += vector1[i] * vector1[i];
                acc2 += vector2[i] * vector2[i];
            }
            d = acc0 / (float) Math.sqrt(acc1 * acc2);
            d = 1 / (d + 1); 	//in cosine distance, the bigger the value, the smaller the distance...
        }
        return d;
    }
}  // PCAcorr
 

Ads help maintain this website.