Ejemplo n.º 1
0
 /// <summary>
 ///  Retrieves the shortest path from one node pf a graph edge to the other,
 ///  or calculates it if it has not yet been found.
 /// </summary>
 /// <param name="edge">The graph edge.</param>
 /// <returns>The shortest path from outside to inside, not containing either and ordered from inside to outside.</returns>
 public ushort[] GetShortestPath(GraphEdge edge)
 {
     return(GetShortestPath(edge.outside, edge.inside));
 }
Ejemplo n.º 2
0
 /// <summary>
 ///  Retrieves the path distance from one node pf a graph edge to the other,
 ///  or calculates it if it has not yet been found.
 /// </summary>
 /// <param name="edge">The graph edge.</param>
 /// <returns>The length of the graph edge (equals the amount of edges
 /// traversed).</returns>
 public int GetDistance(GraphEdge edge)
 {
     return(GetDistance(edge.outside, edge.inside));
 }
Ejemplo n.º 3
0
        /// <summary>
        ///  Uses Prim's algorithm to build an MST spanning the mstNodes.
        /// </summary>
        /// <param name="startFrom">A GraphNode to start from.</param>
        /// <returns>A list of GraphEdges forming the MST.</returns>
        public List <GraphEdge> Span(GraphNode startFrom)
        {
            /// With n nodes, we can have up to n (actually n-1) edges adjacent to each node.
            HeapPriorityQueue <GraphEdge> adjacentEdgeQueue = new HeapPriorityQueue <GraphEdge>(mstNodes.Count * mstNodes.Count);
            /// Removing all edges that satisfy a property (here a certain "outside"
            /// node) from the queue is not actually trivial, since you could only
            /// iterate over all entries (and you want to avoid that) if you don't
            /// have the references to the edges at hand.
            /// I guess this is the easiest way to do it...
            Dictionary <GraphNode, List <GraphEdge> > edgesLeadingToNode =
                new Dictionary <GraphNode, List <GraphEdge> >();

            foreach (GraphNode node in mstNodes)
            {
                edgesLeadingToNode[node] = new List <GraphEdge>();
            }

            // All nodes that are already included.
            HashSet <GraphNode> inMst = new HashSet <GraphNode>();
            // All nodes that are not yet included.
            HashSet <GraphNode> toAdd = new HashSet <GraphNode>(mstNodes);

            List <GraphEdge> mstEdges = new List <GraphEdge>();

            // Initialize the MST with the start nodes.
            inMst.Add(startFrom);
            toAdd.Remove(startFrom);
            edgesLeadingToNode[startFrom] = new List <GraphEdge>();
            foreach (GraphNode otherNode in toAdd)
            {
                GraphEdge adjacentEdge = new GraphEdge(startFrom, otherNode);
                adjacentEdgeQueue.Enqueue(adjacentEdge, distances.GetDistance(adjacentEdge));
                edgesLeadingToNode[otherNode].Add(adjacentEdge);
            }

            while (toAdd.Count > 0 && adjacentEdgeQueue.Count > 0)
            {
                GraphEdge shortestEdge = adjacentEdgeQueue.Dequeue();
                mstEdges.Add(shortestEdge);
                GraphNode newIn = shortestEdge.outside;


                //if (inMst.Contains(newIn)) throw new Exception();
                //if (!toAdd.Contains(newIn)) throw new Exception("No edge to this node should remain!");

                inMst.Add(newIn);
                toAdd.Remove(newIn);

                // Remove all edges that are entirely inside the MST now.
                foreach (GraphEdge obsoleteEdge in edgesLeadingToNode[newIn])
                {
                    //if (!inMst.Contains(obsoleteEdge.inside)) throw new Exception("This edge's inside node is not inside");
                    adjacentEdgeQueue.Remove(obsoleteEdge);
                }
                edgesLeadingToNode.Remove(newIn);

                // Find all newly adjacent edges and enqueue them.
                foreach (GraphNode otherNode in toAdd)
                {
                    GraphEdge adjacentEdge = new GraphEdge(newIn, otherNode);
                    adjacentEdgeQueue.Enqueue(adjacentEdge, distances.GetDistance(adjacentEdge));
                    edgesLeadingToNode[otherNode].Add(adjacentEdge);
                }
            }
            if (toAdd.Count > 0)
            {
                throw new DistanceLookup.GraphNotConnectedException();
            }

            this.SpanningEdges = mstEdges;
            _isSpanned         = true;
            return(mstEdges);
        }
Ejemplo n.º 4
0
 /// <summary>
 ///  Retrieves the path distance from one node pf a graph edge to the other,
 ///  or calculates it if it has not yet been found.
 /// </summary>
 /// <param name="edge">The graph edge.</param>
 /// <returns>The length of the graph edge (equals the amount of edges
 /// traversed).</returns>
 public int GetDistance(GraphEdge edge)
 {
     return GetDistance(edge.outside, edge.inside);
 }
Ejemplo n.º 5
0
 /// <summary>
 ///  Retrieves the shortest path from one node pf a graph edge to the other,
 ///  or calculates it if it has not yet been found.
 /// </summary>
 /// <param name="edge">The graph edge.</param>
 /// <returns>The shortest path from outside to inside, not containing either and ordered from inside to outside.</returns>
 public ushort[] GetShortestPath(GraphEdge edge)
 {
     return GetShortestPath(edge.outside, edge.inside);
 }
Ejemplo n.º 6
0
        /// <summary>
        ///  Uses Prim's algorithm to build an MST spanning the mstNodes.
        /// </summary>
        /// <param name="startFrom">A GraphNode to start from.</param>
        /// <returns>A list of GraphEdges forming the MST.</returns>
        public List<GraphEdge> Span(GraphNode startFrom)
        {
            /// With n nodes, we can have up to n (actually n-1) edges adjacent to each node.
            HeapPriorityQueue<GraphEdge> adjacentEdgeQueue = new HeapPriorityQueue<GraphEdge>(mstNodes.Count * mstNodes.Count);
            /// Removing all edges that satisfy a property (here a certain "outside"
            /// node) from the queue is not actually trivial, since you could only
            /// iterate over all entries (and you want to avoid that) if you don't
            /// have the references to the edges at hand.
            /// I guess this is the easiest way to do it...
            Dictionary<GraphNode, List<GraphEdge>> edgesLeadingToNode =
                new Dictionary<GraphNode, List<GraphEdge>>();
            foreach (GraphNode node in mstNodes)
                edgesLeadingToNode[node] = new List<GraphEdge>();

            // All nodes that are already included.
            HashSet<GraphNode> inMst = new HashSet<GraphNode>();
            // All nodes that are not yet included.
            HashSet<GraphNode> toAdd = new HashSet<GraphNode>(mstNodes);

            List<GraphEdge> mstEdges = new List<GraphEdge>();

            // Initialize the MST with the start nodes.
            inMst.Add(startFrom);
            toAdd.Remove(startFrom);
            edgesLeadingToNode[startFrom] = new List<GraphEdge>();
            foreach (GraphNode otherNode in toAdd)
            {
                GraphEdge adjacentEdge = new GraphEdge(startFrom, otherNode);
                adjacentEdgeQueue.Enqueue(adjacentEdge, distances.GetDistance(adjacentEdge));
                edgesLeadingToNode[otherNode].Add(adjacentEdge);
            }

            while (toAdd.Count > 0 && adjacentEdgeQueue.Count > 0)
            {
                GraphEdge shortestEdge = adjacentEdgeQueue.Dequeue();
                mstEdges.Add(shortestEdge);
                GraphNode newIn = shortestEdge.outside;

                //if (inMst.Contains(newIn)) throw new Exception();
                //if (!toAdd.Contains(newIn)) throw new Exception("No edge to this node should remain!");

                inMst.Add(newIn);
                toAdd.Remove(newIn);

                // Remove all edges that are entirely inside the MST now.
                foreach (GraphEdge obsoleteEdge in edgesLeadingToNode[newIn])
                {
                    //if (!inMst.Contains(obsoleteEdge.inside)) throw new Exception("This edge's inside node is not inside");
                    adjacentEdgeQueue.Remove(obsoleteEdge);
                }
                edgesLeadingToNode.Remove(newIn);

                // Find all newly adjacent edges and enqueue them.
                foreach (GraphNode otherNode in toAdd)
                {
                    GraphEdge adjacentEdge = new GraphEdge(newIn, otherNode);
                    adjacentEdgeQueue.Enqueue(adjacentEdge, distances.GetDistance(adjacentEdge));
                    edgesLeadingToNode[otherNode].Add(adjacentEdge);
                }
            }
            if (toAdd.Count > 0)
                throw new DistanceLookup.GraphNotConnectedException();

            this.SpanningEdges = mstEdges;
            _isSpanned = true;
            return mstEdges;
        }