/**
         * Note that this may not be used externally, because some other members in the class
         * should be updated at the same time.
         *
         * @param startVertexId
         * @param endVertexId
         * @param weight
         */
        protected void AddEdge(int startVertexId, int endVertexId, double weight)
        {
            // actually, we should make sure all vertices ids must be correct.
            if (!idVertexIndex.ContainsKey(startVertexId) ||
                !idVertexIndex.ContainsKey(endVertexId) ||
                startVertexId == endVertexId)
            {
                throw new ArgumentException("The edge from " + startVertexId +
                                            " to " + endVertexId + " does not exist in the graph.");
            }

            // update the adjacent-list of the graph
            ISet <BaseVertex> fanoutVertexSet = new HashSet <BaseVertex>();

            if (fanoutVerticesIndex.ContainsKey(startVertexId))
            {
                fanoutVertexSet = fanoutVerticesIndex[startVertexId];
            }
            fanoutVertexSet.Add(idVertexIndex[endVertexId]);
            fanoutVerticesIndex.AddOrReplace(startVertexId, fanoutVertexSet);
            //
            ISet <BaseVertex> faninVertexSet = new HashSet <BaseVertex>();

            if (faninVerticesIndex.ContainsKey(endVertexId))
            {
                faninVertexSet = faninVerticesIndex[endVertexId];
            }
            faninVertexSet.Add(idVertexIndex[startVertexId]);
            faninVerticesIndex.AddOrReplace(endVertexId, faninVertexSet);
            // store the new edge
            vertexPairWeightIndex.Add(
                new Pair <int, int>(startVertexId, endVertexId),
                weight);
            ++edgeNum;
        }
 public virtual double GetEdgeWeight(BaseVertex source, BaseVertex sink)
 {
     return(vertexPairWeightIndex.ContainsKey(
                new Pair <int, int>(source.GetId(), sink.GetId()))?
            vertexPairWeightIndex[
                new Pair <int, int>(source.GetId(), sink.GetId())]
                                               : DISCONNECTED);
 }
        public static ShortestPathTree ShortestPathTree(Graph graph, String sourceLabel)
        {
            G.IDictionary <String, Node> nodes = graph.GetNodes();
            if (!nodes.ContainsKey(sourceLabel))
            {
                throw new Exception("Source node not found in graph.");
            }
            ShortestPathTree predecessorTree = new ShortestPathTree(sourceLabel);

            ISet <DijkstraNode> visited = new HashSet <DijkstraNode>();

            java.util.PriorityQueue <DijkstraNode> pq = new java.util.PriorityQueue <DijkstraNode>();
            foreach (String nodeLabel in nodes.Keys)
            {
                DijkstraNode newNode = new DijkstraNode(nodeLabel);
                newNode.SetDist(double.MaxValue);
                newNode.SetDepth(int.MaxValue);
                predecessorTree.Add(newNode);
            }
            DijkstraNode sourceNode = predecessorTree.GetNodes()[predecessorTree.GetRoot()];

            sourceNode.SetDist(0);
            sourceNode.SetDepth(0);
            pq.add(sourceNode, sourceNode.GetDist());

            int count = 0;

            while (!pq.isEmpty())
            {
                DijkstraNode current   = pq.poll();
                String       currLabel = current.GetLabel();
                visited.Add(current);
                count++;
                G.IDictionary <String, Double> neighbors = nodes[currLabel].GetNeighbors();
                foreach (String currNeighborLabel in neighbors.Keys)
                {
                    DijkstraNode neighborNode = predecessorTree.GetNodes()[currNeighborLabel];
                    Double       currDistance = neighborNode.GetDist();
                    Double       newDistance  = current.GetDist() + nodes[currLabel].GetNeighbors()[currNeighborLabel];
                    if (newDistance < currDistance)
                    {
                        DijkstraNode neighbor = predecessorTree.GetNodes()[currNeighborLabel];

                        pq.remove(neighbor);
                        neighbor.SetDist(newDistance);
                        neighbor.SetDepth(current.GetDepth() + 1);
                        neighbor.SetParent(currLabel);
                        pq.add(neighbor, neighbor.GetDist());
                    }
                }
            }

            return(predecessorTree);
        }
Пример #4
0
        /**
         * Update the distance from the source to the concerned vertex.
         * @param vertex
         */
        private void UpdateVertex(BaseVertex vertex, bool isSource2sink)
        {
            // 1. get the neighboring vertices
            ISet <BaseVertex> neighborVertexList = isSource2sink ?
                                                   graph.GetAdjacentVertices(vertex) : graph.GetPrecedentVertices(vertex);

            // 2. update the distance passing on current vertex
            foreach (BaseVertex curAdjacentVertex in neighborVertexList)
            {
                // 2.1 skip if visited before
                if (determinedVertexSet.Contains(curAdjacentVertex))
                {
                    continue;
                }

                // 2.2 calculate the new distance
                double distance = startVertexDistanceIndex.ContainsKey(vertex)?
                                  startVertexDistanceIndex[vertex] : Graph.DISCONNECTED;

                distance += isSource2sink ? graph.GetEdgeWeight(vertex, curAdjacentVertex)
                                            : graph.GetEdgeWeight(curAdjacentVertex, vertex);

                // 2.3 update the distance if necessary
                if (!startVertexDistanceIndex.ContainsKey(curAdjacentVertex) ||
                    startVertexDistanceIndex[curAdjacentVertex] > distance)
                {
                    startVertexDistanceIndex.AddOrReplace(curAdjacentVertex, distance);

                    predecessorIndex.AddOrReplace(curAdjacentVertex, vertex);

                    curAdjacentVertex.SetWeight(distance);
                    vertexCandidateQueue.add(curAdjacentVertex, curAdjacentVertex.GetWeight());
                }
            }
        }