using Clustering Core Common using System using System Collections Gen

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using Clustering.Core.Common;
using System;
using System.Collections.Generic;
namespace Clustering.Core
{
public class KMeansAlgorithm
{
public static List<Cluster> DoClustering(PointCollection points, int clusterCount, int dimension)
{
if (clusterCount > points.Count)
{
throw new Exception("Кількість кластерів не повинна перевищувати кількість точок");
}
var allClusters = new List<PointCollection>();
List<List<Point>> allGroups = ListUtility.SplitList(points, clusterCount);
var findNearestCluster = new Func<Point, int>((point) =>
{
double minimumDistance = 0.0;
int nearestClusterIndex = -1;
for (int clusterIndex = 0; clusterIndex < allClusters.Count; clusterIndex++)
{
double distance = Point.FindDistance(point, allClusters[clusterIndex].GetCenter(), dimension);
if (clusterIndex == 0)
{
minimumDistance = distance;
nearestClusterIndex = 0;
}
else if (minimumDistance > distance)
{
minimumDistance = distance;
nearestClusterIndex = clusterIndex;
}
}
return nearestClusterIndex;
});
foreach (List<Point> group in allGroups)
{
var cluster = new PointCollection(dimension);
cluster.AddRange(group);
allClusters.Add(cluster);
}
int movements = 1;
while (movements > 0)
{
movements = 0;
foreach (PointCollection cluster in allClusters)
{
for (int pointIndex = 0; pointIndex < cluster.Count; pointIndex++)
{
Point point = cluster[pointIndex];
int nearestCluster = findNearestCluster(point);
if (nearestCluster != allClusters.IndexOf(cluster) && cluster.Count > 1)
{
Point removedPoint = cluster.RemovePoint(point);
allClusters[nearestCluster].AddPoint(removedPoint);
movements += 1;
}
}
}
}
var clusters = new List<Cluster>();
foreach (var clusterPoints in allClusters)
{
clusters.Add(new Cluster
{
CenterPoint = clusterPoints.GetCenterPoint(),
Points = clusterPoints
});
}
return clusters;
}
}
}