public void SetUp()
        {
            directedGraph = new DirectedSimpleGraph <int, object, object>(Enumerable.Range(0, 10));
            directedGraph.AddEdgeBetween(directedGraph[0], directedGraph[1]);
            directedGraph.AddEdgeBetween(directedGraph[1], directedGraph[3]);
            directedGraph.AddEdgeBetween(directedGraph[1], directedGraph[7]);
            directedGraph.AddEdgeBetween(directedGraph[3], directedGraph[4]);
            directedGraph.AddEdgeBetween(directedGraph[4], directedGraph[0]);
            directedGraph.AddEdgeBetween(directedGraph[5], directedGraph[4]);
            directedGraph.AddEdgeBetween(directedGraph[5], directedGraph[8]);
            directedGraph.AddEdgeBetween(directedGraph[6], directedGraph[2]);
            directedGraph.AddEdgeBetween(directedGraph[6], directedGraph[9]);
            directedGraph.AddEdgeBetween(directedGraph[8], directedGraph[5]);

            undirectedGraph = new UndirectedSimpleGraph <int, object, object>(Enumerable.Range(0, 10));
            undirectedGraph.AddEdgeBetween(undirectedGraph[0], undirectedGraph[1]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[0], undirectedGraph[4]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[1], undirectedGraph[3]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[1], undirectedGraph[7]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[2], undirectedGraph[6]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[3], undirectedGraph[4]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[4], undirectedGraph[5]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[5], undirectedGraph[8]);
            undirectedGraph.AddEdgeBetween(undirectedGraph[6], undirectedGraph[9]);
        }
        public void SetUp()
        {
            graph = new UndirectedSimpleGraph <int, object, WeightProp>(Enumerable.Range(0, 5).ToArray());

            graph.AddEdgeBetween(graph[0], graph[1], new WeightProp {
                Weight = -1.0
            });
            graph.AddEdgeBetween(graph[0], graph[2], new WeightProp {
                Weight = 4.0
            });
            graph.AddEdgeBetween(graph[1], graph[2], new WeightProp {
                Weight = 9.0
            });
            graph.AddEdgeBetween(graph[1], graph[3], new WeightProp {
                Weight = 7.0
            });
            graph.AddEdgeBetween(graph[1], graph[4], new WeightProp {
                Weight = 12.0
            });
            graph.AddEdgeBetween(graph[2], graph[4], new WeightProp {
                Weight = 6.0
            });
            graph.AddEdgeBetween(graph[3], graph[4], new WeightProp {
                Weight = 3.0
            });
        }
        /// <summary>Kruskal algorithm.</summary>
        /// <param name="graph">Undirected weighted graph</param>
        /// <returns>Minimal spanning tree</returns>
        public static IUndirectedGraph <TVertexId, TVertexProperty, TEdgeProperty> Kruskal <TVertexId, TVertexProperty, TEdgeProperty>(
            this IUndirectedGraph <TVertexId, TVertexProperty, TEdgeProperty> graph)
            where TEdgeProperty : IWeighted
        {
            var mst = new UndirectedSimpleGraph <TVertexId, TVertexProperty, TEdgeProperty>(
                graph.Vertices.Select(v => v.Id).ToArray());
            var vertexSets = new DisjointSets <Vertex <TVertexId> >(graph.Vertices);
            var edgeHeap   = new Heap <Edge <TVertexId> >(
                (edge1, edge2) => graph.Properties[edge1].Weight.CompareTo(graph.Properties[edge2].Weight)
                );

            foreach (Edge <TVertexId> edge in graph.Edges)
            {
                edgeHeap.Push(edge);
            }

            while (vertexSets.Count > 1 && edgeHeap.Count > 0)
            {
                Edge <TVertexId> edge = edgeHeap.Pop();

                if (!vertexSets.IsSameSet(edge.Source, edge.Destination))
                {
                    mst.AddEdge(edge, graph.Properties[edge]);
                }

                vertexSets.UnionSet(edge.Source, edge.Destination);
            }

            return(mst);
        }
Beispiel #4
0
        public void FindVertexCut_WhenPresentSeparators_ThenSeparators()
        {
            // given
            var graph = new UndirectedSimpleGraph <int, object, object>(Enumerable.Range(0, 12));

            graph.AddEdgeBetween(graph[0], graph[1]);
            graph.AddEdgeBetween(graph[0], graph[2]);
            graph.AddEdgeBetween(graph[0], graph[7]);
            graph.AddEdgeBetween(graph[1], graph[2]);
            graph.AddEdgeBetween(graph[1], graph[3]);
            graph.AddEdgeBetween(graph[1], graph[4]);
            graph.AddEdgeBetween(graph[3], graph[5]);
            graph.AddEdgeBetween(graph[4], graph[5]);
            graph.AddEdgeBetween(graph[5], graph[6]);
            graph.AddEdgeBetween(graph[7], graph[8]);
            graph.AddEdgeBetween(graph[7], graph[9]);
            graph.AddEdgeBetween(graph[7], graph[11]);
            graph.AddEdgeBetween(graph[8], graph[9]);
            graph.AddEdgeBetween(graph[9], graph[10]);
            graph.AddEdgeBetween(graph[9], graph[11]);
            graph.AddEdgeBetween(graph[10], graph[11]);
            // when
            IEnumerable <Vertex <int> > result = graph.FindVertexCut();

            // then
            result.Should().BeEquivalentTo(
                new[] { graph[0], graph[1], graph[5], graph[7] });
        }
        /// <summary>Prim algorithm.</summary>
        /// <param name="graph">Undirected weighted graph</param>
        /// <param name="source">Starting vertex</param>
        /// <returns>Minimal spanning tree</returns>
        public static IUndirectedGraph <TVertexId, TVertexProperty, TEdgeProperty> Prim <TVertexId, TVertexProperty, TEdgeProperty>(
            IUndirectedGraph <TVertexId, TVertexProperty, TEdgeProperty> graph, Vertex <TVertexId> source)
            where TEdgeProperty : IWeighted
        {
            var mst = new UndirectedSimpleGraph <TVertexId, TVertexProperty, TEdgeProperty>(
                graph.Vertices.Select(v => v.Id).ToArray());
            var visited = new HashSet <Vertex <TVertexId> >();
            var heap    = new Heap <(Edge <TVertexId>, Vertex <TVertexId>)>(
                (pair1, pair2) => graph.Properties[pair1.Item1].Weight.CompareTo(
                    graph.Properties[pair2.Item1].Weight)
                );

            visited.Add(source);

            foreach (Edge <TVertexId> adjacentEdge in graph.GetAdjacentEdges(source))
            {
                Vertex <TVertexId> neighbour = adjacentEdge.GetNeighbour(source);

                if (neighbour != source)
                {
                    heap.Push((adjacentEdge, neighbour));
                }
            }

            while (heap.Count > 0)
            {
                (Edge <TVertexId> edge, Vertex <TVertexId> vertex) = heap.Pop();

                if (!visited.Contains(vertex))
                {
                    visited.Add(vertex);
                    mst.AddEdge(edge, graph.Properties[edge]);

                    foreach (Edge <TVertexId> adjacentEdge in graph.GetAdjacentEdges(vertex))
                    {
                        Vertex <TVertexId> neighbour = adjacentEdge.GetNeighbour(vertex);

                        if (!visited.Contains(neighbour))
                        {
                            heap.Push((adjacentEdge, neighbour));
                        }
                    }
                }
            }

            return(mst);
        }
Beispiel #6
0
        public void FindEdgeCut_WhenNoBridges_ThenEmptyList()
        {
            // given
            var graph = new UndirectedSimpleGraph <int, object, object>(Enumerable.Range(0, 6));

            graph.AddEdgeBetween(graph[0], graph[1]);
            graph.AddEdgeBetween(graph[0], graph[2]);
            graph.AddEdgeBetween(graph[1], graph[2]);
            graph.AddEdgeBetween(graph[1], graph[3]);
            graph.AddEdgeBetween(graph[1], graph[4]);
            graph.AddEdgeBetween(graph[3], graph[5]);
            graph.AddEdgeBetween(graph[4], graph[5]);
            // when
            IEnumerable <Edge <int> > result = graph.FindEdgeCut();

            // then
            result.Should().BeEmpty();
        }
        public void SetUp()
        {
            directedGraph = new DirectedSimpleGraph <int, object, Weighted>(
                Enumerable.Range(0, 10).ToList());
            directedGraph.AddEdgeBetween(directedGraph[0], directedGraph[1],
                                         new Weighted(4.0));
            directedGraph.AddEdgeBetween(directedGraph[1], directedGraph[4],
                                         new Weighted(7.0));
            directedGraph.AddEdgeBetween(directedGraph[1], directedGraph[7],
                                         new Weighted(12.0));
            directedGraph.AddEdgeBetween(directedGraph[2], directedGraph[4],
                                         new Weighted(6.0));
            directedGraph.AddEdgeBetween(directedGraph[2], directedGraph[6],
                                         new Weighted(8.0));
            directedGraph.AddEdgeBetween(directedGraph[3], directedGraph[0],
                                         new Weighted(3.0));
            directedGraph.AddEdgeBetween(directedGraph[3], directedGraph[7],
                                         new Weighted(5.0));
            directedGraph.AddEdgeBetween(directedGraph[4], directedGraph[5],
                                         new Weighted(1.0));
            directedGraph.AddEdgeBetween(directedGraph[4], directedGraph[3],
                                         new Weighted(10.0));
            directedGraph.AddEdgeBetween(directedGraph[5], directedGraph[6],
                                         new Weighted(4.0));
            directedGraph.AddEdgeBetween(directedGraph[5], directedGraph[8],
                                         new Weighted(2.0));
            directedGraph.AddEdgeBetween(directedGraph[6], directedGraph[5],
                                         new Weighted(7.0));
            directedGraph.AddEdgeBetween(directedGraph[7], directedGraph[5],
                                         new Weighted(2.0));
            directedGraph.AddEdgeBetween(directedGraph[7], directedGraph[8],
                                         new Weighted(6.0));
            directedGraph.AddEdgeBetween(directedGraph[8], directedGraph[9],
                                         new Weighted(10.0));
            directedGraph.AddEdgeBetween(directedGraph[9], directedGraph[6],
                                         new Weighted(3.0));

            undirectedGraph = new UndirectedSimpleGraph <int, object, Weighted>(
                Enumerable.Range(0, 10).ToList());
            undirectedGraph.AddEdgeBetween(undirectedGraph[0], undirectedGraph[1],
                                           new Weighted(4.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[1], undirectedGraph[4],
                                           new Weighted(7.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[1], undirectedGraph[7],
                                           new Weighted(12.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[2], undirectedGraph[6],
                                           new Weighted(8.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[3], undirectedGraph[0],
                                           new Weighted(3.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[3], undirectedGraph[7],
                                           new Weighted(5.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[4], undirectedGraph[5],
                                           new Weighted(1.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[4], undirectedGraph[3],
                                           new Weighted(10.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[5], undirectedGraph[8],
                                           new Weighted(2.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[7], undirectedGraph[5],
                                           new Weighted(2.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[7], undirectedGraph[8],
                                           new Weighted(6.0));
            undirectedGraph.AddEdgeBetween(undirectedGraph[9], undirectedGraph[6],
                                           new Weighted(3.0));
        }