示例#1
0
        public void BellmanFordNotReachable()
        {
            var run = new MoveTypeEdgeData {
                moveType = MoveType.Run
            };
            var jump = new MoveTypeEdgeData {
                moveType = MoveType.Jump
            };
            var wallJump = new MoveTypeEdgeData {
                moveType = MoveType.WallJump
            };

            var myGraph = new DirectedWeightedGraph <char, MoveTypeEdgeData>();

            myGraph.AddNodes('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
            myGraph.AddEdges(
                ('a', 'b', 2, run),
                ('a', 'c', 3, run),
                ('a', 'e', 4, wallJump),
                ('b', 'd', 2, jump),
                ('b', 'e', 1, run),
                ('c', 'g', 4, jump),
                ('c', 'h', 11, run),
                ('d', 'c', 3, jump),
                ('d', 'h', 3, wallJump),
                ('f', 'd', 2, run),
                ('f', 'h', 6, wallJump),
                ('g', 'h', 7, run)
                );

            myGraph
            .BellmanFordShortestPath('a', 'f')
            .Should()
            .BeEmpty();
        }
示例#2
0
        public static int?[,] GetShortestPaths(DirectedWeightedGraph graph)
        {
            int n = graph.NodesCount;
            for (int i = 0; i < n; i++)
            {
                graph.AddEdge(n, i, 0);
            }

            var weights = BellmanFord.GetShortestPaths(graph, n);
            if (weights == null)
            {
                return null;
            }

            graph.RemoveNode(n);

            var reweightedGraph = new DirectedWeightedGraph();
            foreach (var edge in graph.GetEdges())
            {
               reweightedGraph.AddEdge(edge.StartNode, edge.EndNode, edge.Weight + weights[edge.StartNode].Value - weights[edge.EndNode].Value);
            }

            var distances = new int?[n, n];
            for (int i = 0; i < n; i++)
            {
                int j = 0;
                foreach (var distance in Dijkstra.Find(reweightedGraph, i))
                {
                    distances[i, j] = distance - weights[i] + weights[j];
                    j++;
                }
            }

            return distances;
        }
        public void VisitAll_ShouldCountNumberOfVisitedVertix_ResultShouldBeTheSameAsNumberOfVerticesInGraph()
        {
            //Arrange
            var graph = new DirectedWeightedGraph <int>(10);

            var vertex1 = graph.AddVertex(1);

            var vertex2 = graph.AddVertex(20);

            var vertex3 = graph.AddVertex(40);

            var vertex4 = graph.AddVertex(40);

            graph.AddEdge(vertex1, vertex2, 1);

            graph.AddEdge(vertex2, vertex3, 1);

            graph.AddEdge(vertex2, vertex4, 1);

            graph.AddEdge(vertex4, vertex1, 1);

            var dfsSearcher = new DepthFirstSearch <int>();

            long countOfVisitedVertices = 0;

            //Act
            dfsSearcher.VisitAll(graph, vertex1, (Vertex <int> vertex) => countOfVisitedVertices++);

            //Assert
            Assert.AreEqual(countOfVisitedVertices, graph.Count);
        }
示例#4
0
        /// <summary>
        /// Implementation of the Dijkstra shortest path algorithm for cyclic graphs.
        /// https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm.
        /// </summary>
        /// <param name="graph">Graph instance.</param>
        /// <param name="startVertex">Starting vertex instance.</param>
        /// <typeparam name="T">Generic Parameter.</typeparam>
        /// <returns>List of distances from current vertex to all other vertices.</returns>
        /// <exception cref="InvalidOperationException">Exception thrown in case when graph is null or start
        /// vertex does not belong to graph instance.</exception>
        public static DistanceModel <T>[] GenerateShortestPath <T>(DirectedWeightedGraph <T> graph, Vertex <T> startVertex)
        {
            ValidateGraphAndStartVertex(graph, startVertex);

            var visitedVertices = new List <Vertex <T> >();

            var distanceArray = InitializeDistanceArray(graph, startVertex);

            var currentVertex = startVertex;

            var currentPath = 0d;

            while (true)
            {
                visitedVertices.Add(currentVertex);

                var neighborVertices = graph
                                       .GetNeighbors(currentVertex)
                                       .Where(x => x != null && !visitedVertices.Contains(x))
                                       .ToList();

                foreach (var vertex in neighborVertices)
                {
                    var adjacentDistance = graph.AdjacentDistance(currentVertex, vertex !);

                    var distance = distanceArray[vertex !.Index];
        public void Test()
        {
            var graph1 = new DirectedWeightedGraph(false);

            for (int i = 'a'; i <= 'h'; i++)
            {
                graph1.AddVertex(Convert.ToString(Convert.ToChar(i)));
            }

            graph1.AddEdge("a", "b", 1);
            graph1.AddEdge("b", "c", 2);
            graph1.AddEdge("c", "d", 3);
            graph1.AddEdge("a", "g", 600);
            graph1.AddEdge("b", "f", 0);
            graph1.AddEdge("e", "b", 7);


            Stack <Vertex> stack = new Stack <Vertex>();

            stack.Push(graph1.GetVertex("d"));
            stack.Push(graph1.GetVertex("c"));
            stack.Push(graph1.GetVertex("f"));
            stack.Push(graph1.GetVertex("b"));
            stack.Push(graph1.GetVertex("g"));
            stack.Push(graph1.GetVertex("a"));
            stack.Push(graph1.GetVertex("e"));
            stack.Push(graph1.GetVertex("h"));

            var testStack = TopologicalSort <DirectedWeightedGraph> .Sort(graph1);

            for (int i = 'a'; i <= 'h'; i++)
            {
                Assert.AreEqual(stack.Pop(), testStack.Pop());
            }
        }
示例#6
0
        public void Ctor_ShouldInitializeAdjacencyLists()
        {
            var graph = new DirectedWeightedGraph <int, int>();

            Assert.NotNull(graph.AdjacencyLists);
            Assert.Empty(graph.AdjacencyLists);
        }
示例#7
0
        public void Ctor_ShouldInitializeAdjacencyListsWithVerticesAndEdgesWithDefaultWeights()
        {
            var vertices = new List <int> {
                0, 1, 2
            };
            var edges = new List <Edge <int> >()
            {
                new Edge <int>(0, 1),
                new Edge <int>(0, 2),
                new Edge <int>(2, 0)
            };
            var expectedAdjacencyLists = new Dictionary <int, IReadOnlyList <int> >()
            {
                [0] = new List <int>()
                {
                    1, 2
                },
                [1] = new List <int>()
                {
                },
                [2] = new List <int>()
                {
                    0
                },
            };

            var graph = new DirectedWeightedGraph <int, int>(vertices, edges);

            Assert.Equal(expectedAdjacencyLists, graph.AdjacencyLists);
            Assert.All(edges, edge =>
            {
                Assert.Equal(default, graph.Weights[edge]);
示例#8
0
        public void DijkstraNegativeWeight()
        {
            var run = new MoveTypeEdgeData {
                moveType = MoveType.Run
            };
            var jump = new MoveTypeEdgeData {
                moveType = MoveType.Jump
            };
            var wallJump = new MoveTypeEdgeData {
                moveType = MoveType.WallJump
            };

            var myGraph = new DirectedWeightedGraph <char, MoveTypeEdgeData>();

            myGraph.AddNodes('a', 'b', 'c', 'd');
            myGraph.AddEdges(
                ('a', 'b', -2, run),
                ('a', 'c', 3, run),
                ('b', 'd', 2, jump),
                ('d', 'c', -3, jump)
                );

            myGraph
            .Invoking(x => x.DijkstraShortestPath('a', 'd').Count())
            .Should()
            .Throw <NegativeWeightException>();
        }
        public static void Main()
        {
            //System.IO.TextReader s = System.IO.File.OpenText("mediumEWD.txt");
            System.IO.TextReader  s     = System.IO.File.OpenText("tinyEWDAG.txt");
            DirectedWeightedGraph graph = new DirectedWeightedGraph(s);

            Console.Write("请输入起点:");
            int       st = int.Parse(Console.ReadLine());
            AcyclicSP sp = new AcyclicSP(graph, st);

            for (int i = 0; i < graph.V; ++i)
            {
                if (i == st)
                {
                    Console.WriteLine("{0}->{0} : 0.0", st);
                    continue;
                }
                if (!sp.HasPathTo(i))
                {
                    Console.WriteLine("{0}->{1} : No paths", st, i);
                    continue;
                }
                Double len = 0.0;
                foreach (var edge in sp.PathTo(i))
                {
                    Console.Write(edge);
                    Console.Write(",");
                    len += edge.Weight;
                }
                Console.WriteLine(" : {0}", len);
            }
        }
示例#10
0
        public void BellmanFordSingleSourceShortestPathNegativeCycle()
        {
            var run = new MoveTypeEdgeData {
                moveType = MoveType.Run
            };
            var jump = new MoveTypeEdgeData {
                moveType = MoveType.Jump
            };
            var wallJump = new MoveTypeEdgeData {
                moveType = MoveType.WallJump
            };

            var myGraph = new DirectedWeightedGraph <char, MoveTypeEdgeData>();

            myGraph.AddNodes('a', 'b', 'c');
            myGraph.AddEdges(
                ('a', 'b', -2, run),
                ('b', 'c', -3, run),
                ('c', 'a', -1, jump)
                );

            myGraph
            .Invoking(x => x.BellmanFordSingleSourceShortestPath('a').Count())
            .Should().
            Throw <NegativeCycleException>();
        }
示例#11
0
        private void FindNegtiveCycle()
        {
            int V = edgeTo.Length;//图的节点数量
            DirectedWeightedGraph spt = new DirectedWeightedGraph(V);

            for (int v = 0; v < V; ++v)
            {
                if (edgeTo[v] != null)
                {
                    spt.AddEdge(edgeTo[v]);
                }
            }
            DirectedCycle cf = new DirectedCycle(spt);
            //需要转换形式
            Queue <DirectedEdge> edges = new Queue <DirectedEdge>();//没有还
            var list = cf.Cycle().ToList();

            if (list.Count == 0)
            {
                return;
            }
            for (int i = 0; i < list.Count - 1; ++i)
            {
                edges.Enqueue(new DirectedEdge(list[i], list[i + 1], spt.GetWeight(list[i], list[i + 1])));
            }
            cycle = edges;
        }
示例#12
0
 public void Relax(DirectedWeightedGraph g, int v)
 {
     foreach (DirectedEdge edge in g.GetEdge(v))
     {
         int w = edge.End;
         //如果存在放松的条件
         if (distTo[w] > distTo[v] + edge.Weight)
         {
             distTo[w] = distTo[v] + edge.Weight;
             edgeTo[w] = edge;
             //添加为需要继续放松的
             if (this.onQueue[w] == false)
             {
                 this.queue.Enqueue(w);
                 this.onQueue[w] = true;
             }
         }
         if (cost++ % g.V == 0)//根据436 页 定理X.V 个不含有负权环图的节点,放松 V 次可以得到最短路径
         {
             FindNegtiveCycle();
             if (HasNegativeCycle())
             {
                 return;
             }
         }
     }
 }
示例#13
0
        public void DijkstraTest3_Success()
        {
            var graph = new DirectedWeightedGraph <char>(5);
            var a     = graph.AddVertex('A');
            var b     = graph.AddVertex('B');
            var c     = graph.AddVertex('C');

            graph.AddEdge(a, b, 1);
            graph.AddEdge(b, a, 1);

            graph.AddEdge(a, c, 3);
            graph.AddEdge(c, a, 3);

            var shortestPathList = DijkstraAlgorithm.GenerateShortestPath(graph, a);

            shortestPathList.Length.Should().Be(3);
            shortestPathList[0].Vertex.Should().Be(a);
            shortestPathList[0].Distance.Should().Be(0);
            shortestPathList[0].PreviousVertex.Should().Be(a);
            shortestPathList[0].ToString().Should()
            .Be($"Vertex: {a} - Distance: {0} - Previous: {a}");

            shortestPathList[1].Vertex.Should().Be(b);
            shortestPathList[1].Distance.Should().Be(1);
            shortestPathList[1].PreviousVertex.Should().Be(a);
            shortestPathList[1].ToString().Should()
            .Be($"Vertex: {b} - Distance: {1} - Previous: {a}");

            shortestPathList[2].Vertex.Should().Be(c);
            shortestPathList[2].Distance.Should().Be(3);
            shortestPathList[2].PreviousVertex.Should().Be(a);
            shortestPathList[2].ToString().Should()
            .Be($"Vertex: {c} - Distance: {3} - Previous: {a}");
        }
示例#14
0
        public void Test()
        {
            // orientovaný ohodnocený.
            var graph1 = new DirectedWeightedGraph(false);

            for (int i = 'a'; i < 'h'; i++)
            {
                graph1.AddVertex(Convert.ToString(Convert.ToChar(i)));
            }

            graph1.AddEdge("a", "b", 1);
            graph1.AddEdge("b", "c", 2);
            graph1.AddEdge("c", "d", 3);
            graph1.AddEdge("d", "e", -4);
            graph1.AddEdge("f", "c", 5);
            graph1.AddEdge("a", "g", 600);
            graph1.AddEdge("b", "f", 0);
            graph1.AddEdge("b", "e", 7);

            DepthFirstSearch <DirectedWeightedGraph> .Search(graph1, "a");

            Assert.AreEqual(0, graph1.GetVertex("a").distance);
            Assert.AreEqual(1, graph1.GetVertex("b").distance);
            Assert.AreEqual(2, graph1.GetVertex("c").distance);
            Assert.AreEqual(3, graph1.GetVertex("d").distance);
            Assert.AreEqual(4, graph1.GetVertex("e").distance);
            Assert.AreEqual(2, graph1.GetVertex("f").distance);
            Assert.AreEqual(1, graph1.GetVertex("g").distance);
        }
 private double[] inw; //inw[i] 记录i入边的权值
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="digraph">有向图</param>
 /// <param name="root">起点</param>
 public ZhuLiuAlgorithmInMinimumTreeGraph(DirectedWeightedGraph digraph, int root)
 {
     pre       = new int[digraph.V];
     vis       = new int[digraph.V];
     id        = new int[digraph.V];
     inw       = new double[digraph.V];
     MinWeight = Solve(digraph, root);
 }
示例#16
0
        public void AddNode()
        {
            var myGraph = new DirectedWeightedGraph <int, EdgeData>();

            myGraph.AddNode(4);

            myGraph.Exists(4).Should().BeTrue();
        }
        public void GraphRemoveVertexTest_ShouldThrowVertexNotInGraph()
        {
            var graph   = new DirectedWeightedGraph <char>(10);
            var vertexA = new Vertex <char>('A', 0);

            Action removeVertex = () => graph.RemoveVertex(vertexA);

            removeVertex.Should().Throw <InvalidOperationException>()
            .WithMessage($"Vertex does not belong to graph: {vertexA}.");
        }
        public void GraphAddVertexTest_Success()
        {
            var graph = new DirectedWeightedGraph <char>(10);

            graph.AddVertex('A');
            graph.AddVertex('B');
            graph.AddVertex('C');

            graph.Count.Should().Be(3);
        }
示例#19
0
 private Double[] distTo;       // disTo[i] 保存的是从 v 到 i 的距离
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="g">有向加权非负权图</param>
 /// <param name="s">起点</param>
 public AcyclicSP(DirectedWeightedGraph g, int s)
 {
     edgeTo = new DirectedEdge[g.V];
     distTo = new Double[g.V];
     for (Int32 v = 0; v < g.V; ++v)
     {
         distTo[v] = Double.PositiveInfinity;
     }
     Topological top = new Topological(g);
 }
示例#20
0
        public void DijkstraMethodTest_ShouldThrow_GraphIsNull()
        {
            var graph = new DirectedWeightedGraph <char>(5);
            var a     = graph.AddVertex('A');

            Func <DistanceModel <char>[]> action = () => DijkstraAlgorithm.GenerateShortestPath(null !, a);

            action.Should().Throw <ArgumentNullException>()
            .WithMessage($"Value cannot be null. (Parameter '{nameof(graph)}')");
        }
        public void GraphAddEdgeTest_ShouldThrowZeroWeight()
        {
            var graph   = new DirectedWeightedGraph <char>(10);
            var vertexA = graph.AddVertex('A');
            var vertexB = graph.AddVertex('B');

            Action addZeroEdge = () => graph.AddEdge(vertexA, vertexB, 0);

            addZeroEdge.Should().Throw <InvalidOperationException>()
            .WithMessage("Edge weight cannot be zero.");
        }
        public void GraphRemoveEdgeTest_ShouldThrowVertexNotInGraph()
        {
            var graph   = new DirectedWeightedGraph <char>(10);
            var vertexA = graph.AddVertex('A');
            var vertexB = new Vertex <char>('B', 1);

            Action removeEdge = () => graph.RemoveEdge(vertexA, vertexB);

            removeEdge.Should().Throw <InvalidOperationException>()
            .WithMessage($"Vertex does not belong to graph: {vertexB}.");
        }
        public static void Main()
        {
            var sf      = "criticalPath.txt";
            var txr     = System.IO.File.OpenText(sf);
            var digrpah = new DirectedWeightedGraph(txr);
            var crt     = new CriticalPath(digrpah);

            foreach (var p in crt.GetCriticalPaths())
            {
                Console.WriteLine($"活动:{p}");
            }
        }
        public void GraphRemoveEdgeTest_Success()
        {
            var graph   = new DirectedWeightedGraph <char>(10);
            var vertexA = graph.AddVertex('A');
            var vertexB = graph.AddVertex('B');

            graph.AddEdge(vertexA, vertexB, 5);

            graph.RemoveEdge(vertexA, vertexB);

            graph.AreAdjacent(vertexA, vertexB).Should().BeFalse();
        }
        public void Test()
        {
            #region Orientovaná kružnice

            // orientovaný ohodnocený.
            var graph1 = new DirectedWeightedGraph(false);

            for (int i = 'a'; i < 'h'; i++)
            {
                graph1.AddVertex(Convert.ToString(Convert.ToChar(i)));
            }

            graph1.AddEdge("a", "b", 1);
            graph1.AddEdge("b", "c", 2);
            graph1.AddEdge("c", "d", 3);
            graph1.AddEdge("d", "e", -4);
            graph1.AddEdge("f", "c", 5);
            graph1.AddEdge("a", "g", 600);
            graph1.AddEdge("b", "f", 0);
            graph1.AddEdge("e", "b", 7);


            Assert.IsTrue(Cycle.ContainsCycle <DirectedWeightedGraph>(graph1));

            graph1.Clear();

            #endregion

            #region Orientovaný bez kružnice

            // orientovaný ohodnocený.
            var graph3 = new DirectedUnweightedGraph(false);

            for (int i = 'a'; i < 'h'; i++)
            {
                graph3.AddVertex(Convert.ToString(Convert.ToChar(i)));
            }


            graph3.AddEdge("a", "b");
            graph3.AddEdge("b", "c");
            graph3.AddEdge("c", "d");
            graph3.AddEdge("a", "g");
            graph3.AddEdge("b", "f");
            graph3.AddEdge("e", "b");

            Assert.IsFalse(Cycle.ContainsCycle <DirectedUnweightedGraph>(graph3));

            graph3.Clear();

            #endregion
        }
示例#26
0
        private void RunClick(object sender, RoutedEventArgs e)
        {
            var graph = DirectedWeightedGraph.CreateEmpty(3);

            graph.AddEdge(new DirectedWeightedEdge(graph.Vertices[0], graph.Vertices[1], 2));
            graph.AddEdge(new DirectedWeightedEdge(graph.Vertices[0], graph.Vertices[2], 6));
            graph.Vertices[0].DisplayName = "hi";
            Visualizer.Graph = graph;
            //((Vertex)Visualizer.Vertices[3]).Background = new SolidColorBrush(Colors.Magenta);
            //((Vertex)Visualizer.Vertices[1]).Radius = 30;
            _visualizerGraphProto       = graph;
            ((Button)sender).Visibility = Visibility.Collapsed;
        }
示例#27
0
        public void AddEdge()
        {
            var myGraph = new DirectedWeightedGraph <int, EdgeData>();

            myGraph.AddNodes(5, 6);
            myGraph.AddEdge(5, 6, 10, dummyEdgeData);

            myGraph.Neighbors(5).Should().Contain(6);
            myGraph.Weight(5, 6).Should().Be(10);
            myGraph.EdgeData(5, 6).Should().Be(dummyEdgeData);

            myGraph.Invoking(x => x.AddEdge(5, 6, 3, dummyEdgeData)).Should().Throw <ArgumentException>();
        }
 private void Relax(DirectedWeightedGraph g, int v)
 {
     foreach (DirectedEdge edge in g.GetEdge(v))
     {
         int w = edge.End;
         //如果存在放松的条件
         if (distTo[w] > distTo[v] + edge.Weight)
         {
             distTo[w] = distTo[v] + edge.Weight;
             edgeTo[w] = edge;
         }
     }
 }
        public static void Main()
        {
            StreamReader          reader = File.OpenText("zhuliudirectedgraph.txt");
            DirectedWeightedGraph graph  = new DirectedWeightedGraph(reader);

            foreach (DirectedEdge edge in graph)
            {
                Console.WriteLine(edge.Src + "->" + edge.End);
            }
            ZhuLiuAlgorithmInMinimumTreeGraph minimumTreeGraph = new ZhuLiuAlgorithmInMinimumTreeGraph(graph, 1);
            double res = minimumTreeGraph.MinWeight;
            int    j   = 25;
        }
示例#30
0
        public void Weight()
        {
            var myGraph = new DirectedWeightedGraph <int, EdgeData>();

            myGraph.AddNodes(1, 2, 3);
            myGraph.AddEdges(
                (1, 2, 4, dummyEdgeData),
                (2, 3, 5, dummyEdgeData)
                );

            myGraph.Weight(1, 2).Should().Be(4);
            myGraph.Weight(2, 3).Should().Be(5);
            myGraph.Invoking(x => x.Weight(3, 4)).Should().Throw <System.ArgumentException>();
        }
示例#31
0
        public BasicCompositor(ObjectManager objm, RendererContext rc)
        {
            graphLock = new object();

            _CompositorGraph = objm.CreateOrRecycle<DirectedWeightedGraph<CompositorNode, CompositorEdgeDescriptionListWrapper>>();
            _CompositorGraph.Init();

            _Nodes = new List<DirectedWeightedNode<CompositorNode, CompositorEdgeDescriptionListWrapper>>();
            _Edges = new List<DirectedWeightedEdge<CompositorNode, CompositorEdgeDescriptionListWrapper>>();

            DummyNode = _CompositorGraph.AddNode(null);

            RendererContext = rc;
        }
        public void GraphGetNeighborsTest_ShouldThrowVertexNotInGraph()
        {
            var graph   = new DirectedWeightedGraph <char>(10);
            var vertexA = new Vertex <char>('A', 0);

            Func <List <Vertex <char>?> > getNeighbors = () =>
            {
                var enumerable = graph.GetNeighbors(vertexA);
                return(enumerable.ToList());
            };

            getNeighbors.Should().Throw <InvalidOperationException>()
            .WithMessage($"Vertex does not belong to graph: {vertexA}.");
        }