edgepair getMinEdge(graph &g) // iterate through whole graph and finds the edge from // marked node to unmarked node with minimum weight // returns a struct with marked, unmarked, and weight { int minCost = HIGH; int marked = NONE; int unmarked = NONE; // find the minimum edge for (int i = 0; i < g.numNodes() ; i++) { if (g.isMarked(i)) { for (int j = 0; j < g.numNodes(); j++) { if (!g.isMarked(j) && g.isEdge(i, j) && g.getEdgeWeight(i, j) < minCost) { minCost = g.getEdgeWeight(i,j); marked = i; unmarked = j; } } } } edgepair pair = {marked, unmarked, minCost}; return pair; }
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 findCycle(int curr, int start, bool &found, graph &g) // checks for cycles in a graph { g.mark(curr); vector<int> lst = getNeighbors(curr, g); for (int i = 0; i < lst.size(); i++) { if (start == lst[i]) { continue; } if (g.isMarked(lst[i])) { found = true; } else if (!g.isVisited(lst[i])) { findCycle(lst[i], curr, found, g); } } // for g.unMark(curr); g.visit(curr); } // findCycle
void findMSF(graph &g, graph &sf, int start) // finds a minimum spanning tree in graph 'g' { priority_queue<edge, vector<edge>, CompareEdge> pq; vector<int> lst = getNeighbors(start, g); // build our priority queue for (int i = 0; i < lst.size(); i++) { pq.push(g.getEdge(start, lst[i])); g.mark(start, lst[i]); } // visit the start node g.visit(start); int src, dst, w; edge top; while (!pq.empty()) { top = pq.top(); pq.pop(); src = top.getSource(); dst = top.getDest(); w = top.getWeight(); // add edges if (!sf.isEdge(src, dst)) { sf.addEdge(src, dst, w); sf.addEdge(dst, src, w); // delete edges if we make a cycle if (isCyclic(sf)) { sf.removeEdge(src, dst); sf.removeEdge(dst, src); } else { g.visit(src); lst = getNeighbors(dst, g); for (int i = 0; i < lst.size(); i++) { if (!g.isMarked(dst, lst[i])) { pq.push(g.getEdge(dst, lst[i])); g.mark(dst, lst[i]); } } // for } // else } // if } // while } // findMSF
pqueue getEdges(graph &g) // iterate through graph and construct a priority queue with minimum cost // only add an edgepair for edge between marked node and unmarked node { pqueue edges; for (int i = 0; i < g.numNodes(); i++) { g.mark(i); for (int j = 0; j < g.numNodes(); j++) { if (g.isMarked(i) && !g.isMarked(j) && g.isEdge(i, j)) { edgepair pair = {i, j, g.getEdgeWeight(i, j)}; edges.push(pair); } } } return edges; }
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; } } } }