@Override
	public void train(Matrix features, Matrix labels, int k) throws Exception {

		
		double[][] adjacencyMatrix = initializeAdjacencyMatrix(features);
		
		String[] clusterNames = new String[features.rows()];
		for (int i = 0; i < features.rows(); i++) {
			clusterNames[i] = i + "";
		}
		
		
		// Change this to change the given linking rule.
//		LinkingRule howToCluster = new SingleLinkingRule();
		LinkingRule howToCluster = new CompleteLinkingRule();
//		LinkingRule howToCluster = new AverageLinkingRule();
		
		// Main clustering algorithm
		ClusteringAlgorithm algorithm = new ClusteringAlgorithm();
		System.out.println("k = " + k);
		List<Cluster> finalClusters = 
				algorithm.performClustering(adjacencyMatrix
										  , clusterNames
										  , howToCluster
										  , k
										  , features);
		int counter = 0;
		double totalSSE = 0;
		System.out.println("=`=`=`=`=`=`=`=`=`=`=`=`=`=`=`\n");
		System.out.println("FINAL\n");
		for (Cluster finalCluster : finalClusters) {
			Set<Integer> instances = new HashSet<Integer>();
			finalCluster.findChildren(instances);
			finalCluster.setAllInstances(instances);
			finalCluster.updateCentroid(features);
			totalSSE += finalCluster.getSSE(features);
			System.out.println("Cluster " + counter);
			printCentroids(features, finalCluster);
			counter++;
		}
		
		System.out.println("Total SSE : " + totalSSE);
		
		double min = 100000;
		for (Cluster finalCluster : finalClusters) {
			for (Cluster otherCluster : finalClusters) {
				if (otherCluster != finalCluster) {
					double distance = 
							getEuclidDistance(otherCluster.getCentroid()
									, finalCluster.getCentroid()
									, features);
					if (min > distance)
						min = distance;
				}
			}
		}
//		System.out.println(min);
//		System.out.println(totalSSE);
//		DendrogramPanel dp = new DendrogramPanel();
//		dp.setModel(finalCluster);
//		displayDendrogram(finalCluster);
		
	}