dijkstra SSSP
							parent
							
								
									031a0e1e23
								
							
						
					
					
						commit
						5b1c05819e
					
				| 
						 | 
					@ -224,10 +224,10 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            sccs.Clear();
 | 
					            sccs.Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var preorder = new PooledDictionary<TNode, uint>();
 | 
					            var preorder = new PooledDictionary<TNode, uint>(ClearMode.Always);
 | 
				
			||||||
            var lowlink = new PooledDictionary<TNode, uint>();
 | 
					            var lowlink = new PooledDictionary<TNode, uint>(ClearMode.Always);
 | 
				
			||||||
            var sccFound = new PooledDictionary<TNode, bool>();
 | 
					            var sccFound = new PooledDictionary<TNode, bool>(ClearMode.Always);
 | 
				
			||||||
            var sccQueue = new PooledStack<TNode>();
 | 
					            var sccQueue = new PooledStack<TNode>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            uint preorderCounter = 0;
 | 
					            uint preorderCounter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                            if (lowlink[v] == preorder[v])
 | 
					                            if (lowlink[v] == preorder[v])
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                sccFound[v] = true;
 | 
					                                sccFound[v] = true;
 | 
				
			||||||
                                var scc = new PooledList<TNode>
 | 
					                                var scc = new PooledList<TNode>(ClearMode.Always)
 | 
				
			||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    v
 | 
					                                    v
 | 
				
			||||||
                                };
 | 
					                                };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,5 +112,50 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            yield break;
 | 
					            yield break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<(TNode, TNode, int)> DijkstraSingleSourceShortestPath(TNode source)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            CheckNodes(source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var distance = new PooledDictionary<TNode, int>(ClearMode.Always);
 | 
				
			||||||
 | 
					            var previous = new PooledDictionary<TNode, TNode>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var node in Nodes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                distance[node] = int.MaxValue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            distance[source] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var q = Nodes.ToPooledList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            while (q.Count > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var node = q.MinBy(n => distance[n]).First();
 | 
				
			||||||
 | 
					                q.Remove(node);
 | 
				
			||||||
 | 
					                if (distance[node] == int.MaxValue) { break; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach (var neighbor in Neighbors(node))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var alt = distance[node] + Weight(node, neighbor);
 | 
				
			||||||
 | 
					                    if (alt < distance[neighbor])
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        distance[neighbor] = alt;
 | 
				
			||||||
 | 
					                        previous[neighbor] = node;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var node in Nodes)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (!node.Equals(source))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    yield return (node, previous[node], distance[node]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            distance.Dispose();
 | 
				
			||||||
 | 
					            previous.Dispose();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,9 +32,9 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var colors = new PooledDictionary<TNode, Color>();
 | 
					                var colors = new PooledDictionary<TNode, Color>(ClearMode.Always);
 | 
				
			||||||
                var d = new PooledDictionary<TNode, int>();
 | 
					                var d = new PooledDictionary<TNode, int>(ClearMode.Always);
 | 
				
			||||||
                var partition = new PooledDictionary<TNode, int>();
 | 
					                var partition = new PooledDictionary<TNode, int>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                foreach (var node in Nodes)
 | 
					                foreach (var node in Nodes)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                partition[start] = 1;
 | 
					                partition[start] = 1;
 | 
				
			||||||
                d[start] = 0;
 | 
					                d[start] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var stack = new PooledStack<TNode>();
 | 
					                var stack = new PooledStack<TNode>(ClearMode.Always);
 | 
				
			||||||
                stack.Push(start);
 | 
					                stack.Push(start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                while (stack.Count > 0)
 | 
					                while (stack.Count > 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -221,5 +221,48 @@ namespace Tests
 | 
				
			||||||
            // have to call Count() because otherwise the lazy evaluation wont trigger
 | 
					            // have to call Count() because otherwise the lazy evaluation wont trigger
 | 
				
			||||||
            myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 1).Count()).Should().Throw<System.ArgumentException>();
 | 
					            myGraph.Invoking(x => x.AStarShortestPath('a', 'z', (x, y) => 1).Count()).Should().Throw<System.ArgumentException>();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Test]
 | 
				
			||||||
 | 
					        public void DijkstraSingleSourceShortestPath()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            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', 'f', 2, run),
 | 
				
			||||||
 | 
					                ('d', 'h', 3, wallJump),
 | 
				
			||||||
 | 
					                ('e', 'f', 5, run),
 | 
				
			||||||
 | 
					                ('f', 'd', 2, run),
 | 
				
			||||||
 | 
					                ('f', 'h', 6, wallJump),
 | 
				
			||||||
 | 
					                ('g', 'h', 7, run),
 | 
				
			||||||
 | 
					                ('h', 'f', 1, jump)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            myGraph
 | 
				
			||||||
 | 
					                .DijkstraSingleSourceShortestPath('a')
 | 
				
			||||||
 | 
					                .Should()
 | 
				
			||||||
 | 
					                .Contain(('b', 'a', 2)).And
 | 
				
			||||||
 | 
					                .Contain(('c', 'a', 3)).And
 | 
				
			||||||
 | 
					                .Contain(('d', 'b', 4)).And
 | 
				
			||||||
 | 
					                .Contain(('e', 'b', 3)).And
 | 
				
			||||||
 | 
					                .Contain(('f', 'd', 6)).And
 | 
				
			||||||
 | 
					                .Contain(('g', 'c', 7)).And
 | 
				
			||||||
 | 
					                .Contain(('h', 'd', 7)).And
 | 
				
			||||||
 | 
					                .HaveCount(7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // have to call Count() because otherwise the lazy evaluation wont trigger
 | 
				
			||||||
 | 
					            myGraph.Invoking(x => x.DijkstraSingleSourceShortestPath('z').Count()).Should().Throw<System.ArgumentException>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue