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
        }
示例#3
0
        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);
        }
示例#7
0
        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]);
                }
            }
        }
示例#9
0
        /// <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];
                        }
                    }
                }
            }
        }