📄 mmd.c
字号:
nqnbrs = xqnbr - jstrt; if (nqnbrs > 0) { goto L1600; }/* ----------------------------- *//* THEN MERGE RNODE WITH MDNODE. *//* ----------------------------- */ qsize[*mdnode] += qsize[rnode]; qsize[rnode] = 0; marker[rnode] = *maxint; dforw[rnode] = -(*mdnode); dbakw[rnode] = -(*maxint); goto L1700;L1600:/* -------------------------------------- *//* ELSE FLAG RNODE FOR DEGREE UPDATE, AND *//* ADD MDNODE AS A NABOR OF RNODE. *//* -------------------------------------- */ dforw[rnode] = nqnbrs + 1; dbakw[rnode] = 0; adjncy[xqnbr] = *mdnode; ++xqnbr; if (xqnbr <= jstop) { adjncy[xqnbr] = 0; }L1700: ; }L1800: return 0;} /* mmdelm_dist *//* *************************************************************** *//* *************************************************************** *//* ***** MMDUPD ..... MULTIPLE MINIMUM DEGREE UPDATE ***** *//* *************************************************************** *//* *************************************************************** *//* AUTHOR - JOSEPH W.H. LIU *//* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. *//* PURPOSE - THIS ROUTINE UPDATES THE DEGREES OF NODES *//* AFTER A MULTIPLE ELIMINATION STEP. *//* INPUT PARAMETERS - *//* EHEAD - THE BEGINNING OF THE LIST OF ELIMINATED *//* NODES (I.E., NEWLY FORMED ELEMENTS). *//* NEQNS - NUMBER OF EQUATIONS. *//* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. *//* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. *//* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) *//* INTEGER. *//* UPDATED PARAMETERS - *//* MDEG - NEW MINIMUM DEGREE AFTER DEGREE UPDATE. *//* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. *//* QSIZE - SIZE OF SUPERNODE. *//* LLIST - WORKING LINKED LIST. *//* MARKER - MARKER VECTOR FOR DEGREE UPDATE. *//* TAG - TAG VALUE. *//* *************************************************************** *//* Subroutine */ int mmdupd_dist(int *ehead, int *neqns, int *xadj, shortint *adjncy, int *delta, int *mdeg, shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize, shortint *llist, shortint *marker, int *maxint, int *tag){ /* System generated locals */ int i__1, i__2; /* Local variables */ static int node, mtag, link, mdeg0, i, j, enode, fnode, nabor, elmnt, istop, jstop, q2head, istrt, jstrt, qxhead, iq2, deg, deg0;/* *************************************************************** *//* *************************************************************** */ /* Parameter adjustments */ --marker; --llist; --qsize; --dbakw; --dforw; --dhead; --adjncy; --xadj; /* Function Body */ mdeg0 = *mdeg + *delta; elmnt = *ehead;L100:/* ------------------------------------------------------- *//* FOR EACH OF THE NEWLY FORMED ELEMENT, DO THE FOLLOWING. *//* (RESET TAG VALUE IF NECESSARY.) *//* ------------------------------------------------------- */ if (elmnt <= 0) { return 0; } mtag = *tag + mdeg0; if (mtag < *maxint) { goto L300; } *tag = 1; i__1 = *neqns; for (i = 1; i <= i__1; ++i) { if (marker[i] < *maxint) { marker[i] = 0; }/* L200: */ } mtag = *tag + mdeg0;L300:/* --------------------------------------------- *//* CREATE TWO LINKED LISTS FROM NODES ASSOCIATED *//* WITH ELMNT: ONE WITH TWO NABORS (Q2HEAD) IN *//* ADJACENCY STRUCTURE, AND THE OTHER WITH MORE *//* THAN TWO NABORS (QXHEAD). ALSO COMPUTE DEG0, *//* NUMBER OF NODES IN THIS ELEMENT. *//* --------------------------------------------- */ q2head = 0; qxhead = 0; deg0 = 0; link = elmnt;L400: istrt = xadj[link]; istop = xadj[link + 1] - 1; i__1 = istop; for (i = istrt; i <= i__1; ++i) { enode = adjncy[i]; link = -enode; if (enode < 0) { goto L400; } else if (enode == 0) { goto L800; } else { goto L500; }L500: if (qsize[enode] == 0) { goto L700; } deg0 += qsize[enode]; marker[enode] = mtag;/* ---------------------------------- *//* IF ENODE REQUIRES A DEGREE UPDATE, *//* THEN DO THE FOLLOWING. *//* ---------------------------------- */ if (dbakw[enode] != 0) { goto L700; }/* --------------------------------------- *//* PLACE EITHER IN QXHEAD OR Q2HEAD LISTS. *//* --------------------------------------- */ if (dforw[enode] == 2) { goto L600; } llist[enode] = qxhead; qxhead = enode; goto L700;L600: llist[enode] = q2head; q2head = enode;L700: ; }L800:/* -------------------------------------------- *//* FOR EACH ENODE IN Q2 LIST, DO THE FOLLOWING. *//* -------------------------------------------- */ enode = q2head; iq2 = 1;L900: if (enode <= 0) { goto L1500; } if (dbakw[enode] != 0) { goto L2200; } ++(*tag); deg = deg0;/* ------------------------------------------ *//* IDENTIFY THE OTHER ADJACENT ELEMENT NABOR. *//* ------------------------------------------ */ istrt = xadj[enode]; nabor = adjncy[istrt]; if (nabor == elmnt) { nabor = adjncy[istrt + 1]; }/* ------------------------------------------------ *//* IF NABOR IS UNELIMINATED, INCREASE DEGREE COUNT. *//* ------------------------------------------------ */ link = nabor; if (dforw[nabor] < 0) { goto L1000; } deg += qsize[nabor]; goto L2100;L1000:/* -------------------------------------------- *//* OTHERWISE, FOR EACH NODE IN THE 2ND ELEMENT, *//* DO THE FOLLOWING. *//* -------------------------------------------- */ istrt = xadj[link]; istop = xadj[link + 1] - 1; i__1 = istop; for (i = istrt; i <= i__1; ++i) { node = adjncy[i]; link = -node; if (node == enode) { goto L1400; } if (node < 0) { goto L1000; } else if (node == 0) { goto L2100; } else { goto L1100; }L1100: if (qsize[node] == 0) { goto L1400; } if (marker[node] >= *tag) { goto L1200; }/* ------------------------------------- *//* CASE WHEN NODE IS NOT YET CONSIDERED. *//* ------------------------------------- */ marker[node] = *tag; deg += qsize[node]; goto L1400;L1200:/* ---------------------------------------- *//* CASE WHEN NODE IS INDISTINGUISHABLE FROM *//* ENODE. MERGE THEM INTO A NEW SUPERNODE. *//* ---------------------------------------- */ if (dbakw[node] != 0) { goto L1400; } if (dforw[node] != 2) { goto L1300; } qsize[enode] += qsize[node]; qsize[node] = 0; marker[node] = *maxint; dforw[node] = -enode; dbakw[node] = -(*maxint); goto L1400;L1300:/* -------------------------------------- *//* CASE WHEN NODE IS OUTMATCHED BY ENODE. *//* -------------------------------------- */ if (dbakw[node] == 0) { dbakw[node] = -(*maxint); }L1400: ; } goto L2100;L1500:/* ------------------------------------------------ *//* FOR EACH ENODE IN THE QX LIST, DO THE FOLLOWING. *//* ------------------------------------------------ */ enode = qxhead; iq2 = 0;L1600: if (enode <= 0) { goto L2300; } if (dbakw[enode] != 0) { goto L2200; } ++(*tag); deg = deg0;/* --------------------------------- *//* FOR EACH UNMARKED NABOR OF ENODE, *//* DO THE FOLLOWING. *//* --------------------------------- */ istrt = xadj[enode]; istop = xadj[enode + 1] - 1; i__1 = istop; for (i = istrt; i <= i__1; ++i) { nabor = adjncy[i]; if (nabor == 0) { goto L2100; } if (marker[nabor] >= *tag) { goto L2000; } marker[nabor] = *tag; link = nabor;/* ------------------------------ *//* IF UNELIMINATED, INCLUDE IT IN *//* DEG COUNT. *//* ------------------------------ */ if (dforw[nabor] < 0) { goto L1700; } deg += qsize[nabor]; goto L2000;L1700:/* ------------------------------- *//* IF ELIMINATED, INCLUDE UNMARKED *//* NODES IN THIS ELEMENT INTO THE *//* DEGREE COUNT. *//* ------------------------------- */ jstrt = xadj[link]; jstop = xadj[link + 1] - 1; i__2 = jstop; for (j = jstrt; j <= i__2; ++j) { node = adjncy[j]; link = -node; if (node < 0) { goto L1700; } else if (node == 0) { goto L2000; } else { goto L1800; }L1800: if (marker[node] >= *tag) { goto L1900; } marker[node] = *tag; deg += qsize[node];L1900: ; }L2000: ; }L2100:/* ------------------------------------------- *//* UPDATE EXTERNAL DEGREE OF ENODE IN DEGREE *//* STRUCTURE, AND MDEG (MIN DEG) IF NECESSARY. *//* ------------------------------------------- */ deg = deg - qsize[enode] + 1; fnode = dhead[deg]; dforw[enode] = fnode; dbakw[enode] = -deg; if (fnode > 0) { dbakw[fnode] = enode; } dhead[deg] = enode; if (deg < *mdeg) { *mdeg = deg; }L2200:/* ---------------------------------- *//* GET NEXT ENODE IN CURRENT ELEMENT. *//* ---------------------------------- */ enode = llist[enode]; if (iq2 == 1) { goto L900; } goto L1600;L2300:/* ----------------------------- *//* GET NEXT ELEMENT IN THE LIST. *//* ----------------------------- */ *tag = mtag; elmnt = llist[elmnt]; goto L100;} /* mmdupd_dist *//* *************************************************************** *//* *************************************************************** *//* ***** MMDNUM ..... MULTI MINIMUM DEGREE NUMBERING ***** *//* *************************************************************** *//* *************************************************************** *//* AUTHOR - JOSEPH W.H. LIU *//* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. *//* PURPOSE - THIS ROUTINE PERFORMS THE FINAL STEP IN *//* PRODUCING THE PERMUTATION AND INVERSE PERMUTATION *//* VECTORS IN THE MULTIPLE ELIMINATION VERSION OF THE *//* MINIMUM DEGREE ORDERING ALGORITHM. *//* INPUT PARAMETERS - *//* NEQNS - NUMBER OF EQUATIONS. *//* QSIZE - SIZE OF SUPERNODES AT ELIMINATION. *//* UPDATED PARAMETERS - *//* INVP - INVERSE PERMUTATION VECTOR. ON INPUT, *//* IF QSIZE(NODE)=0, THEN NODE HAS BEEN MERGED *//* INTO THE NODE -INVP(NODE); OTHERWISE, *//* -INVP(NODE) IS ITS INVERSE LABELLING. *//* OUTPUT PARAMETERS - *//* PERM - THE PERMUTATION VECTOR. *//* *************************************************************** *//* Subroutine */ int mmdnum_dist(int *neqns, shortint *perm, shortint *invp, shortint *qsize){ /* System generated locals */ int i__1; /* Local variables */ static int node, root, nextf, father, nqsize, num;/* *************************************************************** *//* *************************************************************** */ /* Parameter adjustments */ --qsize; --invp; --perm; /* Function Body */ i__1 = *neqns; for (node = 1; node <= i__1; ++node) { nqsize = qsize[node]; if (nqsize <= 0) { perm[node] = invp[node]; } if (nqsize > 0) { perm[node] = -invp[node]; }/* L100: */ }/* ------------------------------------------------------ *//* FOR EACH NODE WHICH HAS BEEN MERGED, DO THE FOLLOWING. *//* ------------------------------------------------------ */ i__1 = *neqns; for (node = 1; node <= i__1; ++node) { if (perm[node] > 0) { goto L500; }/* ----------------------------------------- *//* TRACE THE MERGED TREE UNTIL ONE WHICH HAS *//* NOT BEEN MERGED, CALL IT ROOT. *//* ----------------------------------------- */ father = node;L200: if (perm[father] > 0) { goto L300; } father = -perm[father]; goto L200;L300:/* ----------------------- *//* NUMBER NODE AFTER ROOT. *//* ----------------------- */ root = father; num = perm[root] + 1; invp[node] = -num; perm[root] = num;/* ------------------------ *//* SHORTEN THE MERGED TREE. *//* ------------------------ */ father = node;L400: nextf = -perm[father]; if (nextf <= 0) { goto L500; } perm[father] = -root; father = nextf; goto L400;L500: ; }/* ---------------------- *//* READY TO COMPUTE PERM. *//* ---------------------- */ i__1 = *neqns; for (node = 1; node <= i__1; ++node) { num = -invp[node]; invp[node] = num; perm[num] = node;/* L600: */ } return 0;} /* mmdnum_dist */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -