void findSpanningForest(graph &g, graph &sf) // Create a graph sf that contains a spanning forest on the graph g. { if (isConnected(g) && !isCyclic(g)) { sf = g; } else { // add nodes to sf for (int i = 0; i < g.numNodes(); i++) { sf.addNode(g.getNode(i)); } // build sf for (int i = 0; i < g.numNodes(); i++) { for (int j = 0; j < g.numNodes(); j++) { if (g.isEdge(i, j) && !sf.isEdge(i, j)) { sf.addEdge(i, j, g.getEdgeWeight(i, j)); sf.addEdge(j, i, g.getEdgeWeight(j, i)); if(isCyclic(sf)) { sf.removeEdge(j, i); sf.removeEdge(i, j); } // if } // if } // for } // for } // else } // findSpanningForest
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; }
bool isConnected(graph &g) // Returns true if the graph g is connected. Otherwise returns false. { queue<int> que; int id=0,count=1; que.push(id); g.visit(id); while(count<g.numNodes() && !que.empty()) { id=que.front(); for(int i=0;i<g.numNodes();i++) { if (g.isEdge(id,i) && !g.isVisited(i)) { g.visit(i); que.push(i); count++; } } que.pop(); } for (int z=0;z<g.numNodes();z++) g.unVisit(z); if(count==g.numNodes()) return true; else return false; }
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; }
bool eq(graph &g1, graph &g2) { if (g1.numNodes() != g2.numNodes()) { return false; } for (int n = 0; n < g1.numNodes(); n++) { if(g1.getColor(n) != g2.getColor(n)) { return false; } } return true; }
bool isCyclic(graph &g) // Returns true if the graph g contains a cycle. Otherwise, returns false. { queue<int> que; int id=0,count=1; bool first=true; vector<int> parentCount(g.numNodes(),-1); que.push(id); g.visit(id); while(count<g.numNodes() || !que.empty()) { if (que.empty()) { id=count; que.push(id); g.visit(id); count++; } else id=que.front(); for(int i=0;i<g.numNodes();i++) { if (g.isEdge(id,i) && i!=que.front()) { if(!g.isVisited(i)) { g.visit(i); que.push(i); count++; parentCount[i]=id; } else if(parentCount[id]==i) continue; else { for (int z=0;z<g.numNodes();z++) g.unVisit(z); return true; } } } que.pop(); } for (int z=0;z<g.numNodes();z++) g.unVisit(z); return false; }
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 findSpanningForest(graph &g, graph &sf) // Create a graph sf that contains a spanning forest on the graph g. { queue<int> que; int id=0,count=1; bool first=true; vector<int> parentCount(g.numNodes(),-1); que.push(id); g.visit(id); while(count<g.numNodes() || !que.empty()) { if (que.empty()) { id=count; que.push(id); g.visit(id); count++; } else id=que.front(); for(int i=0;i<g.numNodes();i++) { if (g.isEdge(id,i) && i!=que.front()) { if(!g.isVisited(i) && parentCount[id]!=i) { g.visit(i); sf.addEdge(id,i,g.getEdgeWeight(i,id)); sf.addEdge(i,id,g.getEdgeWeight(i,id)); que.push(i); count++; parentCount[id]++; } } } que.pop(); } for (int z=0;z<g.numNodes();z++) g.unVisit(z); }
void prim(graph &g, graph &msf) // Given a weighted graph g, sets msf equal to a minimum spanning // forest on g. Uses Prim's algorithm. { // build msf for (int i = 0; i < g.numNodes(); i++) { msf.addNode(g.getNode(i)); } // populate msf using findMSF for (int i = 0; i < g.numNodes(); i++) { if (!g.isVisited(i)) { findMSF(g, msf, i); } } } // prim
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; }
vector<int> getNeighbors(graph &g, int current) // loops through nodes and check if there is an edge between // current and node, returns a vector of neighboring nodes { vector<int> neighbors; for (int i = 0; i < g.numNodes(); i++) { if (g.isEdge(current, i)) neighbors.push_back(i); } return neighbors; }
void findSpanningForest(graph &g, graph &sf) // Create a graph sf that contains a spanning forest on the graph g. { g.clearVisit(); // if a node is not visited, call dfsAddEdges on it // to create a tree with the node as the start for (int i = 0; i < sf.numNodes(); i++) { if (!sf.isVisited(i)) dfsAddEdges(g, i, sf); } }
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); }
bool isConnected(graph &g) // Returns true if the graph g is connected. Otherwise returns false. { g.clearVisit(); int start = 0; dfs(g, start); for (int i = 0; i < g.numNodes(); i++) { if (!g.isVisited(i)) return false; } return true; }
vector<int> getNeighbors(int id, graph &g) // get all neighbors of the node with given id in graph g { vector<int> lst; for (int i = 0; i < g.numNodes(); i++) { if (g.isEdge(id, i)) { lst.push_back(i); } } return lst; }
vector<int> getNeighbors(int id, graph &g) // get all neighbors of the node (id) in the graph (g) { vector<int> lst; for (int i = 0; i < g.numNodes(); i++) { if (g.isEdge(id, i)) { lst.push_back(i); } } // for return lst; } // getNeighbors
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); } } } } } }
int numComponents(graph &sf) // given a spanning forest, finds the number of trees, // or connected components in that forest { int components = 0; sf.clearVisit(); for (int i = 0; i < sf.numNodes(); i++) { if (!sf.isVisited(i)) { dfs(sf, i); components++; } } return components; }
//unmodified natural greedy algortihm // int naturalGreedyColoring(graph &g, int numColors, int t) { //vector to hold answer with least conflicts seen so far //initially ever node is color 0 //can be usd in testing //vector<int> answer(g.numNodes(), 0); //iterate over all nodes for (int n = 0; n < g.numNodes(); n++) { //can be used in testing //answer[n] = g.getfirstAvailColor(n, numColors); //pick color with fewest conflicts and assign to node g.setColor(n, g.getfirstAvailColor(n, numColors)); } return g.numConflicts(); }
bool isCyclic(graph &g) // Returns true if the graph g contains a cycle. Otherwise, returns false. // checks all spanning tree components in the graph { g.clearVisit(); int prev = NONE; for (int i = 0; i < g.numNodes(); i++) { // if node is not visited, call traversal with it as the start if (!g.isVisited(i) && dfsCyclic(g, i, prev)) return true; } return false; }
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
// 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 isCyclic(graph &g,int nodeNumber) // Returns true if the graph g contains a cycle. Otherwise, returns false. { if (g.isVisited(nodeNumber)) { return true; } //Visit the node g.visit(nodeNumber); for (int i=0;i<g.numNodes();i++) { if (g.isEdge(nodeNumber,i)) { return isCyclic(g,i); } } return false; }
// Helper Functions void visitNodes(int start, graph &g) // Visit all nodes reachable from the start node { bool found = false; // Mark the start node as visited. g.visit(start); int v = 0; // Keep looking for legal moves as long as there are more neighbors // to check. while (!found && v < g.numNodes()) { // if v is an unvisited neighbor of the start node, recurse. if (g.isEdge(start, v) && !g.isVisited(v)) { visitNodes(v, g); } v++; } } // visitNodes
//method finds coloring of graph to minimize conflicts //returns number of conflicts int exhaustiveColoring(graph &g, int numColors, int t) { //vector to hold answer with least conflicts seen so far //initially ever node is color 1 vector<int> bestAnswer(g.numNodes(), 1); //vector to hold answer currently being tested //also set to all color 1 vector<int> currentAnswer = bestAnswer; //int to hold number of conflicts in bestAnswer //initialized to max number of cnflicts for given graph int conflicts = g.numEdges(); //initilize starting time double startTime = (double) (clock() / CLOCKS_PER_SEC); //while time elapsed is within given time while ( (double)(clock() / CLOCKS_PER_SEC) - startTime < t) { //change graph to have coloration of currentAnswer for (int i = 0; i < currentAnswer.size(); i++) { g.setColor(i, currentAnswer[i]); } //if current graph is asgood as or better than best graph //set best graph to current graph if (g.numConflicts() <= conflicts) { conflicts = g.numConflicts(); bestAnswer = currentAnswer; } //break if all permutations of colors have been tested //algorithm is done if (!increment(currentAnswer, numColors)) { break; } } //set coloration of graph to best rsult for (int i = 0; i < bestAnswer.size(); i++) { g.setColor(i, bestAnswer[i]); } return conflicts; }
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; } } } }