void prim(graph &g, graph &sf) // from weighted graph g, set sf to minimum spanning forest // finds the minimum cost edge from a marked node to an unmarked node and adds it // loop through all nodes and if a node is not marked, // start adding edges with it as start { g.clearMark(); for (int n = 0; n < g.numNodes(); n++) // loop through all nodes { if (!g.isMarked(n)) { g.mark(n); edgepair pair = getMinEdge(g); while (pair.i != NONE && pair.j != NONE) { // mark edge g.mark(pair.i, pair.j); g.mark(pair.j, pair.i); // add both edges to create undirected edge sf.addEdge(pair.i, pair.j, pair.cost); sf.addEdge(pair.j, pair.i, pair.cost); g.mark(pair.j); // mark the unmarked node pair = getMinEdge(g); // get next edge } } // if node is marked, just continue } }
void kruskal(graph &g, graph &sf) // from weighted graph g, set sf to minimum spanning forest // uses a priority queue with edges sorted from large to min weight // since top of queue is the back of underlying vector // for every edge, add to sf, but if it creates cycle, then // remove it and move to next edge { g.clearMark(); pqueue edges = getEdges(g); while (!edges.empty()) { edgepair pair = edges.top(); edges.pop(); // add both edges to create undirected edges sf.addEdge(pair.i, pair.j, pair.cost); sf.addEdge(pair.j, pair.i, pair.cost); if (isCyclic(sf)) { sf.removeEdge(pair.i, pair.j); sf.removeEdge(pair.j, pair.i); } } }
void maze::findPathNonRecursive(graph &g) // method for finding a path in the maze given a graph g representing the maze // uses a stack based DFS { g.clearVisit(); g.clearMark(); int start = getMap(0, 0); int end = getMap(numRows() - 1, numCols() - 1); vector< stack<int> > rpaths = nonRecursiveDFS(start, end, g); stack<int> reverse_path; for(int i = 0; i < rpaths.size(); i++) if (rpaths[i].size() > reverse_path.size()) reverse_path = rpaths[i]; stack<int> path; while (!reverse_path.empty()) { int top = reverse_path.top(); reverse_path.pop(); if (g.isVisited(top)) { path.push(top); } } printPath(path); }
bool maze::findShortestPath1(graph &g) //finds the shortest path in the given graph using DFS { g.clearVisit(); g.clearMark(); int start = getMap(0, 0); int end = getMap(numRows() - 1, numCols() - 1); vector< stack<int> > rpaths = nonRecursiveDFS(start, end, g); stack<int> reverse_path; for(int i = 0; i < rpaths.size(); i++) if (rpaths[i].size() > reverse_path.size()) reverse_path = rpaths[i]; stack<int> path; while (!reverse_path.empty()) { int top = reverse_path.top(); reverse_path.pop(); if (g.isVisited(top)) { path.push(top); } } printPath(path); }
int getNumComponents(graph &g) { g.clearMark(); g.clearVisit(); int numComponents = 0; queue<int> currentMoves; for (int n=0;n<g.numNodes();n++) { if (!g.isVisited(n)) { numComponents++; int nodeNumber=n; g.visit(nodeNumber); currentMoves.push(nodeNumber); while(currentMoves.size() > 0) { int currentNode = currentMoves.front(); currentMoves.pop(); //Populate a list of nodes that can be visited for (int i=0;i<g.numNodes();i++) { if (g.isEdge(currentNode,i) && !g.isVisited(i)) { g.mark(currentNode,i); g.visit(i); currentMoves.push(i); } } } } } return numComponents; }
// Project Functions bool isCyclic(graph &g) // Returns true if the graph g contains a cycle. Otherwise, returns false. { g.clearVisit(); g.clearMark(); bool cycle = false; for (int i = 0; i < g.numNodes(); i++) { if (!g.isVisited(i)) findCycle(i, i, cycle, g); } g.clearMark(); g.clearVisit(); return cycle; } // isCyclic
bool maze::findShortestPath2(graph &g) // finds the shortest path in the given graph using BFS { g.clearVisit(); g.clearMark(); int start = getMap(0, 0); int end = getMap(numRows() - 1, numCols() - 1); stack<int> path = nonRecursiveBFS(start, end, g); printPath(path); }
void maze::findPathRecursive(graph &g) // method for finding a path in the maze given a graph g representing the maze // uses recursion based DFS { g.clearVisit(); g.clearMark(); stack<int> path; int start = getMap(0, 0); int end = getMap(numRows() - 1, numCols() - 1); bool done = false; recursiveDFS(start, end, g, path, done); printPath(path); }
bool isConnected(graph &g) // Returns true if the graph g is connected. Otherwise returns false. { g.clearVisit(); g.clearMark(); visitNodes(0, g); // start at '0' the 'first' node for (int i = 0; i < g.numNodes(); i++) { if (!g.isVisited(i)) { return false; } } // for return true; } // isConnected
void kruskal(graph &g, graph &sf) // Given a weighted graph g, sets sf equal to a minimum spanning // forest on g. Uses Kruskal's algorithm. { g.clearMark(); g.clearVisit(); numComponents=0; while(!g.allNodesVisited()) { // find the smallest edge int smallestEdgeWeight = -1; int smallestEdgeBeg = -1; int smallestEdgeEnd = -1; for(int i = 0; i < g.numNodes(); i++) { for(int j = 0; j < g.numNodes(); j++) { if(g.isEdge(i, j) && !g.isVisited(i, j) && !g.isVisited(j, i) && (!g.isVisited(i) || !g.isVisited(j))) { if(g.getEdgeWeight(i, j) < smallestEdgeWeight || smallestEdgeWeight == -1) { smallestEdgeWeight = g.getEdgeWeight(i, j); smallestEdgeBeg = i; smallestEdgeEnd = j; } } } } // add the new edge g.visit(smallestEdgeBeg); g.visit(smallestEdgeEnd); g.visit(smallestEdgeBeg, smallestEdgeEnd); sf.addEdge(smallestEdgeBeg, smallestEdgeEnd); sf.setEdgeWeight(smallestEdgeBeg, smallestEdgeEnd, smallestEdgeWeight); } numComponents = getNumComponents(sf); }
void prim(graph &g, graph &sf) // Given a weighted graph g, sets sf equal to a minimum spanning // forest on g. Uses Prim's algorithm. { g.clearMark(); g.clearVisit(); numComponents=0; int currentNode = 0; while(!g.allNodesVisited()) { // find next currentNode while(g.isVisited(currentNode) && currentNode < g.numNodes()) { currentNode++; } g.visit(currentNode); int smallestEdgeWeight = -1; int smallestEdgeNode = -1; // find shortest new edge from currentNode for(int i = 0; i < g.numNodes(); i++) { if(g.isEdge(currentNode, i)) { if(g.getEdgeWeight(currentNode, i) < smallestEdgeWeight || smallestEdgeWeight == -1) { smallestEdgeWeight = g.getEdgeWeight(currentNode, i); smallestEdgeNode = i; } } } // add the new edge g.visit(smallestEdgeNode); sf.addEdge(currentNode, smallestEdgeNode); sf.setEdgeWeight(currentNode, smallestEdgeNode, smallestEdgeWeight); } numComponents = getNumComponents(sf); }
void findSpanningForest(graph &g, graph &sf) // Create a graph sf that contains a spanning forest on the graph g. { g.clearMark(); g.clearVisit(); numComponents=0; queue<int> currentMoves; for (int n=0;n<g.numNodes();n++) { if (!g.isVisited(n)) { numComponents++; int nodeNumber=n; g.visit(nodeNumber); currentMoves.push(nodeNumber); while(currentMoves.size() > 0) { int currentNode = currentMoves.front(); currentMoves.pop(); //Populate a list of nodes that can be visited for (int i=0;i<g.numNodes();i++) { if (g.isEdge(currentNode,i) && !g.isVisited(i)) { g.mark(currentNode,i); sf.addEdge(currentNode,i); sf.setEdgeWeight(currentNode, i, g.getEdgeWeight(currentNode, i)); g.visit(i); currentMoves.push(i); } } } } } }
void prim(graph &g, graph &sf) // Given a weighted graph g, sets sf equal to a minimum spanning // forest on g. Uses Prim's algorithm. { NodeWeight minWeight = 0; NodeWeight minR, minP; bool edgeFound; g.clearMark(); for(int i=0; i<g.numNodes(); i++) { if(!g.isMarked(i)) { g.mark(i); for(int j=0; j<g.numNodes()-1; j++) //start at i and grow a spanning tree untill no more can be added { edgeFound = false; minWeight = MaxEdgeWeight; for(int r=0; r<g.numNodes(); r++) { for(int p=0; p<g.numNodes(); p++) { if(g.isEdge(r,p) && g.isMarked(r) && !g.isMarked(p)) { if(g.getEdgeWeight(r,p) < minWeight) { minWeight = g.getEdgeWeight(r,p); minR= r; minP= p; edgeFound = true; } } } } //if edge was found add it to the tree if(edgeFound) { g.mark(minR,minP); g.mark(minP, minR); g.mark(minP); } } } } //add marked edges to spanning forest graph for(int i=0; i<g.numNodes(); i++) { for(int j=i+1; j<g.numNodes(); j++) { if(g.isEdge(i,j) && g.isMarked(i,j)) { sf.addEdge(i,j,g.getEdgeWeight(i,j)); sf.addEdge(j,i,g.getEdgeWeight(j,i)); cout<<"adding edge "<< i << " "<< j << endl; cout<<"num edges: "<<sf.numEdges() << endl; } } } }