예제 #1
0
        //Remove a node from the graph, and thus all of the edges connected to it
        public void removeNode(NodeMx <T> x)
        {
            //First remove all edges invovling this node
            for (int n = 0; n < edges.Count; n++)
            {
                if (edges[n].nodes[0].identifier == x.identifier || edges[n].nodes[1].identifier == x.identifier)
                {
                    //First remove the edge from the 2 nodes it connects
                    edges[n].nodes[0].removeEdge(edges[n]);
                    if (!edges[n].isDirected)
                    {
                        edges[n].nodes[1].removeEdge(edges[n]);
                    }

                    //Then remove from the graph
                    edges.RemoveAt(n);
                    edges.TrimExcess();
                    n = n - 1; //So we don't skip an element after removal
                }
            }
            edgeCount = edges.Count;

            //Then remove the node from the graph completely
            for (int n = 0; n < nodes.Count; n++)
            {
                if (nodes[n].identifier == x.identifier)
                {
                    nodes.RemoveAt(n);
                    nodes.TrimExcess();
                    nodeCount = nodes.Count;
                    break;
                }
            }
        }
        public static List <NodeMx <int> > BFS(GraphMx <int> G, int startNode)
        {
            List <NodeMx <int> > foundNodes = new List <NodeMx <int> >();

            Queue exploredNodes = new Queue();

            exploredNodes.Enqueue(G.nodes[startNode]);
            G.nodes[startNode].isVisited = true;

            while (exploredNodes.Count != 0)
            {
                NodeMx <int> v = (NodeMx <int>)exploredNodes.Dequeue();
                foundNodes.Add(v);
                for (int n = 0; n < v.nodeEdges.Count; n++)
                {
                    NodeMx <int> w = v.nodeEdges[n].nodes[1];
                    if (w.isVisited == false)
                    {
                        w.isVisited = true;
                        exploredNodes.Enqueue(w);
                    }
                }
            }
            return(foundNodes);
        }
 //If the edge is directed then the convention is that a is the tail, and b is the head
 public EdgeMx(NodeMx <T> a, NodeMx <T> b, bool directed, int i)
 {
     nodes[0]   = a;
     nodes[1]   = b;
     isDirected = directed;
     identifier = i;
 }
 //If the edge is un directed but weighted
 public EdgeMx(NodeMx <T> a, NodeMx <T> b, double edgeWeigt, int i)
 {
     nodes[0]   = a;
     nodes[1]   = b;
     isWeighted = true;
     weight     = edgeWeigt;
     identifier = i;
 }
예제 #5
0
        //Adds a directed weighted connection between nodes a and b
        public void addDirectedConnection(NodeMx <T> a, NodeMx <T> b, double w)
        {
            EdgeMx <T> edgeA = new EdgeMx <T>(a, b, w, uniqueNodeID);

            edges.Add(edgeA);
            a.addEdge(edgeA);
            edgeCount = edges.Count;
            uniqueNodeID++;
        }
        public int CompareTo(object obj)
        {
            if (obj == null)
            {
                return(1);
            }
            NodeMx <T> n = obj as NodeMx <T>;

            return(this.identifier.CompareTo(n.identifier));
        }
예제 #7
0
        //Creates and unweights and undirected connection between nodes a and b
        public void addConnection(NodeMx <T> a, NodeMx <T> b)
        {
            EdgeMx <T> edgeA = new EdgeMx <T>(a, b, uniqueEdgeID);
            EdgeMx <T> edgeB = new EdgeMx <T>(b, a, uniqueEdgeID);

            edges.Add(edgeA);
            a.addEdge(edgeA);
            b.addEdge(edgeB);
            edgeCount = edges.Count;
            uniqueEdgeID++;
        }
        public static List <NodeMx <int> > DFS(GraphMx <int> G, int startNode)
        {
            List <NodeMx <int> > foundNodes = new List <NodeMx <int> >();

            NodeMx <int> s = G.nodes[startNode];

            s.isVisited = true;
            foundNodes.Add(s);

            for (int n = 0; n < s.nodeEdges.Count; n++)
            {
                NodeMx <int> v = s.nodeEdges[n].nodes[1];
                if (v.isVisited == false)
                {
                    v.isVisited = true;
                    List <NodeMx <int> > foundNodesTemp = DFS(G, v.identifier);
                    foundNodes.AddRange(foundNodesTemp);
                }
            }

            return(foundNodes);
        }
        public static double[] DijkstraShortestPath(GraphMx <int> G, int S, out List <NodeMx <int> >[] paths)
        {
            double[] shortestPaths = new double[G.nodeCount];
            paths = new List <NodeMx <int> > [G.nodeCount];

            //Set all the initials shortest paths to basically infinity and then reassign them to an
            //initial value of -1 for the nodes that are reachable
            for (int n = 0; n < shortestPaths.Length; n++)
            {
                shortestPaths[n] = Double.MaxValue;
            }

            //First we need to figure out which nodes arent reachable from out starting node S.
            List <NodeMx <int> > ReachableNodes = BFS(G, S);

            for (int n = 0; n < ReachableNodes.Count; n++)
            {
                shortestPaths[ReachableNodes[n].identifier] = -1;
            }

            //During the process of the breadth first search (BFS) we will have set the "isVisited" flag to true
            //for each node which we now need to undo
            for (int n = 0; n < G.nodeCount; n++)
            {
                G.nodes[n].isVisited = false;
            }

            //Initialize the paths to unreachable nodes as null
            for (int n = 0; n < G.nodeCount; n++)
            {
                if (shortestPaths[n] > -1)
                {
                    paths[n] = null;
                }
                else
                {
                    paths[n] = new List <NodeMx <int> >();
                    paths[n].Add(G.nodes[S]);
                }
            }

            //Initialize our explored nodes with our starting node
            List <NodeMx <int> > exploredNodes = new List <NodeMx <int> >();

            exploredNodes.Add(G.nodes[S]);
            G.nodes[S].isVisited = true;
            shortestPaths[S]     = 0;


            while (exploredNodes.Count < ReachableNodes.Count)
            {
                //For each node we have explored
                List <EdgeMx <int> > edgesToConsider = new List <EdgeMx <int> >();
                for (int n = 0; n < exploredNodes.Count; n++)
                {
                    NodeMx <int> tempNodeTail = exploredNodes[n];

                    //Find all of its edges in the region which we have not yet explored
                    for (int m = 0; m < tempNodeTail.nodeEdges.Count; m++)
                    {
                        NodeMx <int> tempNodeHead = tempNodeTail.nodeEdges[m].nodes[1];
                        if (tempNodeHead.isVisited == false)
                        {
                            edgesToConsider.Add(tempNodeTail.nodeEdges[m]);
                        }
                    }
                }

                //Now that we have the list of candidate edges we need to compute the Dijkstra criteria for each edge
                EdgeMx <int> nextEdge   = edgesToConsider[0];
                double       DijstraMin = Double.MaxValue;
                double       tempDijkstra;
                for (int n = 0; n < edgesToConsider.Count; n++)
                {
                    tempDijkstra = shortestPaths[edgesToConsider[n].nodes[0].identifier] + edgesToConsider[n].weight;
                    if (tempDijkstra < DijstraMin)
                    {
                        DijstraMin = tempDijkstra;
                        nextEdge   = edgesToConsider[n];
                    }
                }

                //Now that we have found the edge that minimizes the Dijkstra criteria we will add the node at the
                //head of the edge to the list of explored nodes and update its shortest path length and shortest
                //path in our other variables
                NodeMx <int> nodeToAdd = nextEdge.nodes[1];
                nodeToAdd.isVisited = true;
                exploredNodes.Add(nodeToAdd);

                //The shortest path of the node we are going to add is equal to the shortest path of the node from which we
                //came from plus the weight of the edge
                shortestPaths[nodeToAdd.identifier] = shortestPaths[nextEdge.nodes[0].identifier] + nextEdge.weight;
                List <NodeMx <int> > pathUptillNow = paths[nextEdge.nodes[0].identifier];
                for (int n = 1; n < pathUptillNow.Count; n++)
                {
                    paths[nodeToAdd.identifier].Add(pathUptillNow[n]);
                }
                paths[nodeToAdd.identifier].Add(nodeToAdd);
            }

            return(shortestPaths);
        }
예제 #10
0
 //Default constructor for the undirected and unweighted case
 public EdgeMx(NodeMx <T> a, NodeMx <T> b, int i)
 {
     nodes[0]   = a;
     nodes[1]   = b;
     identifier = i;
 }