public static DijkstraValues GetDijkstraValues(this IGraphNode node, bool ignoreDirection = false, GraphSearchMode searchMode = GraphSearchMode.ShortestPath) { if (searchMode != GraphSearchMode.ShortestPath) { throw new NotImplementedException(); } var allGraphNodes = node.Entity.Level.Entities.Where(entity => entity.Implements <IGraphNode>()) .Select(entity => entity.GetImplementation <IGraphNode>()).ToList(); var distances = new Dictionary <IGraphNode, float>(); var predecessors = new Dictionary <IGraphNode, IGraphNode>(); foreach (var graphNode in allGraphNodes) { distances.Add(graphNode, float.MaxValue); predecessors.Add(graphNode, null); } distances[node] = 0; while (allGraphNodes.Count > 0) { var currentNode = allGraphNodes.OrderBy(_ => distances[_]).First(); allGraphNodes.Remove(currentNode); foreach (var neighborTuple in GetNeighbors(currentNode, ignoreDirection)) { if (!allGraphNodes.Contains(neighborTuple.Item1)) { continue; } var neighborDistance = distances[neighborTuple.Item1]; var alternativeDistance = distances[currentNode] + neighborTuple.Item2; if (alternativeDistance < neighborDistance) { distances[neighborTuple.Item1] = alternativeDistance; predecessors[neighborTuple.Item1] = currentNode; } } } return(new DijkstraValues(distances, predecessors)); }
public static bool FindPath(Vertex fromNode, Vertex target, List <Vertex> path, GraphSearchMode searchMode = GraphSearchMode.DepthFirst) { Queue <Vertex> queue = new Queue <Vertex>(); if (fromNode == null || fromNode.Visited) { return(false); } if (searchMode == GraphSearchMode.DepthFirst) { path.Add(fromNode); fromNode.Visited = true; if (fromNode.Value.CompareTo(target.Value) == 0) { return(true); } if (fromNode.ConnectToNodes != null) { foreach (var destination in fromNode.ConnectToNodes) { var found = FindPath(destination, target, path, searchMode); if (found) { return(true); } } } } else { fromNode.Visited = true; queue.Enqueue(fromNode); while (queue.Count > 0) { var v = queue.Dequeue(); path.Add(v); if (v.Value.CompareTo(target.Value) == 0) { return(true); } if (v.ConnectToNodes != null) { foreach (Vertex adjacent in v.ConnectToNodes) { if (!adjacent.Visited) { adjacent.Visited = true; queue.Enqueue(adjacent); } } } } } return(false); }