Annotation of researchv10no/cmd/dag/dag_levels.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.