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);
        }