|
|
1.1 ! root 1: #include "draw_dag.h" ! 2: ! 3: #include <sys/types.h> ! 4: #include <sys/times.h> ! 5: #define TIC 60 ! 6: ! 7: /* ! 8: Assign levels to nodes of an acyclic digraph. ! 9: ! 10: Definition: the length of an edge is the difference ! 11: in the levels of its adjacent nodes. ! 12: ! 13: Optimization objective: minimize the total edge length ! 14: of all edges. ! 15: */ ! 16: static void setlevels(int,int), balance(); ! 17: ! 18: #ifdef DEBUG ! 19: static void verifylevel(), verifytree(), verifycycle(), fatal(), ! 20: checklevel(int*), checkcycle(), printtree(int); ! 21: #endif ! 22: ! 23: void dag_levels(int source, int sink, int hasequi) ! 24: { ! 25: struct tms begtm, endtm; ! 26: ! 27: if(Verbose) ! 28: { ! 29: #ifndef TIMING ! 30: fprintf(stderr,"Assign levels\n"); ! 31: #endif ! 32: times(&begtm); ! 33: } ! 34: ! 35: #ifdef DEBUG ! 36: verifycycle(); ! 37: #endif ! 38: ! 39: // space to store level assignments ! 40: Level = new int[N_nodes]; ! 41: ! 42: // solve associated lp problems ! 43: setlevels(source,sink); ! 44: #ifdef DEBUG ! 45: verifylevel(); ! 46: #endif ! 47: ! 48: // set levels for stems ! 49: if(N_flat_edges <= 0) ! 50: { ! 51: for(int in = 0; in < 2; ++in) ! 52: { ! 53: edge_t **edges = in ? Istems : Ostems; ! 54: for(int v = 0; v < N_nodes; ++v) ! 55: { ! 56: if(!edges[v]) ! 57: continue; ! 58: int lev = Level[v] + (in ? -1 : 1); ! 59: for(edge_t *e = edges[v]; e; e = e->next) ! 60: Level[e->node] = lev; ! 61: } ! 62: } ! 63: } ! 64: ! 65: // compute Maxlevel ! 66: Maxlevel = 0; ! 67: for(int v = 0; v < N_nodes; v++) ! 68: if(Level[v] > Maxlevel) ! 69: Maxlevel = Level[v]; ! 70: ! 71: // balance lists of nodes ! 72: if(!hasequi) ! 73: balance(); ! 74: #ifdef DEBUG ! 75: verifylevel(); ! 76: #endif ! 77: ! 78: if(Verbose) ! 79: { ! 80: times(&endtm); ! 81: int total = (endtm.tms_utime-begtm.tms_utime) + ! 82: (endtm.tms_stime-begtm.tms_stime); ! 83: int percent = (total - (total/TIC)*TIC)*100/TIC; ! 84: #ifdef TIMING ! 85: fprintf(stderr,"%d.%02d\t",total/TIC,percent); ! 86: #else ! 87: fprintf(stderr,"Time in level assignment: %d.%02ds\n", ! 88: total/TIC, percent); ! 89: fprintf(stderr,"Number of levels = %d\n",Maxlevel+1); ! 90: #endif ! 91: } ! 92: } ! 93: ! 94: ! 95: static void balance() ! 96: { ! 97: int *size = new int[N_nodes]; ! 98: for(int v = 0; v < N_nodes; v++) ! 99: size[Level[v]] += 1; ! 100: for (v = 0; v < N_nodes; ++v) ! 101: { ! 102: int inweight = 0, outweight = 0; ! 103: int low = 0, high = N_nodes; ! 104: ! 105: for (edge_t *e = Inedges[v]; e; e = e->next) ! 106: { ! 107: inweight += e->weight; ! 108: if (Level[e->node] > low) ! 109: low = Level[e->node]; ! 110: } ! 111: ! 112: for (e = Outedges[v]; e; e = e->next) ! 113: { ! 114: outweight += e->weight; ! 115: if (Level[e->node] < high) ! 116: high = Level[e->node]; ! 117: } ! 118: ! 119: if (inweight && (inweight == outweight) && (low+1 < high-1)) ! 120: { ! 121: int best = low+1; ! 122: for(int n = low+2; n < high; ++n) ! 123: if(size[n] < size[best]) ! 124: best = n; ! 125: size[Level[v]] -= 1; ! 126: size[best] += 1; ! 127: Level[v] = best; ! 128: } ! 129: } ! 130: delete size; ! 131: } ! 132: ! 133: ! 134: ! 135: /* ! 136: Below are data structures and code for the network simplex algorithm. ! 137: */ ! 138: static struct edge_l ! 139: { ! 140: int node; // the other end ! 141: int weight; // edge weight ! 142: int minlen; // minimum edge length ! 143: int cutvalue; // value of cut set if this is a tree edge ! 144: edge_l *next; // doubly linked for constant time insert/delete ! 145: edge_l *last; ! 146: edge_l *link; // links for identifying pairs of out/in edges ! 147: ! 148: // this routine assume edge insertions are done at the head of the list ! 149: edge_l(int innode, int inweight, int inminlen, edge_l *innext) ! 150: { ! 151: node = innode; ! 152: weight = inweight; ! 153: minlen = inminlen; ! 154: cutvalue = 0; ! 155: last = NULL; ! 156: next = innext; ! 157: if(innext) ! 158: innext->last = this; ! 159: } ! 160: }; ! 161: ! 162: static edge_l **Oedges, // static in/out-edge lists. No multiple edges ! 163: **Iedges, // are in these lists. ! 164: **Itree, // Edges in a feasible spanning tree ! 165: **Otree; ! 166: ! 167: static int n_nodes, // number of mega-nodes ! 168: *Merge; // mapping from normal nodes to mega-nodes. ! 169: // The mega-nodes are nodes resulted from ! 170: // merging sets of nodes which are specified ! 171: // to be on the same levels. ! 172: ! 173: ! 174: // add a new edge ! 175: static void addedge(int tail, int head, int weight, int minlen) ! 176: { ! 177: // map real nodes to corresponding mega-nodes ! 178: head = Merge[head]; ! 179: tail = Merge[tail]; ! 180: ! 181: // check for multiple edges ! 182: for(edge_l *e = Oedges[tail]; e; e = e->next) ! 183: if(e->node == head) ! 184: { ! 185: e->weight += weight; ! 186: e->link->weight += weight; ! 187: e->minlen = max(e->minlen,minlen); ! 188: return; ! 189: } ! 190: ! 191: // a new edge ! 192: Oedges[tail] = new edge_l(head,weight,minlen,Oedges[tail]); ! 193: Iedges[head] = new edge_l(tail,weight,minlen,Iedges[head]); ! 194: ! 195: // link the two versions of the edge ! 196: Oedges[tail]->link = Iedges[head]; ! 197: Iedges[head]->link = Oedges[tail]; ! 198: } ! 199: ! 200: ! 201: // delete an edge from its linked list ! 202: static void delete_edge(edge_l *e, edge_l **elist) ! 203: { ! 204: if(e->last) ! 205: e->last->next = e->next; ! 206: else elist[0] = e->next; ! 207: if(e->next) ! 208: e->next->last = e->last; ! 209: } ! 210: ! 211: ! 212: // insert an edge into a linked list ! 213: static void insert_edge(edge_l *e, edge_l **elist) ! 214: { ! 215: e->last = NULL; ! 216: e->next = elist[0]; ! 217: if(elist[0]) ! 218: elist[0]->last = e; ! 219: elist[0] = e; ! 220: } ! 221: ! 222: ! 223: // breadth-first search for initial level assignment ! 224: static int bfs(int me,int *level,edge_l **edges,int *queue,int *marked,int iter) ! 225: { ! 226: #define ENQUEUE(x) queue[tail] = x; if(++tail >= n_nodes) tail = 0; ! 227: #define DEQUEUE(x) x = queue[head]; if(++head >= n_nodes) head = 0; ! 228: #define NOTNULL() head != tail ! 229: ! 230: int head = 0, tail = 0; ! 231: ENQUEUE(me); ! 232: ! 233: int level_inc = edges == Oedges ? 1 : -1; ! 234: int n_bfs = 0; ! 235: while(NOTNULL()) ! 236: { ! 237: DEQUEUE(me); ! 238: for(edge_l *e = edges[me]; e; e = e->next) ! 239: { ! 240: int it = e->node; ! 241: int length = level_inc*(level[it]-level[me]); ! 242: ! 243: if(level[it] == Maxint || length < e->minlen) ! 244: { ! 245: ENQUEUE(it); ! 246: marked[it] = iter; ! 247: n_bfs++; ! 248: level[it] = level[me] + level_inc*e->minlen; ! 249: } ! 250: } ! 251: } ! 252: return n_bfs; ! 253: } ! 254: ! 255: ! 256: ! 257: // construct an initial level assignment ! 258: static void initlevel(int me,int *level,int *queue,int *marked) ! 259: { ! 260: for(int n = 0; n < n_nodes; ++n) ! 261: marked[n] = 0; ! 262: level[me] = 0; ! 263: marked[me] = 2; ! 264: ! 265: // level assignment ! 266: for(int iter = 1;; ++iter) ! 267: { ! 268: // odd iter: search down, even iter: search up ! 269: edge_l **edges = iter%2 ? Oedges : Iedges; ! 270: ! 271: int nextiter = iter+1; ! 272: int alldone = 1; ! 273: for(n = 0; n < n_nodes; ++n) ! 274: if(marked[n] >= iter) ! 275: { ! 276: if(bfs(n,level,edges,queue,marked,nextiter) > 0) ! 277: alldone = 0; ! 278: if(marked[n] > iter && alldone) ! 279: alldone = 0; ! 280: } ! 281: if(alldone) ! 282: return; ! 283: } ! 284: } ! 285: ! 286: ! 287: // compute a feasible spanning tree ! 288: static void spantree(int me, int *level, int *queue, int *marked) ! 289: { ! 290: for(int v = 0; v < n_nodes; ++v) ! 291: marked[v] = 0; ! 292: ! 293: int head = 0, tail = 0; ! 294: ENQUEUE(me); ! 295: marked[me] = 1; ! 296: while(NOTNULL()) ! 297: { ! 298: DEQUEUE(me); ! 299: for(int isdown = 0; isdown < 2; ++isdown) ! 300: { ! 301: int dir = isdown ? 1 : -1; ! 302: edge_l **these_edges = isdown ? Oedges : Iedges; ! 303: edge_l **those_edges = isdown ? Iedges : Oedges; ! 304: edge_l **these_tree = isdown ? Otree : Itree; ! 305: edge_l **those_tree = isdown ? Itree : Otree; ! 306: ! 307: edge_l *e, *enext; ! 308: for(e = these_edges[me]; e; e = enext) ! 309: { ! 310: enext = e->next; ! 311: ! 312: int it = e->node; ! 313: if(marked[it]) ! 314: continue; ! 315: ! 316: if(dir*(level[it]-level[me]) == e->minlen) ! 317: { ! 318: delete_edge(e,these_edges+me); ! 319: insert_edge(e,these_tree+me); ! 320: delete_edge(e->link,those_edges+it); ! 321: insert_edge(e->link,those_tree+it); ! 322: ! 323: marked[it] = 1; ! 324: ENQUEUE(it); ! 325: } ! 326: } ! 327: } ! 328: } ! 329: } ! 330: ! 331: ! 332: // compute all nodes on one side of the cutset ! 333: static void cutset(int me, int *marked, int val) ! 334: { ! 335: marked[me] = val; ! 336: for(int isdown = 0; isdown < 2; ++isdown) ! 337: for(edge_l *e = isdown ? Otree[me] : Itree[me]; e; e = e->next) ! 338: if(marked[e->node] == 0) ! 339: cutset(e->node,marked,val); ! 340: } ! 341: ! 342: ! 343: // compute the initial values of edges in a spanning forest ! 344: static void treevalue(int *marked) ! 345: { ! 346: for(int i = 0; i < n_nodes; ++i) ! 347: for(edge_l *e = Otree[i]; e; e = e->next) ! 348: { ! 349: // compute the cutset partition ! 350: for(int n = 0; n < n_nodes; ++n) ! 351: marked[n] = 0; ! 352: ! 353: // break the edge ! 354: marked[i] = 1; ! 355: marked[e->node] = -1; ! 356: ! 357: // search the two sides ! 358: cutset(i,marked,1); ! 359: cutset(e->node,marked,-1); ! 360: ! 361: int cutvalue = e->weight; ! 362: for(n = 0; n < n_nodes; ++n) ! 363: { ! 364: if(marked[n] == 0) ! 365: continue; ! 366: for(edge_l *f = Oedges[n]; f; f = f->next) ! 367: { ! 368: if(marked[n] != marked[f->node]) ! 369: { ! 370: if(marked[n] > 0) ! 371: cutvalue += f->weight; ! 372: else cutvalue -= f->weight; ! 373: } ! 374: } ! 375: } ! 376: ! 377: e->cutvalue = e->link->cutvalue = cutvalue; ! 378: } ! 379: } ! 380: ! 381: ! 382: // update values of tree edges on a fundamental cycle being altered ! 383: static int treeupdate(int here, int to_be, int cutvalue, int *marked) ! 384: { ! 385: marked[here] = 1; ! 386: ! 387: for(int isdown = 0; isdown < 2; ++isdown) ! 388: { ! 389: for(edge_l *e = isdown ? Otree[here] : Itree[here]; e; e = e->next) ! 390: { ! 391: int found = e->node == to_be ? 1 : 0; ! 392: if(!found && !marked[e->node]) ! 393: found = treeupdate(e->node,to_be,cutvalue,marked); ! 394: if(found) ! 395: { ! 396: e->cutvalue += isdown ? cutvalue : -cutvalue; ! 397: e->link->cutvalue = e->cutvalue; ! 398: return 1; ! 399: } ! 400: } ! 401: } ! 402: return 0; ! 403: } ! 404: ! 405: ! 406: // the network simplex algorithm for computing levels ! 407: static void networksimplex(int *level) ! 408: { ! 409: // construct a feasible level assignment ! 410: int *queue = new int[n_nodes]; ! 411: int *marked = new int[n_nodes]; ! 412: for(int i = 0; i < n_nodes; ++i) ! 413: { ! 414: marked[i] = 0; ! 415: level[i] = Maxint; ! 416: } ! 417: for(i = 0; i < n_nodes; ++i) ! 418: if(level[i] == Maxint) ! 419: { ! 420: // assign levels to node in the component containing i ! 421: initlevel(i,level,queue,marked); ! 422: ! 423: // now find a feasible spanning tree ! 424: spantree(i,level,queue,marked); ! 425: } ! 426: ! 427: // initial values of tree edges ! 428: treevalue(marked); ! 429: ! 430: // network simplex loop ! 431: for(int iter = 0;; ++iter) ! 432: { ! 433: #ifdef DEBUG ! 434: printtree(iter); ! 435: verifytree(); ! 436: checklevel(level); ! 437: #endif ! 438: // find a negative tree edge ! 439: int cutvalue = 0, treetail; ! 440: edge_l *treeedge; ! 441: for(i = 0; i < n_nodes; ++i) ! 442: for(edge_l *e = Otree[i]; e; e = e->next) ! 443: if(e->cutvalue < cutvalue) ! 444: { ! 445: cutvalue = e->cutvalue; ! 446: treetail = i; ! 447: treeedge = e; ! 448: } ! 449: // done; the tree is positive ! 450: if(cutvalue >= 0) ! 451: break; ! 452: ! 453: // compute the cutset partition for this tree edge ! 454: for(i = 0; i < n_nodes; ++i) ! 455: marked[i] = 0; ! 456: ! 457: marked[treetail] = 1; // break the edge ! 458: marked[treeedge->node] = -1; ! 459: cutset(treetail,marked,1); ! 460: cutset(treeedge->node,marked,-1); ! 461: ! 462: // find a non-tree edge to be switched in ! 463: int length = Maxint; ! 464: int nontail; ! 465: edge_l *nonedge = NULL; ! 466: for(i = 0; i < n_nodes; ++i) ! 467: { ! 468: if(marked[i] >= 0) ! 469: continue; ! 470: int level_i = level[i]; ! 471: for(e = Oedges[i]; e; e = e->next) ! 472: { ! 473: if(marked[e->node] < 0) ! 474: continue; ! 475: int len = (level[e->node] - level_i) - e->minlen; ! 476: if(len < length) ! 477: { ! 478: length = len; ! 479: nontail = i; ! 480: nonedge = e; ! 481: } ! 482: } ! 483: } ! 484: ! 485: // update the value of edges on the involved basic cycle ! 486: for(i = 0; i < n_nodes; ++i) ! 487: queue[i] = 0; ! 488: (void)treeupdate(nontail,nonedge->node,treeedge->cutvalue,queue); ! 489: ! 490: // now switch the edges ! 491: treeedge->cutvalue = treeedge->link->cutvalue = 0; ! 492: delete_edge(treeedge,Otree+treetail); ! 493: delete_edge(treeedge->link,Itree+treeedge->node); ! 494: insert_edge(treeedge,Oedges+treetail); ! 495: insert_edge(treeedge->link,Iedges+treeedge->node); ! 496: ! 497: nonedge->cutvalue = nonedge->link->cutvalue = -cutvalue; ! 498: delete_edge(nonedge,Oedges+nontail); ! 499: delete_edge(nonedge->link,Iedges+nonedge->node); ! 500: insert_edge(nonedge,Otree+nontail); ! 501: insert_edge(nonedge->link,Itree+nonedge->node); ! 502: ! 503: // update level info ! 504: if(length > 0) ! 505: { ! 506: for(i = 0; i < n_nodes; ++i) ! 507: if(marked[i] > 0) ! 508: level[i] -= length; ! 509: } ! 510: #ifdef DEBUG ! 511: printtree(iter); ! 512: verifytree(); ! 513: checklevel(level); ! 514: #endif ! 515: } ! 516: ! 517: #ifndef TIMING ! 518: if(Verbose) ! 519: fprintf(stderr,"# of network simplex iterations = %d\n",iter); ! 520: #endif ! 521: ! 522: // make the level assignment starts from 0 for each connected component ! 523: for(i = 0; i < n_nodes; ++i) ! 524: marked[i] = 0; ! 525: for(i = 0; i < n_nodes; ++i) ! 526: { ! 527: if(marked[i]) ! 528: continue; ! 529: ! 530: // use breadth-first search to get all nodes in this component. ! 531: int n = 0, n_elt = 0; ! 532: queue[n_elt++] = i; ! 533: marked[i] = 1; ! 534: while(n < n_elt) ! 535: { ! 536: int me = queue[n++]; ! 537: for(int isdown = 0; isdown < 2; ++isdown) ! 538: { ! 539: edge_l *e = isdown ? Otree[me] : Itree[me]; ! 540: for(; e; e = e->next) ! 541: if(!marked[e->node]) ! 542: { ! 543: queue[n_elt++] = e->node; ! 544: marked[e->node] = 1; ! 545: } ! 546: } ! 547: } ! 548: ! 549: int minlev = Maxint; ! 550: for(n = 0; n < n_elt; ++n) ! 551: if(level[queue[n]] < minlev) ! 552: minlev = level[queue[n]]; ! 553: if(minlev != 0 && minlev != Maxint) ! 554: for(n = 0; n < n_elt; ++n) ! 555: level[queue[n]] -= minlev; ! 556: } ! 557: ! 558: // restore space ! 559: delete marked; ! 560: delete queue; ! 561: } ! 562: ! 563: ! 564: static void setlevels(int source, int sink) ! 565: { ! 566: // Merge[] contains new names of the mega-nodes that represent ! 567: // true nodes that are specified to be at the same levels. ! 568: Merge = new int[N_nodes]; ! 569: n_nodes = 0; ! 570: for(int i = 0; i < N_nodes; ++i) ! 571: if(i == Root[i]) ! 572: Merge[i] = n_nodes++; ! 573: for(i = 0; i < N_nodes; ++i) ! 574: Merge[i] = Merge[Root[i]]; ! 575: ! 576: // construct the new edge lists. ! 577: // Since no min_edge_length info is kept, this is 1 ! 578: Oedges = new edge_l*[n_nodes]; ! 579: Iedges = new edge_l*[n_nodes]; ! 580: for(i = 0; i < N_nodes; ++i) ! 581: for(edge_t *e = Outedges[i]; e; e = e->next) ! 582: addedge(i,e->node,e->weight,e->minlen); ! 583: ! 584: // add constraint edges for sources and sinks. ! 585: // These edges have zero weight and zero min_edge_length ! 586: if(source >= 0 || sink >= 0) ! 587: { ! 588: for(i = 0; i < N_nodes; ++i) ! 589: if(i == Root[i]) ! 590: { ! 591: if(source >= 0 && i != source) ! 592: addedge(source,i,0,0); ! 593: if(sink >= 0 && i != sink) ! 594: addedge(i,sink,0,0); ! 595: } ! 596: } ! 597: ! 598: // get level assignment ! 599: Otree = new edge_l*[n_nodes]; ! 600: Itree = new edge_l*[n_nodes]; ! 601: int *level = new int[n_nodes]; ! 602: networksimplex(level); ! 603: #ifdef DEBUG ! 604: checklevel(level); ! 605: #endif ! 606: ! 607: // now reassign level assignment to real nodes ! 608: for(i = 0; i < N_nodes; ++i) ! 609: Level[i] = level[Merge[i]]; ! 610: #ifdef DEBUG ! 611: verifylevel(); ! 612: #endif ! 613: ! 614: // restore space used ! 615: for(i = 0; i < n_nodes; ++i) ! 616: { ! 617: edge_l *enext; ! 618: for(edge_l *e = Oedges[i]; e; e = enext) ! 619: { ! 620: enext = e->next; ! 621: delete e; ! 622: } ! 623: for(e = Iedges[i]; e; e = enext) ! 624: { ! 625: enext = e->next; ! 626: delete e; ! 627: } ! 628: for(e = Otree[i]; e; e = enext) ! 629: { ! 630: enext = e->next; ! 631: delete e; ! 632: } ! 633: for(e = Itree[i]; e; e = enext) ! 634: { ! 635: enext = e->next; ! 636: delete e; ! 637: } ! 638: } ! 639: delete Iedges; ! 640: delete Oedges; ! 641: delete Itree; ! 642: delete Otree; ! 643: delete Merge; ! 644: delete level; ! 645: } ! 646: ! 647: ! 648: #ifdef DEBUG ! 649: static void fatal() ! 650: { ! 651: (void) abort(); ! 652: } ! 653: ! 654: static void printtree(int iter) ! 655: { ! 656: fprintf(stderr,"Iteration=%d\n",iter); ! 657: for(int i = 0; i < n_nodes; ++i) ! 658: for(edge_l *e = Otree[i]; e; e = e->next) ! 659: fprintf(stderr,"%d -> %d : cutvalue=%d\n",i,e->node,e->cutvalue); ! 660: for(i = 0; i < n_nodes; ++i) ! 661: for(e = Oedges[i]; e; e = e->next) ! 662: fprintf(stderr,"%d -> %d\n", i,e->node); ! 663: } ! 664: ! 665: static void verifytree() ! 666: { ! 667: int *marked = new int[n_nodes]; ! 668: ! 669: for(int i = 0; i < n_nodes; ++i) ! 670: for(edge_l *e = Otree[i]; e; e = e->next) ! 671: { ! 672: // compute the cutset partition ! 673: for(int n = 0; n < n_nodes; ++n) ! 674: marked[n] = 0; ! 675: ! 676: // break the edge ! 677: marked[i] = 1; ! 678: marked[e->node] = -1; ! 679: cutset(i,marked,1); ! 680: cutset(e->node,marked,-1); ! 681: ! 682: int cutvalue = e->weight; ! 683: for(n = 0; n < n_nodes; ++n) ! 684: { ! 685: if(marked[n] == 0) ! 686: continue; ! 687: for(edge_l *f = Oedges[n]; f; f = f->next) ! 688: if(marked[n] != marked[f->node]) ! 689: { ! 690: if(marked[f->node] == 0) ! 691: fatal(); ! 692: if(marked[n] > 0) ! 693: cutvalue += f->weight; ! 694: else cutvalue -= f->weight; ! 695: } ! 696: } ! 697: ! 698: if(e->cutvalue != cutvalue) ! 699: fatal(); ! 700: } ! 701: ! 702: delete marked; ! 703: } ! 704: ! 705: static void checklevel(int *level) ! 706: { ! 707: for(int v = 0; v < n_nodes; ++v) ! 708: { ! 709: for(edge_l *e = Oedges[v]; e; e = e->next) ! 710: if(level[e->node]-level[v] < e->minlen) ! 711: fatal(); ! 712: for(e = Otree[v]; e; e = e->next) ! 713: if(level[e->node]-level[v] != e->minlen) ! 714: fatal(); ! 715: for(e = Iedges[v]; e; e = e->next) ! 716: if(level[v]-level[e->node] < e->minlen) ! 717: fatal(); ! 718: for(e = Itree[v]; e; e = e->next) ! 719: if(level[v]-level[e->node] != e->minlen) ! 720: fatal(); ! 721: } ! 722: } ! 723: ! 724: static void verifylevel() ! 725: { ! 726: for(int v = 0; v < N_nodes; ++v) ! 727: { ! 728: for(edge_t *e = Outedges[v]; e; e = e->next) ! 729: if(Level[v] >= Level[e->node]) ! 730: fatal(); ! 731: for(e = Inedges[v]; e; e = e->next) ! 732: if(Level[v] <= Level[e->node]) ! 733: fatal(); ! 734: } ! 735: } ! 736: ! 737: static void checksearch(int v, int *marked, int isdown) ! 738: { ! 739: marked[v] = 1; ! 740: for(edge_l *e = isdown ? Oedges[v] : Iedges[v]; e; e = e->next) ! 741: { ! 742: if(marked[e->node] == 1) ! 743: fatal(); ! 744: if(!marked[e->node]) ! 745: checksearch(e->node,marked,isdown); ! 746: } ! 747: marked[v] = 2; ! 748: } ! 749: static void checkcycle() ! 750: { ! 751: int *marked = new int[n_nodes]; ! 752: for(int v = 0; v < n_nodes; ++v) ! 753: if(!marked[v]) ! 754: checksearch(v,marked,1); ! 755: ! 756: for(v = 0; v < n_nodes; ++v) ! 757: marked[v] = 0; ! 758: for(v = 0; v < n_nodes; ++v) ! 759: if(!marked[v]) ! 760: checksearch(v,marked,0); ! 761: ! 762: delete marked; ! 763: } ! 764: ! 765: static void verifysearch(int v, int *marked, int isdown) ! 766: { ! 767: marked[v] = 1; ! 768: for(edge_t *e = isdown ? Outedges[v] : Inedges[v]; e; e = e->next) ! 769: { ! 770: if(marked[e->node] == 1) ! 771: fatal(); ! 772: if(!marked[e->node]) ! 773: verifysearch(e->node,marked,isdown); ! 774: } ! 775: marked[v] = 2; ! 776: } ! 777: static void verifycycle() ! 778: { ! 779: int *marked = new int[N_nodes]; ! 780: for(int v = 0; v < N_nodes; ++v) ! 781: if(!marked[v]) ! 782: verifysearch(v,marked,1); ! 783: ! 784: for(v = 0; v < N_nodes; ++v) ! 785: marked[v] = 0; ! 786: for(v = 0; v < N_nodes; ++v) ! 787: if(!marked[v]) ! 788: verifysearch(v,marked,0); ! 789: ! 790: for(v = 0; v < N_nodes; ++v) ! 791: { ! 792: for(edge_t *e = Outedges[v]; e; e = e->next) ! 793: if(e->minlen < 1) ! 794: fatal(); ! 795: for(e = Inedges[v]; e; e = e->next) ! 796: if(e->minlen < 1) ! 797: fatal(); ! 798: } ! 799: ! 800: delete marked; ! 801: } ! 802: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.