public static HCCluster Join(HCCluster a, HCCluster b) { List <HCPoint> pointList = new(a.Points); pointList.AddRange(b.Points); return(new(pointList)); }
public static List <HCCluster> ClusterPerPoint(List <HCPoint> points) { List <HCCluster> clusters = new(); foreach (HCPoint p in points) { clusters.Add(HCCluster.FromSinglePoint(p)); } return(clusters); }
public static double SingleLinkage(HCCluster a, HCCluster b) { double minDistance = double.PositiveInfinity; for (var i = 0; i < a.Points.Count; i++) { for (var j = 0; j < b.Points.Count; j++) { minDistance = Math.Min(minDistance, Metric.Euclid(a.Points[i], b.Points[j])); } } return(minDistance); }
public bool Step() { var prevIteration = State.Iterations.Last(); if (prevIteration.Clusters.Count <= 1) { return(false); } if (MinClusters > 0 && prevIteration.Clusters.Count <= MinClusters) { return(false); } if (DistanceLimit > 0 && prevIteration.ClosestPair.Distance >= DistanceLimit) { return(false); } HCCluster clusterI = prevIteration.ClosestPair.I; HCCluster clusterJ = prevIteration.ClosestPair.J; HCCluster joinedCluster = HCCluster.Join(clusterI, clusterJ); List <HCCluster> newClusters = new(); foreach (HCCluster oldCluster in prevIteration.Clusters) { if (oldCluster != clusterI && oldCluster != clusterJ) { newClusters.Add(oldCluster); } } var closest = distanceMatrix.FindClosestPair( clusterPairs: joinedCluster.PairsWith(newClusters), metric: (joinedCluster, other) => distanceMatrix.LanceWillamsSingleLinkage(clusterI, clusterJ, other) ); newClusters.Add(joinedCluster); if (closest.Distance > prevIteration.ClosestPair.Distance) { closest = distanceMatrix.FindClosestPair( clusterPairs: HCCluster.AllPairs(newClusters), metric: distanceMatrix.GetDistance ); } State.Iterations.Add(new HCIteration( clusters: newClusters, closestPair: closest )); return(true); }
public void InitState(List <HCPoint> points) { State = new(); List <HCCluster> clusters = HCCluster.ClusterPerPoint(points); HCClusterPair closest = distanceMatrix.FindClosestPair( clusterPairs: HCCluster.AllPairs(clusters), metric: Metric.SingleLinkage ); State.Iterations.Add(new HCIteration( clusters: clusters, closestPair: closest )); }
public HCClusterPair(HCCluster clusterI, HCCluster clusterJ, double distance) { I = clusterI; J = clusterJ; Distance = distance; }
public static double LanceWillamsSingleLinkage(this IDistanceMatrix dm, HCCluster joinedA, HCCluster joinedB, HCCluster other) { return(0.5 * dm.GetDistance(joinedA, other) + 0.5 * dm.GetDistance(joinedB, other) - 0.5 * Math.Abs(dm.GetDistance(joinedA, other) - dm.GetDistance(joinedB, other))); }