コード例 #1
0
ファイル: HCData.cs プロジェクト: lionsoon/HCWpf
        public static HCCluster Join(HCCluster a, HCCluster b)
        {
            List <HCPoint> pointList = new(a.Points);

            pointList.AddRange(b.Points);
            return(new(pointList));
        }
コード例 #2
0
ファイル: HCData.cs プロジェクト: lionsoon/HCWpf
        public static List <HCCluster> ClusterPerPoint(List <HCPoint> points)
        {
            List <HCCluster> clusters = new();

            foreach (HCPoint p in points)
            {
                clusters.Add(HCCluster.FromSinglePoint(p));
            }
            return(clusters);
        }
コード例 #3
0
ファイル: Metric.cs プロジェクト: lionsoon/HCWpf
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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
                                     ));
        }
コード例 #6
0
ファイル: HCData.cs プロジェクト: lionsoon/HCWpf
 public HCClusterPair(HCCluster clusterI, HCCluster clusterJ, double distance)
 {
     I        = clusterI;
     J        = clusterJ;
     Distance = distance;
 }
コード例 #7
0
ファイル: Metric.cs プロジェクト: lionsoon/HCWpf
 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)));
 }