public HCluster(int id, HCluster left, HCluster right ) { Id = id; Left = left; Right = right; Points = left.Points.Concat(right.Points); }
public HCluster(int id, HCluster left, HCluster right) { Id = id; Left = left; Right = right; Points = left.Points.Concat(right.Points); }
public HCluster Generate(IEnumerable <T> examples, ILinker linker) { // Initialize Linker = linker; var clusters = new List <HCluster>(); var distances = new Dictionary <Tuple <int, int>, double>(); // Load data if (Description == null) { Description = Converter.GetDescription(typeof(T)).BuildDictionaries <T>(examples); } Matrix X = Converter.Convert <T>(examples, Description.Features); // Create a new cluster for each data point for (int i = 0; i < X.Rows; i++) { clusters.Add(new HCluster { Id = i, Points = new Vector[] { X[i, VectorType.Row] } }); } // Set the current closest distance/pair to the first pair of clusters var key = new Tuple <int, int>(0, 0); var distance = 0.0; var clusterId = -1; while (clusters.Count > 1) { var closestClusters = new Tuple <int, int>(0, 1); var smallestDistance = Linker.Distance(clusters[0].Points, clusters[1].Points); // Loop through each of the clusters looking for the two closest for (int i = 0; i < clusters.Count; i++) { for (int j = i + 1; j < clusters.Count; j++) { key = new Tuple <int, int>(clusters[i].Id, clusters[j].Id); // Cache the distance if it hasn't been calculated yet if (!distances.ContainsKey(key)) { distances.Add(key, Linker.Distance(clusters[i].Points, clusters[j].Points)); } // Update closest clusters and distance if necessary distance = distances[key]; if (distance < smallestDistance) { smallestDistance = distance; closestClusters = new Tuple <int, int>(i, j); } } } var min = System.Math.Min(closestClusters.Item1, closestClusters.Item2); var max = System.Math.Max(closestClusters.Item1, closestClusters.Item2); var newCluster = new HCluster(clusterId, clusters[min], clusters[max]); // Remove the merged clusters clusters.RemoveAt(min); clusters.RemoveAt(max - 1); // Add new cluster clusters.Add(newCluster); clusterId += 1; } return(clusters.Single()); }