private static void RunConnectedComponentsAndCheck <TVertex, TEdge>( [NotNull] IUndirectedGraph <TVertex, TEdge> graph) where TEdge : IEdge <TVertex> { var algorithm = new ConnectedComponentsAlgorithm <TVertex, TEdge>(graph); algorithm.Compute(); Assert.AreEqual(graph.VertexCount, algorithm.Components.Count); if (graph.VertexCount == 0) { Assert.IsTrue(algorithm.ComponentCount == 0); return; } Assert.Positive(algorithm.ComponentCount); Assert.LessOrEqual(algorithm.ComponentCount, graph.VertexCount); foreach (KeyValuePair <TVertex, int> pair in algorithm.Components) { Assert.GreaterOrEqual(pair.Value, 0); Assert.IsTrue(pair.Value < algorithm.ComponentCount, $"{pair.Value} < {algorithm.ComponentCount}"); } foreach (TVertex vertex in graph.Vertices) { foreach (TEdge edge in graph.AdjacentEdges(vertex)) { Assert.AreEqual(algorithm.Components[edge.Source], algorithm.Components[edge.Target]); } } }
public void Constructor() { var graph = new UndirectedGraph <int, Edge <int> >(); var components = new Dictionary <int, int>(); var algorithm = new ConnectedComponentsAlgorithm <int, Edge <int> >(graph); AssertAlgorithmProperties(algorithm, graph); algorithm = new ConnectedComponentsAlgorithm <int, Edge <int> >(graph, components); AssertAlgorithmProperties(algorithm, graph); algorithm = new ConnectedComponentsAlgorithm <int, Edge <int> >(null, graph, components); AssertAlgorithmProperties(algorithm, graph); #region Local function void AssertAlgorithmProperties <TVertex, TEdge>( ConnectedComponentsAlgorithm <TVertex, TEdge> algo, IUndirectedGraph <TVertex, TEdge> g) where TEdge : IEdge <TVertex> { AssertAlgorithmState(algo, g); Assert.AreEqual(0, algo.ComponentCount); CollectionAssert.IsEmpty(algo.Components); } #endregion }
public ComponentWithEdges CheckComponentsWithEdges() { var componentsAlgorithm = new ConnectedComponentsAlgorithm <TVertex, TEdge>(_graph); componentsAlgorithm.Compute(); bool[] hasEdgesInComponent = new bool[componentsAlgorithm.ComponentCount]; foreach (KeyValuePair <TVertex, int> verticesAndComponent in componentsAlgorithm.Components) { hasEdgesInComponent[verticesAndComponent.Value] = !_graph.IsAdjacentEdgesEmpty(verticesAndComponent.Key); } TrueIndexes trueIndexes = FirstAndSecondIndexOfTrue(hasEdgesInComponent); if (!trueIndexes.FirstIndex.HasValue) { return(ComponentWithEdges.NoComponent); } if (trueIndexes.SecondIndex.HasValue) { return(ComponentWithEdges.ManyComponents); } return(ComponentWithEdges.OneComponent); }
public void TwoComponents() { var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 3), new Edge <int>(4, 2), new Edge <int>(4, 3), new Edge <int>(5, 6), new Edge <int>(5, 7), new Edge <int>(7, 6) }); var algorithm = new ConnectedComponentsAlgorithm <int, Edge <int> >(graph); algorithm.Compute(); Assert.AreEqual(2, algorithm.ComponentCount); CollectionAssert.AreEquivalent( new Dictionary <int, int> { [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 1, [6] = 1, [7] = 1 }, algorithm.Components); }
public static IDictionary <int, int> Get(UndirectedGraph <int, Edge <int> > g) { var algorithm = new ConnectedComponentsAlgorithm <int, Edge <int> >(g); algorithm.Compute(); return(algorithm.Components); }
public static IDictionary <string, int> Get(UndirectedGraph <string, TaggedEdge <string, string> > g) { var algorithm = new ConnectedComponentsAlgorithm <string, TaggedEdge <string, string> >(g); algorithm.Compute(); return(algorithm.Components); }
public int getGCC() { int max = 0; int[] maxs; var x = new ConnectedComponentsAlgorithm <int, UndirectedEdge <int> >(g); x.Compute(); maxs = new int[x.ComponentCount]; IEnumerator <KeyValuePair <int, int> > enumerator = x.Components.GetEnumerator(); //Console.WriteLine("Value : " + enumerator.Current.Value); //maxs[enumerator.Current.Value]++; while (enumerator.MoveNext()) { //Console.WriteLine("Value : " + enumerator.Current.Value); maxs[enumerator.Current.Value]++; } for (int i = 0; i < x.ComponentCount; i++) { if (maxs[i] > max) { max = maxs[i]; } } return(max); }
private static void Compute <TVertex, TEdge>([NotNull] IUndirectedGraph <TVertex, TEdge> graph) where TEdge : IEdge <TVertex> { var dfs = new ConnectedComponentsAlgorithm <TVertex, TEdge>(graph); dfs.Compute(); if (graph.VertexCount == 0) { Assert.IsTrue(dfs.ComponentCount == 0); return; } Assert.IsTrue(0 < dfs.ComponentCount); Assert.IsTrue(dfs.ComponentCount <= graph.VertexCount); foreach (KeyValuePair <TVertex, int> pair in dfs.Components) { Assert.IsTrue(0 <= pair.Value); Assert.IsTrue(pair.Value < dfs.ComponentCount, $"{pair.Value} < {dfs.ComponentCount}"); } foreach (TVertex vertex in graph.Vertices) { foreach (TEdge edge in graph.AdjacentEdges(vertex)) { Assert.AreEqual(dfs.Components[edge.Source], dfs.Components[edge.Target]); } } }
/// <summary> /// Выполнить кластеризацию. /// </summary> /// <param name="data">Исходные данные.</param> /// <param name="outData">Множество точек, которые являются представителями кластеров.</param> public void Learn(Point[] data, out Point[] outData) { outData = new Point[K]; // 1. Построим граф. UndirectedGraph <int, WeightedEdge <int> > graph = new UndirectedGraph <int, WeightedEdge <int> >(true); InitDistMatrix(data); double min = _minDistBetweenTwoPoints.Min(); int index = Array.FindIndex(_minDistBetweenTwoPoints, el => Math.Abs(el - min) < double.Epsilon); int firstVertex = index; int secondVertex = _numVertex[index]; graph.AddVertex(firstVertex); graph.AddVertex(secondVertex); graph.AddEdge(new WeightedEdge <int>(firstVertex, secondVertex, min)); _points.Remove(firstVertex); _points.Remove(secondVertex); while (_points.Count != 0) { double minDist = double.MaxValue; foreach (int vertexGraph in graph.Vertices) { foreach (int point in _points) { double currDist = _distMatrix[vertexGraph, point]; if (Math.Abs(currDist) < double.Epsilon) { currDist = _distMatrix[point, vertexGraph]; } if (currDist < minDist) { firstVertex = vertexGraph; secondVertex = point; minDist = _distMatrix[vertexGraph, point]; } } } graph.AddVertex(firstVertex); graph.AddVertex(secondVertex); graph.AddEdge(new WeightedEdge <int>(firstVertex, secondVertex, minDist)); _points.Remove(firstVertex); _points.Remove(secondVertex); } // 2. Удалим K − 1 самых длинных рёбер. Func <WeightedEdge <int>, double> edgeCost = edge => edge.Weight; for (int i = 0; i < K - 1; ++i) { var minWeight = graph.Edges.Max(edgeCost); var edge = graph.Edges.First(el => Math.Abs(el.Weight - minWeight) < double.Epsilon); graph.RemoveEdge(edge); } // 3. Выделенение компонентов связности. ConnectedComponentsAlgorithm <int, WeightedEdge <int> > algorithm = new ConnectedComponentsAlgorithm <int, WeightedEdge <int> >(graph); algorithm.Compute(); // 4. Сформируем выходные данные. Clusters = new Cluster[K]; for (int i = 0; i < data.Length; ++i) { var numCluster = algorithm.Components[i]; if (Clusters[numCluster] == null) { Clusters[numCluster] = new Cluster(); } Clusters[numCluster].Add(i); } for (int i = 0; i < K; ++i) { for (int j = 0; j < Clusters[i].Count; ++j) { if (j == 0) { outData[i] = data[Clusters[i][j]]; Clusters[i].MapGenCentroid = Clusters[i][j]; } else { if (data[Clusters[i][j]].Depth < outData[i].Depth) { outData[i] = data[Clusters[i][j]]; Clusters[i].MapGenCentroid = Clusters[i][j]; } } } } }