private bool GetUnvistedEdge(AbstractDiGraph <TNode> graph, TNode sourceNode, out TNode destinationNode) { destinationNode = default(TNode); bool hasUnvistitedNodes = graph.GetNeighbourNodes(sourceNode) .Any( y => !_vistedEdges.Any(x => x.Item1.Equals(sourceNode) && x.Item2.Equals(y))); if (hasUnvistitedNodes) { destinationNode = graph.GetNeighbourNodes(sourceNode) .First( y => !_vistedEdges.Any(x => x.Item1.Equals(sourceNode) && x.Item2.Equals(y))); } return(hasUnvistitedNodes); }
public AbstractGraphPath <TNode> GetShortestPath(AbstractDiGraph <TNode> graph, TNode sourceNode, TNode destinationNode) { //Validate Input if (graph == null) { throw new ArgumentNullException("graph"); } if (graph.AllEdges.Any(x => x.Item3 <= 0)) { throw new InvalidEdgeWeightException( string.Format("The graph contains one or more edges with edge weight less than or equal to zero")); } //Initialise data structures Initialise(graph, sourceNode); //Compute Shortest Path while (_shortestPathUnKnownNodesQueue.Any() && !_shortestPathKnownNodes.Contains(destinationNode)) { foreach (var shortestPathKnownNode in _shortestPathKnownNodes) { foreach ( var neighbour in graph.GetNeighbourNodes(shortestPathKnownNode) .Where(x => !_shortestPathKnownNodes.Contains(x))) { int edgeWeight = graph.GetEdgeWeight(shortestPathKnownNode, neighbour); int newestimatedDistance = _estimatedDistances[shortestPathKnownNode].PathWeight + edgeWeight; if (IsEstimatedDistanceBetter(neighbour, newestimatedDistance)) { _estimatedDistances[neighbour].PathWeight = newestimatedDistance; _predessorNodes[neighbour] = shortestPathKnownNode; } } } DequeueShortestPathKnownNode(); } CompletePaths(); var result = _estimatedDistances.SingleOrDefault(x => x.Value.DestinationNode.Equals(destinationNode)).Value; if (result.PathWeight == Infinity) { return(null); } return(result); }
private void DFSVisit(AbstractDiGraph <TNode> graph, TNode node) { _startTime[node] = ++_time; foreach (TNode neighbour in graph.GetNeighbourNodes(node)) { var dfsEdge = new DepthFirstSearchEdge <TNode> { SourceNode = node, DestinationNode = neighbour }; dfsEdge.EdgeWeight = graph.GetEdgeWeight(dfsEdge.SourceNode, dfsEdge.DestinationNode); _dfsEdges.Add(dfsEdge); bool isNeighbourVisited = IsNodeinParentOrChild(neighbour); if (!isNeighbourVisited) { _parent[neighbour] = node; dfsEdge.EdgeType = DepthFirstSearchEdgeType.TreeEdge; DFSVisit(graph, neighbour); } else if (!_endTime.ContainsKey(neighbour)) { dfsEdge.EdgeType = DepthFirstSearchEdgeType.BackEdge; } else if (_startTime[node] < _startTime[neighbour]) { dfsEdge.EdgeType = DepthFirstSearchEdgeType.ForwardEdge; } else { dfsEdge.EdgeType = DepthFirstSearchEdgeType.CrossEdge; } } _endTime[node] = ++_time; _order.Add(node, _order.Count + 1); }