blob: 2ca0f1d49f63950a0d83effc5cb647563d9d0167 [file] [log] [blame]
Anand Shuklad3d1fcd2002-02-26 18:58:39 +00001//===--Graph.cpp--- implements Graph class ---------------- ------*- C++ -*--=//
2//
3// This implements Graph for helping in trace generation
Chris Lattner5328c6f2002-02-26 19:40:28 +00004// This graph gets used by "ProfilePaths" class
Anand Shuklad3d1fcd2002-02-26 18:58:39 +00005//
6//===----------------------------------------------------------------------===//
7
Anand Shukla21906892002-06-25 21:14:58 +00008#include "llvm/Transforms/Instrumentation/Graph.h"
Anand Shuklafd61c602002-07-18 20:56:47 +00009#include "llvm/iTerminators.h"
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000010#include "llvm/BasicBlock.h"
Chris Lattner3cf37822002-10-01 22:38:37 +000011#include "Support/Statistic.h"
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000012#include <algorithm>
Chris Lattner5328c6f2002-02-26 19:40:28 +000013
Anand Shukla21906892002-06-25 21:14:58 +000014//using std::list;
15//using std::set;
Chris Lattner5328c6f2002-02-26 19:40:28 +000016using std::map;
17using std::vector;
18using std::cerr;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000019
Anand Shukla21906892002-06-25 21:14:58 +000020const graphListElement *findNodeInList(const Graph::nodeList &NL,
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000021 Node *N) {
22 for(Graph::nodeList::const_iterator NI = NL.begin(), NE=NL.end(); NI != NE;
23 ++NI)
24 if (*NI->element== *N)
25 return &*NI;
26 return 0;
27}
28
Anand Shukla21906892002-06-25 21:14:58 +000029graphListElement *findNodeInList(Graph::nodeList &NL, Node *N) {
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000030 for(Graph::nodeList::iterator NI = NL.begin(), NE=NL.end(); NI != NE; ++NI)
31 if (*NI->element== *N)
32 return &*NI;
33 return 0;
34}
35
36//graph constructor with root and exit specified
Anand Shukla21906892002-06-25 21:14:58 +000037Graph::Graph(std::vector<Node*> n, std::vector<Edge> e,
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000038 Node *rt, Node *lt){
39 strt=rt;
40 ext=lt;
Anand Shukla21906892002-06-25 21:14:58 +000041 for(vector<Node* >::iterator x=n.begin(), en=n.end(); x!=en; ++x)
42 //nodes[*x] = list<graphListElement>();
43 nodes[*x] = vector<graphListElement>();
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000044
Anand Shukla21906892002-06-25 21:14:58 +000045 for(vector<Edge >::iterator x=e.begin(), en=e.end(); x!=en; ++x){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000046 Edge ee=*x;
47 int w=ee.getWeight();
Anand Shukla21906892002-06-25 21:14:58 +000048 //nodes[ee.getFirst()].push_front(graphListElement(ee.getSecond(),w, ee.getRandId()));
49 nodes[ee.getFirst()].push_back(graphListElement(ee.getSecond(),w, ee.getRandId()));
Anand Shuklad3d1fcd2002-02-26 18:58:39 +000050 }
51
52}
53
Anand Shuklafd61c602002-07-18 20:56:47 +000054//sorting edgelist, called by backEdgeVist ONLY!!!
Anand Shuklaf94ad682002-09-16 05:26:51 +000055Graph::nodeList &Graph::sortNodeList(Node *par, nodeList &nl, vector<Edge> &be){
Anand Shuklafd61c602002-07-18 20:56:47 +000056 assert(par && "null node pointer");
57 BasicBlock *bbPar = par->getElement();
58
59 if(nl.size()<=1) return nl;
Anand Shuklaf94ad682002-09-16 05:26:51 +000060 if(getExit() == par) return nl;
Anand Shuklafd61c602002-07-18 20:56:47 +000061
62 for(nodeList::iterator NLI = nl.begin(), NLE = nl.end()-1; NLI != NLE; ++NLI){
63 nodeList::iterator min = NLI;
64 for(nodeList::iterator LI = NLI+1, LE = nl.end(); LI!=LE; ++LI){
65 //if LI < min, min = LI
Anand Shuklaf94ad682002-09-16 05:26:51 +000066 if(min->element->getElement() == LI->element->getElement() &&
67 min->element == getExit()){
Anand Shuklafd61c602002-07-18 20:56:47 +000068
Anand Shuklaf94ad682002-09-16 05:26:51 +000069 //same successors: so might be exit???
70 //if it is exit, then see which is backedge
71 //check if LI is a left back edge!
72
73 TerminatorInst *tti = par->getElement()->getTerminator();
74 BranchInst *ti = cast<BranchInst>(tti);
75
76 assert(ti && "not a branch");
77 assert(ti->getNumSuccessors()==2 && "less successors!");
78
79 BasicBlock *tB = ti->getSuccessor(0);
80 BasicBlock *fB = ti->getSuccessor(1);
81 //so one of LI or min must be back edge!
82 //Algo: if succ(0)!=LI (and so !=min) then succ(0) is backedge
83 //and then see which of min or LI is backedge
84 //THEN if LI is in be, then min=LI
85 if(LI->element->getElement() != tB){//so backedge must be made min!
86 for(vector<Edge>::iterator VBEI = be.begin(), VBEE = be.end();
87 VBEI != VBEE; ++VBEI){
88 if(VBEI->getRandId() == LI->randId){
89 min = LI;
90 break;
91 }
92 else if(VBEI->getRandId() == min->randId)
93 break;
94 }
95 }
96 else{// if(LI->element->getElement() != fB)
97 for(vector<Edge>::iterator VBEI = be.begin(), VBEE = be.end();
98 VBEI != VBEE; ++VBEI){
99 if(VBEI->getRandId() == min->randId){
100 min = LI;
101 break;
102 }
103 else if(VBEI->getRandId() == LI->randId)
104 break;
105 }
106 }
107 }
Anand Shuklafd61c602002-07-18 20:56:47 +0000108
Anand Shuklaf94ad682002-09-16 05:26:51 +0000109 else if (min->element->getElement() != LI->element->getElement()){
110 TerminatorInst *tti = par->getElement()->getTerminator();
111 BranchInst *ti = cast<BranchInst>(tti);
112 assert(ti && "not a branch");
113
114 if(ti->getNumSuccessors()<=1) continue;
115
116 assert(ti->getNumSuccessors()==2 && "less successors!");
117
118 BasicBlock *tB = ti->getSuccessor(0);
119 BasicBlock *fB = ti->getSuccessor(1);
120
121 if(tB == LI->element->getElement() || fB == min->element->getElement())
122 min = LI;
123 }
Anand Shuklafd61c602002-07-18 20:56:47 +0000124 }
125
126 graphListElement tmpElmnt = *min;
127 *min = *NLI;
128 *NLI = tmpElmnt;
129 }
130 return nl;
131}
132
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000133//check whether graph has an edge
134//having an edge simply means that there is an edge in the graph
135//which has same endpoints as the given edge
Anand Shuklafd61c602002-07-18 20:56:47 +0000136bool Graph::hasEdge(Edge ed){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000137 if(ed.isNull())
138 return false;
139
Anand Shuklafd61c602002-07-18 20:56:47 +0000140 nodeList &nli= nodes[ed.getFirst()]; //getNodeList(ed.getFirst());
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000141 Node *nd2=ed.getSecond();
142
143 return (findNodeInList(nli,nd2)!=NULL);
144
145}
146
147
148//check whether graph has an edge, with a given wt
149//having an edge simply means that there is an edge in the graph
150//which has same endpoints as the given edge
151//This function checks, moreover, that the wt of edge matches too
Anand Shuklafd61c602002-07-18 20:56:47 +0000152bool Graph::hasEdgeAndWt(Edge ed){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000153 if(ed.isNull())
154 return false;
155
156 Node *nd2=ed.getSecond();
Anand Shuklafd61c602002-07-18 20:56:47 +0000157 nodeList nli = nodes[ed.getFirst()];//getNodeList(ed.getFirst());
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000158
159 for(nodeList::iterator NI=nli.begin(), NE=nli.end(); NI!=NE; ++NI)
160 if(*NI->element == *nd2 && ed.getWeight()==NI->weight)
161 return true;
162
163 return false;
164}
165
166//add a node
167void Graph::addNode(Node *nd){
Anand Shukla21906892002-06-25 21:14:58 +0000168 vector<Node *> lt=getAllNodes();
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000169
Anand Shukla21906892002-06-25 21:14:58 +0000170 for(vector<Node *>::iterator LI=lt.begin(), LE=lt.end(); LI!=LE;++LI){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000171 if(**LI==*nd)
172 return;
173 }
Anand Shukla21906892002-06-25 21:14:58 +0000174 //chng
175 nodes[nd] =vector<graphListElement>(); //list<graphListElement>();
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000176}
177
178//add an edge
179//this adds an edge ONLY when
180//the edge to be added doesn not already exist
181//we "equate" two edges here only with their
182//end points
183void Graph::addEdge(Edge ed, int w){
184 nodeList &ndList = nodes[ed.getFirst()];
185 Node *nd2=ed.getSecond();
186
187 if(findNodeInList(nodes[ed.getFirst()], nd2))
188 return;
189
Anand Shukla21906892002-06-25 21:14:58 +0000190 //ndList.push_front(graphListElement(nd2,w, ed.getRandId()));
191 ndList.push_back(graphListElement(nd2,w, ed.getRandId()));//chng
Anand Shuklafd61c602002-07-18 20:56:47 +0000192 //sortNodeList(ed.getFirst(), ndList);
Anand Shukla21906892002-06-25 21:14:58 +0000193
194 //sort(ndList.begin(), ndList.end(), NodeListSort());
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000195}
196
197//add an edge EVEN IF such an edge already exists
198//this may make a multi-graph
199//which does happen when we add dummy edges
200//to the graph, for compensating for back-edges
201void Graph::addEdgeForce(Edge ed){
Anand Shukla21906892002-06-25 21:14:58 +0000202 //nodes[ed.getFirst()].push_front(graphListElement(ed.getSecond(),
203 //ed.getWeight(), ed.getRandId()));
204 nodes[ed.getFirst()].push_back
205 (graphListElement(ed.getSecond(), ed.getWeight(), ed.getRandId()));
206
Anand Shuklafd61c602002-07-18 20:56:47 +0000207 //sortNodeList(ed.getFirst(), nodes[ed.getFirst()]);
Anand Shukla21906892002-06-25 21:14:58 +0000208 //sort(nodes[ed.getFirst()].begin(), nodes[ed.getFirst()].end(), NodeListSort());
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000209}
210
211//remove an edge
212//Note that it removes just one edge,
213//the first edge that is encountered
214void Graph::removeEdge(Edge ed){
215 nodeList &ndList = nodes[ed.getFirst()];
216 Node &nd2 = *ed.getSecond();
217
218 for(nodeList::iterator NI=ndList.begin(), NE=ndList.end(); NI!=NE ;++NI) {
219 if(*NI->element == nd2) {
220 ndList.erase(NI);
221 break;
222 }
223 }
224}
225
Anand Shukla21906892002-06-25 21:14:58 +0000226//remove an edge with a given wt
227//Note that it removes just one edge,
228//the first edge that is encountered
229void Graph::removeEdgeWithWt(Edge ed){
230 nodeList &ndList = nodes[ed.getFirst()];
231 Node &nd2 = *ed.getSecond();
232
233 for(nodeList::iterator NI=ndList.begin(), NE=ndList.end(); NI!=NE ;++NI) {
234 if(*NI->element == nd2 && NI->weight==ed.getWeight()) {
235 ndList.erase(NI);
236 break;
237 }
238 }
239}
240
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000241//set the weight of an edge
242void Graph::setWeight(Edge ed){
243 graphListElement *El = findNodeInList(nodes[ed.getFirst()], ed.getSecond());
244 if (El)
245 El->weight=ed.getWeight();
246}
247
248
249
250//get the list of successor nodes
Anand Shuklafd61c602002-07-18 20:56:47 +0000251vector<Node *> Graph::getSuccNodes(Node *nd){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000252 nodeMapTy::const_iterator nli = nodes.find(nd);
253 assert(nli != nodes.end() && "Node must be in nodes map");
Anand Shuklafd61c602002-07-18 20:56:47 +0000254 const nodeList &nl = getNodeList(nd);//getSortedNodeList(nd);
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000255
Anand Shukla21906892002-06-25 21:14:58 +0000256 vector<Node *> lt;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000257 for(nodeList::const_iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI)
258 lt.push_back(NI->element);
259
260 return lt;
261}
262
Anand Shukla21906892002-06-25 21:14:58 +0000263//get the number of outgoing edges
264int Graph::getNumberOfOutgoingEdges(Node *nd) const {
265 nodeMapTy::const_iterator nli = nodes.find(nd);
266 assert(nli != nodes.end() && "Node must be in nodes map");
267 const nodeList &nl = nli->second;
268
269 int count=0;
270 for(nodeList::const_iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI)
271 count++;
272
273 return count;
274}
275
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000276//get the list of predecessor nodes
Anand Shuklafd61c602002-07-18 20:56:47 +0000277vector<Node *> Graph::getPredNodes(Node *nd){
Anand Shukla21906892002-06-25 21:14:58 +0000278 vector<Node *> lt;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000279 for(nodeMapTy::const_iterator EI=nodes.begin(), EE=nodes.end(); EI!=EE ;++EI){
280 Node *lnode=EI->first;
281 const nodeList &nl = getNodeList(lnode);
282
283 const graphListElement *N = findNodeInList(nl, nd);
284 if (N) lt.push_back(lnode);
285 }
286 return lt;
287}
288
Anand Shukla21906892002-06-25 21:14:58 +0000289//get the number of predecessor nodes
Anand Shuklafd61c602002-07-18 20:56:47 +0000290int Graph::getNumberOfIncomingEdges(Node *nd){
Anand Shukla21906892002-06-25 21:14:58 +0000291 int count=0;
292 for(nodeMapTy::const_iterator EI=nodes.begin(), EE=nodes.end(); EI!=EE ;++EI){
293 Node *lnode=EI->first;
294 const nodeList &nl = getNodeList(lnode);
295 for(Graph::nodeList::const_iterator NI = nl.begin(), NE=nl.end(); NI != NE;
296 ++NI)
297 if (*NI->element== *nd)
298 count++;
299 }
300 return count;
301}
302
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000303//get the list of all the vertices in graph
Anand Shukla21906892002-06-25 21:14:58 +0000304vector<Node *> Graph::getAllNodes() const{
305 vector<Node *> lt;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000306 for(nodeMapTy::const_iterator x=nodes.begin(), en=nodes.end(); x != en; ++x)
307 lt.push_back(x->first);
308
309 return lt;
310}
311
Anand Shukla21906892002-06-25 21:14:58 +0000312//get the list of all the vertices in graph
313vector<Node *> Graph::getAllNodes(){
314 vector<Node *> lt;
315 for(nodeMapTy::const_iterator x=nodes.begin(), en=nodes.end(); x != en; ++x)
316 lt.push_back(x->first);
317
318 return lt;
319}
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000320
321//class to compare two nodes in graph
322//based on their wt: this is used in
323//finding the maximal spanning tree
324struct compare_nodes {
325 bool operator()(Node *n1, Node *n2){
326 return n1->getWeight() < n2->getWeight();
327 }
328};
329
330
Chris Lattner5328c6f2002-02-26 19:40:28 +0000331static void printNode(Node *nd){
332 cerr<<"Node:"<<nd->getElement()->getName()<<"\n";
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000333}
334
335//Get the Maximal spanning tree (also a graph)
336//of the graph
337Graph* Graph::getMaxSpanningTree(){
338 //assume connected graph
339
340 Graph *st=new Graph();//max spanning tree, undirected edges
341 int inf=9999999;//largest key
Anand Shukla21906892002-06-25 21:14:58 +0000342 vector<Node *> lt = getAllNodes();
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000343
344 //initially put all vertices in vector vt
345 //assign wt(root)=0
346 //wt(others)=infinity
347 //
348 //now:
349 //pull out u: a vertex frm vt of min wt
350 //for all vertices w in vt,
351 //if wt(w) greater than
352 //the wt(u->w), then assign
353 //wt(w) to be wt(u->w).
354 //
355 //make parent(u)=w in the spanning tree
356 //keep pulling out vertices from vt till it is empty
357
358 vector<Node *> vt;
359
360 map<Node*, Node* > parent;
361 map<Node*, int > ed_weight;
362
363 //initialize: wt(root)=0, wt(others)=infinity
364 //parent(root)=NULL, parent(others) not defined (but not null)
Anand Shukla21906892002-06-25 21:14:58 +0000365 for(vector<Node *>::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000366 Node *thisNode=*LI;
367 if(*thisNode == *getRoot()){
368 thisNode->setWeight(0);
369 parent[thisNode]=NULL;
370 ed_weight[thisNode]=0;
371 }
372 else{
373 thisNode->setWeight(inf);
374 }
375 st->addNode(thisNode);//add all nodes to spanning tree
376 //we later need to assign edges in the tree
377 vt.push_back(thisNode); //pushed all nodes in vt
378 }
379
380 //keep pulling out vertex of min wt from vt
381 while(!vt.empty()){
382 Node *u=*(min_element(vt.begin(), vt.end(), compare_nodes()));
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000383 DEBUG(cerr<<"popped wt"<<(u)->getWeight()<<"\n";
384 printNode(u));
385
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000386 if(parent[u]!=NULL){ //so not root
387 Edge edge(parent[u],u, ed_weight[u]); //assign edge in spanning tree
388 st->addEdge(edge,ed_weight[u]);
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000389
390 DEBUG(cerr<<"added:\n";
391 printEdge(edge));
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000392 }
393
394 //vt.erase(u);
395
396 //remove u frm vt
397 for(vector<Node *>::iterator VI=vt.begin(), VE=vt.end(); VI!=VE; ++VI){
398 if(**VI==*u){
399 vt.erase(VI);
400 break;
401 }
402 }
403
404 //assign wt(v) to all adjacent vertices v of u
405 //only if v is in vt
406 Graph::nodeList nl=getNodeList(u);
407 for(nodeList::iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI){
408 Node *v=NI->element;
409 int weight=-NI->weight;
410 //check if v is in vt
411 bool contains=false;
412 for(vector<Node *>::iterator VI=vt.begin(), VE=vt.end(); VI!=VE; ++VI){
413 if(**VI==*v){
414 contains=true;
415 break;
416 }
417 }
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000418 DEBUG(cerr<<"wt:v->wt"<<weight<<":"<<v->getWeight()<<"\n";
419 printNode(v);cerr<<"node wt:"<<(*v).weight<<"\n");
420
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000421 //so if v in in vt, change wt(v) to wt(u->v)
422 //only if wt(u->v)<wt(v)
423 if(contains && weight<v->getWeight()){
424 parent[v]=u;
425 ed_weight[v]=weight;
426 v->setWeight(weight);
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000427
428 DEBUG(cerr<<v->getWeight()<<":Set weight------\n";
429 printGraph();
430 printEdge(Edge(u,v,weight)));
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000431 }
432 }
433 }
434 return st;
435}
436
437//print the graph (for debugging)
438void Graph::printGraph(){
Anand Shukla21906892002-06-25 21:14:58 +0000439 vector<Node *> lt=getAllNodes();
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000440 cerr<<"Graph---------------------\n";
Anand Shukla21906892002-06-25 21:14:58 +0000441 for(vector<Node *>::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000442 cerr<<((*LI)->getElement())->getName()<<"->";
443 Graph::nodeList nl=getNodeList(*LI);
444 for(Graph::nodeList::iterator NI=nl.begin(), NE=nl.end(); NI!=NE; ++NI){
445 cerr<<":"<<"("<<(NI->element->getElement())
446 ->getName()<<":"<<NI->element->getWeight()<<","<<NI->weight<<")";
447 }
448 cerr<<"--------\n";
449 }
450}
451
452
453//get a list of nodes in the graph
454//in r-topological sorted order
455//note that we assumed graph to be connected
Anand Shuklafd61c602002-07-18 20:56:47 +0000456vector<Node *> Graph::reverseTopologicalSort(){
Anand Shukla21906892002-06-25 21:14:58 +0000457 vector <Node *> toReturn;
458 vector<Node *> lt=getAllNodes();
459 for(vector<Node *>::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000460 if((*LI)->getWeight()!=GREY && (*LI)->getWeight()!=BLACK)
461 DFS_Visit(*LI, toReturn);
462 }
Anand Shuklafd61c602002-07-18 20:56:47 +0000463
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000464 return toReturn;
465}
466
467//a private method for doing DFS traversal of graph
468//this is used in determining the reverse topological sort
469//of the graph
Anand Shuklafd61c602002-07-18 20:56:47 +0000470void Graph::DFS_Visit(Node *nd, vector<Node *> &toReturn){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000471 nd->setWeight(GREY);
Anand Shukla21906892002-06-25 21:14:58 +0000472 vector<Node *> lt=getSuccNodes(nd);
473 for(vector<Node *>::iterator LI=lt.begin(), LE=lt.end(); LI!=LE; ++LI){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000474 if((*LI)->getWeight()!=GREY && (*LI)->getWeight()!=BLACK)
475 DFS_Visit(*LI, toReturn);
476 }
477 toReturn.push_back(nd);
478}
479
480//Ordinarily, the graph is directional
481//this converts the graph into an
482//undirectional graph
483//This is done by adding an edge
484//v->u for all existing edges u->v
485void Graph::makeUnDirectional(){
Anand Shukla21906892002-06-25 21:14:58 +0000486 vector<Node* > allNodes=getAllNodes();
487 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000488 ++NI) {
489 nodeList nl=getNodeList(*NI);
490 for(nodeList::iterator NLI=nl.begin(), NLE=nl.end(); NLI!=NLE; ++NLI){
491 Edge ed(NLI->element, *NI, NLI->weight);
492 if(!hasEdgeAndWt(ed)){
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000493 DEBUG(cerr<<"######doesn't hv\n";
494 printEdge(ed));
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000495 addEdgeForce(ed);
496 }
497 }
498 }
499}
500
501//reverse the sign of weights on edges
502//this way, max-spanning tree could be obtained
503//usin min-spanning tree, and vice versa
504void Graph::reverseWts(){
Anand Shukla21906892002-06-25 21:14:58 +0000505 vector<Node *> allNodes=getAllNodes();
506 for(vector<Node *>::iterator NI=allNodes.begin(), NE=allNodes.end(); NI!=NE;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000507 ++NI) {
508 nodeList node_list=getNodeList(*NI);
509 for(nodeList::iterator NLI=nodes[*NI].begin(), NLE=nodes[*NI].end();
510 NLI!=NLE; ++NLI)
511 NLI->weight=-NLI->weight;
512 }
513}
514
515
516//getting the backedges in a graph
517//Its a variation of DFS to get the backedges in the graph
518//We get back edges by associating a time
519//and a color with each vertex.
520//The time of a vertex is the time when it was first visited
521//The color of a vertex is initially WHITE,
522//Changes to GREY when it is first visited,
523//and changes to BLACK when ALL its neighbors
524//have been visited
525//So we have a back edge when we meet a successor of
526//a node with smaller time, and GREY color
Anand Shuklafd61c602002-07-18 20:56:47 +0000527void Graph::getBackEdges(vector<Edge > &be, map<Node *, int> &d){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000528 map<Node *, Color > color;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000529 int time=0;
Anand Shuklaf94ad682002-09-16 05:26:51 +0000530
531 getBackEdgesVisit(getRoot(), be, color, d, time);
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000532}
533
534//helper function to get back edges: it is called by
535//the "getBackEdges" function above
536void Graph::getBackEdgesVisit(Node *u, vector<Edge > &be,
537 map<Node *, Color > &color,
Anand Shuklafd61c602002-07-18 20:56:47 +0000538 map<Node *, int > &d, int &time) {
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000539 color[u]=GREY;
540 time++;
541 d[u]=time;
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000542
Anand Shuklaf94ad682002-09-16 05:26:51 +0000543 vector<graphListElement> &succ_list = getNodeList(u);
Anand Shuklafd61c602002-07-18 20:56:47 +0000544
545 for(vector<graphListElement>::iterator vl=succ_list.begin(),
Anand Shukla21906892002-06-25 21:14:58 +0000546 ve=succ_list.end(); vl!=ve; ++vl){
547 Node *v=vl->element;
Anand Shuklaf94ad682002-09-16 05:26:51 +0000548 if(color[v]!=GREY && color[v]!=BLACK){
549 getBackEdgesVisit(v, be, color, d, time);
550 }
Anand Shuklafd61c602002-07-18 20:56:47 +0000551
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000552 //now checking for d and f vals
Anand Shukla21906892002-06-25 21:14:58 +0000553 if(color[v]==GREY){
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000554 //so v is ancestor of u if time of u > time of v
Anand Shukla21906892002-06-25 21:14:58 +0000555 if(d[u] >= d[v]){
556 Edge *ed=new Edge(u, v,vl->weight, vl->randId);
557 if (!(*u == *getExit() && *v == *getRoot()))
Anand Shuklad3d1fcd2002-02-26 18:58:39 +0000558 be.push_back(*ed); // choose the forward edges
559 }
560 }
561 }
562 color[u]=BLACK;//done with visiting the node and its neighbors
563}
564
565