protected void Compute(IEnumerable <T> Collection, Func <T, T, double> WeightFunction, Func <T, T, double, bool> ConnectionFunction, int?MaxIterations = null) { CWGraph Graph = CreateGraph(Collection, WeightFunction, ConnectionFunction); int IterationIndex = 0; bool isChanged = false; Dictionary <int, double> WeightMap = new Dictionary <int, double>(); do { isChanged = false; IterationIndex++; Randomize(Graph.Vertices); foreach (CWVertex Vertex in Graph.Vertices) { foreach (CWEdge Edge in Vertex.Edges) { if (Edge.GetVertex(Vertex).Edges.Count == 0) { continue; } if (!WeightMap.ContainsKey(Edge.GetVertex(Vertex).Cluster)) { WeightMap.Add(Edge.GetVertex(Vertex).Cluster, 0); } WeightMap[Edge.GetVertex(Vertex).Cluster] += Edge.Weight;// Edge.GetVertex(Vertex).Edges.Sum(edge => edge.Weight); } if (WeightMap.Count == 0) { continue; } KeyValuePair <int, double> Max = GetMaxPair(WeightMap); if (Max.Key != Vertex.Cluster) { isChanged = true; Vertex.Cluster = Max.Key; } WeightMap.Clear(); } }while (isChanged || (MaxIterations.HasValue && IterationIndex >= MaxIterations.Value)); _Clusters = Graph.Vertices.GroupBy(c => c.Cluster).Select(group => group.AsEnumerable().Select(v => v.Source)).ToList(); }
protected CWGraph CreateGraph(IEnumerable <T> Collection, Func <T, T, double> WeightFunction, Func <T, T, double, bool> ConnectionFunction) { CWGraph Graph = new CWGraph(); if (Collection is ICollection <T> ) { Graph.Vertices = new List <CWVertex>(((ICollection <T>)Collection).Count); } else { Graph.Vertices = new List <CWVertex>(); } foreach (T Source in Collection) { CWVertex Vertex = new CWVertex() { Source = Source }; Vertex.Cluster = Vertex.GetHashCode(); Graph.Vertices.Add(Vertex); } for (int i = 0; i < Graph.Vertices.Count; i++) { for (int j = i + 1; j < Graph.Vertices.Count; j++) { double Weight = WeightFunction(Graph.Vertices[i].Source, Graph.Vertices[j].Source); if (ConnectionFunction == null || ConnectionFunction(Graph.Vertices[i].Source, Graph.Vertices[j].Source, Weight)) { CWEdge Edge = new CWEdge() { Vertex1 = Graph.Vertices[i], Vertex2 = Graph.Vertices[j], Weight = Weight }; Graph.Vertices[i].Edges.Add(Edge); Graph.Vertices[j].Edges.Add(Edge); } } } return(Graph); }