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);
        }
Example #2
0
        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);
        }