26 mindiff = abs(tpwgts[0]-graph->
pwgts[0]);
29 if (graph->
pwgts[0] > tpwgts[0] && graph->
pwgts[0] < (
int)(ubfactor*tpwgts[0]))
31 if (graph->
pwgts[1] > tpwgts[1] && graph->
pwgts[1] < (
int)(ubfactor*tpwgts[1]))
49 int i,
ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to,
tmp;
50 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
53 int higain, oldgain, mincut, mindiff;
71 mindiff = abs(tpwgts[0]-pwgts[0]);
72 from = (pwgts[0] < tpwgts[0] ? 1 : 0);
76 printf(
"Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n",
77 pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
90 for (
ii=0;
ii<nbnd;
ii++) {
92 ASSERT(ed[bndind[i]] > 0 ||
id[bndind[i]] == 0);
93 ASSERT(bndptr[bndind[i]] != -1);
94 if (where[bndind[i]] == from && vwgt[bndind[i]] <= mindiff)
95 PQueueInsert(&parts, bndind[i], ed[bndind[i]]-
id[bndind[i]]);
99 for (nswaps=0; nswaps<nvtxs; nswaps++) {
102 ASSERT(bndptr[higain] != -1);
104 if (pwgts[to]+vwgt[higain] > tpwgts[to])
107 mincut -= (ed[higain]-
id[higain]);
108 INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
111 moved[higain] = nswaps;
114 printf(
"Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-
id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1]));
119 SWAP(
id[higain], ed[higain],
tmp);
120 if (ed[higain] == 0 && xadj[higain] < xadj[higain+1])
123 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
125 oldgain = ed[k]-
id[k];
127 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
131 if (bndptr[k] != -1) {
134 if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
138 if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
145 if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
153 printf(
"\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd));
175 int i,
ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to,
tmp;
176 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
179 int higain, oldgain, mincut, mindiff;
181 nvtxs = graph->
nvtxs;
186 where = graph->
where;
189 pwgts = graph->
pwgts;
197 mindiff = abs(tpwgts[0]-pwgts[0]);
198 from = (pwgts[0] < tpwgts[0] ? 1 : 0);
202 printf(
"Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n",
203 pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
215 for (
ii=0;
ii<nvtxs;
ii++) {
217 if (where[i] == from && vwgt[i] <= mindiff)
223 for (nswaps=0; nswaps<nvtxs; nswaps++) {
227 if (pwgts[to]+vwgt[higain] > tpwgts[to])
230 mincut -= (ed[higain]-
id[higain]);
231 INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
234 moved[higain] = nswaps;
237 printf(
"Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-
id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1]));
242 SWAP(
id[higain], ed[higain],
tmp);
243 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
245 if (ed[higain] > 0 && bndptr[higain] == -1)
248 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
250 oldgain = ed[k]-
id[k];
252 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
256 if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff)
260 if (ed[k] == 0 && bndptr[k] != -1)
262 else if (ed[k] > 0 && bndptr[k] == -1)
268 printf(
"\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd));
307 counts =
idxsmalloc(max+2, 0,
"BucketSortKeysInc: counts");
315 perm[counts[keys[i]]++] = i;
344 int i, j,
jj, k,
kk,
m,
istart,
iend, nvtxs, nedges, ncon, cnedges, v, u, mask, dovsize;
345 idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;
347 idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;
348 float *nvwgt, *cnvwgt;
354 if (cnvtxs < 8*mask || graph->nedges/graph->
nvtxs > 15) {
361 nvtxs = graph->
nvtxs;
365 vsize = graph->
vsize;
366 nvwgt = graph->
nvwgt;
374 cxadj = cgraph->
xadj;
375 cvwgt = cgraph->
vwgt;
376 cvsize = cgraph->
vsize;
377 cnvwgt = cgraph->
nvwgt;
386 for (i=0; i<
iend; i++)
387 auxadj[i] = cmap[auxadj[i]];
391 cxadj[0] = cnvtxs = cnedges = 0;
392 for (i=0; i<nvtxs; i++) {
394 if (cmap[v] != cnvtxs)
399 cvwgt[cnvtxs] = vwgt[v];
401 scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);
404 cvsize[cnvtxs] = vsize[v];
406 cadjwgtsum[cnvtxs] = adjwgtsum[v];
414 if ((
m = htable[
kk]) == -1) {
416 cadjwgt[nedges] = adjwgt[j];
417 htable[
kk] = nedges++;
419 else if (cadjncy[
m] == k) {
420 cadjwgt[
m] += adjwgt[j];
423 for (
jj=0;
jj<nedges;
jj++) {
424 if (cadjncy[
jj] == k) {
425 cadjwgt[
jj] += adjwgt[j];
431 cadjwgt[nedges++] = adjwgt[j];
438 cvwgt[cnvtxs] += vwgt[u];
440 saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);
443 cvsize[cnvtxs] += vsize[u];
445 cadjwgtsum[cnvtxs] += adjwgtsum[u];
452 if ((
m = htable[
kk]) == -1) {
454 cadjwgt[nedges] = adjwgt[j];
455 htable[
kk] = nedges++;
457 else if (cadjncy[
m] == k) {
458 cadjwgt[
m] += adjwgt[j];
461 for (
jj=0;
jj<nedges;
jj++) {
462 if (cadjncy[
jj] == k) {
463 cadjwgt[
jj] += adjwgt[j];
469 cadjwgt[nedges++] = adjwgt[j];
475 jj = htable[cnvtxs&mask];
476 if (
jj >= 0 && cadjncy[
jj] != cnvtxs) {
477 for (
jj=0;
jj<nedges;
jj++) {
478 if (cadjncy[
jj] == cnvtxs)
482 if (
jj >= 0 && cadjncy[
jj] == cnvtxs) {
483 cadjwgtsum[cnvtxs] -= cadjwgt[
jj];
484 cadjncy[
jj] = cadjncy[--nedges];
485 cadjwgt[
jj] = cadjwgt[nedges];
489 ASSERTP(cadjwgtsum[cnvtxs] ==
idxsum(nedges, cadjwgt), (
"%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs],
idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));
491 for (j=0; j<nedges; j++)
492 htable[cadjncy[j]&mask] = -1;
493 htable[cnvtxs&mask] = -1;
496 cxadj[++cnvtxs] = cnedges;
517 int i, j, k,
m,
istart,
iend, nvtxs, nedges, ncon, cnedges, v, u, dovsize;
518 idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;
520 idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;
521 float *nvwgt, *cnvwgt;
528 nvtxs = graph->
nvtxs;
532 vsize = graph->
vsize;
533 nvwgt = graph->
nvwgt;
542 cxadj = cgraph->
xadj;
543 cvwgt = cgraph->
vwgt;
544 cvsize = cgraph->
vsize;
545 cnvwgt = cgraph->
nvwgt;
556 for (i=0; i<
iend; i++)
557 auxadj[i] = cmap[auxadj[i]];
559 cxadj[0] = cnvtxs = cnedges = 0;
560 for (i=0; i<nvtxs; i++) {
562 if (cmap[v] != cnvtxs)
567 cvwgt[cnvtxs] = vwgt[v];
569 scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);
572 cvsize[cnvtxs] = vsize[v];
574 cadjwgtsum[cnvtxs] = adjwgtsum[v];
581 if ((
m = htable[k]) == -1) {
583 cadjwgt[nedges] = adjwgt[j];
584 htable[k] = nedges++;
587 cadjwgt[
m] += adjwgt[j];
593 cvwgt[cnvtxs] += vwgt[u];
595 saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);
598 cvsize[cnvtxs] += vsize[u];
600 cadjwgtsum[cnvtxs] += adjwgtsum[u];
606 if ((
m = htable[k]) == -1) {
608 cadjwgt[nedges] = adjwgt[j];
609 htable[k] = nedges++;
612 cadjwgt[
m] += adjwgt[j];
617 if ((j = htable[cnvtxs]) != -1) {
618 ASSERT(cadjncy[j] == cnvtxs);
619 cadjwgtsum[cnvtxs] -= cadjwgt[j];
620 cadjncy[j] = cadjncy[--nedges];
621 cadjwgt[j] = cadjwgt[nedges];
626 ASSERTP(cadjwgtsum[cnvtxs] ==
idxsum(nedges, cadjwgt), (
"%d %d\n", cadjwgtsum[cnvtxs],
idxsum(nedges, cadjwgt)));
628 for (j=0; j<nedges; j++)
629 htable[cadjncy[j]] = -1;
632 cxadj[++cnvtxs] = cnedges;
652 int i, j,
jj, k,
kk,
m,
istart,
iend, nvtxs, nedges, ncon, cnedges, v, u, mask;
653 idxtype *xadj, *adjncy, *adjwgtsum, *auxadj;
655 idxtype *cxadj, *cvwgt, *cadjncy, *cadjwgt, *cadjwgtsum;
656 float *nvwgt, *cnvwgt;
662 nvtxs = graph->
nvtxs;
665 nvwgt = graph->
nvwgt;
672 cxadj = cgraph->
xadj;
673 cvwgt = cgraph->
vwgt;
674 cnvwgt = cgraph->
nvwgt;
683 for (i=0; i<
iend; i++)
684 auxadj[i] = cmap[auxadj[i]];
689 cxadj[0] = cnvtxs = cnedges = 0;
690 for (i=0; i<nvtxs; i++) {
692 if (cmap[v] != cnvtxs)
697 cadjwgtsum[cnvtxs] = adjwgtsum[v];
705 if ((
m = htable[
kk]) == -1) {
708 htable[
kk] = nedges++;
710 else if (cadjncy[
m] == k) {
714 for (
jj=0;
jj<nedges;
jj++) {
715 if (cadjncy[
jj] == k) {
722 cadjwgt[nedges++] = 1;
729 cadjwgtsum[cnvtxs] += adjwgtsum[u];
736 if ((
m = htable[
kk]) == -1) {
739 htable[
kk] = nedges++;
741 else if (cadjncy[
m] == k) {
745 for (
jj=0;
jj<nedges;
jj++) {
746 if (cadjncy[
jj] == k) {
753 cadjwgt[nedges++] = 1;
759 jj = htable[cnvtxs&mask];
760 if (
jj >= 0 && cadjncy[
jj] != cnvtxs) {
761 for (
jj=0;
jj<nedges;
jj++) {
762 if (cadjncy[
jj] == cnvtxs)
766 if (
jj >= 0 && cadjncy[
jj] == cnvtxs) {
767 cadjwgtsum[cnvtxs] -= cadjwgt[
jj];
768 cadjncy[
jj] = cadjncy[--nedges];
769 cadjwgt[
jj] = cadjwgt[nedges];
773 ASSERTP(cadjwgtsum[cnvtxs] ==
idxsum(nedges, cadjwgt), (
"%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs],
idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));
775 for (j=0; j<nedges; j++)
776 htable[cadjncy[j]&mask] = -1;
777 htable[cnvtxs&mask] = -1;
780 cxadj[++cnvtxs] = cnedges;
804 cgraph->
nvtxs = cnvtxs;
807 cgraph->
finer = graph;
812 if (graph->
ncon == 1) {
819 cgraph->
cmap = cgraph->
gdata + 4*cnvtxs+1;
828 cgraph->
cmap = cgraph->
gdata + 3*cnvtxs+1;
839 cgraph->
cmap = cgraph->
gdata + 3*cnvtxs+1;
847 cgraph->
cmap = cgraph->
gdata + 2*cnvtxs+1;
869 if (graph->
ncon == 1) {
949 if (ctrl->
CType > 20) {
962 switch (ctrl->
CType) {
1025 int i,
ii, iii, j,
jj, k, l, cnvtxs, cnedges;
1026 idxtype *cxadj, *cadjncy, *cvwgt, *mark, *map;
1029 mark =
idxsmalloc(nvtxs, -1,
"CompressGraph: mark");
1030 map =
idxsmalloc(nvtxs, -1,
"CompressGraph: map");
1034 for (i=0; i<nvtxs; i++) {
1036 for (j=xadj[i]; j<xadj[i+1]; j++)
1045 for (cnvtxs=i=0; i<nvtxs; i++) {
1047 if (map[
ii] == -1) {
1049 for (j=xadj[
ii]; j<xadj[
ii+1]; j++)
1050 mark[adjncy[j]] = i;
1055 for (j=i+1; j<nvtxs; j++) {
1058 if (keys[i].key != keys[j].key || xadj[
ii+1]-xadj[
ii] != xadj[iii+1]-xadj[iii])
1061 if (map[iii] == -1) {
1062 for (
jj=xadj[iii];
jj<xadj[iii+1];
jj++) {
1063 if (mark[adjncy[
jj]] != i)
1067 if (
jj == xadj[iii+1]) {
1084 graph->
nvtxs = nvtxs;
1085 graph->
nedges = xadj[nvtxs];
1098 for (i=0; i<nvtxs; i++)
1099 graph->
adjwgtsum[i] = xadj[i+1]-xadj[i];
1102 for (i=0; i<nvtxs; i++)
1103 graph->
label[i] = i;
1107 for (i=0; i<cnvtxs; i++) {
1109 cnedges += xadj[
ii+1]-xadj[
ii];
1113 graph->
gdata =
idxmalloc(4*cnvtxs+1 + 2*cnedges,
"CompressGraph: gdata");
1115 cvwgt = graph->
vwgt = graph->
gdata + cnvtxs+1;
1117 graph->
cmap = graph->
gdata + 3*cnvtxs+1;
1118 cadjncy = graph->
adjncy = graph->
gdata + 4*cnvtxs+1;
1119 graph->
adjwgt = graph->
gdata + 4*cnvtxs+1 + cnedges;
1124 for (i=0; i<cnvtxs; i++) {
1125 cvwgt[i] = cptr[i+1]-cptr[i];
1127 for (j=cptr[i]; j<cptr[i+1]; j++) {
1130 k = map[adjncy[
jj]];
1139 graph->
nvtxs = cnvtxs;
1144 for (i=0; i<cnvtxs; i++)
1145 graph->
adjwgtsum[i] = cxadj[i+1]-cxadj[i];
1148 for (i=0; i<cnvtxs; i++)
1149 graph->
label[i] = i;
1153 GKfree((
void **) &keys, (
void **) &map, (
void **) &mark,
LTERM);
1164 int i, j, k, l, nlarge, pnvtxs, pnedges;
1168 perm =
idxmalloc(nvtxs,
"PruneGraph: perm");
1170 factor = factor*xadj[nvtxs]/nvtxs;
1172 pnvtxs = pnedges = nlarge = 0;
1173 for (i=0; i<nvtxs; i++) {
1174 if (xadj[i+1]-xadj[i] < factor) {
1176 iperm[pnvtxs++] = i;
1177 pnedges += xadj[i+1]-xadj[i];
1180 perm[i] = nvtxs - ++nlarge;
1181 iperm[nvtxs-nlarge] = i;
1190 graph->
nvtxs = nvtxs;
1191 graph->
nedges = xadj[nvtxs];
1204 for (i=0; i<nvtxs; i++)
1205 graph->
adjwgtsum[i] = xadj[i+1]-xadj[i];
1208 for (i=0; i<nvtxs; i++)
1209 graph->
label[i] = i;
1213 graph->
gdata =
idxmalloc(4*pnvtxs+1 + 2*pnedges,
"PruneGraph: gdata");
1217 graph->
cmap = graph->
gdata + 3*pnvtxs+1;
1218 padjncy = graph->
adjncy = graph->
gdata + 4*pnvtxs+1;
1219 graph->
adjwgt = graph->
gdata + 4*pnvtxs+1 + pnedges;
1221 pxadj[0] = pnedges = l = 0;
1222 for (i=0; i<nvtxs; i++) {
1223 if (xadj[i+1]-xadj[i] < factor) {
1224 for (j=xadj[i]; j<xadj[i+1]; j++) {
1225 k = perm[adjncy[j]];
1227 padjncy[pnedges++] = k;
1229 pxadj[++l] = pnedges;
1233 graph->
nvtxs = pnvtxs;
1239 for (i=0; i<pnvtxs; i++)
1240 graph->
adjwgtsum[i] = pxadj[i+1]-pxadj[i];
1243 for (i=0; i<pnvtxs; i++)
1244 graph->
label[i] = i;
1282 if (graph->
adjwgt == NULL) {
1283 for (cut=0, i=0; i<graph->
nvtxs; i++) {
1284 for (j=graph->
xadj[i]; j<graph->xadj[i+1]; j++)
1285 if (where[i] != where[graph->
adjncy[j]])
1290 for (cut=0, i=0; i<graph->
nvtxs; i++) {
1291 for (j=graph->
xadj[i]; j<graph->xadj[i+1]; j++)
1292 if (where[i] != where[graph->
adjncy[j]])
1306 int i, j, nvtxs, nbnd;
1307 idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
1309 nvtxs = graph->
nvtxs;
1312 where = graph->
where;
1316 for (nbnd=0, i=0; i<nvtxs; i++) {
1317 if (xadj[i+1]-xadj[i] == 0)
1320 for (j=xadj[i]; j<xadj[i+1]; j++) {
1321 if (where[i] != where[adjncy[j]]) {
1324 ASSERT(bndind[bndptr[i]] == i);
1342 int i, j, nvtxs, nbnd, id, ed;
1343 idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
1345 nvtxs = graph->
nvtxs;
1348 where = graph->
where;
1352 for (nbnd=0, i=0; i<nvtxs; i++) {
1354 for (j=xadj[i]; j<xadj[i+1]; j++) {
1355 if (where[i] != where[adjncy[j]])
1360 if (ed -
id >= 0 && xadj[i] < xadj[i+1]) {
1362 ASSERTP(bndptr[i] != -1, (
"%d %d %d\n", i,
id, ed));
1363 ASSERT(bndind[bndptr[i]] == i);
1378 idxtype *xadj, *adjncy, *where, *bndptr, *bndind;
1380 nvtxs = graph->
nvtxs;
1383 where = graph->
where;
1387 for (nbnd=0, i=0; i<nvtxs; i++) {
1392 ASSERTP(nbnd == onbnd, (
"%d %d\n", nbnd, onbnd));
1394 for (i=0; i<nvtxs; i++) {
1395 if (where[i] != 2) {
1396 ASSERTP(bndptr[i] == -1, (
"%d %d\n", i, bndptr[i]));
1399 ASSERTP(bndptr[i] != -1, (
"%d %d\n", i, bndptr[i]));
1415 for (i=0; i<rinfo->
ndegrees; i++) {
1416 for (j=i+1; j<rinfo->
ndegrees; j++)
1430 int i, j, nvtxs, me, other;
1431 idxtype *xadj, *adjncy, *adjwgt, *vwgt, *where;
1432 idxtype edegrees[2], pwgts[3];
1434 nvtxs = graph->
nvtxs;
1440 where = graph->
where;
1445 pwgts[0] = pwgts[1] = pwgts[2] = 0;
1446 for (i=0; i<nvtxs; i++) {
1448 pwgts[me] += vwgt[i];
1451 edegrees[0] = edegrees[1] = 0;
1453 for (j=xadj[i]; j<xadj[i+1]; j++) {
1454 other = where[adjncy[j]];
1456 edegrees[other] += vwgt[adjncy[j]];
1459 printf(
"Something wrong with edegrees: %d %d %d %d %d\n", i, edegrees[0], edegrees[1], graph->
nrinfo[i].
edegrees[0], graph->
nrinfo[i].
edegrees[1]);
1465 if (pwgts[0] != graph->
pwgts[0] || pwgts[1] != graph->
pwgts[1] || pwgts[2] != graph->
pwgts[2])
1466 printf(
"Something wrong with part-weights: %d %d %d %d %d %d\n", pwgts[0], pwgts[1], pwgts[2], graph->
pwgts[0], graph->
pwgts[1], graph->
pwgts[2]);
1477 int i, j, nvtxs, other;
1478 idxtype *xadj, *adjncy, *where;
1480 nvtxs = graph->
nvtxs;
1483 where = graph->
where;
1485 for (i=0; i<nvtxs; i++) {
1488 other = (where[i]+1)%2;
1489 for (j=xadj[i]; j<xadj[i+1]; j++) {
1490 ASSERTP(where[adjncy[j]] != other, (
"%d %d %d %d %d %d\n", i, where[i], adjncy[j], where[adjncy[j]], xadj[i+1]-xadj[i], xadj[adjncy[j]+1]-xadj[adjncy[j]]));
1521 int nedges, nlevels;
1522 float vfraction, efraction, vmult, emult;
1523 int coresize, gdata, rdata;
1528 nedges = xadj[*nvtxs];
1539 coresize += 2*(*nvtxs);
1543 nlevels = (int)(log(100.0/(*nvtxs))/log(vfraction) + .5);
1544 vmult = 0.5 + (1.0 - pow(vfraction, nlevels))/(1.0 - vfraction);
1545 emult = 1.0 + (1.0 - pow(efraction, nlevels+1))/(1.0 - efraction);
1547 gdata += vmult*4*(*nvtxs) + emult*2*nedges;
1548 if ((vmult-1.0)*4*(*nvtxs) + (emult-1.0)*2*nedges < 5*(*nvtxs))
1553 *nbytes =
sizeof(
idxtype)*(coresize+gdata+rdata+(*nvtxs));
1565 int i,
ii, j, cnvtxs, cnedges, maxidx;
1574 for (
ii=0;
ii<nvtxs;
ii++) {
1581 for (j=xadj[i]; j<xadj[i+1]; j++) {
1588 cmap[i] = cmap[maxidx] = cnvtxs++;
1596 *vfraction = (1.0*cnvtxs)/(1.0*nvtxs);
1597 *efraction = (1.0*cnedges)/(1.0*xadj[nvtxs]);
1599 GKfree((
void **) &cmap, (
void **) &match, (
void **) &perm,
LTERM);
1615 cnvtxs = cnedges = 0;
1616 for (i=0; i<nvtxs; i++) {
1618 if (cmap[v] != cnvtxs)
1621 htable[cnvtxs] = cnvtxs;
1628 k = cmap[adjncy[j]];
1629 if (htable[k] != cnvtxs) {
1639 k = cmap[adjncy[j]];
1640 if (htable[k] != cnvtxs) {
1676 int i,
ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, limit,
tmp;
1677 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts;
1678 idxtype *moved, *swaps, *perm;
1680 int higain, oldgain, mincut, mindiff, origdiff, initcut, newcut, mincutorder, avgvwgt;
1682 nvtxs = graph->
nvtxs;
1687 where = graph->
where;
1690 pwgts = graph->
pwgts;
1698 limit =
amin(
amax(0.01*nvtxs, 15), 100);
1699 avgvwgt =
amin((pwgts[0]+pwgts[1])/20, 2*(pwgts[0]+pwgts[1])/nvtxs);
1706 printf(
"Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d\n",
1707 pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
1709 origdiff = abs(tpwgts[0]-pwgts[0]);
1710 idxset(nvtxs, -1, moved);
1711 for (pass=0; pass<npasses; pass++) {
1716 newcut = mincut = initcut = graph->
mincut;
1717 mindiff = abs(tpwgts[0]-pwgts[0]);
1725 for (
ii=0;
ii<nbnd;
ii++) {
1727 ASSERT(ed[bndind[i]] > 0 ||
id[bndind[i]] == 0);
1728 ASSERT(bndptr[bndind[i]] != -1);
1729 PQueueInsert(&parts[where[bndind[i]]], bndind[i], ed[bndind[i]]-
id[bndind[i]]);
1732 for (nswaps=0; nswaps<nvtxs; nswaps++) {
1733 from = (tpwgts[0]-pwgts[0] < tpwgts[1]-pwgts[1] ? 0 : 1);
1738 ASSERT(bndptr[higain] != -1);
1740 newcut -= (ed[higain]-
id[higain]);
1741 INC_DEC(pwgts[to], pwgts[from], vwgt[higain]);
1743 if ((newcut < mincut && abs(tpwgts[0]-pwgts[0]) <= origdiff+avgvwgt) ||
1744 (newcut == mincut && abs(tpwgts[0]-pwgts[0]) < mindiff)) {
1746 mindiff = abs(tpwgts[0]-pwgts[0]);
1747 mincutorder = nswaps;
1749 else if (nswaps-mincutorder > limit) {
1750 newcut += (ed[higain]-
id[higain]);
1751 INC_DEC(pwgts[from], pwgts[to], vwgt[higain]);
1756 moved[higain] = nswaps;
1757 swaps[nswaps] = higain;
1760 printf(
"Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-
id[higain], vwgt[higain], newcut, pwgts[0], pwgts[1]));
1765 SWAP(
id[higain], ed[higain],
tmp);
1766 if (ed[higain] == 0 && xadj[higain] < xadj[higain+1])
1767 BNDDelete(nbnd, bndind, bndptr, higain);
1769 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
1771 oldgain = ed[k]-
id[k];
1773 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
1777 if (bndptr[k] != -1) {
1785 PQueueUpdate(&parts[where[k]], k, oldgain, ed[k]-
id[k]);
1803 for (i=0; i<nswaps; i++)
1804 moved[swaps[i]] = -1;
1805 for (nswaps--; nswaps>mincutorder; nswaps--) {
1806 higain = swaps[nswaps];
1808 to = where[higain] = (where[higain]+1)%2;
1809 SWAP(
id[higain], ed[higain],
tmp);
1810 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
1811 BNDDelete(nbnd, bndind, bndptr, higain);
1812 else if (ed[higain] > 0 && bndptr[higain] == -1)
1813 BNDInsert(nbnd, bndind, bndptr, higain);
1815 INC_DEC(pwgts[to], pwgts[(to+1)%2], vwgt[higain]);
1816 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
1819 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
1822 if (bndptr[k] != -1 && ed[k] == 0)
1824 if (bndptr[k] == -1 && ed[k] > 0)
1830 printf(
"\tMinimum cut: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
1835 if (mincutorder == -1 || mincut == initcut)
1873 for (i=0; i<=nvtxs; i++)
1876 nedges = xadj[nvtxs];
1877 for (i=0; i<nedges; i++)
1888 for (i=0; i<nvtxs; i++)
1891 nedges = xadj[nvtxs];
1892 for (i=0; i<nedges; i++)
1895 for (i=0; i<=nvtxs; i++)
1906 nedges = xadj[nvtxs];
1907 for (i=0; i<nedges; i++)
1910 for (i=0; i<=nvtxs; i++)
1923 for (i=0; i<nvtxs; i++) {
1928 nedges = xadj[nvtxs];
1929 for (i=0; i<nedges; i++)
1932 for (i=0; i<=nvtxs; i++)
1962 nedges = xadj[nvtxs];
1963 for (i=0; i<nedges; i++)
1966 for (i=0; i<=nvtxs; i++)
1982 for (i=0; i<ne; i++)
1985 for (i=0; i<nn; i++)
2007 void METIS_PARTGRAPHRECURSIVE(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2009 METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2011 void metis_partgraphrecursive(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2013 METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2015 void metis_partgraphrecursive_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2017 METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2019 void metis_partgraphrecursive__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2021 METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2025 void METIS_WPARTGRAPHRECURSIVE(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2027 METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2029 void metis_wpartgraphrecursive(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2031 METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2033 void metis_wpartgraphrecursive_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2035 METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2037 void metis_wpartgraphrecursive__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2039 METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2044 void METIS_PARTGRAPHKWAY(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2046 METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2048 void metis_partgraphkway(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2050 METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2052 void metis_partgraphkway_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2054 METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2056 void metis_partgraphkway__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2058 METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2063 void METIS_WPARTGRAPHKWAY(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2065 METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2067 void metis_wpartgraphkway(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2069 METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2071 void metis_wpartgraphkway_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2073 METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2075 void metis_wpartgraphkway__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
2077 METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut,
part);
2084 METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2088 METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2092 METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2096 METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2103 METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2107 METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2111 METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2115 METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm);
2122 METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
2126 METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
2130 METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
2134 METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm);
2230 void METIS_MCPARTGRAPHRECURSIVE(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2232 METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2234 void metis_mcpartgraphrecursive(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2236 METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2238 void metis_mcpartgraphrecursive_(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2240 METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2242 void metis_mcpartgraphrecursive__(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
2244 METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut,
part);
2248 void METIS_MCPARTGRAPHKWAY(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *rubvec,
int *options,
int *edgecut,
idxtype *
part)
2250 METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut,
part);
2252 void metis_mcpartgraphkway(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *rubvec,
int *options,
int *edgecut,
idxtype *
part)
2254 METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut,
part);
2256 void metis_mcpartgraphkway_(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *rubvec,
int *options,
int *edgecut,
idxtype *
part)
2258 METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut,
part);
2260 void metis_mcpartgraphkway__(
int *nvtxs,
int *ncon,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
float *rubvec,
int *options,
int *edgecut,
idxtype *
part)
2262 METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut,
part);
2266 void METIS_PARTGRAPHVKWAY(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *volume,
idxtype *
part)
2268 METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume,
part);
2270 void metis_partgraphvkway(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *volume,
idxtype *
part)
2272 METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume,
part);
2274 void metis_partgraphvkway_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *volume,
idxtype *
part)
2276 METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume,
part);
2278 void metis_partgraphvkway__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
int *options,
int *volume,
idxtype *
part)
2280 METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume,
part);
2283 void METIS_WPARTGRAPHVKWAY(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *volume,
idxtype *
part)
2285 METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume,
part);
2287 void metis_wpartgraphvkway(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *volume,
idxtype *
part)
2289 METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume,
part);
2291 void metis_wpartgraphvkway_(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *volume,
idxtype *
part)
2293 METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume,
part);
2295 void metis_wpartgraphvkway__(
int *nvtxs,
idxtype *xadj,
idxtype *adjncy,
idxtype *vwgt,
idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
float *tpwgts,
int *options,
int *volume,
idxtype *
part)
2297 METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume,
part);
2325 int i, j, sum, gsize;
2329 if (OpType ==
OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) {
2336 graph->
nvtxs = nvtxs;
2337 graph->
nedges = xadj[nvtxs];
2344 if ((wgtflag&2) == 0)
2346 if ((wgtflag&1) == 0)
2355 if ((wgtflag&2) == 0) {
2362 if ((wgtflag&1) == 0) {
2374 for (i=0; i<nvtxs; i++) {
2376 for (j=xadj[i]; j<xadj[i+1]; j++)
2387 if ((wgtflag&1) == 0)
2395 for (i=0; i<ncon; i++)
2398 nvwgt = graph->
nvwgt =
fmalloc(ncon*nvtxs,
"SetUpGraph: nvwgt");
2400 for (i=0; i<nvtxs; i++) {
2401 for (j=0; j<ncon; j++)
2402 nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
2407 if ((wgtflag&1) == 0) {
2418 for (i=0; i<nvtxs; i++) {
2420 for (j=xadj[i]; j<xadj[i+1]; j++)
2433 for (i=0; i<nvtxs; i++)
2434 graph->
label[i] = i;
2449 graph->
nvtxs = nvtxs;
2450 graph->
nedges = xadj[nvtxs];
2462 for (i=0; i<nvtxs; i++)
2463 graph->
adjwgtsum[i] = xadj[i+1]-xadj[i];
2479 graph->
nvtxs = nvtxs;
2480 graph->
nedges = xadj[nvtxs];
2486 graph->
nvwgt =
fmalloc(nvtxs*ncon,
"SetUpGraph2: graph->nvwgt");
2493 for (i=0; i<nvtxs; i++) {
2495 for (j=xadj[i]; j<xadj[i+1]; j++)
2503 for (i=0; i<nvtxs; i++)
2504 graph->
label[i] = i;
2515 int i, j, sum, gsize;
2522 graph->
nvtxs = nvtxs;
2523 graph->
nedges = xadj[nvtxs];
2530 if ((wgtflag&2) == 0)
2532 if ((wgtflag&1) == 0)
2541 if ((wgtflag&2) == 0) {
2548 if ((wgtflag&1) == 0) {
2553 graph->
vsize = vsize;
2559 for (i=0; i<nvtxs; i++) {
2560 for (j=xadj[i]; j<xadj[i+1]; j++)
2561 adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
2569 for (i=0; i<nvtxs; i++) {
2571 for (j=xadj[i]; j<xadj[i+1]; j++)
2582 if ((wgtflag&1) == 0)
2591 if ((wgtflag&2) == 0)
2592 vwgt =
idxsmalloc(nvtxs, 1,
"SetUpGraph: vwgt");
2594 for (i=0; i<ncon; i++)
2597 nvwgt = graph->
nvwgt =
fmalloc(ncon*nvtxs,
"SetUpGraph: nvwgt");
2599 for (i=0; i<nvtxs; i++) {
2600 for (j=0; j<ncon; j++)
2601 nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
2603 if ((wgtflag&2) == 0)
2608 if ((wgtflag&1) == 0) {
2613 graph->
vsize = vsize;
2619 for (i=0; i<nvtxs; i++) {
2620 for (j=xadj[i]; j<xadj[i+1]; j++)
2621 adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
2628 for (i=0; i<nvtxs; i++) {
2630 for (j=xadj[i]; j<xadj[i+1]; j++)
2643 for (i=0; i<nvtxs; i++)
2644 graph->
label[i] = i;
2655 int i, j, k, l,
tmp, nvtxs;
2656 idxtype *xadj, *adjncy, *adjwgt;
2658 nvtxs = graph->
nvtxs;
2663 for (i=0; i<nvtxs; i++) {
2664 l = xadj[i+1]-xadj[i];
2665 for (j=xadj[i]; j<xadj[i+1]; j++) {
2667 SWAP(adjncy[j], adjncy[k],
tmp);
2668 SWAP(adjwgt[j], adjwgt[k],
tmp);
2679 int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
2680 idxtype *xadj, *adjncy, *where, *touched, *queue;
2683 nvtxs = graph->
nvtxs;
2686 where = graph->
where;
2688 touched =
idxsmalloc(nvtxs, 0,
"IsConnected: touched");
2689 queue =
idxmalloc(nvtxs,
"IsConnected: queue");
2690 cptr =
idxmalloc(nvtxs,
"IsConnected: cptr");
2693 for (i=0; i<nvtxs; i++) {
2694 if (where[i] == pid)
2698 for (i=0; i<nvtxs; i++) {
2699 if (where[i] == pid)
2705 first = 0; last = 1;
2709 while (first != nleft) {
2710 if (first == last) {
2711 cptr[++ncmps] = first;
2712 for (i=0; i<nvtxs; i++) {
2713 if (where[i] == pid && !touched[i])
2721 for (j=xadj[i]; j<xadj[i+1]; j++) {
2723 if (where[k] == pid && !touched[k]) {
2729 cptr[++ncmps] = first;
2731 if (ncmps > 1 && report) {
2732 printf(
"The graph has %d connected components in partition %d:\t", ncmps, pid);
2733 for (i=0; i<ncmps; i++) {
2735 for (j=cptr[i]; j<cptr[i+1]; j++)
2736 wgt += graph->
vwgt[queue[j]];
2737 printf(
"[%5d %5d] ", cptr[i+1]-cptr[i], wgt);
2746 GKfree((
void **) &touched, (
void **) &queue, (
void **) &cptr,
LTERM);
2748 return (ncmps == 1 ? 1 : 0);
2757 int i, j, k, nvtxs, first, last;
2758 idxtype *xadj, *adjncy, *touched, *queue;
2760 nvtxs = graph->
nvtxs;
2764 touched =
idxsmalloc(nvtxs, 0,
"IsConnected: touched");
2765 queue =
idxmalloc(nvtxs,
"IsConnected: queue");
2769 first = 0; last = 1;
2771 while (first < last) {
2773 for (j=xadj[i]; j<xadj[i+1]; j++) {
2782 if (first != nvtxs && report)
2783 printf(
"The graph is not connected. It has %d disconnected vertices!\n", nvtxs-first);
2785 return (first == nvtxs ? 1 : 0);
2794 int i, j, k, nvtxs, first, last, nleft, ncmps;
2795 idxtype *xadj, *adjncy, *where, *touched, *queue;
2798 nvtxs = graph->
nvtxs;
2801 where = graph->
where;
2803 touched =
idxsmalloc(nvtxs, 0,
"IsConnected: touched");
2804 queue =
idxmalloc(nvtxs,
"IsConnected: queue");
2805 cptr =
idxmalloc(nvtxs,
"IsConnected: cptr");
2810 first = 0; last = 1;
2814 while (first != nleft) {
2815 if (first == last) {
2816 cptr[++ncmps] = first;
2817 for (i=0; i<nvtxs; i++) {
2826 for (j=xadj[i]; j<xadj[i+1]; j++) {
2834 cptr[++ncmps] = first;
2836 if (ncmps > 1 && report) {
2837 printf(
"%d connected components:\t", ncmps);
2838 for (i=0; i<ncmps; i++) {
2839 if (cptr[i+1]-cptr[i] > 200)
2840 printf(
"[%5d] ", cptr[i+1]-cptr[i]);
2845 GKfree((
void **) &touched, (
void **) &queue, (
void **) &cptr,
LTERM);
2847 return (ncmps == 1 ? 1 : 0);
2857 int i, j, k, nvtxs, first, last, nleft, ncmps;
2858 idxtype *xadj, *adjncy, *where, *touched, *queue;
2860 nvtxs = graph->
nvtxs;
2863 where = graph->
where;
2865 touched =
idxsmalloc(nvtxs, 0,
"IsConnected: queue");
2867 for (i=0; i<graph->
nbnd; i++)
2868 touched[graph->
bndind[i]] = 1;
2873 for (i=0; i<nvtxs; i++) {
2878 for (i=0; i<nvtxs; i++) {
2885 first = 0; last = 1;
2889 while (first != nleft) {
2890 if (first == last) {
2891 cptr[++ncmps] = first;
2892 for (i=0; i<nvtxs; i++) {
2901 for (j=xadj[i]; j<xadj[i+1]; j++) {
2909 cptr[++ncmps] = first;
2948 switch (ctrl->
IType) {
2956 errexit(
"Unknown initial partition type: %d\n", ctrl->
IType);
3001 int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], minpwgt[2], maxpwgt[2], bestcut, nbfs;
3002 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where;
3003 idxtype *queue, *touched, *bestwhere;
3006 nvtxs = graph->
nvtxs;
3013 where = graph->
where;
3015 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
3016 queue =
idxmalloc(nvtxs,
"BisectGraph: queue");
3017 touched =
idxmalloc(nvtxs,
"BisectGraph: touched");
3019 ASSERTP(tpwgts[0]+tpwgts[1] ==
idxsum(nvtxs, vwgt), (
"%d %d\n", tpwgts[0]+tpwgts[1],
idxsum(nvtxs, vwgt)));
3021 maxpwgt[0] = ubfactor*tpwgts[0];
3022 maxpwgt[1] = ubfactor*tpwgts[1];
3023 minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
3024 minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
3028 for (; nbfs>0; nbfs--) {
3029 idxset(nvtxs, 0, touched);
3031 pwgts[1] = tpwgts[0]+tpwgts[1];
3037 touched[queue[0]] = 1;
3038 first = 0; last = 1;
3044 if (first == last) {
3045 if (nleft == 0 || drain)
3049 for (i=0; i<nvtxs; i++) {
3050 if (touched[i] == 0) {
3060 first = 0; last = 1;;
3065 if (pwgts[0] > 0 && pwgts[1]-vwgt[i] < minpwgt[1]) {
3071 INC_DEC(pwgts[0], pwgts[1], vwgt[i]);
3072 if (pwgts[1] <= maxpwgt[1])
3076 for (j=xadj[i]; j<xadj[i+1]; j++) {
3078 if (touched[k] == 0) {
3087 if (pwgts[1] == 0) {
3090 INC_DEC(pwgts[1], pwgts[0], vwgt[i]);
3105 if (bestcut > graph->
mincut) {
3107 idxcopy(nvtxs, where, bestwhere);
3114 idxcopy(nvtxs, bestwhere, where);
3116 GKfree((
void **) &bestwhere, (
void **) &queue, (
void **) &touched,
LTERM);
3129 int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], tpwgts[2], minpwgt[2], maxpwgt[2], bestcut, nbfs;
3130 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *bndind;
3131 idxtype *queue, *touched, *bestwhere;
3133 nvtxs = graph->
nvtxs;
3139 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
3140 queue =
idxmalloc(nvtxs,
"BisectGraph: queue");
3141 touched =
idxmalloc(nvtxs,
"BisectGraph: touched");
3143 tpwgts[0] =
idxsum(nvtxs, vwgt);
3144 tpwgts[1] = tpwgts[0]/2;
3145 tpwgts[0] -= tpwgts[1];
3147 maxpwgt[0] = ubfactor*tpwgts[0];
3148 maxpwgt[1] = ubfactor*tpwgts[1];
3149 minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
3150 minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
3153 graph->
rdata =
idxmalloc(5*nvtxs+3,
"GrowBisectionNode: graph->rdata");
3159 graph->
id = graph->
rdata + 3*nvtxs + 3;
3160 graph->
ed = graph->
rdata + 4*nvtxs + 3;
3162 where = graph->
where;
3166 bestcut = tpwgts[0]+tpwgts[1];
3167 for (nbfs++; nbfs>0; nbfs--) {
3168 idxset(nvtxs, 0, touched);
3170 pwgts[1] = tpwgts[0]+tpwgts[1];
3176 touched[queue[0]] = 1;
3177 first = 0; last = 1;
3184 if (first == last) {
3185 if (nleft == 0 || drain)
3189 for (i=0; i<nvtxs; i++) {
3190 if (touched[i] == 0) {
3200 first = 0; last = 1;;
3205 if (pwgts[1]-vwgt[i] < minpwgt[1]) {
3211 INC_DEC(pwgts[0], pwgts[1], vwgt[i]);
3212 if (pwgts[1] <= maxpwgt[1])
3216 for (j=xadj[i]; j<xadj[i+1]; j++) {
3218 if (touched[k] == 0) {
3235 for (i=0; i<graph->
nbnd; i++)
3236 where[bndind[i]] = 2;
3243 if (bestcut > graph->
mincut) {
3245 idxcopy(nvtxs, where, bestwhere);
3250 idxcopy(nvtxs, bestwhere, where);
3254 GKfree((
void **) &bestwhere, (
void **) &queue, (
void **) &touched,
LTERM);
3265 int i,
ii, nvtxs, pwgts[2], minpwgt[2], maxpwgt[2], bestcut, nbfs;
3266 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where;
3269 nvtxs = graph->
nvtxs;
3276 where = graph->
where;
3278 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
3279 perm =
idxmalloc(nvtxs,
"BisectGraph: queue");
3281 ASSERTP(tpwgts[0]+tpwgts[1] ==
idxsum(nvtxs, vwgt), (
"%d %d\n", tpwgts[0]+tpwgts[1],
idxsum(nvtxs, vwgt)));
3283 maxpwgt[0] = ubfactor*tpwgts[0];
3284 maxpwgt[1] = ubfactor*tpwgts[1];
3285 minpwgt[0] = (1.0/ubfactor)*tpwgts[0];
3286 minpwgt[1] = (1.0/ubfactor)*tpwgts[1];
3290 for (; nbfs>0; nbfs--) {
3294 pwgts[1] = tpwgts[0]+tpwgts[1];
3299 for (
ii=0;
ii<nvtxs;
ii++) {
3301 if (pwgts[0]+vwgt[i] < maxpwgt[0]) {
3303 pwgts[0] += vwgt[i];
3304 pwgts[1] -= vwgt[i];
3305 if (pwgts[0] > minpwgt[0])
3323 if (bestcut > graph->
mincut) {
3325 idxcopy(nvtxs, where, bestwhere);
3332 idxcopy(nvtxs, bestwhere, where);
3334 GKfree((
void **) &bestwhere, (
void **) &perm,
LTERM);
3362 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
3368 tpwgts =
fmalloc(*nparts,
"KMETIS: tpwgts");
3369 for (i=0; i<*nparts; i++)
3370 tpwgts[i] = 1.0/(1.0*(*nparts));
3373 tpwgts, options, edgecut,
part);
3383 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
3384 float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
3394 if (options[0] == 0) {
3435 int wgtflag=3, numflag=0, options[10], edgecut;
3449 cgraph->
adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options,
3450 &edgecut, cgraph->
where);
3453 IFSET(ctrl->
dbglvl,
DBG_IPART, printf(
"Initial %d-way partitioning cut: %d\n", nparts, edgecut));
3457 RefineKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor);
3489 idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
3495 tpwgts =
fmalloc(*nparts,
"KMETIS: tpwgts");
3496 for (i=0; i<*nparts; i++)
3497 tpwgts[i] = 1.0/(1.0*(*nparts));
3500 tpwgts, options, volume,
part);
3510 idxtype *vsize,
int *wgtflag,
int *numflag,
int *nparts,
3511 float *tpwgts,
int *options,
int *volume,
idxtype *
part)
3521 if (options[0] == 0) {
3560 float *tpwgts,
float ubfactor)
3563 int wgtflag=3, numflag=0, options[10], edgecut;
3577 cgraph->
adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options,
3578 &edgecut, cgraph->
where);
3581 IFSET(ctrl->
dbglvl,
DBG_IPART, printf(
"Initial %d-way partitioning cut: %d\n", nparts, edgecut));
3585 RefineVolKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor);
3615 int i,
ii, iii, j, k, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees;
3616 int from, me, to, oldcut, vwgt, gain;
3617 idxtype *xadj, *adjncy, *adjwgt;
3618 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts;
3622 nvtxs = graph->
nvtxs;
3630 where = graph->
where;
3631 pwgts = graph->
pwgts;
3637 tvwgt =
idxsum(nparts, pwgts);
3640 for (i=0; i<nparts; i++) {
3641 itpwgts[i] = tpwgts[i]*tvwgt;
3642 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
3643 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
3649 printf(
"Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
3650 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
3654 for (pass=0; pass<npasses; pass++) {
3661 for (nmoves=iii=0; iii<graph->
nbnd; iii++) {
3667 myrinfo = graph->
rinfo+i;
3669 if (myrinfo->
ed >= myrinfo->
id) {
3671 vwgt = graph->
vwgt[i];
3673 if (myrinfo->
id > 0 && pwgts[from]-vwgt < minwgt[from])
3680 for (k=0; k<myndegrees; k++) {
3681 to = myedegrees[k].
pid;
3682 gain = myedegrees[k].
ed-j;
3683 if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0)
3686 if (k == myndegrees)
3689 for (j=k+1; j<myndegrees; j++) {
3690 to = myedegrees[j].
pid;
3691 if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
3692 (myedegrees[j].ed == myedegrees[k].ed &&
3693 itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
3697 to = myedegrees[k].
pid;
3700 if (myedegrees[k].ed-myrinfo->
id > 0)
3702 else if (myedegrees[k].ed-myrinfo->
id == 0) {
3703 if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
3712 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
3718 INC_DEC(pwgts[to], pwgts[from], vwgt);
3719 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
3720 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
3721 if (myedegrees[k].ed == 0)
3722 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
3724 myedegrees[k].
pid = from;
3726 if (myrinfo->
ed-myrinfo->
id < 0)
3730 for (j=xadj[i]; j<xadj[i+1]; j++) {
3746 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
3749 else if (me == to) {
3752 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
3758 for (k=0; k<myrinfo->
ndegrees; k++) {
3759 if (myedegrees[k].pid == from) {
3760 if (myedegrees[k].ed == adjwgt[j])
3761 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
3763 myedegrees[k].
ed -= adjwgt[j];
3771 for (k=0; k<myrinfo->
ndegrees; k++) {
3772 if (myedegrees[k].pid == to) {
3773 myedegrees[k].
ed += adjwgt[j];
3779 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
3794 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
3798 if (graph->
mincut == oldcut)
3818 int i,
ii, iii, j, k, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain;
3819 int from, me, to, oldcut, vwgt;
3820 idxtype *xadj, *adjncy, *adjwgt;
3821 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
3826 nvtxs = graph->
nvtxs;
3834 where = graph->
where;
3835 pwgts = graph->
pwgts;
3841 tvwgt =
idxsum(nparts, pwgts);
3844 for (i=0; i<nparts; i++) {
3845 itpwgts[i] = tpwgts[i]*tvwgt;
3846 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
3847 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
3856 printf(
"Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
3857 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
3861 for (pass=0; pass<npasses; pass++) {
3865 idxset(nvtxs, -1, moved);
3871 for (
ii=0;
ii<nbnd;
ii++) {
3872 i = bndind[perm[
ii]];
3877 for (iii=0;;iii++) {
3882 myrinfo = graph->
rinfo+i;
3884 vwgt = graph->
vwgt[i];
3886 if (pwgts[from]-vwgt < minwgt[from])
3893 for (k=0; k<myndegrees; k++) {
3894 to = myedegrees[k].
pid;
3895 gain = myedegrees[k].
ed-j;
3896 if (pwgts[to]+vwgt <= maxwgt[to]+gain && gain >= 0)
3899 if (k == myndegrees)
3902 for (j=k+1; j<myndegrees; j++) {
3903 to = myedegrees[j].
pid;
3904 if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
3905 (myedegrees[j].ed == myedegrees[k].ed &&
3906 itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
3910 to = myedegrees[k].
pid;
3913 if (myedegrees[k].ed-myrinfo->
id > 0)
3915 else if (myedegrees[k].ed-myrinfo->
id == 0) {
3916 if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
3925 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
3931 INC_DEC(pwgts[to], pwgts[from], vwgt);
3932 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
3933 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
3934 if (myedegrees[k].ed == 0)
3935 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
3937 myedegrees[k].
pid = from;
3939 if (myrinfo->
ed < myrinfo->
id)
3943 for (j=xadj[i]; j<xadj[i+1]; j++) {
3956 oldgain = (myrinfo->
ed-myrinfo->
id);
3961 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
3964 else if (me == to) {
3967 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
3973 for (k=0; k<myrinfo->
ndegrees; k++) {
3974 if (myedegrees[k].pid == from) {
3975 if (myedegrees[k].ed == adjwgt[j])
3976 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
3978 myedegrees[k].
ed -= adjwgt[j];
3986 for (k=0; k<myrinfo->
ndegrees; k++) {
3987 if (myedegrees[k].pid == to) {
3988 myedegrees[k].
ed += adjwgt[j];
3994 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
3999 if (me == to || me == from) {
4000 gain = myrinfo->
ed-myrinfo->
id;
4001 if (moved[
ii] == 2) {
4009 else if (moved[
ii] == -1 && gain >= 0) {
4024 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Cut: %6d\n",
4028 if (graph->
mincut == oldcut)
4048 int i,
ii, j, k, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves;
4049 int from, me, to, oldcut, vwgt;
4050 idxtype *xadj, *adjncy, *adjwgt;
4051 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
4056 nvtxs = graph->
nvtxs;
4064 where = graph->
where;
4065 pwgts = graph->
pwgts;
4071 tvwgt =
idxsum(nparts, pwgts);
4074 for (i=0; i<nparts; i++) {
4075 itpwgts[i] = tpwgts[i]*tvwgt;
4076 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
4077 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
4086 printf(
"Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n",
4087 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
4091 for (pass=0; pass<npasses; pass++) {
4095 for (i=0; i<nparts; i++) {
4096 if (pwgts[i] > maxwgt[i])
4103 idxset(nvtxs, -1, moved);
4109 for (
ii=0;
ii<nbnd;
ii++) {
4110 i = bndind[perm[
ii]];
4121 myrinfo = graph->
rinfo+i;
4123 vwgt = graph->
vwgt[i];
4125 if (pwgts[from]-vwgt < minwgt[from])
4131 for (k=0; k<myndegrees; k++) {
4132 to = myedegrees[k].
pid;
4133 if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from])
4136 if (k == myndegrees)
4139 for (j=k+1; j<myndegrees; j++) {
4140 to = myedegrees[j].
pid;
4141 if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])
4145 to = myedegrees[k].
pid;
4147 if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->
id < 0)
4153 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
4159 INC_DEC(pwgts[to], pwgts[from], vwgt);
4160 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
4161 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
4162 if (myedegrees[k].ed == 0)
4163 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
4165 myedegrees[k].
pid = from;
4167 if (myrinfo->
ed == 0)
4171 for (j=xadj[i]; j<xadj[i+1]; j++) {
4184 oldgain = (myrinfo->
ed-myrinfo->
id);
4189 if (myrinfo->
ed > 0 && bndptr[
ii] == -1)
4192 else if (me == to) {
4195 if (myrinfo->
ed == 0 && bndptr[
ii] != -1)
4201 for (k=0; k<myrinfo->
ndegrees; k++) {
4202 if (myedegrees[k].pid == from) {
4203 if (myedegrees[k].ed == adjwgt[j])
4204 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
4206 myedegrees[k].
ed -= adjwgt[j];
4214 for (k=0; k<myrinfo->
ndegrees; k++) {
4215 if (myedegrees[k].pid == to) {
4216 myedegrees[k].
ed += adjwgt[j];
4222 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
4227 if (me == to || me == from) {
4228 gain = myrinfo->
ed-myrinfo->
id;
4229 if (moved[
ii] == 2) {
4230 if (myrinfo->
ed > 0)
4237 else if (moved[
ii] == -1 && myrinfo->
ed > 0) {
4252 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d\n",
4254 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves, graph->
mincut));
4288 int i, nlevels, mustfree=0;
4306 for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->
finer, nlevels++);
4315 if (2*i >= nlevels && !
IsBalanced(graph->
pwgts, nparts, tpwgts, 1.04*ubfactor)) {
4324 switch (ctrl->
RType) {
4337 if (graph == orggraph)
4342 graph = graph->
finer;
4345 if (graph->
vwgt == NULL) {
4385 nvtxs = graph->
nvtxs;
4387 pad64 = (3*nvtxs+nparts)%2;
4409 int i, j, k, nvtxs, nbnd, mincut, me, other;
4410 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr;
4414 nvtxs = graph->
nvtxs;
4420 where = graph->
where;
4424 rinfo = graph->
rinfo;
4432 for (i=0; i<nvtxs; i++) {
4434 pwgts[me] += vwgt[i];
4440 for (j=xadj[i]; j<xadj[i+1]; j++) {
4441 if (me != where[adjncy[j]])
4442 myrinfo->
ed += adjwgt[j];
4446 if (myrinfo->
ed > 0)
4447 mincut += myrinfo->
ed;
4449 if (myrinfo->
ed-myrinfo->
id >= 0)
4453 if (myrinfo->
ed > 0) {
4457 for (j=xadj[i]; j<xadj[i+1]; j++) {
4458 other = where[adjncy[j]];
4460 for (k=0; k<myrinfo->
ndegrees; k++) {
4461 if (myedegrees[k].pid == other) {
4462 myedegrees[k].
ed += adjwgt[j];
4468 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
4477 graph->
mincut = mincut/2;
4490 int i, j, k, nvtxs, nbnd, me, other,
istart,
iend, ndegrees;
4491 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
4492 idxtype *cmap, *where, *bndptr, *bndind;
4500 cwhere = cgraph->
where;
4501 crinfo = cgraph->
rinfo;
4503 nvtxs = graph->
nvtxs;
4511 where = graph->
where;
4512 rinfo = graph->
rinfo;
4517 for (i=0; i<nvtxs; i++) {
4519 where[i] = cwhere[k];
4520 cmap[i] = crinfo[k].
ed;
4526 for (nbnd=0, i=0; i<nvtxs; i++) {
4533 myrinfo->
id = adjwgtsum[i];
4544 other = where[adjncy[j]];
4546 myrinfo->
ed += adjwgt[j];
4547 if ((k = htable[other]) == -1) {
4548 htable[other] = ndegrees;
4549 myedegrees[ndegrees].
pid = other;
4550 myedegrees[ndegrees++].
ed = adjwgt[j];
4553 myedegrees[k].
ed += adjwgt[j];
4557 myrinfo->
id -= myrinfo->
ed;
4560 if (myrinfo->
ed == 0) {
4565 if (myrinfo->
ed-myrinfo->
id >= 0)
4570 for (j=0; j<ndegrees; j++)
4571 htable[myedegrees[j].pid] = -1;
4599 tvwgt =
idxsum(nparts, pwgts);
4600 for (i=0; i<nparts; i++) {
4601 if (pwgts[i] > tpwgts[i]*tvwgt*(ubfactor+0.005))
4617 nvtxs = graph->
nvtxs;
4626 for (i=0; i<nvtxs; i++) {
4642 nvtxs = graph->
nvtxs;
4651 for (i=0; i<nvtxs; i++) {
4678 float ubfactor,
int npasses,
int ffactor)
4680 int i,
ii, iii, j, k, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain;
4681 int from, to, oldcut, oldvol, vwgt;
4682 idxtype *xadj, *adjncy, *adjwgt;
4683 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
4687 nvtxs = graph->
nvtxs;
4695 where = graph->
where;
4696 pwgts = graph->
pwgts;
4702 tvwgt =
idxsum(nparts, pwgts);
4705 updind =
idxmalloc(nvtxs,
"Random_KWayVolRefine: updind");
4706 marker =
idxsmalloc(nvtxs, 0,
"Random_KWayVolRefine: marker");
4707 phtable =
idxsmalloc(nparts, -1,
"Random_KWayVolRefine: phtable");
4709 for (i=0; i<nparts; i++) {
4710 itpwgts[i] = tpwgts[i]*tvwgt;
4711 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
4712 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
4718 printf(
"VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n",
4719 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
4723 for (pass=0; pass<npasses; pass++) {
4730 for (nmoves=iii=0; iii<graph->
nbnd; iii++) {
4735 myrinfo = graph->
vrinfo+i;
4737 if (myrinfo->
gv >= 0) {
4739 vwgt = graph->
vwgt[i];
4741 if (myrinfo->
id > 0 && pwgts[from]-vwgt < minwgt[from])
4744 xgain = (myrinfo->
id == 0 && myrinfo->
ed > 0 ? graph->
vsize[i] : 0);
4749 for (k=0; k<myndegrees; k++) {
4750 to = myedegrees[k].
pid;
4751 if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0)
4754 if (k == myndegrees)
4757 for (j=k+1; j<myndegrees; j++) {
4758 to = myedegrees[j].
pid;
4759 if (pwgts[to]+vwgt > maxwgt[to])
4761 if (myedegrees[j].gv > myedegrees[k].gv ||
4762 (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) ||
4763 (myedegrees[j].
gv == myedegrees[k].
gv && myedegrees[j].
ed == myedegrees[k].
ed &&
4764 itpwgts[myedegrees[k].
pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].
pid]))
4768 to = myedegrees[k].
pid;
4771 if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->
id > 0)
4773 else if (myedegrees[k].ed-myrinfo->
id == 0) {
4774 if ((iii&5) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
4783 INC_DEC(pwgts[to], pwgts[from], vwgt);
4784 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
4785 graph->
minvol -= (xgain+myedegrees[k].
gv);
4788 IFSET(ctrl->
dbglvl,
DBG_MOVEINFO, printf(
"\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n",
4789 i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->
id, graph->
mincut, graph->
minvol));
4791 KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
4800 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
4802 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves, graph->
mincut,
4805 if (graph->
minvol == oldvol && graph->
mincut == oldcut)
4809 GKfree((
void **) &marker, (
void **) &updind, (
void **) &phtable,
LTERM);
4822 float ubfactor,
int npasses,
int ffactor)
4824 int i,
ii, iii, j, k, l, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain;
4825 int from, me, to, oldcut, oldvol, vwgt, nadd, maxndoms;
4826 idxtype *xadj, *adjncy, *adjwgt;
4827 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
4828 idxtype *pmat, *pmatptr, *ndoms;
4832 nvtxs = graph->
nvtxs;
4840 where = graph->
where;
4841 pwgts = graph->
pwgts;
4847 tvwgt =
idxsum(nparts, pwgts);
4850 updind =
idxmalloc(nvtxs,
"Random_KWayVolRefine: updind");
4851 marker =
idxsmalloc(nvtxs, 0,
"Random_KWayVolRefine: marker");
4852 phtable =
idxsmalloc(nparts, -1,
"Random_KWayVolRefine: phtable");
4859 for (i=0; i<nparts; i++) {
4860 itpwgts[i] = tpwgts[i]*tvwgt;
4861 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
4862 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
4868 printf(
"VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n",
4869 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
4873 for (pass=0; pass<npasses; pass++) {
4876 maxndoms = ndoms[
idxamax(nparts, ndoms)];
4882 for (nmoves=iii=0; iii<graph->
nbnd; iii++) {
4887 myrinfo = graph->
vrinfo+i;
4889 if (myrinfo->
gv >= 0) {
4891 vwgt = graph->
vwgt[i];
4893 if (myrinfo->
id > 0 && pwgts[from]-vwgt < minwgt[from])
4896 xgain = (myrinfo->
id == 0 && myrinfo->
ed > 0 ? graph->
vsize[i] : 0);
4902 for (j=0; j<myndegrees; j++) {
4903 to = myedegrees[j].
pid;
4905 pmatptr = pmat + to*nparts;
4906 for (nadd=0, k=0; k<myndegrees; k++) {
4910 l = myedegrees[k].
pid;
4911 if (pmatptr[l] == 0) {
4912 if (ndoms[l] > maxndoms-1) {
4920 if (ndoms[to]+nadd > maxndoms)
4926 for (k=0; k<myndegrees; k++) {
4927 to = myedegrees[k].
pid;
4930 if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0)
4933 if (k == myndegrees)
4936 for (j=k+1; j<myndegrees; j++) {
4937 to = myedegrees[j].
pid;
4938 if (!phtable[to] || pwgts[to]+vwgt > maxwgt[to])
4940 if (myedegrees[j].gv > myedegrees[k].gv ||
4941 (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) ||
4942 (myedegrees[j].
gv == myedegrees[k].
gv && myedegrees[j].
ed == myedegrees[k].
ed &&
4943 itpwgts[myedegrees[k].
pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].
pid]))
4947 to = myedegrees[k].
pid;
4950 if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->
id > 0)
4952 else if (myedegrees[k].ed-myrinfo->
id == 0) {
4953 if ((iii&5) == 0 || phtable[myedegrees[k].
pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
4960 for (j=0; j<myndegrees; j++)
4961 phtable[myedegrees[j].pid] = -1;
4967 INC_DEC(pwgts[to], pwgts[from], vwgt);
4968 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
4969 graph->
minvol -= (xgain+myedegrees[k].
gv);
4972 IFSET(ctrl->
dbglvl,
DBG_MOVEINFO, printf(
"\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n",
4973 i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->
id, graph->
mincut, graph->
minvol));
4976 pmat[from*nparts+to] += (myrinfo->
id-myedegrees[k].
ed);
4977 pmat[to*nparts+from] += (myrinfo->
id-myedegrees[k].
ed);
4978 if (pmat[from*nparts+to] == 0) {
4980 if (ndoms[from]+1 == maxndoms)
4981 maxndoms = ndoms[
idxamax(nparts, ndoms)];
4983 if (pmat[to*nparts+from] == 0) {
4985 if (ndoms[to]+1 == maxndoms)
4986 maxndoms = ndoms[
idxamax(nparts, ndoms)];
4989 for (j=xadj[i]; j<xadj[i+1]; j++) {
4994 if (me != from && me != to) {
4995 pmat[me*nparts+from] -= adjwgt[j];
4996 pmat[from*nparts+me] -= adjwgt[j];
4997 if (pmat[me*nparts+from] == 0) {
4999 if (ndoms[me]+1 == maxndoms)
5000 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5002 if (pmat[from*nparts+me] == 0) {
5004 if (ndoms[from]+1 == maxndoms)
5005 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5008 if (pmat[me*nparts+to] == 0) {
5010 if (ndoms[me] > maxndoms) {
5011 printf(
"You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
5012 maxndoms = ndoms[me];
5015 if (pmat[to*nparts+me] == 0) {
5017 if (ndoms[to] > maxndoms) {
5018 printf(
"You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
5019 maxndoms = ndoms[to];
5022 pmat[me*nparts+to] += adjwgt[j];
5023 pmat[to*nparts+me] += adjwgt[j];
5027 KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
5036 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
5038 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves, graph->
mincut,
5041 if (graph->
minvol == oldvol && graph->
mincut == oldcut)
5045 GKfree((
void **) &marker, (
void **) &updind, (
void **) &phtable,
LTERM);
5061 float ubfactor,
int npasses)
5063 int i,
ii, j, k, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain;
5065 idxtype *xadj, *adjncy, *adjwgt;
5066 idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
5071 nvtxs = graph->
nvtxs;
5079 where = graph->
where;
5080 pwgts = graph->
pwgts;
5086 tvwgt =
idxsum(nparts, pwgts);
5089 updind =
idxmalloc(nvtxs,
"Random_KWayVolRefine: updind");
5090 marker =
idxsmalloc(nvtxs, 0,
"Random_KWayVolRefine: marker");
5091 phtable =
idxsmalloc(nparts, -1,
"Random_KWayVolRefine: phtable");
5093 for (i=0; i<nparts; i++) {
5094 itpwgts[i] = tpwgts[i]*tvwgt;
5095 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
5096 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
5105 printf(
"VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n",
5106 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
5111 for (pass=0; pass<npasses; pass++) {
5114 for (i=0; i<nparts; i++) {
5115 if (pwgts[i] > maxwgt[i])
5122 idxset(nvtxs, -1, moved);
5126 i = bndind[perm[
ii]];
5136 myrinfo = graph->
vrinfo+i;
5138 vwgt = graph->
vwgt[i];
5140 if (pwgts[from]-vwgt < minwgt[from])
5143 xgain = (myrinfo->
id == 0 && myrinfo->
ed > 0 ? graph->
vsize[i] : 0);
5148 for (k=0; k<myndegrees; k++) {
5149 to = myedegrees[k].
pid;
5150 if (pwgts[to]+vwgt <= maxwgt[to] ||
5151 itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from])
5154 if (k == myndegrees)
5157 for (j=k+1; j<myndegrees; j++) {
5158 to = myedegrees[j].
pid;
5159 if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])
5163 to = myedegrees[k].
pid;
5165 if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] &&
5166 (xgain+myedegrees[k].gv < 0 ||
5167 (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->
id < 0))
5175 INC_DEC(pwgts[to], pwgts[from], vwgt);
5176 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
5177 graph->
minvol -= (xgain+myedegrees[k].
gv);
5180 IFSET(ctrl->
dbglvl,
DBG_MOVEINFO, printf(
"\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n",
5181 i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->
id, graph->
mincut, graph->
minvol));
5183 KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
5191 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
5193 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves, graph->
mincut,
5198 GKfree((
void **) &marker, (
void **) &updind, (
void **) &phtable,
LTERM);
5215 float ubfactor,
int npasses)
5217 int i,
ii, j, k, l, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain;
5218 int from, me, to, vwgt, maxndoms, nadd;
5219 idxtype *xadj, *adjncy, *adjwgt;
5220 idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable;
5221 idxtype *pmat, *pmatptr, *ndoms;
5226 nvtxs = graph->
nvtxs;
5234 where = graph->
where;
5235 pwgts = graph->
pwgts;
5241 tvwgt =
idxsum(nparts, pwgts);
5244 updind =
idxmalloc(nvtxs,
"Random_KWayVolRefine: updind");
5245 marker =
idxsmalloc(nvtxs, 0,
"Random_KWayVolRefine: marker");
5246 phtable =
idxsmalloc(nparts, -1,
"Random_KWayVolRefine: phtable");
5253 for (i=0; i<nparts; i++) {
5254 itpwgts[i] = tpwgts[i]*tvwgt;
5255 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
5256 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
5265 printf(
"VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n",
5266 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
5271 for (pass=0; pass<npasses; pass++) {
5274 for (i=0; i<nparts; i++) {
5275 if (pwgts[i] > maxwgt[i])
5282 idxset(nvtxs, -1, moved);
5286 i = bndind[perm[
ii]];
5291 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5298 myrinfo = graph->
vrinfo+i;
5300 vwgt = graph->
vwgt[i];
5302 if (pwgts[from]-vwgt < minwgt[from])
5305 xgain = (myrinfo->
id == 0 && myrinfo->
ed > 0 ? graph->
vsize[i] : 0);
5311 for (j=0; j<myndegrees; j++) {
5312 to = myedegrees[j].
pid;
5314 pmatptr = pmat + to*nparts;
5315 for (nadd=0, k=0; k<myndegrees; k++) {
5319 l = myedegrees[k].
pid;
5320 if (pmatptr[l] == 0) {
5321 if (ndoms[l] > maxndoms-1) {
5329 if (ndoms[to]+nadd > maxndoms)
5333 for (k=0; k<myndegrees; k++) {
5334 to = myedegrees[k].
pid;
5337 if (pwgts[to]+vwgt <= maxwgt[to] ||
5338 itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from])
5341 if (k == myndegrees)
5344 for (j=k+1; j<myndegrees; j++) {
5345 to = myedegrees[j].
pid;
5348 if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])
5352 to = myedegrees[k].
pid;
5354 for (j=0; j<myndegrees; j++)
5355 phtable[myedegrees[j].pid] = -1;
5357 if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] &&
5358 (xgain+myedegrees[k].gv < 0 ||
5359 (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->
id < 0))
5367 INC_DEC(pwgts[to], pwgts[from], vwgt);
5368 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
5369 graph->
minvol -= (xgain+myedegrees[k].
gv);
5372 IFSET(ctrl->
dbglvl,
DBG_MOVEINFO, printf(
"\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n",
5373 i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->
id, graph->
mincut, graph->
minvol));
5376 pmat[from*nparts+to] += (myrinfo->
id-myedegrees[k].
ed);
5377 pmat[to*nparts+from] += (myrinfo->
id-myedegrees[k].
ed);
5378 if (pmat[from*nparts+to] == 0) {
5380 if (ndoms[from]+1 == maxndoms)
5381 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5383 if (pmat[to*nparts+from] == 0) {
5385 if (ndoms[to]+1 == maxndoms)
5386 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5389 for (j=xadj[i]; j<xadj[i+1]; j++) {
5394 if (me != from && me != to) {
5395 pmat[me*nparts+from] -= adjwgt[j];
5396 pmat[from*nparts+me] -= adjwgt[j];
5397 if (pmat[me*nparts+from] == 0) {
5399 if (ndoms[me]+1 == maxndoms)
5400 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5402 if (pmat[from*nparts+me] == 0) {
5404 if (ndoms[from]+1 == maxndoms)
5405 maxndoms = ndoms[
idxamax(nparts, ndoms)];
5408 if (pmat[me*nparts+to] == 0) {
5410 if (ndoms[me] > maxndoms) {
5411 printf(
"You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
5412 maxndoms = ndoms[me];
5415 if (pmat[to*nparts+me] == 0) {
5417 if (ndoms[to] > maxndoms) {
5418 printf(
"You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
5419 maxndoms = ndoms[to];
5422 pmat[me*nparts+to] += adjwgt[j];
5423 pmat[to*nparts+me] += adjwgt[j];
5427 KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind);
5435 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n",
5437 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves, graph->
mincut,
5442 GKfree((
void **) &marker, (
void **) &updind, (
void **) &phtable,
LTERM);
5466 int ii, j,
jj, k,
kk, u, nupd, other, me, myidx;
5467 idxtype *xadj, *vsize, *adjncy, *adjwgt, *where;
5474 vsize = graph->
vsize;
5475 where = graph->
where;
5477 myrinfo = graph->
vrinfo+v;
5484 for (k=0; k<myrinfo->
ndegrees; k++)
5485 phtable[myedegrees[k].pid] = k;
5488 myidx = phtable[to];
5490 for (j=xadj[v]; j<xadj[v+1]; j++) {
5496 if (other == from) {
5497 for (k=0; k<orinfo->
ndegrees; k++) {
5498 if (phtable[oedegrees[k].pid] == -1)
5499 oedegrees[k].
gv += vsize[v];
5503 ASSERT(phtable[other] != -1);
5505 if (myedegrees[phtable[other]].ned > 1) {
5506 for (k=0; k<orinfo->
ndegrees; k++) {
5507 if (phtable[oedegrees[k].pid] == -1)
5508 oedegrees[k].
gv += vsize[v];
5512 for (k=0; k<orinfo->
ndegrees; k++) {
5513 if (phtable[oedegrees[k].pid] != -1)
5514 oedegrees[k].
gv -= vsize[v];
5520 for (k=0; k<myrinfo->
ndegrees; k++)
5521 phtable[myedegrees[k].pid] = -1;
5528 myrinfo->
ed += myrinfo->
id-myedegrees[myidx].
ed;
5529 SWAP(myrinfo->
id, myedegrees[myidx].
ed, j);
5530 SWAP(myrinfo->
nid, myedegrees[myidx].
ned, j);
5531 if (myedegrees[myidx].ed == 0)
5532 myedegrees[myidx] = myedegrees[--myrinfo->
ndegrees];
5534 myedegrees[myidx].
pid = from;
5542 for (j=xadj[v]; j<xadj[v+1]; j++) {
5548 updind[nupd++] =
ii;
5562 else if (me == to) {
5569 for (k=0; k<myrinfo->
ndegrees; k++) {
5570 if (myedegrees[k].pid == from) {
5571 if (myedegrees[k].ned == 1) {
5572 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
5579 orinfo = graph->
vrinfo+u;
5583 if (oedegrees[
kk].pid == from) {
5584 oedegrees[
kk].
gv -= vsize[
ii];
5591 myedegrees[k].
ed -= adjwgt[j];
5592 myedegrees[k].
ned--;
5595 if (myedegrees[k].ned == 1) {
5600 orinfo = graph->
vrinfo+u;
5603 if (other == from) {
5605 oedegrees[
kk].gv += vsize[
ii];
5619 for (k=0; k<myrinfo->
ndegrees; k++) {
5620 if (myedegrees[k].pid == to) {
5621 myedegrees[k].
ed += adjwgt[j];
5622 myedegrees[k].
ned++;
5625 if (myedegrees[k].ned == 2) {
5630 orinfo = graph->
vrinfo+u;
5633 if (u != v && other == to) {
5635 oedegrees[
kk].gv -= vsize[
ii];
5646 myedegrees[myrinfo->
ndegrees].
ed = adjwgt[j];
5654 orinfo = graph->
vrinfo+u;
5658 if (oedegrees[
kk].pid == to) {
5659 oedegrees[
kk].
gv += vsize[
ii];
5677 myrinfo = graph->
vrinfo+v;
5679 for (k=0; k<myrinfo->
ndegrees; k++)
5680 phtable[myedegrees[k].pid] = k;
5683 for (j=xadj[v]; j<xadj[v+1]; j++) {
5690 for (k=0; k<orinfo->
ndegrees; k++) {
5691 if (phtable[oedegrees[k].pid] == -1)
5692 oedegrees[k].
gv -= vsize[v];
5696 ASSERT(phtable[other] != -1);
5698 if (myedegrees[phtable[other]].ned > 1) {
5699 for (k=0; k<orinfo->
ndegrees; k++) {
5700 if (phtable[oedegrees[k].pid] == -1)
5701 oedegrees[k].
gv -= vsize[v];
5705 for (k=0; k<orinfo->
ndegrees; k++) {
5706 if (phtable[oedegrees[k].pid] != -1)
5707 oedegrees[k].
gv += vsize[v];
5712 for (k=0; k<myrinfo->
ndegrees; k++)
5713 phtable[myedegrees[k].pid] = -1;
5727 for (j=0; j<nupd; j++) {
5730 myrinfo = graph->
vrinfo+k;
5732 if ((myrinfo->
gv >= 0 || myrinfo->
ed-myrinfo->
id >= 0) && graph->
bndptr[k] == -1)
5735 if (myrinfo->
gv < 0 && myrinfo->
ed-myrinfo->
id < 0 && graph->
bndptr[k] != -1)
5749 int ii, iii, i, j, k,
kk, nvtxs, me, other;
5750 idxtype *xadj, *vsize, *adjncy, *adjwgt, *where;
5754 nvtxs = graph->
nvtxs;
5756 vsize = graph->
vsize;
5759 where = graph->
where;
5766 for (iii=0; iii<nupd; iii++) {
5773 if (marker[i] == 1) {
5774 for (k=0; k<myrinfo->
ndegrees; k++)
5775 myedegrees[k].gv = 0;
5777 for (j=xadj[i]; j<xadj[i+1]; j++) {
5784 phtable[oedegrees[
kk].pid] =
kk;
5789 for (k=0; k<myrinfo->
ndegrees; k++) {
5790 if (phtable[myedegrees[k].pid] == -1)
5791 myedegrees[k].
gv -= vsize[
ii];
5795 ASSERT(phtable[me] != -1);
5798 if (oedegrees[phtable[me]].ned == 1) {
5800 for (k=0; k<myrinfo->
ndegrees; k++) {
5801 if (phtable[myedegrees[k].pid] != -1)
5802 myedegrees[k].
gv += vsize[
ii];
5807 for (k=0; k<myrinfo->
ndegrees; k++) {
5808 if (phtable[myedegrees[k].pid] == -1)
5809 myedegrees[k].
gv -= vsize[
ii];
5815 phtable[oedegrees[
kk].pid] = -1;
5816 phtable[other] = -1;
5822 for (k=0; k<myrinfo->
ndegrees; k++) {
5823 if (myedegrees[k].gv > myrinfo->
gv)
5824 myrinfo->
gv = myedegrees[k].
gv;
5826 if (myrinfo->
ed > 0 && myrinfo->
id == 0)
5827 myrinfo->
gv += vsize[i];
5840 int i, j, k, nvtxs, nparts, totalv;
5841 idxtype *xadj, *adjncy, *vsize, *marker;
5844 nvtxs = graph->
nvtxs;
5849 nparts = where[
idxamax(nvtxs, where)]+1;
5850 marker =
idxsmalloc(nparts, -1,
"ComputeVolume: marker");
5854 for (i=0; i<nvtxs; i++) {
5855 marker[where[i]] = i;
5856 for (j=xadj[i]; j<xadj[i+1]; j++) {
5857 k = where[adjncy[j]];
5858 if (marker[k] != i) {
5879 int i,
ii, j, k,
kk, nvtxs, me, other, pid;
5880 idxtype *xadj, *vsize, *adjncy, *adjwgt, *where;
5881 VRInfoType *rinfo, *myrinfo, *orinfo, tmprinfo;
5884 nvtxs = graph->
nvtxs;
5886 vsize = graph->
vsize;
5889 where = graph->
where;
5897 for (i=0; i<nvtxs; i++) {
5903 for (k=0; k<myrinfo->
ndegrees; k++)
5904 tmpdegrees[k] = myedegrees[k];
5907 tmprinfo.
id = myrinfo->
id;
5908 tmprinfo.
ed = myrinfo->
ed;
5910 myrinfo = &tmprinfo;
5911 myedegrees = tmpdegrees;
5914 for (k=0; k<myrinfo->
ndegrees; k++)
5915 myedegrees[k].gv = 0;
5917 for (j=xadj[i]; j<xadj[i+1]; j++) {
5925 for (k=0; k<myrinfo->
ndegrees; k++) {
5926 pid = myedegrees[k].
pid;
5928 if (oedegrees[
kk].pid == pid)
5932 myedegrees[k].
gv -= vsize[
ii];
5937 for (k=0; k<orinfo->
ndegrees; k++) {
5938 if (oedegrees[k].pid == me)
5942 if (oedegrees[k].ned == 1) {
5943 for (k=0; k<myrinfo->
ndegrees; k++) {
5944 if (myedegrees[k].pid == other) {
5945 myedegrees[k].
gv += vsize[
ii];
5951 for (k=0; k<myrinfo->
ndegrees; k++) {
5952 if ((pid = myedegrees[k].pid) == other)
5955 if (oedegrees[
kk].pid == pid) {
5956 myedegrees[k].
gv += vsize[
ii];
5965 for (k=0; k<myrinfo->
ndegrees; k++) {
5966 if ((pid = myedegrees[k].pid) == other)
5969 if (oedegrees[
kk].pid == pid)
5973 myedegrees[k].
gv -= vsize[
ii];
5982 for (k=0; k<myrinfo->
ndegrees; k++) {
5983 pid = myedegrees[k].
pid;
5985 if (tmpdegrees[
kk].pid == pid) {
5986 if (tmpdegrees[
kk].gv != myedegrees[k].gv)
5987 printf(
"[%d %d %d %d]\n", i, pid, myedegrees[k].gv, tmpdegrees[
kk].gv);
6005 int i, j, k, me, nvtxs, ndegrees;
6006 idxtype *xadj, *adjncy, *adjwgt, *where;
6010 nvtxs = graph->
nvtxs;
6014 where = graph->
where;
6017 idxset(nparts*nparts, 0, pmat);
6019 for (i=0; i<nvtxs; i++) {
6020 if (rinfo[i].ed > 0) {
6026 for (j=0; j<ndegrees; j++)
6027 pmat[k+edegrees[j].pid] += edegrees[j].ed;
6031 for (i=0; i<nparts; i++) {
6033 for (j=0; j<nparts; j++) {
6034 if (pmat[i*nparts+j] > 0)
6047 int i,
ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd;
6048 int min, move, cpwgt, tvwgt;
6049 idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind;
6052 nvtxs = graph->
nvtxs;
6058 where = graph->
where;
6071 for (i=0; i<nvtxs; i++) {
6073 pwgts[me] += vwgt[i];
6074 for (j=xadj[i]; j<xadj[i+1]; j++) {
6077 pmat[me*nparts+where[k]] += adjwgt[j];
6082 tvwgt =
idxsum(nparts, pwgts);
6083 for (i=0; i<nparts; i++)
6084 maxpwgt[i] = 1.25*tpwgts[i]*tvwgt;
6087 for (i=0; i<nparts; i++) {
6088 for (k=0, j=0; j<nparts; j++) {
6089 if (pmat[i*nparts+j] > 0)
6097 total =
idxsum(nparts, ndoms);
6099 max = ndoms[
idxamax(nparts, ndoms)];
6107 mypmat = pmat + me*nparts;
6108 totalout =
idxsum(nparts, mypmat);
6113 for (ncand2=0, i=0; i<nparts; i++) {
6114 if (mypmat[i] > 0) {
6115 cand2[ncand2].
key = mypmat[i];
6116 cand2[ncand2++].
val = i;
6122 for (min=0; min<ncand2; min++) {
6123 if (cand2[min].key > totalout/(2*ndoms[me]))
6126 other = cand2[min].
val;
6130 idxset(nparts, 0, otherpmat);
6133 for (nind=0, i=0; i<nvtxs; i++) {
6134 if (where[i] == other) {
6135 for (j=xadj[i]; j<xadj[i+1]; j++) {
6136 if (where[adjncy[j]] == me) {
6145 for (cpwgt=0,
ii=0;
ii<nind;
ii++) {
6149 for (j=xadj[i]; j<xadj[i+1]; j++) {
6151 if (where[k] != other)
6152 otherpmat[where[k]] += adjwgt[j];
6156 for (ncand=0, i=0; i<nparts; i++) {
6157 if (otherpmat[i] > 0) {
6158 cand[ncand].
key = -otherpmat[i];
6159 cand[ncand++].
val = i;
6169 target = target2 = -1;
6170 for (i=0; i<ncand; i++) {
6173 if (mypmat[k] > 0) {
6174 if (pwgts[k] + cpwgt > maxpwgt[k])
6177 for (j=0; j<nparts; j++) {
6178 if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0)
6182 for (nadd=0, j=0; j<nparts; j++) {
6183 if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0)
6188 if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) {
6198 if (target == -1 && target2 != -1)
6209 INC_DEC(pwgts[target], pwgts[other], cpwgt);
6212 for (
ii=0;
ii<nind;
ii++) {
6217 for (j=xadj[i]; j<xadj[i+1]; j++) {
6219 if (where[k] != other) {
6220 if (pmat[nparts*other + where[k]] == 0)
6221 printf(
"Something wrong\n");
6222 pmat[nparts*other + where[k]] -= adjwgt[j];
6223 if (pmat[nparts*other + where[k]] == 0)
6226 if (pmat[nparts*where[k] + other] == 0)
6227 printf(
"Something wrong\n");
6228 pmat[nparts*where[k] + other] -= adjwgt[j];
6229 if (pmat[nparts*where[k] + other] == 0)
6235 for (j=xadj[i]; j<xadj[i+1]; j++) {
6237 if (where[k] != target) {
6238 if (pmat[nparts*target + where[k]] == 0)
6240 pmat[nparts*target + where[k]] += adjwgt[j];
6242 if (pmat[nparts*where[k] + target] == 0)
6244 pmat[nparts*where[k] + target] += adjwgt[j];
6274 int i,
ii, j,
jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, ncand, other, target, deltawgt;
6275 idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt;
6276 idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps;
6280 nvtxs = graph->
nvtxs;
6286 where = graph->
where;
6298 for (i=0; i<nvtxs; i++)
6299 perm[i] = todo[i] = i;
6306 if (first == last) {
6307 cptr[++ncmps] = first;
6308 ASSERT(touched[todo[0]] == 0);
6318 j = todo[k] = todo[--nleft];
6321 for (j=xadj[i]; j<xadj[i+1]; j++) {
6323 if (where[k] == me && !touched[k]) {
6329 cptr[++ncmps] = first;
6333 if (ncmps > nparts) {
6337 for (i=0; i<nvtxs; i++)
6338 pwgts[where[i]] += vwgt[i];
6339 tvwgt =
idxsum(nparts, pwgts);
6340 for (i=0; i<nparts; i++)
6341 maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt;
6343 deltawgt = tvwgt/(100*nparts);
6346 for (i=0; i<ncmps; i++) {
6347 me = where[cind[cptr[i]]];
6348 if (npcmps[me] == 1)
6354 idxset(nparts, 0, cpvec);
6355 for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) {
6359 other = where[adjncy[
jj]];
6361 cpvec[other] += adjwgt[
jj];
6367 if (cwgt > .30*pwgts[me])
6370 for (ncand=0, j=0; j<nparts; j++) {
6372 cand[ncand].
key = -cpvec[j];
6373 cand[ncand++].
val = j;
6382 for (j=0; j<ncand; j++) {
6384 if (cwgt < deltawgt || pwgts[k] + cwgt < maxpwgt[k]) {
6395 pwgts[target] += cwgt;
6398 for (j=cptr[i]; j<cptr[i+1]; j++)
6399 where[cind[j]] = target;
6401 graph->
mincut -= cpvec[target];
6413 marker =
idxset(nparts, -1, cpvec);
6414 for (ttlv=0, i=0; i<nvtxs; i++) {
6415 marker[where[i]] = i;
6416 for (j=xadj[i]; j<xadj[i+1]; j++) {
6417 if (marker[where[adjncy[j]]] != i) {
6418 ttlv += graph->
vsize[i];
6419 marker[where[adjncy[j]]] = i;
6457 float *tpwgts,
float ubfactor)
6474 for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->
finer, nlevels++);
6484 if (2*i >= nlevels && !
IsBalanced(graph->
pwgts, nparts, tpwgts, 1.04*ubfactor)) {
6486 switch (ctrl->
RType) {
6497 switch (ctrl->
RType) {
6507 if (graph == orggraph)
6512 graph = graph->
finer;
6521 switch (ctrl->
RType) {
6547 nvtxs = graph->
nvtxs;
6549 pad64 = (3*nvtxs+nparts)%2;
6567 int i, j, k, nvtxs, mincut, me, other;
6568 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where;
6572 nvtxs = graph->
nvtxs;
6578 where = graph->
where;
6588 for (i=0; i<nvtxs; i++) {
6590 pwgts[me] += vwgt[i];
6596 for (j=xadj[i]; j<xadj[i+1]; j++) {
6597 if (me == where[adjncy[j]]) {
6598 myrinfo->
id += adjwgt[j];
6604 mincut += myrinfo->
ed;
6607 if (myrinfo->
ed > 0) {
6611 for (j=xadj[i]; j<xadj[i+1]; j++) {
6612 other = where[adjncy[j]];
6614 for (k=0; k<myrinfo->
ndegrees; k++) {
6615 if (myedegrees[k].pid == other) {
6616 myedegrees[k].
ed += adjwgt[j];
6617 myedegrees[k].
ned++;
6624 myedegrees[myrinfo->
ndegrees].
ed = adjwgt[j];
6633 graph->
mincut = mincut/2;
6647 int i,
ii, j, k,
kk, nvtxs, me, other, myndegrees;
6648 idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *bndind, *bndptr, *ophtable;
6652 nvtxs = graph->
nvtxs;
6654 vsize = graph->
vsize;
6658 where = graph->
where;
6669 for (i=0; i<nvtxs; i++) {
6678 graph->
minvol += myndegrees*vsize[i];
6680 for (j=xadj[i]; j<xadj[i+1]; j++) {
6687 ophtable[oedegrees[k].pid] = k;
6688 ophtable[other] = 1;
6692 for (k=0; k<myndegrees; k++) {
6693 if (ophtable[myedegrees[k].pid] == -1)
6694 myedegrees[k].
gv -= vsize[
ii];
6698 ASSERT(ophtable[me] != -1);
6700 if (oedegrees[ophtable[me]].ned == 1) {
6702 for (k=0; k<myndegrees; k++) {
6703 if (ophtable[myedegrees[k].pid] != -1)
6704 myedegrees[k].
gv += vsize[
ii];
6709 for (k=0; k<myndegrees; k++) {
6710 if (ophtable[myedegrees[k].pid] == -1)
6711 myedegrees[k].
gv -= vsize[
ii];
6717 ophtable[oedegrees[
kk].pid] = -1;
6718 ophtable[other] = -1;
6722 for (k=0; k<myndegrees; k++) {
6723 if (myedegrees[k].gv > myrinfo->
gv)
6724 myrinfo->
gv = myedegrees[k].
gv;
6728 if (myrinfo->
ed > 0 && myrinfo->
id == 0)
6729 myrinfo->
gv += vsize[i];
6731 if (myrinfo->
gv >= 0 || myrinfo->
ed-myrinfo->
id >= 0)
6747 int i, j, k, nvtxs, me, other,
istart,
iend, ndegrees;
6748 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
6757 cwhere = cgraph->
where;
6760 nvtxs = graph->
nvtxs;
6768 where = graph->
where;
6772 for (i=0; i<nvtxs; i++) {
6774 where[i] = cwhere[k];
6775 cmap[i] = crinfo[k].
ed;
6781 for (i=0; i<nvtxs; i++) {
6788 myrinfo->
id = adjwgtsum[i];
6789 myrinfo->
nid = xadj[i+1]-xadj[i];
6800 other = where[adjncy[j]];
6802 myrinfo->
ed += adjwgt[j];
6804 if ((k = htable[other]) == -1) {
6805 htable[other] = ndegrees;
6806 myedegrees[ndegrees].
gv = 0;
6807 myedegrees[ndegrees].
pid = other;
6808 myedegrees[ndegrees].
ed = adjwgt[j];
6809 myedegrees[ndegrees++].
ned = 1;
6812 myedegrees[k].
ed += adjwgt[j];
6813 myedegrees[k].
ned++;
6817 myrinfo->
id -= myrinfo->
ed;
6820 if (myrinfo->
ed == 0) {
6827 for (j=0; j<ndegrees; j++)
6828 htable[myedegrees[j].pid] = -1;
6855 nvtxs = graph->
nvtxs;
6864 for (i=0; i<nvtxs; i++) {
6880 nvtxs = graph->
nvtxs;
6889 for (i=0; i<nvtxs; i++) {
6920 int i,
ii, j, nvtxs, cnvtxs, maxidx;
6921 idxtype *xadj, *vwgt, *adjncy, *adjwgt;
6926 nvtxs = graph->
nvtxs;
6939 for (
ii=0;
ii<nvtxs;
ii++) {
6946 for (j=xadj[i]; j<xadj[i+1]; j++) {
6947 if (match[adjncy[j]] ==
UNMATCHED && vwgt[i]+vwgt[adjncy[j]] <= ctrl->
maxvwgt) {
6953 cmap[i] = cmap[maxidx] = cnvtxs++;
6973 int i,
ii, j, nvtxs, cnvtxs, maxidx;
6979 nvtxs = graph->
nvtxs;
6990 for (
ii=0;
ii<nvtxs;
ii++) {
6997 for (j=xadj[i]; j<xadj[i+1]; j++) {
7004 cmap[i] = cmap[maxidx] = cnvtxs++;
7025 int i,
ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt;
7026 idxtype *xadj, *vwgt, *adjncy, *adjwgt;
7031 nvtxs = graph->
nvtxs;
7044 for (
ii=0;
ii<nvtxs;
ii++) {
7052 for (j=xadj[i]; j<xadj[i+1]; j++) {
7054 if (match[k] ==
UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[k] <= ctrl->
maxvwgt) {
7060 cmap[i] = cmap[maxidx] = cnvtxs++;
7081 int i,
ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree;
7082 idxtype *xadj, *vwgt, *adjncy, *adjwgt;
7083 idxtype *match, *cmap, *degrees, *perm, *tperm;
7087 nvtxs = graph->
nvtxs;
7101 avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
7102 for (i=0; i<nvtxs; i++)
7103 degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
7109 for (
ii=0;
ii<nvtxs;
ii++) {
7113 if (xadj[i] < xadj[i+1])
7117 for (j=nvtxs-1; j>
ii; j--) {
7119 if (match[k] ==
UNMATCHED && xadj[k] < xadj[k+1]) {
7125 cmap[i] = cmap[maxidx] = cnvtxs++;
7132 for (;
ii<nvtxs;
ii++) {
7140 for (j=xadj[i]; j<xadj[i+1]; j++) {
7141 if (match[adjncy[j]] ==
UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[adjncy[j]] <= ctrl->
maxvwgt) {
7147 cmap[i] = cmap[maxidx] = cnvtxs++;
7201 int i,
ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, limit,
tmp, cnum;
7202 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
7203 idxtype *moved, *swaps, *perm, *qnum;
7206 int higain, oldgain, mincut, newcut, mincutorder;
7207 float *maxwgt, *minwgt, tvec[
MAXNCON];
7210 nvtxs = graph->
nvtxs;
7213 nvwgt = graph->
nvwgt;
7216 where = graph->
where;
7228 limit =
amin(
amax(0.01*nvtxs, 15), 100);
7234 for (i=0; i<2; i++) {
7235 for (j=0; j<ncon; j++) {
7236 maxwgt[i*ncon+j] = tpwgts[i]*
ubvec[j];
7237 minwgt[i*ncon+j] = tpwgts[i]*(1.0/
ubvec[j]);
7243 for (i=0; i<ncon; i++) {
7247 for (i=0; i<nvtxs; i++)
7248 qnum[i] =
samax(ncon, nvwgt+i*ncon);
7251 for (i=0; i<ncon; i++)
7252 minbal[i] = origbal[i];
7254 newcut = mincut = graph->
mincut;
7259 for (l=0; l<ncon; l++)
7260 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
7261 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1],
7263 for (i=0; i<ncon; i++)
7264 printf(
"%.3f ", origbal[i]);
7268 idxset(nvtxs, -1, moved);
7276 for (
ii=0;
ii<nvtxs;
ii++) {
7278 PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-
id[i]);
7282 for (nswaps=0; nswaps<nvtxs; nswaps++) {
7286 SelectQueue3(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt);
7289 if (from == -1 || (higain =
PQueueGetMax(&parts[cnum][from])) == -1)
7292 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7293 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
7294 newcut -= (ed[higain]-
id[higain]);
7300 for (i=0; i<ncon; i++)
7301 minbal[i] = newbal[i];
7302 mincutorder = nswaps;
7304 else if (nswaps-mincutorder > limit) {
7305 newcut += (ed[higain]-
id[higain]);
7306 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
7307 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7312 moved[higain] = nswaps;
7313 swaps[nswaps] = higain;
7316 printf(
"Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], newcut);
7317 for (i=0; i<ncon; i++)
7318 printf(
"(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]);
7322 for (i=0; i<ncon; i++)
7323 printf(
"%.3f ", tvec[i]);
7324 if (mincutorder == nswaps)
7334 SWAP(
id[higain], ed[higain],
tmp);
7335 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
7336 BNDDelete(nbnd, bndind, bndptr, higain);
7337 if (ed[higain] > 0 && bndptr[higain] == -1)
7338 BNDInsert(nbnd, bndind, bndptr, higain);
7340 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
7342 oldgain = ed[k]-
id[k];
7344 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
7349 PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-
id[k]);
7352 if (ed[k] == 0 && bndptr[k] != -1)
7354 else if (ed[k] > 0 && bndptr[k] == -1)
7365 for (i=0; i<nswaps; i++)
7366 moved[swaps[i]] = -1;
7367 for (nswaps--; nswaps>mincutorder; nswaps--) {
7368 higain = swaps[nswaps];
7370 to = where[higain] = (where[higain]+1)%2;
7371 SWAP(
id[higain], ed[higain],
tmp);
7372 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
7373 BNDDelete(nbnd, bndind, bndptr, higain);
7374 else if (ed[higain] > 0 && bndptr[higain] == -1)
7375 BNDInsert(nbnd, bndind, bndptr, higain);
7377 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7378 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
7379 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
7382 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
7385 if (bndptr[k] != -1 && ed[k] == 0)
7387 if (bndptr[k] == -1 && ed[k] > 0)
7393 printf(
"\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
7394 for (i=0; i<ncon; i++)
7395 printf(
"(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]);
7398 for (i=0; i<ncon; i++)
7399 printf(
"%.3f ", tvec[i]);
7407 for (i=0; i<ncon; i++) {
7428 void SelectQueue3(
int ncon,
float *npwgts,
float *tpwgts,
int *from,
int *cnum,
7431 int i, j, maxgain=0;
7432 float maxdiff=0.0, diff;
7438 for (j=0; j<2; j++) {
7439 for (i=0; i<ncon; i++) {
7440 diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i];
7441 if (diff >= maxdiff) {
7457 if (*from != -1 &&
PQueueGetSize(&queues[*cnum][*from]) == 0) {
7458 for (i=0; i<ncon; i++) {
7460 maxdiff = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]);
7466 for (i++; i<ncon; i++) {
7467 diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i];
7468 if (diff > maxdiff &&
PQueueGetSize(&queues[i][*from]) > 0) {
7478 for (j=0; j<2; j++) {
7479 for (i=0; i<ncon; i++) {
7528 int i,
ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, limit,
tmp, cnum;
7529 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
7530 idxtype *moved, *swaps, *perm, *qnum;
7531 float *nvwgt, *npwgts, mindiff[
MAXNCON], origbal, minbal, newbal;
7533 int higain, oldgain, mincut, newcut, mincutorder;
7536 nvtxs = graph->
nvtxs;
7539 nvwgt = graph->
nvwgt;
7542 where = graph->
where;
7554 limit =
amin(
amax(0.01*nvtxs, 15), 100);
7557 for (i=0; i<ncon; i++) {
7560 qsizes[i][0] = qsizes[i][1] = 0;
7563 for (i=0; i<nvtxs; i++) {
7564 qnum[i] =
samax(ncon, nvwgt+i*ncon);
7565 qsizes[qnum[i]][where[i]]++;
7575 for (from=0; from<2; from++) {
7576 for (j=0; j<ncon; j++) {
7577 if (qsizes[j][from] == 0) {
7578 for (i=0; i<nvtxs; i++) {
7579 if (where[i] != from)
7582 k =
samax2(ncon, nvwgt+i*ncon);
7583 if (k == j && qsizes[qnum[i]][from] > qsizes[j][from] && nvwgt[i*ncon+qnum[i]] < 1.3*nvwgt[i*ncon+j]) {
7584 qsizes[qnum[i]][from]--;
7602 for (i=0; i<ncon; i++)
7603 mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
7605 newcut = mincut = graph->
mincut;
7610 for (l=0; l<ncon; l++)
7611 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
7612 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut, origbal);
7615 idxset(nvtxs, -1, moved);
7623 for (
ii=0;
ii<nvtxs;
ii++) {
7625 PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-
id[i]);
7628 for (nswaps=0; nswaps<nvtxs; nswaps++) {
7629 if (minbal < lbfactor)
7632 SelectQueue(ncon, npwgts, tpwgts, &from, &cnum, parts);
7635 if (from == -1 || (higain =
PQueueGetMax(&parts[cnum][from])) == -1)
7638 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7639 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
7640 newcut -= (ed[higain]-
id[higain]);
7643 if (newbal < minbal || (newbal == minbal &&
7644 (newcut < mincut || (newcut == mincut &&
BetterBalance(ncon, npwgts, tpwgts, mindiff))))) {
7647 mincutorder = nswaps;
7648 for (i=0; i<ncon; i++)
7649 mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
7651 else if (nswaps-mincutorder > limit) {
7652 newcut += (ed[higain]-
id[higain]);
7653 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
7654 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7659 moved[higain] = nswaps;
7660 swaps[nswaps] = higain;
7663 printf(
"Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], newcut);
7664 for (l=0; l<ncon; l++)
7665 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
7666 printf(
", %.3f LB: %.3f\n", minbal, newbal);
7673 SWAP(
id[higain], ed[higain],
tmp);
7674 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
7675 BNDDelete(nbnd, bndind, bndptr, higain);
7676 if (ed[higain] > 0 && bndptr[higain] == -1)
7677 BNDInsert(nbnd, bndind, bndptr, higain);
7679 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
7681 oldgain = ed[k]-
id[k];
7683 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
7688 PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-
id[k]);
7691 if (ed[k] == 0 && bndptr[k] != -1)
7693 else if (ed[k] > 0 && bndptr[k] == -1)
7703 for (nswaps--; nswaps>mincutorder; nswaps--) {
7704 higain = swaps[nswaps];
7706 to = where[higain] = (where[higain]+1)%2;
7707 SWAP(
id[higain], ed[higain],
tmp);
7708 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
7709 BNDDelete(nbnd, bndind, bndptr, higain);
7710 else if (ed[higain] > 0 && bndptr[higain] == -1)
7711 BNDInsert(nbnd, bndind, bndptr, higain);
7713 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
7714 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
7715 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
7718 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
7721 if (bndptr[k] != -1 && ed[k] == 0)
7723 if (bndptr[k] == -1 && ed[k] > 0)
7729 printf(
"\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
7730 for (l=0; l<ncon; l++)
7731 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
7739 for (i=0; i<ncon; i++) {
7781 printf(
"%6d %7d %10d [%d] [%6.4f", cgraph->
nvtxs, cgraph->
nedges,
7783 for (i=0; i<graph->
ncon; i++)
7788 switch (ctrl->
CType) {
7829 printf(
"%6d %7d %10d [%d] [%6.4f", cgraph->
nvtxs, cgraph->
nedges,
7831 for (i=0; i<graph->
ncon; i++)
8021 graph->
label = NULL;
8025 graph->
id = graph->
ed = NULL;
8027 graph->
rinfo = NULL;
8032 graph->
nvwgt = NULL;
8035 graph->
vsize = NULL;
8077 int esizes[] = {-1, 3, 4, 8, 4};
8082 GENDUALMETIS(*ne, *nn, *etype, elmnts, dxadj, dadjncy);
8096 int esizes[] = {-1, 3, 4, 8, 4};
8127 int i, j,
jj, k,
kk, kkk, l,
m, n, mask;
8129 idxtype *mark, ind[200], wgt[200];
8130 int esize, esizes[] = {-1, 3, 4, 8, 4},
8131 mgcnum, mgcnums[] = {-1, 2, 3, 4, 2};
8134 mark =
idxsmalloc(mask+1, -1,
"GENDUALMETIS: mark");
8137 esize = esizes[etype];
8138 mgcnum = mgcnums[etype];
8141 nptr =
idxsmalloc(nvtxs+1, 0,
"GENDUALMETIS: nptr");
8142 for (j=esize*nelmnts, i=0; i<j; i++)
8146 nind =
idxmalloc(nptr[nvtxs],
"GENDUALMETIS: nind");
8147 for (k=i=0; i<nelmnts; i++) {
8148 for (j=0; j<esize; j++, k++)
8149 nind[nptr[elmnts[k]]++] = i;
8151 for (i=nvtxs; i>0; i--)
8152 nptr[i] = nptr[i-1];
8155 for (i=0; i<nelmnts; i++)
8158 for (i=0; i<nelmnts; i++) {
8159 for (
m=j=0; j<esize; j++) {
8160 n = elmnts[esize*i+j];
8161 for (k=nptr[n+1]-1; k>=nptr[n]; k--) {
8162 if ((
kk = nind[k]) <= i)
8166 if ((l = mark[kkk]) == -1) {
8171 else if (ind[l] ==
kk) {
8176 if (ind[
jj] ==
kk) {
8188 for (j=0; j<
m; j++) {
8189 if (wgt[j] == mgcnum) {
8191 dadjncy[dxadj[i]++] = k;
8192 dadjncy[dxadj[k]++] = i;
8194 mark[ind[j]&mask] = -1;
8199 for (j=i=0; i<nelmnts; i++) {
8200 for (k=esize*i; k<dxadj[i]; k++, j++)
8201 dadjncy[j] = dadjncy[k];
8204 for (i=nelmnts; i>0; i--)
8205 dxadj[i] = dxadj[i-1];
8222 int i, j,
jj, k,
kk, nedges;
8227 nptr =
idxsmalloc(nvtxs+1, 0,
"TRINODALMETIS: nptr");
8228 for (j=3*nelmnts, i=0; i<j; i++)
8232 nind =
idxmalloc(nptr[nvtxs],
"TRINODALMETIS: nind");
8233 for (k=i=0; i<nelmnts; i++) {
8234 for (j=0; j<3; j++, k++)
8235 nind[nptr[elmnts[k]]++] = i;
8237 for (i=nvtxs; i>0; i--)
8238 nptr[i] = nptr[i-1];
8242 mark =
idxsmalloc(nvtxs, -1,
"TRINODALMETIS: mark");
8244 nedges = dxadj[0] = 0;
8245 for (i=0; i<nvtxs; i++) {
8247 for (j=nptr[i]; j<nptr[i+1]; j++) {
8248 for (
jj=3*nind[j], k=0; k<3; k++,
jj++) {
8250 if (mark[
kk] != i) {
8252 dadjncy[nedges++] =
kk;
8256 dxadj[i+1] = nedges;
8271 int i, j,
jj, k,
kk, nedges;
8276 nptr =
idxsmalloc(nvtxs+1, 0,
"TETNODALMETIS: nptr");
8277 for (j=4*nelmnts, i=0; i<j; i++)
8281 nind =
idxmalloc(nptr[nvtxs],
"TETNODALMETIS: nind");
8282 for (k=i=0; i<nelmnts; i++) {
8283 for (j=0; j<4; j++, k++)
8284 nind[nptr[elmnts[k]]++] = i;
8286 for (i=nvtxs; i>0; i--)
8287 nptr[i] = nptr[i-1];
8291 mark =
idxsmalloc(nvtxs, -1,
"TETNODALMETIS: mark");
8293 nedges = dxadj[0] = 0;
8294 for (i=0; i<nvtxs; i++) {
8296 for (j=nptr[i]; j<nptr[i+1]; j++) {
8297 for (
jj=4*nind[j], k=0; k<4; k++,
jj++) {
8299 if (mark[
kk] != i) {
8301 dadjncy[nedges++] =
kk;
8305 dxadj[i+1] = nedges;
8320 int i, j,
jj, k,
kk, nedges;
8323 int table[8][3] = {{1, 3, 4},
8333 nptr =
idxsmalloc(nvtxs+1, 0,
"HEXNODALMETIS: nptr");
8334 for (j=8*nelmnts, i=0; i<j; i++)
8338 nind =
idxmalloc(nptr[nvtxs],
"HEXNODALMETIS: nind");
8339 for (k=i=0; i<nelmnts; i++) {
8340 for (j=0; j<8; j++, k++)
8341 nind[nptr[elmnts[k]]++] = i;
8343 for (i=nvtxs; i>0; i--)
8344 nptr[i] = nptr[i-1];
8348 mark =
idxsmalloc(nvtxs, -1,
"HEXNODALMETIS: mark");
8350 nedges = dxadj[0] = 0;
8351 for (i=0; i<nvtxs; i++) {
8353 for (j=nptr[i]; j<nptr[i+1]; j++) {
8355 for (k=0; k<8; k++) {
8356 if (elmnts[
jj+k] == i)
8362 kk = elmnts[
jj+table[k][0]];
8363 if (mark[
kk] != i) {
8365 dadjncy[nedges++] =
kk;
8367 kk = elmnts[
jj+table[k][1]];
8368 if (mark[
kk] != i) {
8370 dadjncy[nedges++] =
kk;
8372 kk = elmnts[
jj+table[k][2]];
8373 if (mark[
kk] != i) {
8375 dadjncy[nedges++] =
kk;
8378 dxadj[i+1] = nedges;
8393 int i, j,
jj, k,
kk, nedges;
8396 int table[4][2] = {{1, 3},
8402 nptr =
idxsmalloc(nvtxs+1, 0,
"QUADNODALMETIS: nptr");
8403 for (j=4*nelmnts, i=0; i<j; i++)
8407 nind =
idxmalloc(nptr[nvtxs],
"QUADNODALMETIS: nind");
8408 for (k=i=0; i<nelmnts; i++) {
8409 for (j=0; j<4; j++, k++)
8410 nind[nptr[elmnts[k]]++] = i;
8412 for (i=nvtxs; i>0; i--)
8413 nptr[i] = nptr[i-1];
8417 mark =
idxsmalloc(nvtxs, -1,
"QUADNODALMETIS: mark");
8419 nedges = dxadj[0] = 0;
8420 for (i=0; i<nvtxs; i++) {
8422 for (j=nptr[i]; j<nptr[i+1]; j++) {
8424 for (k=0; k<4; k++) {
8425 if (elmnts[
jj+k] == i)
8431 kk = elmnts[
jj+table[k][0]];
8432 if (mark[
kk] != i) {
8434 dadjncy[nedges++] =
kk;
8436 kk = elmnts[
jj+table[k][1]];
8437 if (mark[
kk] != i) {
8439 dadjncy[nedges++] =
kk;
8442 dxadj[i+1] = nedges;
8475 idxtype *xadj, *adjncy, *pwgts;
8476 int options[10], pnumflag=0, wgtflag=0;
8477 int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
8478 int esize, esizes[] = {-1, 3, 4, 8, 4};
8480 esize = esizes[*etype];
8485 xadj =
idxmalloc(*nn+1,
"METIS_MESHPARTNODAL: xadj");
8486 adjncy =
idxmalloc(20*(*nn),
"METIS_MESHPARTNODAL: adjncy");
8490 adjncy = realloc(adjncy, xadj[*nn]*
sizeof(
idxtype));
8493 METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart);
8497 pwgts =
idxsmalloc(*nparts, 0,
"METIS_MESHPARTNODAL: pwgts");
8498 for (i=0; i<*ne; i++) {
8499 me = npart[elmnts[i*esize]];
8500 for (j=1; j<esize; j++) {
8501 if (npart[elmnts[i*esize+j]] != me)
8510 maxpwgt = 1.03*(*ne)/(*nparts);
8511 for (i=0; i<*ne; i++) {
8512 if (epart[i] == -1) {
8514 for (j=0; j<esize; j++) {
8515 me = npart[elmnts[i*esize+j]];
8516 for (k=0; k<nnbrs; k++) {
8517 if (nbrind[k] == me) {
8524 nbrwgt[nnbrs++] = 1;
8528 j =
iamax(nnbrs, nbrwgt);
8529 if (pwgts[nbrind[j]] < maxpwgt) {
8530 epart[i] = nbrind[j];
8534 for (j=0; j<nnbrs; j++) {
8535 if (pwgts[nbrind[j]] < maxpwgt) {
8536 epart[i] = nbrind[j];
8541 epart[i] = nbrind[
iamax(nnbrs, nbrwgt)];
8550 GKfree((
void **) &xadj, (
void **) &adjncy, (
void **) &pwgts,
LTERM);
8563 idxtype *xadj, *adjncy, *pwgts, *nptr, *nind;
8564 int options[10], pnumflag=0, wgtflag=0;
8565 int nnbrs, nbrind[200], nbrwgt[200], maxpwgt;
8566 int esize, esizes[] = {-1, 3, 4, 8, 4};
8568 esize = esizes[*etype];
8573 xadj =
idxmalloc(*ne+1,
"METIS_MESHPARTNODAL: xadj");
8574 adjncy =
idxmalloc(esize*(*ne),
"METIS_MESHPARTNODAL: adjncy");
8579 METIS_PartGraphKway(ne, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, epart);
8582 nptr =
idxsmalloc(*nn+1, 0,
"METIS_MESHPARTDUAL: nptr");
8583 for (j=esize*(*ne), i=0; i<j; i++)
8587 nind =
idxmalloc(nptr[*nn],
"METIS_MESHPARTDUAL: nind");
8588 for (k=i=0; i<(*ne); i++) {
8589 for (j=0; j<esize; j++, k++)
8590 nind[nptr[elmnts[k]]++] = i;
8592 for (i=(*nn); i>0; i--)
8593 nptr[i] = nptr[i-1];
8599 pwgts =
idxsmalloc(*nparts, 0,
"METIS_MESHPARTDUAL: pwgts");
8600 for (i=0; i<*nn; i++) {
8601 me = epart[nind[nptr[i]]];
8602 for (j=nptr[i]+1; j<nptr[i+1]; j++) {
8603 if (epart[nind[j]] != me)
8606 if (j == nptr[i+1]) {
8612 maxpwgt = 1.03*(*nn)/(*nparts);
8613 for (i=0; i<*nn; i++) {
8614 if (npart[i] == -1) {
8616 for (j=nptr[i]; j<nptr[i+1]; j++) {
8617 me = epart[nind[j]];
8618 for (k=0; k<nnbrs; k++) {
8619 if (nbrind[k] == me) {
8626 nbrwgt[nnbrs++] = 1;
8630 j =
iamax(nnbrs, nbrwgt);
8631 if (pwgts[nbrind[j]] < maxpwgt) {
8632 npart[i] = nbrind[j];
8636 npart[i] = nbrind[0];
8637 for (j=0; j<nnbrs; j++) {
8638 if (pwgts[nbrind[j]] < maxpwgt) {
8639 npart[i] = nbrind[j];
8651 GKfree((
void **) &xadj, (
void **) &adjncy, (
void **) &pwgts,
8652 (
void **) &nptr, (
void **) &nind,
LTERM);
8677 int i,
ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, limit,
tmp, cnum;
8678 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
8679 idxtype *moved, *swaps, *perm, *qnum;
8682 int higain, oldgain, mincut, initcut, newcut, mincutorder;
8685 nvtxs = graph->
nvtxs;
8688 nvwgt = graph->
nvwgt;
8691 where = graph->
where;
8703 limit =
amin(
amax(0.01*nvtxs, 15), 100);
8706 for (i=0; i<ncon; i++) {
8707 origdiff[i] = fabs(tpwgts[0]-npwgts[i]);
8708 ubvec[i] =
amax(origbal[i], orgubvec[i]);
8715 for (i=0; i<2; i++) {
8716 for (j=0; j<ncon; j++) {
8717 maxwgt[i*ncon+j] = tpwgts[i]*
ubvec[j];
8718 minwgt[i*ncon+j] = tpwgts[i]*(1.0/
ubvec[j]);
8723 for (i=0; i<ncon; i++) {
8727 for (i=0; i<nvtxs; i++)
8728 qnum[i] =
samax(ncon, nvwgt+i*ncon);
8733 for (l=0; l<ncon; l++)
8734 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
8735 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1],
8737 for (i=0; i<ncon; i++)
8738 printf(
"%.3f ", origbal[i]);
8742 idxset(nvtxs, -1, moved);
8743 for (pass=0; pass<npasses; pass++) {
8744 for (i=0; i<ncon; i++) {
8750 newcut = mincut = initcut = graph->
mincut;
8759 for (
ii=0;
ii<nbnd;
ii++) {
8760 i = bndind[perm[
ii]];
8761 ASSERT(ed[i] > 0 ||
id[i] == 0);
8763 PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-
id[i]);
8766 for (nswaps=0; nswaps<nvtxs; nswaps++) {
8767 SelectQueue2(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt);
8770 if (from == -1 || (higain =
PQueueGetMax(&parts[cnum][from])) == -1)
8772 ASSERT(bndptr[higain] != -1);
8774 newcut -= (ed[higain]-
id[higain]);
8775 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
8776 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
8782 for (i=0; i<ncon; i++)
8783 minbal[i] = tvec[i];
8784 mincutorder = nswaps;
8786 else if (nswaps-mincutorder > limit) {
8787 newcut += (ed[higain]-
id[higain]);
8788 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
8789 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
8794 moved[higain] = nswaps;
8795 swaps[nswaps] = higain;
8798 printf(
"Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], newcut);
8799 for (l=0; l<ncon; l++)
8800 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
8803 for (i=0; i<ncon; i++)
8804 printf(
"%.3f ", tvec[i]);
8805 if (mincutorder == nswaps)
8815 SWAP(
id[higain], ed[higain],
tmp);
8816 if (ed[higain] == 0 && xadj[higain] < xadj[higain+1])
8817 BNDDelete(nbnd, bndind, bndptr, higain);
8819 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
8821 oldgain = ed[k]-
id[k];
8823 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
8827 if (bndptr[k] != -1) {
8835 PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-
id[k]);
8842 PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-
id[k]);
8853 for (i=0; i<nswaps; i++)
8854 moved[swaps[i]] = -1;
8855 for (nswaps--; nswaps>mincutorder; nswaps--) {
8856 higain = swaps[nswaps];
8858 to = where[higain] = (where[higain]+1)%2;
8859 SWAP(
id[higain], ed[higain],
tmp);
8860 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
8861 BNDDelete(nbnd, bndind, bndptr, higain);
8862 else if (ed[higain] > 0 && bndptr[higain] == -1)
8863 BNDInsert(nbnd, bndind, bndptr, higain);
8865 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
8866 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
8867 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
8870 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
8873 if (bndptr[k] != -1 && ed[k] == 0)
8875 if (bndptr[k] == -1 && ed[k] > 0)
8881 printf(
"\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
8882 for (l=0; l<ncon; l++)
8883 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
8886 for (i=0; i<ncon; i++)
8887 printf(
"%.3f ", tvec[i]);
8894 if (mincutorder == -1 || mincut == initcut)
8898 for (i=0; i<ncon; i++) {
8917 void SelectQueue2(
int ncon,
float *npwgts,
float *tpwgts,
int *from,
int *cnum,
8920 int i, j, maxgain=0;
8921 float diff, max, maxdiff=0.0;
8927 for (j=0; j<2; j++) {
8928 for (i=0; i<ncon; i++) {
8929 diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i];
8930 if (diff >= maxdiff) {
8938 if (*from != -1 &&
PQueueGetSize(&queues[*cnum][*from]) == 0) {
8940 for (i=0; i<ncon; i++) {
8942 max = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]);
8948 for (i++; i<ncon; i++) {
8949 diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i];
8958 if (maxdiff <= 0.0 || *from == -1) {
8961 for (j=0; j<2; j++) {
8962 for (i=0; i<ncon; i++) {
8983 float max1=0.0, max2=0.0, sum1=0.0, sum2=0.0,
tmp;
8985 for (i=0; i<ncon; i++) {
8987 max1 = (max1 <
tmp ?
tmp : max1);
8991 max2 = (max2 <
tmp ?
tmp : max2);
8997 else if (max1 > max2)
9000 return sum1 <= sum2;
9025 int i,
ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, limit,
tmp, cnum;
9026 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
9027 idxtype *moved, *swaps, *perm, *qnum;
9028 float *nvwgt, *npwgts, mindiff[
MAXNCON], origbal, minbal, newbal;
9030 int higain, oldgain, mincut, initcut, newcut, mincutorder;
9033 nvtxs = graph->
nvtxs;
9036 nvwgt = graph->
nvwgt;
9039 where = graph->
where;
9051 limit =
amin(
amax(0.01*nvtxs, 25), 150);
9054 for (i=0; i<ncon; i++) {
9058 for (i=0; i<nvtxs; i++)
9059 qnum[i] =
samax(ncon, nvwgt+i*ncon);
9063 rtpwgts[0] = origbal*tpwgts[0];
9064 rtpwgts[1] = origbal*tpwgts[1];
9069 for (l=0; l<ncon; l++)
9070 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9071 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f\n", tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut, origbal);
9074 idxset(nvtxs, -1, moved);
9075 for (pass=0; pass<npasses; pass++) {
9076 for (i=0; i<ncon; i++) {
9082 newcut = mincut = initcut = graph->
mincut;
9083 for (i=0; i<ncon; i++)
9084 mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
9093 for (
ii=0;
ii<nbnd;
ii++) {
9094 i = bndind[perm[
ii]];
9095 ASSERT(ed[i] > 0 ||
id[i] == 0);
9097 PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-
id[i]);
9100 for (nswaps=0; nswaps<nvtxs; nswaps++) {
9101 SelectQueue(ncon, npwgts, rtpwgts, &from, &cnum, parts);
9104 if (from == -1 || (higain =
PQueueGetMax(&parts[cnum][from])) == -1)
9106 ASSERT(bndptr[higain] != -1);
9108 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
9109 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
9111 newcut -= (ed[higain]-
id[higain]);
9114 if ((newcut < mincut && newbal-origbal <= .00001) ||
9115 (newcut == mincut && (newbal < minbal ||
9116 (newbal == minbal &&
BetterBalance(ncon, npwgts, tpwgts, mindiff))))) {
9119 mincutorder = nswaps;
9120 for (i=0; i<ncon; i++)
9121 mindiff[i] = fabs(tpwgts[0]-npwgts[i]);
9123 else if (nswaps-mincutorder > limit) {
9124 newcut += (ed[higain]-
id[higain]);
9125 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
9126 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
9131 moved[higain] = nswaps;
9132 swaps[nswaps] = higain;
9135 printf(
"Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], newcut);
9136 for (l=0; l<ncon; l++)
9137 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9138 printf(
", %.3f LB: %.3f\n", minbal, newbal);
9145 SWAP(
id[higain], ed[higain],
tmp);
9146 if (ed[higain] == 0 && xadj[higain] < xadj[higain+1])
9147 BNDDelete(nbnd, bndind, bndptr, higain);
9149 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
9151 oldgain = ed[k]-
id[k];
9153 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
9157 if (bndptr[k] != -1) {
9165 PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-
id[k]);
9172 PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-
id[k]);
9183 for (i=0; i<nswaps; i++)
9184 moved[swaps[i]] = -1;
9185 for (nswaps--; nswaps>mincutorder; nswaps--) {
9186 higain = swaps[nswaps];
9188 to = where[higain] = (where[higain]+1)%2;
9189 SWAP(
id[higain], ed[higain],
tmp);
9190 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
9191 BNDDelete(nbnd, bndind, bndptr, higain);
9192 else if (ed[higain] > 0 && bndptr[higain] == -1)
9193 BNDInsert(nbnd, bndind, bndptr, higain);
9195 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
9196 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1);
9197 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
9200 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
9203 if (bndptr[k] != -1 && ed[k] == 0)
9205 if (bndptr[k] == -1 && ed[k] > 0)
9211 printf(
"\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd);
9212 for (l=0; l<ncon; l++)
9213 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9220 if (mincutorder == -1 || mincut == initcut)
9224 for (i=0; i<ncon; i++) {
9243 int i,
part, maxgain=0;
9244 float max, maxdiff=0.0;
9251 for (i=0; i<ncon; i++) {
9252 if (npwgts[
part*ncon+i]-tpwgts[
part] >= maxdiff) {
9253 maxdiff = npwgts[
part*ncon+i]-tpwgts[
part];
9262 if (*from != -1 &&
PQueueGetSize(&queues[*cnum][*from]) == 0) {
9264 for (i=0; i<ncon; i++) {
9266 max = npwgts[(*from)*ncon + i];
9272 for (i++; i<ncon; i++) {
9273 if (npwgts[(*from)*ncon + i] > max &&
PQueueGetSize(&queues[i][*from]) > 0) {
9274 max = npwgts[(*from)*ncon + i];
9281 if (maxdiff <= 0.0 || *from == -1) {
9285 for (i=0; i<ncon; i++) {
9311 for (i=0; i<ncon; i++)
9312 ndiff[i] = fabs(tpwgts[0]-npwgts[i]);
9325 float max=0.0,
temp;
9327 for (i=0; i<ncon; i++) {
9329 temp = fabs(tpwgts[0]-npwgts[i])/tpwgts[0];
9344 for (i=0; i<ncon; i++)
9345 lbvec[i] = 1.0 + fabs(tpwgts[0]-npwgts[i])/tpwgts[0];
9392 idxtype *mate, *queue, *flag, *level, *lst;
9393 int fptr, rptr, lstptr;
9394 int row, maxlevel, col;
9396 mate =
idxsmalloc(bsize, -1,
"MinCover: mate");
9397 flag =
idxmalloc(bsize,
"MinCover: flag");
9398 level =
idxmalloc(bsize,
"MinCover: level");
9399 queue =
idxmalloc(bsize,
"MinCover: queue");
9400 lst =
idxmalloc(bsize,
"MinCover: lst");
9403 for (i=0; i<asize; i++) {
9404 for (j=xadj[i]; j<xadj[i+1]; j++) {
9405 if (mate[adjncy[j]] == -1) {
9406 mate[i] = adjncy[j];
9407 mate[adjncy[j]] = i;
9418 for (i=0; i<bsize; i++) {
9425 for (i=0; i<asize; i++)
9426 if (mate[i] == -1) {
9432 while (fptr != rptr) {
9433 row = queue[fptr++];
9434 if (level[row] < maxlevel) {
9436 for (j=xadj[row]; j<xadj[row+1]; j++) {
9440 if (mate[col] == -1) {
9441 maxlevel = level[row];
9442 lst[lstptr++] = col;
9445 if (flag[mate[col]])
9446 printf(
"\nSomething wrong, flag[%d] is 1",mate[col]);
9447 queue[rptr++] = mate[col];
9448 level[mate[col]] = level[row] + 1;
9459 for (i=0; i<lstptr; i++)
9465 GKfree((
void **) &mate, (
void **) &flag, (
void **) &level,
9466 (
void **) &queue, (
void **) &lst,
LTERM);
9481 for (i=xadj[col]; i<xadj[col+1]; i++) {
9484 if (flag[row] == 1) {
9485 if (level[row] == maxlevel) {
9517 where =
idxmalloc(bsize,
"MinCover_Decompose: where");
9518 for (i=0; i<10; i++)
9521 for (i=0; i<asize; i++)
9523 for (; i<bsize; i++)
9526 for (i=0; i<asize; i++)
9529 for (; i<bsize; i++)
9533 for (i=0; i<bsize; i++)
9537 if (abs(card[
VC]+card[
SC]-card[
HR]) < abs(card[
VC]-card[
SR]-card[
HR])) {
9539 for (i=0; i<bsize; i++)
9540 if (where[i] ==
VC || where[i] ==
SC || where[i] ==
HR)
9545 for (i=0; i<bsize; i++)
9546 if (where[i] ==
VC || where[i] ==
SR || where[i] ==
HR)
9564 if (flag ==
INCOL) {
9565 if (where[root] ==
HC)
9568 for (i=xadj[root]; i<xadj[root+1]; i++)
9572 if (where[root] ==
HR)
9575 if (mate[root] != -1)
9589 if (flag ==
INROW) {
9590 if (where[root] ==
VR)
9593 for (i=xadj[root]; i<xadj[root+1]; i++)
9597 if (where[root] ==
VC)
9600 if (mate[root] != -1)
9638 switch (ctrl->
IType) {
9647 errexit(
"Unknown initial partition type: %d\n", ctrl->
IType);
9666 int nvtxs, bestcut, nbfs;
9669 nvtxs = graph->
nvtxs;
9672 where = graph->
where;
9674 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
9678 for (; nbfs>0; nbfs--) {
9691 if (bestcut > graph->
mincut) {
9693 idxcopy(nvtxs, where, bestwhere);
9700 idxcopy(nvtxs, bestwhere, where);
9717 int nvtxs, bestcut, nbfs;
9720 nvtxs = graph->
nvtxs;
9723 where = graph->
where;
9725 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
9729 for (; nbfs>0; nbfs--) {
9739 if (bestcut > graph->
mincut) {
9741 idxcopy(nvtxs, where, bestwhere);
9748 idxcopy(nvtxs, bestwhere, where);
9765 int i,
ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, cnum,
tmp,
imin;
9766 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
9768 float *nvwgt, *npwgts, minwgt;
9770 int higain, oldgain, mincut;
9772 nvtxs = graph->
nvtxs;
9776 nvwgt = graph->
nvwgt;
9778 where = graph->
where;
9795 for (l=0; l<ncon; l++)
9796 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9797 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut,
ComputeLoadImbalance(ncon, 2, npwgts, tpwgts));
9800 for (i=0; i<ncon; i++) {
9805 idxset(nvtxs, -1, moved);
9812 for (i=0; i<nvtxs; i++)
9813 qnum[i] =
samax(ncon, nvwgt+i*ncon);
9817 for (
ii=0;
ii<nvtxs;
ii++) {
9819 if (where[i] == from) {
9834 for (i=1; i<ncon; i++)
9840 for (nswaps=0; nswaps<nvtxs; nswaps++) {
9842 if (npwgts[to*ncon+
imin] > minwgt)
9851 mincut -= (ed[higain]-
id[higain]);
9852 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
9853 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
9856 moved[higain] = nswaps;
9859 printf(
"Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], mincut);
9860 for (l=0; l<ncon; l++)
9861 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9863 if (ed[higain] == 0 &&
id[higain] > 0)
9864 printf(
"\t Pulled from the interior!\n");
9871 SWAP(
id[higain], ed[higain],
tmp);
9872 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
9873 BNDDelete(nbnd, bndind, bndptr, higain);
9874 if (ed[higain] > 0 && bndptr[higain] == -1)
9875 BNDInsert(nbnd, bndind, bndptr, higain);
9877 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
9879 oldgain = ed[k]-
id[k];
9881 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
9885 if (moved[k] == -1 && where[k] == from) {
9886 if (ed[k] > 0 && bndptr[k] == -1) {
9891 if (bndptr[k] == -1)
9892 printf(
"What you thought was wrong!\n");
9893 PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-
id[k]);
9898 if (ed[k] == 0 && bndptr[k] != -1)
9900 else if (ed[k] > 0 && bndptr[k] == -1)
9909 printf(
"\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd);
9910 for (l=0; l<ncon; l++)
9911 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
9918 for (i=0; i<ncon; i++) {
9939 int i, cnum=-1,
imax, maxgain;
9943 for (i=0; i<ncon; i++) {
9949 for (i=0; i<ncon; i++)
9954 for (i=0; i<ncon; i++) {
9964 maxgain = -10000000;
9965 for (i=0; i<ncon; i++) {
10006 switch (ctrl->
IType) {
10014 errexit(
"Unknown initial partition type: %d\n", ctrl->
IType);
10034 int nvtxs, bestcut, nbfs;
10037 nvtxs = graph->
nvtxs;
10040 where = graph->
where;
10042 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
10046 for (; nbfs>0; nbfs--) {
10047 idxset(nvtxs, 1, where);
10059 if (bestcut >= graph->
mincut) {
10060 bestcut = graph->
mincut;
10061 idxcopy(nvtxs, where, bestwhere);
10067 graph->
mincut = bestcut;
10068 idxcopy(nvtxs, bestwhere, where);
10082 int i,
ii, nvtxs, ncon, bestcut, nbfs, qnum;
10083 idxtype *bestwhere, *where, *perm;
10087 nvtxs = graph->
nvtxs;
10088 ncon = graph->
ncon;
10089 nvwgt = graph->
nvwgt;
10092 where = graph->
where;
10094 bestwhere =
idxmalloc(nvtxs,
"BisectGraph: bestwhere");
10097 perm =
idxmalloc(nvtxs,
"BisectGraph: perm");
10099 for (; nbfs>0; nbfs--) {
10100 for (i=0; i<ncon; i++)
10106 for (
ii=0;
ii<nvtxs;
ii++) {
10108 qnum =
samax(ncon, nvwgt+i*ncon);
10109 where[i] = counts[qnum];
10110 counts[qnum] = (counts[qnum]+1)%2;
10128 if (bestcut >= graph->
mincut) {
10129 bestcut = graph->
mincut;
10130 idxcopy(nvtxs, where, bestwhere);
10136 graph->
mincut = bestcut;
10137 idxcopy(nvtxs, bestwhere, where);
10155 int i,
ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, cnum,
tmp;
10156 idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind;
10158 float *nvwgt, *npwgts;
10160 int higain, oldgain, mincut;
10162 nvtxs = graph->
nvtxs;
10163 ncon = graph->
ncon;
10164 xadj = graph->
xadj;
10166 nvwgt = graph->
nvwgt;
10168 where = graph->
where;
10183 printf(
"Parts: [");
10184 for (l=0; l<ncon; l++)
10185 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
10186 printf(
"] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1],
10191 for (i=0; i<ncon; i++) {
10201 for (i=0; i<nvtxs; i++)
10202 qnum[i] =
samax(ncon, nvwgt+i*ncon);
10206 for (
ii=0;
ii<nvtxs;
ii++) {
10208 if (where[i] == from) {
10218 nbnd = graph->
nbnd;
10219 for (nswaps=0; nswaps<nvtxs; nswaps++) {
10220 if (
AreAnyVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, tpwgts[from]))
10229 mincut -= (ed[higain]-
id[higain]);
10230 saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1);
10231 saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1);
10233 where[higain] = to;
10236 printf(
"Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-
id[higain], mincut);
10237 for (l=0; l<ncon; l++)
10238 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
10240 if (ed[higain] == 0 &&
id[higain] > 0)
10241 printf(
"\t Pulled from the interior!\n");
10248 SWAP(
id[higain], ed[higain],
tmp);
10249 if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1])
10250 BNDDelete(nbnd, bndind, bndptr, higain);
10251 if (ed[higain] > 0 && bndptr[higain] == -1)
10252 BNDInsert(nbnd, bndind, bndptr, higain);
10254 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
10256 oldgain = ed[k]-
id[k];
10258 kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]);
10262 if (where[k] == from) {
10263 if (ed[k] > 0 && bndptr[k] == -1) {
10268 if (bndptr[k] == -1)
10269 printf(
"What you thought was wrong!\n");
10270 PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-
id[k]);
10275 if (ed[k] == 0 && bndptr[k] != -1)
10277 else if (ed[k] > 0 && bndptr[k] == -1)
10286 printf(
"\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd);
10287 for (l=0; l<ncon; l++)
10288 printf(
"(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]);
10293 graph->
nbnd = nbnd;
10295 for (i=0; i<ncon; i++) {
10319 for (i=0; i<ncon; i++) {
10320 if (npwgts[from*ncon+i]-tpwgts[from] >= max &&
10322 max = npwgts[from*ncon+i]-tpwgts[0];
10355 int *nparts,
float *rubvec,
int *options,
int *edgecut,
10366 if (options[0] == 0) {
10410 int options[10], edgecut;
10424 for (i=0; i<graph->
ncon; i++) {
10425 if (rubvec[i] > 1.2)
10428 if (i == graph->
ncon)
10431 options, &edgecut, cgraph->
where);
10435 rubvec, options, &edgecut, cgraph->
where);
10439 IFSET(ctrl->
dbglvl,
DBG_IPART, printf(
"Initial %d-way partitioning cut: %d\n", nparts, edgecut));
10474 float *orgubvec,
int npasses)
10476 int i,
ii, iii, j, k, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same;
10477 int from, me, to, oldcut, gain;
10478 idxtype *xadj, *adjncy, *adjwgt;
10479 idxtype *where, *perm, *bndptr, *bndind;
10484 nvtxs = graph->
nvtxs;
10485 ncon = graph->
ncon;
10486 xadj = graph->
xadj;
10493 where = graph->
where;
10501 maxlb = minlb = orgubvec[0];
10502 for (i=1; i<ncon; i++) {
10503 minlb = (orgubvec[i] < minlb ? orgubvec[i] : minlb);
10504 maxlb = (orgubvec[i] > maxlb ? orgubvec[i] : maxlb);
10506 same = (fabs(maxlb-minlb) < .01 ? 1 : 0);
10511 for (i=0; i<ncon; i++)
10515 for (i=0; i<nparts; i++) {
10516 for (j=0; j<ncon; j++) {
10517 maxwgt[i*ncon+j] =
ubvec[j]/nparts;
10518 minwgt[i*ncon+j] = 1.0/(
ubvec[j]*nparts);
10524 for (i=1; i<ncon; i++)
10525 maxlb = (
ubvec[i] > maxlb ?
ubvec[i] : maxlb);
10527 for (i=0; i<nparts; i++) {
10528 for (j=0; j<ncon; j++) {
10529 maxwgt[i*ncon+j] = maxlb/nparts;
10530 minwgt[i*ncon+j] = 1.0/(maxlb*nparts);
10539 printf(
"Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
10540 npwgts[
samin(ncon*nparts, npwgts)], npwgts[
samax(ncon*nparts, npwgts)],
10543 for (i=0; i<ncon; i++)
10544 printf(
"%.3f ", tvec[i]);
10548 for (pass=0; pass<npasses; pass++) {
10552 nbnd = graph->
nbnd;
10555 for (nmoves=iii=0; iii<graph->
nbnd; iii++) {
10561 myrinfo = graph->
rinfo+i;
10563 if (myrinfo->
ed >= myrinfo->
id) {
10565 nvwgt = graph->
nvwgt+i*ncon;
10567 if (myrinfo->
id > 0 &&
AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))
10573 for (k=0; k<myndegrees; k++) {
10574 to = myedegrees[k].
pid;
10575 gain = myedegrees[k].
ed - myrinfo->
id;
10581 if (k == myndegrees)
10584 for (j=k+1; j<myndegrees; j++) {
10585 to = myedegrees[j].
pid;
10586 if ((myedegrees[j].ed > myedegrees[k].ed &&
10589 (myedegrees[j].ed == myedegrees[k].ed &&
10594 to = myedegrees[k].
pid;
10596 if (myedegrees[k].ed-myrinfo->
id == 0
10598 &&
AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon))
10604 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
10609 saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
10610 saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
10612 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
10613 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
10614 if (myedegrees[k].ed == 0)
10615 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
10617 myedegrees[k].
pid = from;
10619 if (myrinfo->
ed-myrinfo->
id < 0)
10623 for (j=xadj[i]; j<xadj[i+1]; j++) {
10639 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
10642 else if (me == to) {
10645 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
10651 for (k=0; k<myrinfo->
ndegrees; k++) {
10652 if (myedegrees[k].pid == from) {
10653 if (myedegrees[k].ed == adjwgt[j])
10654 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
10656 myedegrees[k].
ed -= adjwgt[j];
10664 for (k=0; k<myrinfo->
ndegrees; k++) {
10665 if (myedegrees[k].pid == to) {
10666 myedegrees[k].
ed += adjwgt[j];
10672 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
10684 graph->
nbnd = nbnd;
10687 printf(
"\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
10688 npwgts[
samin(ncon*nparts, npwgts)], npwgts[
samax(ncon*nparts, npwgts)],
10689 nbnd, nmoves, graph->
mincut);
10691 for (i=0; i<ncon; i++)
10692 printf(
"%.3f ", tvec[i]);
10696 if (graph->
mincut == oldcut)
10711 float *
ubvec,
int npasses)
10713 int i,
ii, j, k, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves;
10714 int from, me, to, oldcut;
10715 idxtype *xadj, *adjncy, *adjwgt;
10716 idxtype *where, *perm, *bndptr, *bndind, *moved;
10720 float *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[
MAXNCON];
10722 nvtxs = graph->
nvtxs;
10723 ncon = graph->
ncon;
10724 xadj = graph->
xadj;
10731 where = graph->
where;
10738 for (i=0; i<nparts; i++) {
10739 for (j=0; j<ncon; j++) {
10740 maxwgt[i*ncon+j] =
ubvec[j]/nparts;
10741 minwgt[i*ncon+j] = 1.0/(
ubvec[j]*nparts);
10751 printf(
"Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
10752 npwgts[
samin(ncon*nparts, npwgts)], npwgts[
samax(ncon*nparts, npwgts)],
10755 for (i=0; i<ncon; i++)
10756 printf(
"%.3f ", tvec[i]);
10761 for (pass=0; pass<npasses; pass++) {
10769 idxset(nvtxs, -1, moved);
10772 nbnd = graph->
nbnd;
10775 for (
ii=0;
ii<nbnd;
ii++) {
10776 i = bndind[perm[
ii]];
10787 myrinfo = graph->
rinfo+i;
10789 nvwgt = graph->
nvwgt+i*ncon;
10791 if (
AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))
10797 for (k=0; k<myndegrees; k++) {
10798 to = myedegrees[k].
pid;
10802 if (k == myndegrees)
10805 for (j=k+1; j<myndegrees; j++) {
10806 to = myedegrees[j].
pid;
10811 to = myedegrees[k].
pid;
10814 if (!
AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon))
10816 if (myedegrees[k].ed-myrinfo->
id >= 0)
10818 if (!
AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) &&
10834 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
10839 saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
10840 saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
10842 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
10843 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
10844 if (myedegrees[k].ed == 0)
10845 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
10847 myedegrees[k].
pid = from;
10849 if (myrinfo->
ed == 0)
10853 for (j=xadj[i]; j<xadj[i+1]; j++) {
10866 oldgain = (myrinfo->
ed-myrinfo->
id);
10871 if (myrinfo->
ed > 0 && bndptr[
ii] == -1)
10874 else if (me == to) {
10877 if (myrinfo->
ed == 0 && bndptr[
ii] != -1)
10883 for (k=0; k<myrinfo->
ndegrees; k++) {
10884 if (myedegrees[k].pid == from) {
10885 if (myedegrees[k].ed == adjwgt[j])
10886 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
10888 myedegrees[k].
ed -= adjwgt[j];
10896 for (k=0; k<myrinfo->
ndegrees; k++) {
10897 if (myedegrees[k].pid == to) {
10898 myedegrees[k].
ed += adjwgt[j];
10904 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
10910 if (me == to || me == from) {
10911 gain = myrinfo->
ed-myrinfo->
id;
10912 if (moved[
ii] == 2) {
10913 if (myrinfo->
ed > 0)
10920 else if (moved[
ii] == -1 && myrinfo->
ed > 0) {
10932 graph->
nbnd = nbnd;
10935 printf(
"\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
10936 npwgts[
samin(ncon*nparts, npwgts)], npwgts[
samax(ncon*nparts, npwgts)],
10937 nbnd, nmoves, graph->
mincut);
10939 for (i=0; i<ncon; i++)
10940 printf(
"%.3f ", tvec[i]);
10969 for (i=0; i<ncon; i++)
10970 if (
alpha*vwgt1[i] +
beta*vwgt2[i] > limit[i])
10986 for (i=0; i<ncon; i++)
10987 if (
alpha*vwgt1[i] +
beta*vwgt2[i] < limit[i])
11003 for (i=0; i<ncon; i++) {
11005 for (j=0; j<nparts; j++) {
11006 if (npwgts[j*ncon+i] > max)
11007 max = npwgts[j*ncon+i];
11010 lbvec[i] = max*nparts;
11023 for (i=0; i<ncon; i++) {
11025 for (j=0; j<nparts; j++) {
11026 if (npwgts[j*ncon+i] > max)
11027 max = npwgts[j*ncon+i];
11030 if (
ubvec[i] < max*nparts)
11049 float blb1=0.0, alb1=0.0, sblb=0.0, salb=0.0;
11050 float blb2=0.0, alb2=0.0;
11053 for (i=0; i<ncon; i++) {
11059 else if (blb2 <
temp)
11063 temp =
amax(pfrom[i]-vwgt[i], pto[i]+vwgt[i])*nparts/
ubvec[i];
11068 else if (alb2 <
temp)
11082 return salb < sblb;
11097 float m11=0.0, m12=0.0, m21=0.0, m22=0.0, sm1=0.0, sm2=0.0,
temp;
11099 for (i=0; i<ncon; i++) {
11100 temp = (pt1[i]+vwgt[i])*nparts/
ubvec[i];
11105 else if (m12 <
temp)
11109 temp = (pt2[i]+vwgt[i])*nparts/
ubvec[i];
11114 else if (m22 <
temp)
11172 if (graph == orggraph)
11175 graph = graph->
finer;
11199 int nvtxs, ncon, pad64;
11201 nvtxs = graph->
nvtxs;
11202 ncon = graph->
ncon;
11204 pad64 = (3*nvtxs)%2;
11212 graph->
npwgts =
fmalloc(ncon*nparts,
"MocAllocateKWayPartitionMemory: npwgts");
11221 int i, j, k, nvtxs, ncon, nbnd, mincut, me, other;
11222 idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr;
11225 float *nvwgt, *npwgts;
11227 nvtxs = graph->
nvtxs;
11228 ncon = graph->
ncon;
11229 xadj = graph->
xadj;
11230 nvwgt = graph->
nvwgt;
11234 where = graph->
where;
11235 npwgts =
sset(ncon*nparts, 0.0, graph->
npwgts);
11238 rinfo = graph->
rinfo;
11246 for (i=0; i<nvtxs; i++) {
11248 saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
11254 for (j=xadj[i]; j<xadj[i+1]; j++) {
11255 if (me != where[adjncy[j]])
11256 myrinfo->
ed += adjwgt[j];
11260 if (myrinfo->
ed > 0)
11261 mincut += myrinfo->
ed;
11263 if (myrinfo->
ed-myrinfo->
id >= 0)
11267 if (myrinfo->
ed > 0) {
11271 for (j=xadj[i]; j<xadj[i+1]; j++) {
11272 other = where[adjncy[j]];
11274 for (k=0; k<myrinfo->
ndegrees; k++) {
11275 if (myedegrees[k].pid == other) {
11276 myedegrees[k].
ed += adjwgt[j];
11282 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
11291 graph->
mincut = mincut/2;
11292 graph->
nbnd = nbnd;
11304 int i, j, k, nvtxs, nbnd, me, other,
istart,
iend, ndegrees;
11305 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
11306 idxtype *cmap, *where, *bndptr, *bndind;
11314 cwhere = cgraph->
where;
11315 crinfo = cgraph->
rinfo;
11317 nvtxs = graph->
nvtxs;
11318 cmap = graph->
cmap;
11319 xadj = graph->
xadj;
11325 where = graph->
where;
11326 rinfo = graph->
rinfo;
11331 for (i=0; i<nvtxs; i++) {
11333 where[i] = cwhere[k];
11334 cmap[i] = crinfo[k].
ed;
11340 for (nbnd=0, i=0; i<nvtxs; i++) {
11347 myrinfo->
id = adjwgtsum[i];
11358 other = where[adjncy[j]];
11360 myrinfo->
ed += adjwgt[j];
11361 if ((k = htable[other]) == -1) {
11362 htable[other] = ndegrees;
11363 myedegrees[ndegrees].
pid = other;
11364 myedegrees[ndegrees++].
ed = adjwgt[j];
11367 myedegrees[k].
ed += adjwgt[j];
11371 myrinfo->
id -= myrinfo->
ed;
11374 if (myrinfo->
ed == 0) {
11379 if (myrinfo->
ed-myrinfo->
id >= 0)
11384 for (j=0; j<ndegrees; j++)
11385 htable[myedegrees[j].pid] = -1;
11392 graph->
nbnd = nbnd;
11410 int i, nvtxs, nbnd;
11413 nvtxs = graph->
nvtxs;
11420 for (i=0; i<nvtxs; i++) {
11425 graph->
nbnd = nbnd;
11451 int i,
ii, j, k, nvtxs, ncon, cnvtxs, maxidx;
11452 idxtype *xadj, *adjncy, *adjwgt;
11453 idxtype *match, *cmap, *perm;
11458 nvtxs = graph->
nvtxs;
11459 ncon = graph->
ncon;
11460 xadj = graph->
xadj;
11461 nvwgt = graph->
nvwgt;
11465 cmap = graph->
cmap;
11472 for (
ii=0;
ii<nvtxs;
ii++) {
11479 for (j=xadj[i]; j<xadj[i+1]; j++) {
11487 cmap[i] = cmap[maxidx] = cnvtxs++;
11508 int i,
ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt;
11509 idxtype *xadj, *adjncy, *adjwgt;
11510 idxtype *match, *cmap, *perm;
11515 nvtxs = graph->
nvtxs;
11516 ncon = graph->
ncon;
11517 xadj = graph->
xadj;
11518 nvwgt = graph->
nvwgt;
11522 cmap = graph->
cmap;
11529 for (
ii=0;
ii<nvtxs;
ii++) {
11537 for (j=xadj[i]; j<xadj[i+1]; j++) {
11539 if (match[k] ==
UNMATCHED && maxwgt <= adjwgt[j] &&
11541 maxwgt = adjwgt[j];
11542 maxidx = adjncy[j];
11546 cmap[i] = cmap[maxidx] = cnvtxs++;
11567 int i,
ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
11568 idxtype *xadj, *adjncy, *adjwgt;
11569 idxtype *match, *cmap, *degrees, *perm, *tperm;
11574 nvtxs = graph->
nvtxs;
11575 ncon = graph->
ncon;
11576 xadj = graph->
xadj;
11577 nvwgt = graph->
nvwgt;
11581 cmap = graph->
cmap;
11589 avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
11590 for (i=0; i<nvtxs; i++)
11591 degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
11597 for (
ii=0;
ii<nvtxs;
ii++) {
11601 if (xadj[i] < xadj[i+1])
11605 for (j=nvtxs-1; j>
ii; j--) {
11607 if (match[k] ==
UNMATCHED && xadj[k] < xadj[k+1]) {
11613 cmap[i] = cmap[maxidx] = cnvtxs++;
11620 for (;
ii<nvtxs;
ii++) {
11628 for (j=xadj[i]; j<xadj[i+1]; j++) {
11630 if (match[k] ==
UNMATCHED && maxwgt <= adjwgt[j] &&
11632 maxwgt = adjwgt[j];
11633 maxidx = adjncy[j];
11637 cmap[i] = cmap[maxidx] = cnvtxs++;
11661 int i,
ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
11662 idxtype *xadj, *adjncy, *adjwgt;
11663 idxtype *match, *cmap, *degrees, *perm, *tperm;
11668 nvtxs = graph->
nvtxs;
11669 ncon = graph->
ncon;
11670 xadj = graph->
xadj;
11671 nvwgt = graph->
nvwgt;
11675 cmap = graph->
cmap;
11683 avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
11684 for (i=0; i<nvtxs; i++)
11685 degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
11691 for (
ii=0;
ii<nvtxs;
ii++) {
11695 if (xadj[i] < xadj[i+1])
11699 for (j=nvtxs-1; j>
ii; j--) {
11701 if (match[k] ==
UNMATCHED && xadj[k] < xadj[k+1]) {
11707 cmap[i] = cmap[maxidx] = cnvtxs++;
11714 for (;
ii<nvtxs;
ii++) {
11722 for (j=xadj[i]; j<xadj[i+1]; j++) {
11727 (maxwgt < adjwgt[j] ||
11728 (maxwgt == adjwgt[j] &&
11729 BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon) >= 0
11733 maxwgt = adjwgt[j];
11738 cmap[i] = cmap[maxidx] = cnvtxs++;
11762 int i,
ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
11763 idxtype *xadj, *adjncy, *adjwgt;
11764 idxtype *match, *cmap, *degrees, *perm, *tperm;
11765 float *nvwgt, vbal;
11769 nvtxs = graph->
nvtxs;
11770 ncon = graph->
ncon;
11771 xadj = graph->
xadj;
11772 nvwgt = graph->
nvwgt;
11776 cmap = graph->
cmap;
11784 avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
11785 for (i=0; i<nvtxs; i++)
11786 degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
11792 for (
ii=0;
ii<nvtxs;
ii++) {
11796 if (xadj[i] < xadj[i+1])
11800 for (j=nvtxs-1; j>
ii; j--) {
11802 if (match[k] ==
UNMATCHED && xadj[k] < xadj[k+1]) {
11808 cmap[i] = cmap[maxidx] = cnvtxs++;
11815 for (;
ii<nvtxs;
ii++) {
11824 for (j=xadj[i]; j<xadj[i+1]; j++) {
11828 vbal =
BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon);
11830 if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) {
11831 maxwgt = adjwgt[j];
11837 cmap[i] = cmap[maxidx] = cnvtxs++;
11865 float sum1, sum2, max1, max2, min1, min2, diff1, diff2;
11868 max1 = min1 = vwgt[0]+u1wgt[0];
11869 max2 = min2 = vwgt[0]+u2wgt[0];
11870 sum1 = vwgt[0]+u1wgt[0];
11871 sum2 = vwgt[0]+u2wgt[0];
11873 for (i=1; i<ncon; i++) {
11874 if (max1 < vwgt[i]+u1wgt[i])
11875 max1 = vwgt[i]+u1wgt[i];
11876 if (min1 > vwgt[i]+u1wgt[i])
11877 min1 = vwgt[i]+u1wgt[i];
11879 if (max2 < vwgt[i]+u2wgt[i])
11880 max2 = vwgt[i]+u2wgt[i];
11881 if (min2 > vwgt[i]+u2wgt[i])
11882 min2 = vwgt[i]+u2wgt[i];
11884 sum1 += vwgt[i]+u1wgt[i];
11885 sum2 += vwgt[i]+u2wgt[i];
11890 else if (sum2 == 0.0)
11893 return ((max1-min1)/sum1) - ((max2-min2)/sum2);
11895 else if (norm == 1) {
11897 for (i=0; i<ncon; i++) {
11898 sum1 += vwgt[i]+u1wgt[i];
11899 sum2 += vwgt[i]+u2wgt[i];
11901 sum1 = sum1/(1.0*ncon);
11902 sum2 = sum2/(1.0*ncon);
11904 diff1 = diff2 = 0.0;
11905 for (i=0; i<ncon; i++) {
11906 diff1 += fabs(sum1 - (vwgt[i]+u1wgt[i]));
11907 diff2 += fabs(sum2 - (vwgt[i]+u2wgt[i]));
11910 return diff1 - diff2;
11913 errexit(
"Unknown norm: %d\n", norm);
11927 for (i=0; i<ncon; i++)
11928 if (vwgt1[i] + vwgt2[i] > limit)
11988 int maxint,
int *ncsub)
11990 int ehead, i, mdeg, mdlmt, mdeg_node, nextmd,
num, tag;
11996 xadj--; adjncy--; invp--; perm--; head--; qsize--; list--; marker--;
12000 mmdint(neqns, xadj, adjncy, head, invp, perm, qsize, list, marker);
12007 while (nextmd > 0) {
12008 mdeg_node = nextmd;
12009 nextmd = invp[mdeg_node];
12010 marker[mdeg_node] = maxint;
12011 invp[mdeg_node] = -
num;
12025 while (head[mdeg] <= 0)
12030 mdlmt = mdeg +
delta;
12034 mdeg_node = head[mdeg];
12035 while (mdeg_node <= 0) {
12040 mdeg_node = head[mdeg];
12044 nextmd = invp[mdeg_node];
12045 head[mdeg] = nextmd;
12047 perm[nextmd] = -mdeg;
12048 invp[mdeg_node] = -
num;
12049 *ncsub += mdeg + qsize[mdeg_node] - 2;
12050 if ((
num+qsize[mdeg_node]) > neqns)
12056 if (tag >= maxint) {
12058 for (i = 1; i <= neqns; i++)
12059 if (marker[i] < maxint)
12063 mmdelm(mdeg_node, xadj, adjncy, head, invp, perm, qsize, list, marker, maxint, tag);
12065 num += qsize[mdeg_node];
12066 list[mdeg_node] = ehead;
12076 mmdupd( ehead, neqns, xadj, adjncy,
delta, &mdeg, head, invp, perm, qsize, list, marker, maxint, &tag);
12080 mmdnum( neqns, perm, invp, qsize );
12083 xadj++; adjncy++; invp++; perm++; head++; qsize++; list++; marker++;
12107 int element, i, istop,
istart, j,
12109 nabor, node, npv, nqnbrs, nxnode,
12110 pvnode, rlmt, rloc, rnode, xqnbr;
12114 marker[mdeg_node] = tag;
12115 istart = xadj[mdeg_node];
12116 istop = xadj[mdeg_node+1] - 1;
12124 for ( i =
istart; i <= istop; i++ ) {
12126 if ( nabor == 0 )
break;
12127 if ( marker[nabor] < tag ) {
12128 marker[nabor] = tag;
12129 if ( forward[nabor] < 0 ) {
12130 list[nabor] = element;
12133 adjncy[rloc] = nabor;
12140 while ( element > 0 ) {
12141 adjncy[rlmt] = -element;
12146 jstop = xadj[link+1] - 1;
12147 for ( j =
jstart; j <= jstop; j++ ) {
12150 if ( node < 0 )
goto n400;
12151 if ( node == 0 )
break;
12152 if ((marker[node]<tag)&&(forward[node]>=0)) {
12153 marker[node] = tag;
12155 while ( rloc >= rlmt ) {
12156 link = -adjncy[rlmt];
12158 rlmt = xadj[link+1] - 1;
12160 adjncy[rloc] = node;
12164 element = list[element];
12166 if ( rloc <= rlmt ) adjncy[rloc] = 0;
12172 istop = xadj[link+1] - 1;
12173 for ( i =
istart; i <= istop; i++ ) {
12176 if ( rnode < 0 )
goto n1100;
12177 if ( rnode == 0 )
return;
12180 pvnode = backward[rnode];
12181 if (( pvnode != 0 ) && ( pvnode != (-maxint) )) {
12183 nxnode = forward[rnode];
12184 if ( nxnode > 0 ) backward[nxnode] = pvnode;
12185 if ( pvnode > 0 ) forward[pvnode] = nxnode;
12187 if ( pvnode < 0 ) head[npv] = nxnode;
12192 jstop = xadj[rnode+1] - 1;
12194 for ( j =
jstart; j <= jstop; j++ ) {
12196 if ( nabor == 0 )
break;
12197 if ( marker[nabor] < tag ) {
12198 adjncy[xqnbr] = nabor;
12204 nqnbrs = xqnbr -
jstart;
12205 if ( nqnbrs <= 0 ) {
12207 qsize[mdeg_node] += qsize[rnode];
12209 marker[rnode] = maxint;
12210 forward[rnode] = -mdeg_node;
12211 backward[rnode] = -maxint;
12215 forward[rnode] = nqnbrs + 1;
12216 backward[rnode] = 0;
12217 adjncy[xqnbr] = mdeg_node;
12219 if ( xqnbr <= jstop ) adjncy[xqnbr] = 0;
12241 int fnode, ndeg, node;
12243 for ( node = 1; node <= neqns; node++ ) {
12251 for ( node = 1; node <= neqns; node++ ) {
12252 ndeg = xadj[node+1] - xadj[node];
12255 fnode = head[ndeg];
12256 forward[node] = fnode;
12258 if ( fnode > 0 ) backward[fnode] = node;
12259 backward[node] = -ndeg;
12283 int father, nextf, node, nqsize,
num, root;
12285 for ( node = 1; node <= neqns; node++ ) {
12286 nqsize = qsize[node];
12287 if ( nqsize <= 0 ) perm[node] = invp[node];
12288 if ( nqsize > 0 ) perm[node] = -invp[node];
12292 for ( node = 1; node <= neqns; node++ ) {
12293 if ( perm[node] <= 0 ) {
12298 while ( perm[father] <= 0 )
12299 father = - perm[father];
12303 num = perm[root] + 1;
12309 nextf = - perm[father];
12310 while ( nextf > 0 ) {
12311 perm[father] = -root;
12313 nextf = -perm[father];
12319 for ( node = 1; node <= neqns; node++ ) {
12347 idxtype *marker,
int maxint,
int *tag)
12349 int deg, deg0, element, enode, fnode, i, iq2, istop,
12351 node, q2head, qxhead;
12353 mdeg0 = *mdeg +
delta;
12357 if ( element <= 0 )
return;
12361 mtag = *tag + mdeg0;
12362 if ( mtag >= maxint ) {
12364 for ( i = 1; i <= neqns; i++ )
12365 if ( marker[i] < maxint ) marker[i] = 0;
12366 mtag = *tag + mdeg0;
12380 istop = xadj[link+1] - 1;
12381 for ( i =
istart; i <= istop; i++ ) {
12384 if ( enode < 0 )
goto n400;
12385 if ( enode == 0 )
break;
12386 if ( qsize[enode] != 0 ) {
12387 deg0 += qsize[enode];
12388 marker[enode] = mtag;
12391 if ( backward[enode] == 0 ) {
12393 if ( forward[enode] != 2 ) {
12394 list[enode] = qxhead;
12397 list[enode] = q2head;
12409 if ( enode <= 0 )
goto n1500;
12410 if ( backward[enode] != 0 )
goto n2200;
12417 if ( nabor == element ) nabor = adjncy[
istart+1];
12419 if ( forward[nabor] >= 0 ) {
12421 deg += qsize[nabor];
12429 istop = xadj[link+1] - 1;
12430 for ( i =
istart; i <= istop; i++ ) {
12433 if ( node != enode ) {
12434 if ( node < 0 )
goto n1000;
12435 if ( node == 0 )
goto n2100;
12436 if ( qsize[node] != 0 ) {
12437 if ( marker[node] < *tag ) {
12439 marker[node] = *tag;
12440 deg += qsize[node];
12442 if ( backward[node] == 0 ) {
12443 if ( forward[node] == 2 ) {
12446 qsize[enode] += qsize[node];
12448 marker[node] = maxint;
12449 forward[node] = -enode;
12450 backward[node] = -maxint;
12453 if (backward[node]==0) backward[node] = -maxint;
12467 n1600:
if ( enode <= 0 )
goto n2300;
12468 if ( backward[enode] != 0 )
goto n2200;
12474 istop = xadj[enode+1] - 1;
12475 for ( i =
istart; i <= istop; i++ ) {
12477 if ( nabor == 0 )
break;
12478 if ( marker[nabor] < *tag ) {
12479 marker[nabor] = *tag;
12481 if ( forward[nabor] >= 0 )
12483 deg += qsize[nabor];
12489 jstop = xadj[link+1] - 1;
12490 for ( j =
jstart; j <= jstop; j++ ) {
12493 if ( node < 0 )
goto n1700;
12494 if ( node == 0 )
break;
12495 if ( marker[node] < *tag ) {
12496 marker[node] = *tag;
12497 deg += qsize[node];
12507 deg = deg - qsize[enode] + 1;
12509 forward[enode] = fnode;
12510 backward[enode] = -deg;
12511 if ( fnode > 0 ) backward[fnode] = enode;
12513 if ( deg < *mdeg ) *mdeg = deg;
12517 enode = list[enode];
12518 if ( iq2 == 1 )
goto n900;
12524 element = list[element];
12551 idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
12562 if (options[0] == 0) {
12604 idxtype *vwgt,
idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
12616 if (options[0] == 0) {
12633 myubvec =
fmalloc(*ncon,
"PWMETIS: mytpwgts");
12662 float *nvwgt,
idxtype *adjwgt,
int *nparts,
int *options,
int *edgecut,
idxtype *
part)
12667 SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt);
12669 if (options[0] == 0) {
12708 float *nvwgt,
idxtype *adjwgt,
int *nparts,
float *
ubvec,
int *options,
int *edgecut,
12715 SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt);
12717 if (options[0] == 0) {
12734 myubvec =
fmalloc(*ncon,
"PWMETIS: mytpwgts");
12761 float ubfactor,
int fpart)
12768 nvtxs = graph->
nvtxs;
12770 printf(
"\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
12775 tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts);
12776 tpwgts[1] = 1.0 - tpwgts[0];
12781 label = graph->
label;
12782 where = graph->
where;
12783 for (i=0; i<nvtxs; i++)
12784 part[label[i]] = where[i] + fpart;
12799 else if (nparts == 3) {
12814 float *
ubvec,
int fpart)
12816 int i, nvtxs, ncon, cut;
12819 float tpwgts[2], *npwgts, *lubvec, *rubvec;
12821 lubvec = rubvec = NULL;
12823 nvtxs = graph->
nvtxs;
12824 ncon = graph->
ncon;
12826 printf(
"\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
12831 tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts);
12832 tpwgts[1] = 1.0 - tpwgts[0];
12841 label = graph->
label;
12842 where = graph->
where;
12843 for (i=0; i<nvtxs; i++)
12844 part[label[i]] = where[i] + fpart;
12849 lubvec =
fmalloc(ncon,
"MCHMlevelRecursiveBisection");
12850 rubvec =
fmalloc(ncon,
"MCHMlevelRecursiveBisection");
12852 for (i=0; i<ncon; i++) {
12853 lubvec[i] =
ubvec[i]*tpwgts[0]/npwgts[i];
12854 lubvec[i] =
amax(lubvec[i], 1.01);
12856 rubvec[i] =
ubvec[i]*tpwgts[1]/npwgts[ncon+i];
12857 rubvec[i] =
amax(rubvec[i], 1.01);
12873 else if (nparts == 3) {
12878 GKfree((
void **) &lubvec, (
void **) &rubvec,
LTERM);
12952 switch (ctrl->
RType) {
12958 errexit(
"Unknown refinement type: %d\n", ctrl->
RType);
12962 if (graph == orggraph)
12965 graph = graph->
finer;
12999 for (i=0; i<graph->
ncon; i++)
13011 switch (ctrl->
RType) {
13021 errexit(
"Unknown refinement type: %d\n", ctrl->
RType);
13025 if (graph == orggraph)
13028 graph = graph->
finer;
13048 nvtxs = graph->
nvtxs;
13049 ncon = graph->
ncon;
13051 graph->
rdata =
idxmalloc(5*nvtxs,
"Allocate2WayPartitionMemory: rdata");
13053 graph->
id = graph->
rdata + nvtxs;
13054 graph->
ed = graph->
rdata + 2*nvtxs;
13067 int i, j, nvtxs, ncon, nbnd, mincut;
13068 idxtype *xadj, *adjncy, *adjwgt;
13069 float *nvwgt, *npwgts;
13074 nvtxs = graph->
nvtxs;
13075 ncon = graph->
ncon;
13076 xadj = graph->
xadj;
13077 nvwgt = graph->
nvwgt;
13081 where = graph->
where;
13093 for (i=0; i<nvtxs; i++) {
13094 ASSERT(where[i] >= 0 && where[i] <= 1);
13097 saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1);
13099 for (j=xadj[i]; j<xadj[i+1]; j++) {
13100 if (me == where[adjncy[j]])
13101 id[i] += adjwgt[j];
13103 ed[i] += adjwgt[j];
13106 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
13109 bndind[nbnd++] = i;
13113 graph->
mincut = mincut/2;
13114 graph->
nbnd = nbnd;
13126 int i, j, k, nvtxs, nbnd, me;
13127 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
13128 idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
13129 idxtype *cwhere, *cid, *ced, *cbndptr;
13133 cwhere = cgraph->
where;
13136 cbndptr = cgraph->
bndptr;
13138 nvtxs = graph->
nvtxs;
13139 cmap = graph->
cmap;
13140 xadj = graph->
xadj;
13147 where = graph->
where;
13155 for (i=0; i<nvtxs; i++) {
13157 where[i] = cwhere[k];
13158 cmap[i] = cbndptr[k];
13161 for (nbnd=0, i=0; i<nvtxs; i++) {
13164 id[i] = adjwgtsum[i];
13166 if (xadj[i] == xadj[i+1]) {
13168 bndind[nbnd++] = i;
13171 if (cmap[i] != -1) {
13172 for (j=xadj[i]; j<xadj[i+1]; j++) {
13173 if (me != where[adjncy[j]])
13174 ed[i] += adjwgt[j];
13178 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
13180 bndind[nbnd++] = i;
13187 graph->
nbnd = nbnd;
13219 for (i=0; i<ncon; i++)
13220 if (
alpha*vwgt1[i] +
beta*vwgt2[i] > limit)
13235 for (i=0; i<ncon; i++)
13236 if (
alpha*vwgt1[i] +
beta*vwgt2[i] < limit)
13252 for (i=0; i<ncon; i++)
13253 if (
alpha*vwgt1[i] +
beta*vwgt2[i] < limit)
13269 for (i=0; i<ncon; i++) {
13271 for (j=0; j<nparts; j++) {
13272 if (npwgts[j*ncon+i] > max)
13273 max = npwgts[j*ncon+i];
13275 if (max*nparts > lb)
13290 for (i=0; i<ncon; i++)
13319 static void iiqst(
int *,
int *);
13349 for (j = lo = base; lo++ < hi;) {
13359 for (min = base; (hi = min += 1) < max;) {
13360 while (*(--hi) > *min);
13361 if ((hi += 1) != min) {
13362 for (lo = min + 1; --lo >= min;) {
13364 for (i = j = lo; (j -= 1) >= hi; i = j)
13385 mid = base + ((unsigned) lo>>1);
13387 j = (*base > *mid ? base : mid);
13390 j = (j == base ? mid : base);
13403 for (i = base, j = max - 1;;) {
13404 while (i < mid && *i <= *mid)
13434 if ((lo = j - base) <= (hi = max - i)) {
13477 for (j = lo = base; lo++ < hi;) {
13487 for (min = base; (hi = min += 1) < max;) {
13488 while (*(--hi) > *min);
13489 if ((hi += 1) != min) {
13490 for (lo = min + 1; --lo >= min;) {
13492 for (i = j = lo; (j -= 1) >= hi; i = j)
13501 static void iiqst(
int *base,
int *max)
13514 mid = base + ((unsigned) lo>>1);
13516 j = (*base > *mid ? base : mid);
13519 j = (j == base ? mid : base);
13532 for (i = base, j = max - 1;;) {
13533 while (i < mid && *i <= *mid)
13563 if ((lo = j - base) <= (hi = max - i)) {
13600 keyiqst(base, max);
13606 for (j = lo = base; lo++ < hi;) {
13616 for (min = base; (hi = min += 1) < max;) {
13617 while ((--hi)->key > min->
key);
13618 if ((hi += 1) != min) {
13619 for (lo = min + 1; --lo >= min;) {
13621 for (i = j = lo; (j -= 1) >= hi; i = j)
13631 for (i=0; i<n-1; i++)
13632 if (base[i].key > base[i+1].key)
13633 printf(
"Something went wrong!\n");
13649 lo = (max - base)>>1;
13651 mid = base + ((unsigned) lo>>1);
13653 j = (base->
key > mid->
key ? base : mid);
13655 if (j->
key >
tmp->key) {
13656 j = (j == base ? mid : base);
13669 for (i = base, j = max - 1;;) {
13670 while (i < mid && i->key <= mid->key)
13673 if (mid->
key <= j->
key) {
13700 if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) {
13736 keyvaliqst(base, max);
13742 for (j = lo = base; lo++ < hi;) {
13752 for (min = base; (hi = min += 1) < max;) {
13753 while ((--hi)->key > min->
key || (hi->
key == min->
key && hi->
val > min->
val));
13754 if ((hi += 1) != min) {
13755 for (lo = min + 1; --lo >= min;) {
13757 for (i = j = lo; (j -= 1) >= hi; i = j)
13777 lo = (max - base)>>1;
13779 mid = base + ((unsigned) lo>>1);
13781 j = (base->
key > mid->
key || (base->
key == mid->
key && base->
val > mid->
val) ? base : mid);
13784 j = (j == base ? mid : base);
13797 for (i = base, j = max - 1;;) {
13798 while (i < mid && (i->
key < mid->key || (i->
key == mid->key && i->
val <= mid->val)))
13801 if (mid->key < j->
key || (mid->key == j->
key && mid->val <= j->
val)) {
13828 if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) {
13830 keyvaliqst(base, j);
13836 keyvaliqst(i, max);
13874 if (options[0] == 0) {
13906 for (i=0; i<*nvtxs; i++)
13907 perm[iperm[i]] = i;
13925 idxtype *cptr, *cind, *piperm;
13930 if (options[0] == 0) {
13948 if (ctrl.
nseps < 1)
13963 piperm =
idxmalloc(*nvtxs,
"ONMETIS: piperm");
13965 PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (
float)(0.1*ctrl.
pfactor));
13971 cptr =
idxmalloc(*nvtxs+1,
"ONMETIS: cptr");
13972 cind =
idxmalloc(*nvtxs,
"ONMETIS: cind");
13974 CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind);
13980 else if (2*graph.
nvtxs < *nvtxs && ctrl.
nseps == 1)
14002 if (graph.
nvtxs < *nvtxs) {
14004 for (i=0; i<graph.
nvtxs; i++)
14005 iperm[piperm[i]] = perm[i];
14006 for (i=graph.
nvtxs; i<*nvtxs; i++)
14007 iperm[piperm[i]] = i;
14015 for (i=0; i<graph.
nvtxs; i++)
14016 perm[iperm[i]] = i;
14019 for (j=cptr[i]; j<cptr[i+1]; j++)
14020 iperm[cind[j]] = l++;
14028 for (i=0; i<*nvtxs; i++)
14029 perm[iperm[i]] = i;
14056 if (options[0] == 0) {
14088 for (i=0; i<*nvtxs; i++)
14089 perm[iperm[i]] = i;
14105 int i, nvtxs, nbnd, tvwgt, tpwgts2[2];
14109 nvtxs = graph->
nvtxs;
14113 tpwgts2[0] = tvwgt/2;
14114 tpwgts2[1] = tvwgt-tpwgts2[0];
14134 nbnd = graph->
nbnd;
14136 label = graph->
label;
14137 for (i=0; i<nbnd; i++)
14138 order[label[bndind[i]]] = --lastvtx;
14149 MMDOrder(ctrl, &rgraph, order, lastvtx);
14168 int i, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs;
14173 nvtxs = graph->
nvtxs;
14177 tpwgts2[0] = tvwgt/2;
14178 tpwgts2[1] = tvwgt-tpwgts2[0];
14184 nbnd = graph->
nbnd;
14186 label = graph->
label;
14187 for (i=0; i<nbnd; i++)
14188 order[label[bndind[i]]] = --lastvtx;
14190 cptr =
idxmalloc(nvtxs,
"MlevelNestedDissectionCC: cptr");
14191 cind =
idxmalloc(nvtxs,
"MlevelNestedDissectionCC: cind");
14210 for (rnvtxs=i=0; i<nsgraphs; i++) {
14211 if (sgraphs[i].adjwgt == NULL) {
14212 MMDOrder(ctrl, sgraphs+i, order, lastvtx-rnvtxs);
14213 GKfree((
void **) &sgraphs[i].gdata, (
void **) &sgraphs[i].label,
LTERM);
14218 rnvtxs += sgraphs[i].
nvtxs;
14232 int i, nvtxs, cnvtxs, mincut;
14241 nvtxs = graph->
nvtxs;
14244 bestwhere =
idxmalloc(nvtxs,
"MlevelNodeBisection2: bestwhere");
14247 for (i=ctrl->
nseps; i>0; i--) {
14252 if (graph->
mincut < mincut) {
14275 cnvtxs = cgraph->
nvtxs;
14277 bestwhere =
idxmalloc(cnvtxs,
"MlevelNodeBisection2: bestwhere");
14280 for (i=ctrl->
nseps; i>0; i--) {
14286 if (cgraph->
mincut < mincut) {
14287 mincut = cgraph->
mincut;
14325 switch (ctrl->
IType) {
14354 int i,
ii, j, k, l,
istart,
iend, mypart, nvtxs, snvtxs[3], snedges[3];
14355 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind;
14356 idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2];
14362 nvtxs = graph->
nvtxs;
14363 xadj = graph->
xadj;
14364 vwgt = graph->
vwgt;
14368 label = graph->
label;
14369 where = graph->
where;
14376 snvtxs[0] = snvtxs[1] = snvtxs[2] = snedges[0] = snedges[1] = snedges[2] = 0;
14377 for (i=0; i<nvtxs; i++) {
14379 rename[i] = snvtxs[k]++;
14380 snedges[k] += xadj[i+1]-xadj[i];
14384 sxadj[0] = lgraph->
xadj;
14385 svwgt[0] = lgraph->
vwgt;
14387 sadjncy[0] = lgraph->
adjncy;
14388 sadjwgt[0] = lgraph->
adjwgt;
14389 slabel[0] = lgraph->
label;
14392 sxadj[1] = rgraph->
xadj;
14393 svwgt[1] = rgraph->
vwgt;
14395 sadjncy[1] = rgraph->
adjncy;
14396 sadjwgt[1] = rgraph->
adjwgt;
14397 slabel[1] = rgraph->
label;
14402 for (j=xadj[i]; j<xadj[i+1]; j++)
14403 bndptr[adjncy[j]] = 1;
14406 snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
14407 sxadj[0][0] = sxadj[1][0] = 0;
14408 for (i=0; i<nvtxs; i++) {
14409 if ((mypart = where[i]) == 2)
14414 if (bndptr[i] == -1) {
14415 auxadjncy = sadjncy[mypart] + snedges[mypart] -
istart;
14417 auxadjncy[j] = adjncy[j];
14421 auxadjncy = sadjncy[mypart];
14422 l = snedges[mypart];
14425 if (where[k] == mypart)
14426 auxadjncy[l++] = k;
14428 snedges[mypart] = l;
14431 svwgt[mypart][snvtxs[mypart]] = vwgt[i];
14432 sadjwgtsum[mypart][snvtxs[mypart]] = snedges[mypart]-sxadj[mypart][snvtxs[mypart]];
14433 slabel[mypart][snvtxs[mypart]] = label[i];
14434 sxadj[mypart][++snvtxs[mypart]] = snedges[mypart];
14437 for (mypart=0; mypart<2; mypart++) {
14438 iend = snedges[mypart];
14441 auxadjncy = sadjncy[mypart];
14442 for (i=0; i<
iend; i++)
14443 auxadjncy[i] = rename[auxadjncy[i]];
14446 lgraph->
nvtxs = snvtxs[0];
14447 lgraph->
nedges = snedges[0];
14448 rgraph->
nvtxs = snvtxs[1];
14449 rgraph->
nedges = snedges[1];
14463 int i, k, nvtxs, nofsub, firstvtx;
14464 idxtype *xadj, *adjncy, *label;
14465 idxtype *perm, *iperm, *head, *qsize, *list, *marker;
14467 nvtxs = graph->
nvtxs;
14468 xadj = graph->
xadj;
14473 for (i=0; i<k; i++)
14475 for (i=0; i<nvtxs+1; i++)
14478 perm =
idxmalloc(6*(nvtxs+5),
"MMDOrder: perm");
14479 iperm = perm + nvtxs + 5;
14480 head = iperm + nvtxs + 5;
14481 qsize = head + nvtxs + 5;
14482 list = qsize + nvtxs + 5;
14483 marker = list + nvtxs + 5;
14485 genmmd(nvtxs, xadj, adjncy, iperm, perm, 1, head, qsize, list, marker,
MAXIDX, &nofsub);
14487 label = graph->
label;
14488 firstvtx = lastvtx-nvtxs;
14489 for (i=0; i<nvtxs; i++)
14490 order[label[i]] = firstvtx+iperm[i]-1;
14495 for (i=0; i<nvtxs+1; i++)
14498 for (i=0; i<k; i++)
14509 int i,
ii, iii, j, k, l,
istart,
iend, nvtxs, snvtxs, snedges;
14510 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind;
14511 idxtype *sxadj, *svwgt, *sadjncy, *sadjwgt, *sadjwgtsum, *slabel;
14513 idxtype *auxadjncy, *auxadjwgt;
14517 nvtxs = graph->
nvtxs;
14518 xadj = graph->
xadj;
14519 vwgt = graph->
vwgt;
14523 label = graph->
label;
14524 where = graph->
where;
14532 for (j=xadj[i]; j<xadj[i+1]; j++)
14533 bndptr[adjncy[j]] = 1;
14539 for (iii=0; iii<ncmps; iii++) {
14541 snvtxs = snedges = 0;
14542 for (j=cptr[iii]; j<cptr[iii+1]; j++) {
14544 rename[i] = snvtxs++;
14545 snedges += xadj[i+1]-xadj[i];
14549 sxadj = sgraphs[iii].
xadj;
14550 svwgt = sgraphs[iii].
vwgt;
14552 sadjncy = sgraphs[iii].
adjncy;
14553 sadjwgt = sgraphs[iii].
adjwgt;
14554 slabel = sgraphs[iii].
label;
14556 snvtxs = snedges = sxadj[0] = 0;
14557 for (
ii=cptr[iii];
ii<cptr[iii+1];
ii++) {
14562 if (bndptr[i] == -1) {
14563 auxadjncy = sadjncy + snedges -
istart;
14564 auxadjwgt = sadjwgt + snedges -
istart;
14566 auxadjncy[j] = adjncy[j];
14579 svwgt[snvtxs] = vwgt[i];
14580 sadjwgtsum[snvtxs] = snedges-sxadj[snvtxs];
14581 slabel[snvtxs] = label[i];
14582 sxadj[++snvtxs] = snedges;
14585 idxset(snedges, 1, sadjwgt);
14586 for (i=0; i<snedges; i++)
14587 sadjncy[i] = rename[sadjncy[i]];
14589 sgraphs[iii].
nvtxs = snvtxs;
14590 sgraphs[iii].
nedges = snedges;
14591 sgraphs[iii].
ncon = 1;
14594 sgraphs[iii].
adjwgt = NULL;
14631 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
14637 tpwgts =
fmalloc(*nparts,
"KMETIS: tpwgts");
14638 for (i=0; i<*nparts; i++)
14639 tpwgts[i] = 1.0/(1.0*(*nparts));
14642 tpwgts, options, edgecut,
part);
14653 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
14654 float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
14664 if (options[0] == 0) {
14710 if (options[0] == 0) {
14728 if (ctrl.
nseps < 1)
14743 cptr =
idxmalloc(nvtxs+1,
"ONMETIS: cptr");
14744 cind =
idxmalloc(nvtxs,
"ONMETIS: cind");
14746 CompressGraph(&ctrl, &graph, nvtxs, xadj, adjncy, cptr, cind);
14752 else if (2*graph.
nvtxs < nvtxs && ctrl.
nseps == 1)
14766 idxset(2*npes-1, 0, sizes);
14774 for (i=0; i<graph.
nvtxs; i++)
14775 perm[iperm[i]] = i;
14778 for (j=cptr[i]; j<cptr[i+1]; j++)
14779 iperm[cind[j]] = l++;
14787 for (i=0; i<nvtxs; i++)
14788 perm[iperm[i]] = i;
14801 int npes,
int cpos,
idxtype *sizes)
14803 int i, nvtxs, nbnd, tvwgt, tpwgts2[2];
14808 nvtxs = graph->
nvtxs;
14818 tpwgts2[0] = tvwgt/2;
14819 tpwgts2[1] = tvwgt-tpwgts2[0];
14821 if (cpos >= npes-1)
14831 if (cpos < npes-1) {
14832 sizes[2*npes-2-cpos] = graph->
pwgts[2];
14833 sizes[2*npes-2-(2*cpos+1)] = graph->
pwgts[1];
14834 sizes[2*npes-2-(2*cpos+2)] = graph->
pwgts[0];
14838 nbnd = graph->
nbnd;
14840 label = graph->
label;
14841 for (i=0; i<nbnd; i++)
14842 order[label[bndind[i]]] = --lastvtx;
14853 MMDOrder(ctrl, &rgraph, order, lastvtx);
14876 int tvwgt, tpwgts[2];
14883 if (options[0] == 0) {
14910 tpwgts[0] = tvwgt/2;
14911 tpwgts[1] = tvwgt-tpwgts[0];
14915 *sepsize = graph.
pwgts[2];
14935 int tvwgt, tpwgts[2];
14942 if (options[0] == 0) {
14969 tpwgts[0] = tvwgt/2;
14970 tpwgts[1] = tvwgt-tpwgts[0];
14975 *sepsize = graph.
pwgts[2];
15007 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
15013 tpwgts =
fmalloc(*nparts,
"KMETIS: tpwgts");
15014 for (i=0; i<*nparts; i++)
15015 tpwgts[i] = 1.0/(1.0*(*nparts));
15018 tpwgts, options, edgecut,
part);
15030 idxtype *adjwgt,
int *wgtflag,
int *numflag,
int *nparts,
15031 float *tpwgts,
int *options,
int *edgecut,
idxtype *
part)
15043 if (options[0] == 0) {
15059 mytpwgts =
fmalloc(*nparts,
"PWMETIS: mytpwgts");
15060 for (i=0; i<*nparts; i++)
15061 mytpwgts[i] = tpwgts[i];
15089 int i, nvtxs, cut, tvwgt, tpwgts2[2];
15094 nvtxs = graph->
nvtxs;
15096 printf(
"\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n");
15102 tpwgts2[0] = tvwgt*
ssum(nparts/2, tpwgts);
15103 tpwgts2[1] = tvwgt-tpwgts2[0];
15110 label = graph->
label;
15111 where = graph->
where;
15112 for (i=0; i<nvtxs; i++)
15113 part[label[i]] = where[i] + fpart;
15126 wsum =
ssum(nparts/2, tpwgts);
15127 sscale(nparts/2, 1.0/wsum, tpwgts);
15128 sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2);
15140 else if (nparts == 3) {
15161 Refine2Way(ctrl, graph, cgraph, tpwgts, ubfactor);
15177 int i, j, k,
kk, l,
istart,
iend, mypart, nvtxs, ncon, snvtxs[2], snedges[2], sum;
15178 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr;
15179 idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2];
15181 idxtype *auxadjncy, *auxadjwgt;
15182 float *nvwgt, *snvwgt[2], *npwgts;
15187 nvtxs = graph->
nvtxs;
15188 ncon = graph->
ncon;
15189 xadj = graph->
xadj;
15190 vwgt = graph->
vwgt;
15191 nvwgt = graph->
nvwgt;
15195 label = graph->
label;
15196 where = graph->
where;
15204 snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
15205 for (i=0; i<nvtxs; i++) {
15207 rename[i] = snvtxs[k]++;
15208 snedges[k] += xadj[i+1]-xadj[i];
15212 sxadj[0] = lgraph->
xadj;
15213 svwgt[0] = lgraph->
vwgt;
15214 snvwgt[0] = lgraph->
nvwgt;
15216 sadjncy[0] = lgraph->
adjncy;
15217 sadjwgt[0] = lgraph->
adjwgt;
15218 slabel[0] = lgraph->
label;
15221 sxadj[1] = rgraph->
xadj;
15222 svwgt[1] = rgraph->
vwgt;
15223 snvwgt[1] = rgraph->
nvwgt;
15225 sadjncy[1] = rgraph->
adjncy;
15226 sadjwgt[1] = rgraph->
adjwgt;
15227 slabel[1] = rgraph->
label;
15229 snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0;
15230 sxadj[0][0] = sxadj[1][0] = 0;
15231 for (i=0; i<nvtxs; i++) {
15233 sum = adjwgtsum[i];
15237 if (bndptr[i] == -1) {
15238 auxadjncy = sadjncy[mypart] + snedges[mypart] -
istart;
15239 auxadjwgt = sadjwgt[mypart] + snedges[mypart] -
istart;
15241 auxadjncy[j] = adjncy[j];
15242 auxadjwgt[j] = adjwgt[j];
15247 auxadjncy = sadjncy[mypart];
15248 auxadjwgt = sadjwgt[mypart];
15249 l = snedges[mypart];
15252 if (where[k] == mypart) {
15254 auxadjwgt[l++] = adjwgt[j];
15260 snedges[mypart] = l;
15264 svwgt[mypart][snvtxs[mypart]] = vwgt[i];
15266 for (
kk=0;
kk<ncon;
kk++)
15267 snvwgt[mypart][snvtxs[mypart]*ncon+
kk] = nvwgt[i*ncon+
kk]/npwgts[mypart*ncon+
kk];
15270 sadjwgtsum[mypart][snvtxs[mypart]] = sum;
15271 slabel[mypart][snvtxs[mypart]] = label[i];
15272 sxadj[mypart][++snvtxs[mypart]] = snedges[mypart];
15275 for (mypart=0; mypart<2; mypart++) {
15276 iend = sxadj[mypart][snvtxs[mypart]];
15277 auxadjncy = sadjncy[mypart];
15278 for (i=0; i<
iend; i++)
15279 auxadjncy[i] = rename[auxadjncy[i]];
15282 lgraph->
nedges = snedges[0];
15283 rgraph->
nedges = snedges[1];
15297 sgraph->
nvtxs = snvtxs;
15298 sgraph->
nedges = snedges;
15302 if (graph->
ncon == 1) {
15303 sgraph->
gdata =
idxmalloc(4*snvtxs+1 + 2*snedges,
"SetUpSplitGraph: gdata");
15306 sgraph->
vwgt = sgraph->
gdata + snvtxs+1;
15308 sgraph->
cmap = sgraph->
gdata + 3*snvtxs+1;
15310 sgraph->
adjwgt = sgraph->
gdata + 4*snvtxs+1 + snedges;
15313 sgraph->
gdata =
idxmalloc(3*snvtxs+1 + 2*snedges,
"SetUpSplitGraph: gdata");
15317 sgraph->
cmap = sgraph->
gdata + 2*snvtxs+1;
15319 sgraph->
adjwgt = sgraph->
gdata + 3*snvtxs+1 + snedges;
15324 sgraph->
label =
idxmalloc(snvtxs,
"SetUpSplitGraph: sgraph->label");
15357 queue->
nodes = NULL;
15358 queue->
heap = NULL;
15366 if (queue->
type == 1) {
15385 for (i=0; i<maxnodes; i++)
15388 for (i=0; i<j; i++)
15411 if (queue->
type == 1) {
15416 for (i=0; i<j; i++)
15433 if (queue->
type == 1) {
15471 if (queue->
type == 1) {
15476 newnode = queue->
nodes + node;
15480 newnode->
prev = NULL;
15481 if (newnode->
next != NULL)
15483 queue->
buckets[gain] = newnode;
15491 heap = queue->
heap;
15494 ASSERT(locator[node] == -1);
15499 if (heap[j].key < gain) {
15501 locator[heap[i].
val] = i;
15508 heap[i].
key = gain;
15509 heap[i].
val = node;
15525 int i, j, newgain, oldgain;
15530 if (queue->
type == 1) {
15536 newnode = queue->
nodes+node;
15539 if (newnode->
prev != NULL)
15542 buckets[gain] = newnode->
next;
15543 if (newnode->
next != NULL)
15546 if (buckets[gain] == NULL && gain == queue->
maxgain) {
15554 heap = queue->
heap;
15557 ASSERT(locator[node] != -1);
15558 ASSERT(heap[locator[node]].val == node);
15563 locator[node] = -1;
15568 oldgain = heap[i].
key;
15570 if (oldgain < newgain) {
15573 if (heap[j].key < newgain) {
15575 locator[heap[i].
val] = i;
15583 while ((j=2*i+1) < queue->
nnodes) {
15584 if (heap[j].key > newgain) {
15585 if (j+1 < queue->
nnodes && heap[j+1].
key > heap[j].
key)
15588 locator[heap[i].
val] = i;
15591 else if (j+1 < queue->
nnodes && heap[j+1].
key > newgain) {
15594 locator[heap[i].
val] = i;
15602 heap[i].
key = newgain;
15603 heap[i].
val = node;
15625 if (oldgain == newgain)
15628 if (queue->
type == 1) {
15634 heap = queue->
heap;
15637 ASSERT(locator[node] != -1);
15638 ASSERT(heap[locator[node]].val == node);
15639 ASSERT(heap[locator[node]].key == oldgain);
15644 if (oldgain < newgain) {
15647 if (heap[j].key < newgain) {
15649 locator[heap[i].
val] = i;
15657 while ((j=2*i+1) < queue->
nnodes) {
15658 if (heap[j].key > newgain) {
15659 if (j+1 < queue->
nnodes && heap[j+1].
key > heap[j].
key)
15662 locator[heap[i].
val] = i;
15665 else if (j+1 < queue->
nnodes && heap[j+1].
key > newgain) {
15668 locator[heap[i].
val] = i;
15676 heap[i].
key = newgain;
15677 heap[i].
val = node;
15699 if (oldgain == newgain)
15702 if (queue->
type == 1) {
15708 newnode = queue->
nodes+node;
15711 if (newnode->
prev != NULL)
15714 buckets[oldgain] = newnode->
next;
15715 if (newnode->
next != NULL)
15719 newnode->
next = buckets[newgain];
15720 newnode->
prev = NULL;
15721 if (newnode->
next != NULL)
15723 buckets[newgain] = newnode;
15725 if (queue->
maxgain < newgain)
15729 heap = queue->
heap;
15732 ASSERT(locator[node] != -1);
15733 ASSERT(heap[locator[node]].val == node);
15734 ASSERT(heap[locator[node]].key == oldgain);
15742 if (heap[j].key < newgain) {
15744 locator[heap[i].
val] = i;
15751 heap[i].
key = newgain;
15752 heap[i].
val = node;
15767 int vtx, i, j, gain, node;
15777 if (queue->
type == 1) {
15780 if (tptr->
next != NULL) {
15784 if (queue->
nnodes == 0) {
15794 heap = queue->
heap;
15800 if ((i = queue->
nnodes) > 0) {
15801 gain = heap[i].
key;
15802 node = heap[i].
val;
15804 while ((j=2*i+1) < queue->
nnodes) {
15805 if (heap[j].key > gain) {
15806 if (j+1 < queue->
nnodes && heap[j+1].
key > heap[j].
key)
15809 locator[heap[i].
val] = i;
15812 else if (j+1 < queue->
nnodes && heap[j+1].
key > gain) {
15815 locator[heap[i].
val] = i;
15822 heap[i].
key = gain;
15823 heap[i].
val = node;
15843 if (queue->
type == 1)
15862 if (queue->
type == 1)
15882 heap = queue->
heap;
15889 ASSERT(locator[heap[0].val] == 0);
15890 for (i=1; i<nnodes; i++) {
15891 ASSERTP(locator[heap[i].val] == i, (
"%d %d %d %d\n", nnodes, i, heap[i].val, locator[heap[i].val]));
15892 ASSERTP(heap[i].key <= heap[(i-1)/2].key, (
"%d %d %d %d %d\n", i, (i-1)/2, nnodes, heap[i].key, heap[(i-1)/2].key));
15894 for (i=1; i<nnodes; i++)
15895 ASSERT(heap[i].key <= heap[0].key);
15897 for (j=i=0; i<queue->
maxnodes; i++) {
15898 if (locator[i] != -1)
15901 ASSERTP(j == nnodes, (
"%d %d\n", j, nnodes));
15936 switch (ctrl->
RType) {
15942 errexit(
"Unknown refinement type: %d\n", ctrl->
RType);
15946 if (graph == orggraph)
15949 graph = graph->
finer;
15966 nvtxs = graph->
nvtxs;
15968 graph->
rdata =
idxmalloc(5*nvtxs+2,
"Allocate2WayPartitionMemory: rdata");
15971 graph->
id = graph->
rdata + nvtxs + 2;
15972 graph->
ed = graph->
rdata + 2*nvtxs + 2;
15983 int i, j, nvtxs, nbnd, mincut;
15984 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts;
15989 nvtxs = graph->
nvtxs;
15990 xadj = graph->
xadj;
15991 vwgt = graph->
vwgt;
15995 where = graph->
where;
16007 for (i=0; i<nvtxs; i++) {
16008 ASSERT(where[i] >= 0 && where[i] <= 1);
16010 pwgts[me] += vwgt[i];
16012 for (j=xadj[i]; j<xadj[i+1]; j++) {
16013 if (me == where[adjncy[j]])
16014 id[i] += adjwgt[j];
16016 ed[i] += adjwgt[j];
16019 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
16022 bndind[nbnd++] = i;
16026 graph->
mincut = mincut/2;
16027 graph->
nbnd = nbnd;
16040 int i, j, k, nvtxs, nbnd, me;
16041 idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum;
16042 idxtype *cmap, *where, *id, *ed, *bndptr, *bndind;
16043 idxtype *cwhere, *cid, *ced, *cbndptr;
16047 cwhere = cgraph->
where;
16050 cbndptr = cgraph->
bndptr;
16052 nvtxs = graph->
nvtxs;
16053 cmap = graph->
cmap;
16054 xadj = graph->
xadj;
16061 where = graph->
where;
16069 for (i=0; i<nvtxs; i++) {
16071 where[i] = cwhere[k];
16072 cmap[i] = cbndptr[k];
16075 for (nbnd=0, i=0; i<nvtxs; i++) {
16078 id[i] = adjwgtsum[i];
16080 if (xadj[i] == xadj[i+1]) {
16082 bndind[nbnd++] = i;
16085 if (cmap[i] != -1) {
16086 for (j=xadj[i]; j<xadj[i+1]; j++) {
16087 if (me != where[adjncy[j]])
16088 ed[i] += adjwgt[j];
16092 if (ed[i] > 0 || xadj[i] == xadj[i+1]) {
16094 bndind[nbnd++] = i;
16101 graph->
nbnd = nbnd;
16131 int i, j, nvtxs, nbnd;
16132 idxtype *xadj, *where, *bndind;
16134 nvtxs = graph->
nvtxs;
16135 xadj = graph->
xadj;
16136 nbnd = graph->
nbnd;
16142 for (i=0; i<nbnd; i++) {
16144 if (xadj[j+1]-xadj[j] > 0)
16173 int i,
ii, j,
jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;
16174 idxtype *xadj, *adjncy, *bxadj, *badjncy;
16175 idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover;
16178 nvtxs = graph->
nvtxs;
16179 xadj = graph->
xadj;
16182 nbnd = graph->
nbnd;
16185 where = graph->
where;
16193 bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;
16194 for (i=0; i<nbnd; i++) {
16197 if (xadj[j+1]-xadj[j] > 0) {
16199 bnedges[k] += xadj[j+1]-xadj[j];
16203 bnvtxs[2] = bnvtxs[0]+bnvtxs[1];
16204 bnvtxs[1] = bnvtxs[0];
16207 bxadj =
idxmalloc(bnvtxs[2]+1,
"ConstructMinCoverSeparator: bxadj");
16208 badjncy =
idxmalloc(bnedges[0]+bnedges[1]+1,
"ConstructMinCoverSeparator: badjncy");
16212 for (i=0; i<nbnd; i++) {
16215 if (xadj[j+1]-xadj[j] > 0) {
16216 vmap[j] = bnvtxs[k];
16217 ivmap[bnvtxs[k]++] = j;
16222 bnvtxs[1] = bnvtxs[0];
16225 for (k=0; k<2; k++) {
16226 for (
ii=0;
ii<nbnd;
ii++) {
16228 if (where[i] == k && xadj[i] < xadj[i+1]) {
16229 for (j=xadj[i]; j<xadj[i+1]; j++) {
16231 if (where[
jj] != k) {
16234 badjncy[l++] = vmap[
jj];
16237 bxadj[++bnvtxs[k]] = l;
16242 ASSERT(l <= bnedges[0]+bnedges[1]);
16244 MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);
16247 printf(
"Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->
pwgts[0], graph->
pwgts[1], graph->
mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));
16249 for (i=0; i<csize; i++) {
16250 j = ivmap[cover[i]];
16254 GKfree((
void **) &bxadj, (
void **) &badjncy,
LTERM);
16256 for (i=0; i<nbnd; i++)
16257 bndptr[bndind[i]] = -1;
16258 for (nbnd=i=0; i<nvtxs; i++) {
16259 if (where[i] == 2) {
16261 bndptr[i] = nbnd++;
16267 printf(
"Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->
pwgts[0], graph->
pwgts[1], graph->
mincut, 0, 0, 0));
16273 graph->
nbnd = nbnd;
16288 int i,
ii, j,
jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;
16289 idxtype *xadj, *adjncy, *bxadj, *badjncy;
16290 idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover;
16293 nvtxs = graph->
nvtxs;
16294 xadj = graph->
xadj;
16297 nbnd = graph->
nbnd;
16300 where = graph->
where;
16308 bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;
16309 for (i=0; i<nbnd; i++) {
16312 if (xadj[j+1]-xadj[j] > 0) {
16314 bnedges[k] += xadj[j+1]-xadj[j];
16318 bnvtxs[2] = bnvtxs[0]+bnvtxs[1];
16319 bnvtxs[1] = bnvtxs[0];
16322 bxadj =
idxmalloc(bnvtxs[2]+1,
"ConstructMinCoverSeparator: bxadj");
16323 badjncy =
idxmalloc(bnedges[0]+bnedges[1]+1,
"ConstructMinCoverSeparator: badjncy");
16327 for (i=0; i<nbnd; i++) {
16330 if (xadj[j+1]-xadj[j] > 0) {
16331 vmap[j] = bnvtxs[k];
16332 ivmap[bnvtxs[k]++] = j;
16337 bnvtxs[1] = bnvtxs[0];
16340 for (k=0; k<2; k++) {
16341 for (
ii=0;
ii<nbnd;
ii++) {
16343 if (where[i] == k && xadj[i] < xadj[i+1]) {
16344 for (j=xadj[i]; j<xadj[i+1]; j++) {
16346 if (where[
jj] != k) {
16349 badjncy[l++] = vmap[
jj];
16352 bxadj[++bnvtxs[k]] = l;
16357 ASSERT(l <= bnedges[0]+bnedges[1]);
16359 MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);
16362 printf(
"Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->
pwgts[0], graph->
pwgts[1], graph->
mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));
16364 for (i=0; i<csize; i++) {
16365 j = ivmap[cover[i]];
16369 GKfree((
void **) &bxadj, (
void **) &badjncy,
LTERM);
16373 printf(
"Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->
pwgts[0], graph->
pwgts[1], graph->
mincut, 0, 0, 0));
16415 int i,
ii, j, k,
jj,
kk, nvtxs, nbnd, nswaps, nmind;
16416 idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
16417 idxtype *mptr, *mind, *moved, *swaps, *perm;
16420 int higain, oldgain, mincut, initcut, mincutorder;
16421 int pass, to, other, limit;
16422 int badmaxpwgt, mindiff, newdiff;
16425 nvtxs = graph->
nvtxs;
16426 xadj = graph->
xadj;
16428 vwgt = graph->
vwgt;
16432 where = graph->
where;
16433 pwgts = graph->
pwgts;
16448 printf(
"Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
16450 badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
16452 for (pass=0; pass<npasses; pass++) {
16453 idxset(nvtxs, -1, moved);
16458 initcut = mincut = graph->
mincut;
16459 nbnd = graph->
nbnd;
16462 for (
ii=0;
ii<nbnd;
ii++) {
16463 i = bndind[perm[
ii]];
16465 PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
16466 PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
16477 mptr[0] = nmind = 0;
16478 mindiff = abs(pwgts[0]-pwgts[1]);
16479 to = (pwgts[0] < pwgts[1] ? 0 : 1);
16480 for (nswaps=0; nswaps<nvtxs; nswaps++) {
16483 if (u[0] != -1 && u[1] != -1) {
16484 g[0] = vwgt[u[0]]-rinfo[u[0]].
edegrees[1];
16485 g[1] = vwgt[u[1]]-rinfo[u[1]].
edegrees[0];
16487 to = (
g[0] >
g[1] ? 0 : (
g[0] <
g[1] ? 1 : pass%2));
16490 if (pwgts[to]+vwgt[u[to]] > badmaxpwgt)
16493 else if (u[0] == -1 && u[1] == -1) {
16496 else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) {
16499 else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) {
16508 if (moved[higain] == -1)
16509 PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
16511 ASSERT(bndptr[higain] != -1);
16513 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[other]);
16515 newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
16516 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
16518 mincutorder = nswaps;
16522 if (nswaps - mincutorder > limit) {
16523 pwgts[2] += (vwgt[higain]-rinfo[higain].
edegrees[other]);
16528 BNDDelete(nbnd, bndind, bndptr, higain);
16529 pwgts[to] += vwgt[higain];
16530 where[higain] = to;
16531 moved[higain] = nswaps;
16532 swaps[nswaps] = higain;
16538 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
16540 if (where[k] == 2) {
16541 oldgain = vwgt[k]-rinfo[k].
edegrees[to];
16542 rinfo[k].
edegrees[to] += vwgt[higain];
16543 if (moved[k] == -1 || moved[k] == -(2+other))
16544 PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
16546 else if (where[k] == other) {
16547 ASSERTP(bndptr[k] == -1, (
"%d %d %d\n", k, bndptr[k], where[k]));
16552 pwgts[other] -= vwgt[k];
16555 edegrees[0] = edegrees[1] = 0;
16556 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
16558 if (where[
kk] != 2)
16559 edegrees[where[
kk]] += vwgt[
kk];
16563 if (moved[
kk] == -1 || moved[
kk] == -(2+to))
16569 if (moved[k] == -1) {
16571 moved[k] = -(2+to);
16575 mptr[nswaps+1] = nmind;
16578 printf(
"Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to,
g[to],
g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
16586 for (nswaps--; nswaps>mincutorder; nswaps--) {
16587 higain = swaps[nswaps];
16591 to = where[higain];
16593 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
16595 BNDInsert(nbnd, bndind, bndptr, higain);
16597 edegrees = rinfo[higain].
edegrees;
16598 edegrees[0] = edegrees[1] = 0;
16599 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
16602 rinfo[k].
edegrees[to] -= vwgt[higain];
16604 edegrees[where[k]] += vwgt[k];
16608 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
16612 INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
16614 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
16616 if (where[
kk] == 2)
16622 ASSERT(mincut == pwgts[2]);
16625 printf(
"\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
16628 graph->
nbnd = nbnd;
16630 if (mincutorder == -1 || mincut >= initcut)
16650 int i,
ii, j, k,
jj,
kk, nvtxs, nbnd, nswaps, nmind;
16651 idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
16652 idxtype *mptr, *mind, *moved, *swaps, *perm;
16655 int higain, oldgain, mincut, initcut, mincutorder;
16656 int pass, to, other, limit;
16657 int badmaxpwgt, mindiff, newdiff;
16660 nvtxs = graph->
nvtxs;
16661 xadj = graph->
xadj;
16663 vwgt = graph->
vwgt;
16667 where = graph->
where;
16668 pwgts = graph->
pwgts;
16683 printf(
"Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
16685 badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
16687 for (pass=0; pass<npasses; pass++) {
16688 idxset(nvtxs, -1, moved);
16693 initcut = mincut = graph->
mincut;
16694 nbnd = graph->
nbnd;
16697 for (
ii=0;
ii<nbnd;
ii++) {
16698 i = bndind[perm[
ii]];
16700 PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
16701 PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
16712 mptr[0] = nmind = 0;
16713 mindiff = abs(pwgts[0]-pwgts[1]);
16714 to = (pwgts[0] < pwgts[1] ? 0 : 1);
16715 for (nswaps=0; nswaps<nvtxs; nswaps++) {
16716 badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2]/2)/2);
16720 if (u[0] != -1 && u[1] != -1) {
16721 g[0] = vwgt[u[0]]-rinfo[u[0]].
edegrees[1];
16722 g[1] = vwgt[u[1]]-rinfo[u[1]].
edegrees[0];
16724 to = (
g[0] >
g[1] ? 0 : (
g[0] <
g[1] ? 1 : pass%2));
16727 if (pwgts[to]+vwgt[u[to]] > badmaxpwgt)
16730 else if (u[0] == -1 && u[1] == -1) {
16733 else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) {
16736 else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) {
16745 if (moved[higain] == -1)
16746 PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
16748 ASSERT(bndptr[higain] != -1);
16750 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[other]);
16752 newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
16753 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
16755 mincutorder = nswaps;
16759 if (nswaps - mincutorder > limit) {
16760 pwgts[2] += (vwgt[higain]-rinfo[higain].
edegrees[other]);
16765 BNDDelete(nbnd, bndind, bndptr, higain);
16766 pwgts[to] += vwgt[higain];
16767 where[higain] = to;
16768 moved[higain] = nswaps;
16769 swaps[nswaps] = higain;
16775 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
16777 if (where[k] == 2) {
16778 oldgain = vwgt[k]-rinfo[k].
edegrees[to];
16779 rinfo[k].
edegrees[to] += vwgt[higain];
16780 if (moved[k] == -1 || moved[k] == -(2+other))
16781 PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
16783 else if (where[k] == other) {
16784 ASSERTP(bndptr[k] == -1, (
"%d %d %d\n", k, bndptr[k], where[k]));
16789 pwgts[other] -= vwgt[k];
16792 edegrees[0] = edegrees[1] = 0;
16793 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
16795 if (where[
kk] != 2)
16796 edegrees[where[
kk]] += vwgt[
kk];
16800 if (moved[
kk] == -1 || moved[
kk] == -(2+to))
16806 if (moved[k] == -1) {
16808 moved[k] = -(2+to);
16812 mptr[nswaps+1] = nmind;
16815 printf(
"Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to,
g[to],
g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
16823 for (nswaps--; nswaps>mincutorder; nswaps--) {
16824 higain = swaps[nswaps];
16828 to = where[higain];
16830 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
16832 BNDInsert(nbnd, bndind, bndptr, higain);
16834 edegrees = rinfo[higain].
edegrees;
16835 edegrees[0] = edegrees[1] = 0;
16836 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
16839 rinfo[k].
edegrees[to] -= vwgt[higain];
16841 edegrees[where[k]] += vwgt[k];
16845 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
16849 INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
16851 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
16853 if (where[
kk] == 2)
16859 ASSERT(mincut == pwgts[2]);
16862 printf(
"\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
16865 graph->
nbnd = nbnd;
16867 if (mincutorder == -1 || mincut >= initcut)
16887 int i,
ii, j, k,
jj,
kk, nvtxs, nbnd, nswaps, nmind;
16888 idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
16889 idxtype *mptr, *mind, *moved, *swaps, *perm;
16892 int higain, oldgain, mincut, initcut, mincutorder;
16893 int pass, to, other, limit;
16894 int mindiff, newdiff;
16897 nvtxs = graph->
nvtxs;
16898 xadj = graph->
xadj;
16900 vwgt = graph->
vwgt;
16904 where = graph->
where;
16905 pwgts = graph->
pwgts;
16920 printf(
"Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
16922 for (pass=0; pass<npasses; pass++) {
16923 idxset(nvtxs, -1, moved);
16928 initcut = mincut = graph->
mincut;
16929 nbnd = graph->
nbnd;
16932 for (
ii=0;
ii<nbnd;
ii++) {
16933 i = bndind[perm[
ii]];
16935 PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]);
16936 PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]);
16947 mptr[0] = nmind = 0;
16948 mindiff = abs(pwgts[0]-pwgts[1]);
16949 to = (pwgts[0] < pwgts[1] ? 0 : 1);
16950 for (nswaps=0; nswaps<nvtxs; nswaps++) {
16951 to = (pwgts[0] < pwgts[1] ? 0 : 1);
16953 if (pwgts[0] == pwgts[1]) {
16956 if (u[0] != -1 && u[1] != -1) {
16957 g[0] = vwgt[u[0]]-rinfo[u[0]].
edegrees[1];
16958 g[1] = vwgt[u[1]]-rinfo[u[1]].
edegrees[0];
16960 to = (
g[0] >
g[1] ? 0 : (
g[0] <
g[1] ? 1 : pass%2));
16968 if (moved[higain] == -1)
16969 PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]);
16971 ASSERT(bndptr[higain] != -1);
16973 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[other]);
16975 newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
16976 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
16978 mincutorder = nswaps;
16982 if (nswaps - mincutorder > limit) {
16983 pwgts[2] += (vwgt[higain]-rinfo[higain].
edegrees[other]);
16988 BNDDelete(nbnd, bndind, bndptr, higain);
16989 pwgts[to] += vwgt[higain];
16990 where[higain] = to;
16991 moved[higain] = nswaps;
16992 swaps[nswaps] = higain;
16998 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
17000 if (where[k] == 2) {
17001 oldgain = vwgt[k]-rinfo[k].
edegrees[to];
17002 rinfo[k].
edegrees[to] += vwgt[higain];
17003 if (moved[k] == -1 || moved[k] == -(2+other))
17004 PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]);
17006 else if (where[k] == other) {
17007 ASSERTP(bndptr[k] == -1, (
"%d %d %d\n", k, bndptr[k], where[k]));
17012 pwgts[other] -= vwgt[k];
17015 edegrees[0] = edegrees[1] = 0;
17016 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
17018 if (where[
kk] != 2)
17019 edegrees[where[
kk]] += vwgt[
kk];
17023 if (moved[
kk] == -1 || moved[
kk] == -(2+to))
17029 if (moved[k] == -1) {
17031 moved[k] = -(2+to);
17035 mptr[nswaps+1] = nmind;
17038 printf(
"Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to,
g[to],
g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2]));
17046 for (nswaps--; nswaps>mincutorder; nswaps--) {
17047 higain = swaps[nswaps];
17051 to = where[higain];
17053 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
17055 BNDInsert(nbnd, bndind, bndptr, higain);
17057 edegrees = rinfo[higain].
edegrees;
17058 edegrees[0] = edegrees[1] = 0;
17059 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
17062 rinfo[k].
edegrees[to] -= vwgt[higain];
17064 edegrees[where[k]] += vwgt[k];
17068 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
17072 INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
17074 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
17076 if (where[
kk] == 2)
17082 ASSERT(mincut == pwgts[2]);
17085 printf(
"\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
17088 graph->
nbnd = nbnd;
17090 if (mincutorder == -1 || mincut >= initcut)
17111 int i,
ii, j, k,
jj,
kk, nvtxs, nbnd, nswaps, nmind;
17112 idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
17113 idxtype *mptr, *mind, *swaps, *perm;
17116 int higain, oldgain, mincut, initcut, mincutorder;
17117 int pass, to, other, limit;
17118 int badmaxpwgt, mindiff, newdiff;
17120 nvtxs = graph->
nvtxs;
17121 xadj = graph->
xadj;
17123 vwgt = graph->
vwgt;
17127 where = graph->
where;
17128 pwgts = graph->
pwgts;
17139 printf(
"Partitions-N1: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
17141 badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2);
17143 to = (pwgts[0] < pwgts[1] ? 1 : 0);
17144 for (pass=0; pass<npasses; pass++) {
17151 initcut = mincut = graph->
mincut;
17152 nbnd = graph->
nbnd;
17155 for (
ii=0;
ii<nbnd;
ii++) {
17156 i = bndind[perm[
ii]];
17158 PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]);
17169 mptr[0] = nmind = 0;
17170 mindiff = abs(pwgts[0]-pwgts[1]);
17171 for (nswaps=0; nswaps<nvtxs; nswaps++) {
17176 ASSERT(bndptr[higain] != -1);
17178 if (pwgts[to]+vwgt[higain] > badmaxpwgt)
17181 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[other]);
17183 newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other]));
17184 if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) {
17186 mincutorder = nswaps;
17190 if (nswaps - mincutorder > limit) {
17191 pwgts[2] += (vwgt[higain]-rinfo[higain].
edegrees[other]);
17196 BNDDelete(nbnd, bndind, bndptr, higain);
17197 pwgts[to] += vwgt[higain];
17198 where[higain] = to;
17199 swaps[nswaps] = higain;
17205 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
17207 if (where[k] == 2) {
17208 rinfo[k].
edegrees[to] += vwgt[higain];
17210 else if (where[k] == other) {
17211 ASSERTP(bndptr[k] == -1, (
"%d %d %d\n", k, bndptr[k], where[k]));
17216 pwgts[other] -= vwgt[k];
17219 edegrees[0] = edegrees[1] = 0;
17220 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
17222 if (where[
kk] != 2)
17223 edegrees[where[
kk]] += vwgt[
kk];
17237 mptr[nswaps+1] = nmind;
17241 printf(
"Moved %6d to %3d, Gain: %5d [%5d] \t[%5d %5d %5d] [%3d %2d]\n",
17242 higain, to, (vwgt[higain]-rinfo[higain].edegrees[other]), vwgt[higain], pwgts[0], pwgts[1], pwgts[2], nswaps, limit));
17250 for (nswaps--; nswaps>mincutorder; nswaps--) {
17251 higain = swaps[nswaps];
17254 ASSERT(where[higain] == to);
17256 INC_DEC(pwgts[2], pwgts[to], vwgt[higain]);
17258 BNDInsert(nbnd, bndind, bndptr, higain);
17260 edegrees = rinfo[higain].
edegrees;
17261 edegrees[0] = edegrees[1] = 0;
17262 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
17265 rinfo[k].
edegrees[to] -= vwgt[higain];
17267 edegrees[where[k]] += vwgt[k];
17271 for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) {
17275 INC_DEC(pwgts[other], pwgts[2], vwgt[k]);
17277 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
17279 if (where[
kk] == 2)
17285 ASSERT(mincut == pwgts[2]);
17288 printf(
"\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd));
17291 graph->
nbnd = nbnd;
17293 if (pass%2 == 1 && (mincutorder == -1 || mincut >= initcut))
17312 int i,
ii, j, k,
jj,
kk, nvtxs, nbnd, nswaps;
17313 idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr;
17317 int higain, oldgain;
17320 nvtxs = graph->
nvtxs;
17321 xadj = graph->
xadj;
17323 vwgt = graph->
vwgt;
17327 where = graph->
where;
17328 pwgts = graph->
pwgts;
17331 if (abs(pwgts[0]-pwgts[1]) < (
int)((ubfactor-1.0)*(pwgts[0]+pwgts[1])))
17333 if (abs(pwgts[0]-pwgts[1]) < 3*
idxsum(nvtxs, vwgt)/nvtxs)
17336 to = (pwgts[0] < pwgts[1] ? 0 : 1);
17345 printf(
"Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d [B]\n", pwgts[0], pwgts[1], graph->
nvtxs, graph->
nbnd, graph->
mincut));
17347 nbnd = graph->
nbnd;
17349 for (
ii=0;
ii<nbnd;
ii++) {
17350 i = bndind[perm[
ii]];
17352 PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]);
17361 for (nswaps=0; nswaps<nvtxs; nswaps++) {
17367 if (pwgts[other] - rinfo[higain].edegrees[other] < (pwgts[0]+pwgts[1])/2)
17370 if (pwgts[other] - rinfo[higain].edegrees[other] < pwgts[to]+vwgt[higain])
17374 ASSERT(bndptr[higain] != -1);
17376 pwgts[2] -= (vwgt[higain]-rinfo[higain].
edegrees[other]);
17378 BNDDelete(nbnd, bndind, bndptr, higain);
17379 pwgts[to] += vwgt[higain];
17380 where[higain] = to;
17383 printf(
"Moved %6d to %3d, Gain: %3d, \t[%5d %5d %5d]\n", higain, to, vwgt[higain]-rinfo[higain].edegrees[other], pwgts[0], pwgts[1], pwgts[2]));
17389 for (j=xadj[higain]; j<xadj[higain+1]; j++) {
17391 if (where[k] == 2) {
17392 rinfo[k].
edegrees[to] += vwgt[higain];
17394 else if (where[k] == other) {
17395 ASSERTP(bndptr[k] == -1, (
"%d %d %d\n", k, bndptr[k], where[k]));
17399 pwgts[other] -= vwgt[k];
17402 edegrees[0] = edegrees[1] = 0;
17403 for (
jj=xadj[k];
jj<xadj[k+1];
jj++) {
17405 if (where[
kk] != 2)
17406 edegrees[where[
kk]] += vwgt[
kk];
17412 if (moved[
kk] == -1)
17422 if (pwgts[to] > pwgts[other])
17427 printf(
"\tBalanced sep: %6d at %4d, PWGTS: [%6d %6d], NBND: %6d\n", pwgts[2], nswaps, pwgts[0], pwgts[1], nbnd));
17429 graph->
mincut = pwgts[2];
17430 graph->
nbnd = nbnd;
17448 for (j=xadj[0]; j<xadj[1]; j++)
17449 max += vwgt[adjncy[j]];
17451 for (i=1; i<nvtxs; i++) {
17452 for (k=0, j=xadj[i]; j<xadj[i+1]; j++)
17453 k += vwgt[adjncy[j]];
17489 if (ctrl->
RType != 15)
17492 switch (ctrl->
RType) {
17513 if (graph == orggraph)
17516 graph = graph->
finer;
17533 nvtxs = graph->
nvtxs;
17535 pad64 = (3*nvtxs+3)%2;
17552 int i, j, nvtxs, nbnd;
17553 idxtype *xadj, *adjncy, *adjwgt, *vwgt;
17554 idxtype *where, *pwgts, *bndind, *bndptr, *edegrees;
17558 nvtxs = graph->
nvtxs;
17559 xadj = graph->
xadj;
17560 vwgt = graph->
vwgt;
17564 where = graph->
where;
17575 for (i=0; i<nvtxs; i++) {
17577 pwgts[me] += vwgt[i];
17579 ASSERT(me >=0 && me <= 2);
17585 edegrees[0] = edegrees[1] = 0;
17587 for (j=xadj[i]; j<xadj[i+1]; j++) {
17588 other = where[adjncy[j]];
17590 edegrees[other] += vwgt[adjncy[j]];
17597 graph->
mincut = pwgts[2];
17598 graph->
nbnd = nbnd;
17608 idxtype *cmap, *where, *cwhere;
17612 cwhere = cgraph->
where;
17614 nvtxs = graph->
nvtxs;
17615 cmap = graph->
cmap;
17618 where = graph->
where;
17621 for (i=0; i<nvtxs; i++) {
17622 where[i] = cwhere[cmap[i]];
17623 ASSERTP(where[i] >= 0 && where[i] <= 2, (
"%d %d %d %d\n", i, cmap[i], where[i], cwhere[cmap[i]]));
17653 int i, j, nvtxs, ncon, mustfree=0;
17654 idxtype *xadj, *adjncy, *vwgt, *adjwgt, *kpwgts, *tmpptr;
17655 idxtype *padjncy, *padjwgt, *padjcut;
17657 nvtxs = graph->
nvtxs;
17658 ncon = graph->
ncon;
17659 xadj = graph->
xadj;
17661 vwgt = graph->
vwgt;
17664 if (vwgt == NULL) {
17668 if (adjwgt == NULL) {
17676 kpwgts =
idxsmalloc(ncon*nparts, 0,
"ComputePartitionInfo: kpwgts");
17678 for (i=0; i<nvtxs; i++) {
17679 for (j=0; j<ncon; j++)
17680 kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j];
17684 printf(
"\tBalance: %5.3f out of %5.3f\n",
17685 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)),
17686 1.0*nparts*vwgt[
idxamax(nvtxs, vwgt)]/(1.0*
idxsum(nparts, kpwgts)));
17689 printf(
"\tBalance:");
17690 for (j=0; j<ncon; j++)
17691 printf(
" (%5.3f out of %5.3f)",
17699 padjncy =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjncy");
17700 padjwgt =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjwgt");
17701 padjcut =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjwgt");
17703 idxset(nparts, 0, kpwgts);
17704 for (i=0; i<nvtxs; i++) {
17705 for (j=xadj[i]; j<xadj[i+1]; j++) {
17706 if (where[i] != where[adjncy[j]]) {
17707 padjncy[where[i]*nparts+where[adjncy[j]]] = 1;
17708 padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j];
17709 if (kpwgts[where[adjncy[j]]] == 0) {
17710 padjwgt[where[i]*nparts+where[adjncy[j]]]++;
17711 kpwgts[where[adjncy[j]]] = 1;
17715 for (j=xadj[i]; j<xadj[i+1]; j++)
17716 kpwgts[where[adjncy[j]]] = 0;
17719 for (i=0; i<nparts; i++)
17720 kpwgts[i] =
idxsum(nparts, padjncy+i*nparts);
17721 printf(
"Min/Max/Avg/Bal # of adjacent subdomains: %5d %5d %5.2f %7.3f\n",
17722 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
17723 1.0*
idxsum(nparts, kpwgts)/(1.0*nparts),
17724 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)));
17726 for (i=0; i<nparts; i++)
17727 kpwgts[i] =
idxsum(nparts, padjcut+i*nparts);
17728 printf(
"Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n",
17729 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
idxsum(nparts, kpwgts)/nparts,
17730 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)));
17732 for (i=0; i<nparts; i++)
17733 kpwgts[i] =
idxsum(nparts, padjwgt+i*nparts);
17734 printf(
"Min/Max/Avg/Bal/Frac # of interface nodes: %5d %5d %5d %7.3f %7.3f\n",
17735 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
idxsum(nparts, kpwgts)/nparts,
17736 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)), 1.0*
idxsum(nparts, kpwgts)/(1.0*nvtxs));
17738 tmpptr = graph->
where;
17739 graph->
where = where;
17740 for (i=0; i<nparts; i++)
17742 graph->
where = tmpptr;
17744 if (mustfree == 1 || mustfree == 3) {
17746 graph->
vwgt = NULL;
17748 if (mustfree == 2 || mustfree == 3) {
17753 GKfree((
void **) &kpwgts, (
void **) &padjncy,
17754 (
void **) &padjwgt, (
void **) &padjcut,
LTERM);
17763 int i, j, nvtxs, ncon, mustfree=0;
17764 idxtype *xadj, *adjncy, *vwgt, *vsize, *adjwgt, *kpwgts;
17765 idxtype *padjncy, *padjwgt, *padjcut;
17767 nvtxs = graph->
nvtxs;
17768 ncon = graph->
ncon;
17769 xadj = graph->
xadj;
17771 vwgt = graph->
vwgt;
17772 vsize = graph->
vsize;
17775 if (vwgt == NULL) {
17779 if (adjwgt == NULL) {
17787 kpwgts =
idxsmalloc(ncon*nparts, 0,
"ComputePartitionInfo: kpwgts");
17789 for (i=0; i<nvtxs; i++) {
17790 for (j=0; j<ncon; j++)
17791 kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j];
17795 printf(
"\tBalance: %5.3f out of %5.3f\n",
17796 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)),
17797 1.0*nparts*vwgt[
idxamax(nvtxs, vwgt)]/(1.0*
idxsum(nparts, kpwgts)));
17800 printf(
"\tBalance:");
17801 for (j=0; j<ncon; j++)
17802 printf(
" (%5.3f out of %5.3f)",
17810 padjncy =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjncy");
17811 padjwgt =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjwgt");
17812 padjcut =
idxsmalloc(nparts*nparts, 0,
"ComputePartitionInfo: padjwgt");
17814 idxset(nparts, 0, kpwgts);
17815 for (i=0; i<nvtxs; i++) {
17816 for (j=xadj[i]; j<xadj[i+1]; j++) {
17817 if (where[i] != where[adjncy[j]]) {
17818 padjncy[where[i]*nparts+where[adjncy[j]]] = 1;
17819 padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j];
17820 if (kpwgts[where[adjncy[j]]] == 0) {
17821 padjwgt[where[i]*nparts+where[adjncy[j]]] += vsize[i];
17822 kpwgts[where[adjncy[j]]] = 1;
17826 for (j=xadj[i]; j<xadj[i+1]; j++)
17827 kpwgts[where[adjncy[j]]] = 0;
17830 for (i=0; i<nparts; i++)
17831 kpwgts[i] =
idxsum(nparts, padjncy+i*nparts);
17832 printf(
"Min/Max/Avg/Bal # of adjacent subdomains: %5d %5d %5d %7.3f\n",
17833 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
idxsum(nparts, kpwgts)/nparts,
17834 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)));
17836 for (i=0; i<nparts; i++)
17837 kpwgts[i] =
idxsum(nparts, padjcut+i*nparts);
17838 printf(
"Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n",
17839 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
idxsum(nparts, kpwgts)/nparts,
17840 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)));
17842 for (i=0; i<nparts; i++)
17843 kpwgts[i] =
idxsum(nparts, padjwgt+i*nparts);
17844 printf(
"Min/Max/Avg/Bal/Frac # of interface nodes: %5d %5d %5d %7.3f %7.3f\n",
17845 kpwgts[
idxamin(nparts, kpwgts)], kpwgts[
idxamax(nparts, kpwgts)],
idxsum(nparts, kpwgts)/nparts,
17846 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts)), 1.0*
idxsum(nparts, kpwgts)/(1.0*nvtxs));
17849 if (mustfree == 1 || mustfree == 3) {
17851 graph->
vwgt = NULL;
17853 if (mustfree == 2 || mustfree == 3) {
17858 GKfree((
void **) &kpwgts, (
void **) &padjncy,
17859 (
void **) &padjwgt, (
void **) &padjcut,
LTERM);
17869 int i, j, nvtxs, ncon;
17872 nvtxs = graph->
nvtxs;
17873 ncon = graph->
ncon;
17874 vwgt = graph->
vwgt;
17876 kpwgts =
idxsmalloc(nparts, 0,
"ComputePartitionInfo: kpwgts");
17878 if (vwgt == NULL) {
17879 for (i=0; i<nvtxs; i++)
17880 kpwgts[where[i]]++;
17881 ubvec[0] = 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*nvtxs);
17884 for (j=0; j<ncon; j++) {
17885 idxset(nparts, 0, kpwgts);
17886 for (i=0; i<graph->
nvtxs; i++)
17887 kpwgts[where[i]] += vwgt[i*ncon+j];
17907 kpwgts =
idxsmalloc(nparts, 0,
"ComputeElementBalance: kpwgts");
17909 for (i=0; i<ne; i++)
17910 kpwgts[where[i]]++;
17912 balance = 1.0*nparts*kpwgts[
idxamax(nparts, kpwgts)]/(1.0*
idxsum(nparts, kpwgts));
17942 int i,
ii, iii, j, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees;
17943 int from, me, to, oldcut, vwgt, gain;
17944 int maxndoms, nadd;
17945 idxtype *xadj, *adjncy, *adjwgt;
17946 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts;
17947 idxtype *phtable, *pmat, *pmatptr, *ndoms;
17951 nvtxs = graph->
nvtxs;
17952 xadj = graph->
xadj;
17959 where = graph->
where;
17960 pwgts = graph->
pwgts;
17972 tvwgt =
idxsum(nparts, pwgts);
17975 for (i=0; i<nparts; i++) {
17976 itpwgts[i] = tpwgts[i]*tvwgt;
17977 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
17978 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
17984 printf(
"Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n",
17985 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
17986 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nvtxs, graph->
nbnd,
17989 for (pass=0; pass<npasses; pass++) {
17992 maxndoms = ndoms[
idxamax(nparts, ndoms)];
17995 nbnd = graph->
nbnd;
17998 for (nmoves=iii=0; iii<graph->
nbnd; iii++) {
18004 myrinfo = graph->
rinfo+i;
18006 if (myrinfo->
ed >= myrinfo->
id) {
18008 vwgt = graph->
vwgt[i];
18010 if (myrinfo->
id > 0 && pwgts[from]-vwgt < minwgt[from])
18017 for (j=0; j<myndegrees; j++) {
18018 to = myedegrees[j].
pid;
18020 pmatptr = pmat + to*nparts;
18021 for (nadd=0, k=0; k<myndegrees; k++) {
18025 l = myedegrees[k].
pid;
18026 if (pmatptr[l] == 0) {
18027 if (ndoms[l] > maxndoms-1) {
18035 if (ndoms[to]+nadd > maxndoms)
18043 for (k=0; k<myndegrees; k++) {
18044 to = myedegrees[k].
pid;
18047 gain = myedegrees[k].
ed-j;
18048 if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0)
18051 if (k == myndegrees)
18054 for (j=k+1; j<myndegrees; j++) {
18055 to = myedegrees[j].
pid;
18058 if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) ||
18059 (myedegrees[j].ed == myedegrees[k].ed &&
18060 itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]))
18064 to = myedegrees[k].
pid;
18067 if (myedegrees[k].ed-myrinfo->
id > 0)
18069 else if (myedegrees[k].ed-myrinfo->
id == 0) {
18070 if ( phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from])
18079 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
18084 pmat[from*nparts+to] += (myrinfo->
id-myedegrees[k].
ed);
18085 pmat[to*nparts+from] += (myrinfo->
id-myedegrees[k].
ed);
18086 if (pmat[from*nparts+to] == 0) {
18088 if (ndoms[from]+1 == maxndoms)
18089 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18091 if (pmat[to*nparts+from] == 0) {
18093 if (ndoms[to]+1 == maxndoms)
18094 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18099 INC_DEC(pwgts[to], pwgts[from], vwgt);
18100 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
18101 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
18102 if (myedegrees[k].ed == 0)
18103 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18105 myedegrees[k].
pid = from;
18107 if (myrinfo->
ed-myrinfo->
id < 0)
18111 for (j=xadj[i]; j<xadj[i+1]; j++) {
18127 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
18130 else if (me == to) {
18133 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
18139 for (k=0; k<myrinfo->
ndegrees; k++) {
18140 if (myedegrees[k].pid == from) {
18141 if (myedegrees[k].ed == adjwgt[j])
18142 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18144 myedegrees[k].
ed -= adjwgt[j];
18152 for (k=0; k<myrinfo->
ndegrees; k++) {
18153 if (myedegrees[k].pid == to) {
18154 myedegrees[k].
ed += adjwgt[j];
18160 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
18165 if (me != from && me != to) {
18166 pmat[me*nparts+from] -= adjwgt[j];
18167 pmat[from*nparts+me] -= adjwgt[j];
18168 if (pmat[me*nparts+from] == 0) {
18170 if (ndoms[me]+1 == maxndoms)
18171 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18173 if (pmat[from*nparts+me] == 0) {
18175 if (ndoms[from]+1 == maxndoms)
18176 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18179 if (pmat[me*nparts+to] == 0) {
18181 if (ndoms[me] > maxndoms) {
18182 printf(
"You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
18183 maxndoms = ndoms[me];
18186 if (pmat[to*nparts+me] == 0) {
18188 if (ndoms[to] > maxndoms) {
18189 printf(
"You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
18190 maxndoms = ndoms[to];
18193 pmat[me*nparts+to] += adjwgt[j];
18194 pmat[to*nparts+me] += adjwgt[j];
18205 graph->
nbnd = nbnd;
18208 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %5d, Vol: %5d, %d\n",
18210 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nbnd, nmoves,
18213 if (graph->
mincut == oldcut)
18232 int i,
ii, j, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves;
18233 int from, me, to, oldcut, vwgt, maxndoms, nadd;
18234 idxtype *xadj, *adjncy, *adjwgt;
18235 idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts;
18236 idxtype *phtable, *pmat, *pmatptr, *ndoms;
18241 nvtxs = graph->
nvtxs;
18242 xadj = graph->
xadj;
18249 where = graph->
where;
18250 pwgts = graph->
pwgts;
18263 tvwgt =
idxsum(nparts, pwgts);
18266 for (i=0; i<nparts; i++) {
18267 itpwgts[i] = tpwgts[i]*tvwgt;
18268 maxwgt[i] = tpwgts[i]*tvwgt*ubfactor;
18269 minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor);
18278 printf(
"Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n",
18279 pwgts[
idxamin(nparts, pwgts)], pwgts[
idxamax(nparts, pwgts)], minwgt[0], maxwgt[0],
18280 1.0*nparts*pwgts[
idxamax(nparts, pwgts)]/tvwgt, graph->
nvtxs, graph->
nbnd,
18283 for (pass=0; pass<npasses; pass++) {
18287 for (i=0; i<nparts; i++) {
18288 if (pwgts[i] > maxwgt[i])
18295 idxset(nvtxs, -1, moved);
18298 nbnd = graph->
nbnd;
18301 for (
ii=0;
ii<nbnd;
ii++) {
18302 i = bndind[perm[
ii]];
18307 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18314 myrinfo = graph->
rinfo+i;
18316 vwgt = graph->
vwgt[i];
18318 if (pwgts[from]-vwgt < minwgt[from])
18325 for (j=0; j<myndegrees; j++) {
18326 to = myedegrees[j].
pid;
18328 pmatptr = pmat + to*nparts;
18329 for (nadd=0, k=0; k<myndegrees; k++) {
18333 l = myedegrees[k].
pid;
18334 if (pmatptr[l] == 0) {
18335 if (ndoms[l] > maxndoms-1) {
18343 if (ndoms[to]+nadd > maxndoms)
18347 for (k=0; k<myndegrees; k++) {
18348 to = myedegrees[k].
pid;
18351 if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from])
18354 if (k == myndegrees)
18357 for (j=k+1; j<myndegrees; j++) {
18358 to = myedegrees[j].
pid;
18361 if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])
18365 to = myedegrees[k].
pid;
18367 if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->
id < 0)
18373 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
18378 pmat[from*nparts+to] += (myrinfo->
id-myedegrees[k].
ed);
18379 pmat[to*nparts+from] += (myrinfo->
id-myedegrees[k].
ed);
18380 if (pmat[from*nparts+to] == 0) {
18382 if (ndoms[from]+1 == maxndoms)
18383 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18385 if (pmat[to*nparts+from] == 0) {
18387 if (ndoms[to]+1 == maxndoms)
18388 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18394 INC_DEC(pwgts[to], pwgts[from], vwgt);
18395 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
18396 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
18397 if (myedegrees[k].ed == 0)
18398 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18400 myedegrees[k].
pid = from;
18402 if (myrinfo->
ed == 0)
18406 for (j=xadj[i]; j<xadj[i+1]; j++) {
18419 oldgain = (myrinfo->
ed-myrinfo->
id);
18424 if (myrinfo->
ed > 0 && bndptr[
ii] == -1)
18427 else if (me == to) {
18430 if (myrinfo->
ed == 0 && bndptr[
ii] != -1)
18436 for (k=0; k<myrinfo->
ndegrees; k++) {
18437 if (myedegrees[k].pid == from) {
18438 if (myedegrees[k].ed == adjwgt[j])
18439 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18441 myedegrees[k].
ed -= adjwgt[j];
18449 for (k=0; k<myrinfo->
ndegrees; k++) {
18450 if (myedegrees[k].pid == to) {
18451 myedegrees[k].
ed += adjwgt[j];
18457 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
18462 if (me != from && me != to) {
18463 pmat[me*nparts+from] -= adjwgt[j];
18464 pmat[from*nparts+me] -= adjwgt[j];
18465 if (pmat[me*nparts+from] == 0) {
18467 if (ndoms[me]+1 == maxndoms)
18468 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18470 if (pmat[from*nparts+me] == 0) {
18472 if (ndoms[from]+1 == maxndoms)
18473 maxndoms = ndoms[
idxamax(nparts, ndoms)];
18476 if (pmat[me*nparts+to] == 0) {
18478 if (ndoms[me] > maxndoms) {
18479 printf(
"You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);
18480 maxndoms = ndoms[me];
18483 if (pmat[to*nparts+me] == 0) {
18485 if (ndoms[to] > maxndoms) {
18486 printf(
"You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);
18487 maxndoms = ndoms[to];
18490 pmat[me*nparts+to] += adjwgt[j];
18491 pmat[to*nparts+me] += adjwgt[j];
18495 if (me == to || me == from) {
18496 gain = myrinfo->
ed-myrinfo->
id;
18497 if (moved[
ii] == 2) {
18498 if (myrinfo->
ed > 0)
18505 else if (moved[
ii] == -1 && myrinfo->
ed > 0) {
18517 graph->
nbnd = nbnd;
18520 printf(
"\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, %d\n",
18545 int i, j, k, me, nvtxs, total, max;
18546 idxtype *xadj, *adjncy, *adjwgt, *pmat;
18548 nvtxs = graph->
nvtxs;
18549 xadj = graph->
xadj;
18553 pmat =
idxsmalloc(nparts*nparts, 0,
"ComputeSubDomainGraph: pmat");
18555 for (i=0; i<nvtxs; i++) {
18557 for (j=xadj[i]; j<xadj[i+1]; j++) {
18559 if (where[k] != me)
18560 pmat[me*nparts+where[k]] += adjwgt[j];
18566 for (i=0; i<nparts; i++) {
18567 for (k=0, j=0; j<nparts; j++) {
18568 if (pmat[i*nparts+j] > 0)
18584 printf(
"Total adjacent subdomains: %d, Max: %d\n", total, max);
18596 int i, j, k, me, nvtxs, ndegrees;
18597 idxtype *xadj, *adjncy, *adjwgt, *where;
18601 nvtxs = graph->
nvtxs;
18602 xadj = graph->
xadj;
18605 where = graph->
where;
18606 rinfo = graph->
rinfo;
18608 idxset(nparts*nparts, 0, pmat);
18610 for (i=0; i<nvtxs; i++) {
18611 if (rinfo[i].ed > 0) {
18617 for (j=0; j<ndegrees; j++)
18618 pmat[k+edegrees[j].pid] += edegrees[j].ed;
18622 for (i=0; i<nparts; i++) {
18624 for (j=0; j<nparts; j++) {
18625 if (pmat[i*nparts+j] > 0)
18641 int i,
ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd;
18642 int min, move, cpwgt, tvwgt;
18643 idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind;
18646 nvtxs = graph->
nvtxs;
18647 xadj = graph->
xadj;
18649 vwgt = graph->
vwgt;
18652 where = graph->
where;
18653 pwgts = graph->
pwgts;
18669 tvwgt =
idxsum(nparts, pwgts);
18670 for (i=0; i<nparts; i++)
18671 maxpwgt[i] = 1.25*tpwgts[i]*tvwgt;
18676 total =
idxsum(nparts, ndoms);
18677 avg = total/nparts;
18678 max = ndoms[
idxamax(nparts, ndoms)];
18686 mypmat = pmat + me*nparts;
18687 totalout =
idxsum(nparts, mypmat);
18692 for (ncand2=0, i=0; i<nparts; i++) {
18693 if (mypmat[i] > 0) {
18694 cand2[ncand2].
key = mypmat[i];
18695 cand2[ncand2++].
val = i;
18701 for (min=0; min<ncand2; min++) {
18702 if (cand2[min].key > totalout/(2*ndoms[me]))
18705 other = cand2[min].
val;
18709 idxset(nparts, 0, otherpmat);
18712 for (nind=0, i=0; i<nvtxs; i++) {
18713 if (where[i] == other) {
18714 for (j=xadj[i]; j<xadj[i+1]; j++) {
18715 if (where[adjncy[j]] == me) {
18724 for (cpwgt=0,
ii=0;
ii<nind;
ii++) {
18728 for (j=xadj[i]; j<xadj[i+1]; j++)
18729 otherpmat[where[adjncy[j]]] += adjwgt[j];
18731 otherpmat[other] = 0;
18733 for (ncand=0, i=0; i<nparts; i++) {
18734 if (otherpmat[i] > 0) {
18735 cand[ncand].
key = -otherpmat[i];
18736 cand[ncand++].
val = i;
18746 target = target2 = -1;
18747 for (i=0; i<ncand; i++) {
18750 if (mypmat[k] > 0) {
18751 if (pwgts[k] + cpwgt > maxpwgt[k])
18754 for (j=0; j<nparts; j++) {
18755 if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0)
18759 for (nadd=0, j=0; j<nparts; j++) {
18760 if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0)
18765 if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) {
18775 if (target == -1 && target2 != -1)
18778 if (target == -1) {
18786 INC_DEC(pwgts[target], pwgts[other], cpwgt);
18788 MoveGroupMConn(ctrl, graph, ndoms, pmat, nparts, target, nind, ind);
18803 GKfree((
void **) &cand, (
void **) &cand2,
LTERM);
18811 int nparts,
int to,
int nind,
idxtype *ind)
18813 int i,
ii, iii, j, k, nvtxs, nbnd;
18815 idxtype *xadj, *adjncy, *adjwgt;
18816 idxtype *where, *bndptr, *bndind;
18820 nvtxs = graph->
nvtxs;
18821 xadj = graph->
xadj;
18825 where = graph->
where;
18829 nbnd = graph->
nbnd;
18831 for (iii=0; iii<nind; iii++) {
18835 myrinfo = graph->
rinfo+i;
18844 for (k=0; k<myrinfo->
ndegrees; k++) {
18845 if (myedegrees[k].pid == to)
18849 myedegrees[k].
pid = to;
18850 myedegrees[k].
ed = 0;
18854 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
18857 pmat[from*nparts+to] += (myrinfo->
id-myedegrees[k].
ed);
18858 pmat[to*nparts+from] += (myrinfo->
id-myedegrees[k].
ed);
18859 if (pmat[from*nparts+to] == 0)
18861 if (pmat[to*nparts+from] == 0)
18866 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
18867 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
18868 if (myedegrees[k].ed == 0)
18869 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18871 myedegrees[k].
pid = from;
18873 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[i] != -1)
18877 for (j=xadj[i]; j<xadj[i+1]; j++) {
18893 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
18896 else if (me == to) {
18899 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
18905 for (k=0; k<myrinfo->
ndegrees; k++) {
18906 if (myedegrees[k].pid == from) {
18907 if (myedegrees[k].ed == adjwgt[j])
18908 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
18910 myedegrees[k].
ed -= adjwgt[j];
18918 for (k=0; k<myrinfo->
ndegrees; k++) {
18919 if (myedegrees[k].pid == to) {
18920 myedegrees[k].
ed += adjwgt[j];
18926 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
18931 if (me != from && me != to) {
18932 pmat[me*nparts+from] -= adjwgt[j];
18933 pmat[from*nparts+me] -= adjwgt[j];
18934 if (pmat[me*nparts+from] == 0)
18936 if (pmat[from*nparts+me] == 0)
18939 if (pmat[me*nparts+to] == 0)
18941 if (pmat[to*nparts+me] == 0)
18944 pmat[me*nparts+to] += adjwgt[j];
18945 pmat[to*nparts+me] += adjwgt[j];
18954 graph->
nbnd = nbnd;
18968 int i,
ii, j,
jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, target, deltawgt;
18969 idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt;
18970 idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps;
18972 nvtxs = graph->
nvtxs;
18973 xadj = graph->
xadj;
18975 vwgt = graph->
vwgt;
18978 where = graph->
where;
18979 pwgts = graph->
pwgts;
18990 for (i=0; i<nvtxs; i++)
18991 perm[i] = todo[i] = i;
18997 while (nleft > 0) {
18998 if (first == last) {
18999 cptr[++ncmps] = first;
19000 ASSERT(touched[todo[0]] == 0);
19010 j = todo[k] = todo[--nleft];
19013 for (j=xadj[i]; j<xadj[i+1]; j++) {
19015 if (where[k] == me && !touched[k]) {
19021 cptr[++ncmps] = first;
19025 if (ncmps > nparts) {
19027 tvwgt =
idxsum(nparts, pwgts);
19028 for (i=0; i<nparts; i++)
19029 maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt;
19033 for (i=0; i<ncmps; i++) {
19034 me = where[cind[cptr[i]]];
19035 if (npcmps[me] == 1)
19041 for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++)
19042 cwgt += vwgt[cind[j]];
19044 if (cwgt > .30*pwgts[me])
19048 idxset(nparts, 0, cpvec);
19049 for (j=cptr[i]; j<cptr[i+1]; j++) {
19052 cpvec[where[adjncy[
jj]]] += adjwgt[
jj];
19057 for (j=0; j<nparts; j++) {
19058 if (cpvec[j] > 0 && (cwgt < deltawgt || pwgts[j] + cwgt < maxpwgt[j])) {
19059 if (target == -1 || cpvec[target] < cpvec[j])
19066 if (target != -1) {
19068 INC_DEC(pwgts[target], pwgts[me], cwgt);
19071 MoveGroup(ctrl, graph, nparts, target, i, cptr, cind);
19094 int i,
ii, iii, j, k, nvtxs, nbnd;
19096 idxtype *xadj, *adjncy, *adjwgt;
19097 idxtype *where, *bndptr, *bndind;
19101 nvtxs = graph->
nvtxs;
19102 xadj = graph->
xadj;
19106 where = graph->
where;
19110 nbnd = graph->
nbnd;
19112 for (iii=ptr[gid]; iii<ptr[gid+1]; iii++) {
19116 myrinfo = graph->
rinfo+i;
19125 for (k=0; k<myrinfo->
ndegrees; k++) {
19126 if (myedegrees[k].pid == to)
19130 myedegrees[k].
pid = to;
19131 myedegrees[k].
ed = 0;
19135 graph->
mincut -= myedegrees[k].
ed-myrinfo->
id;
19140 myrinfo->
ed += myrinfo->
id-myedegrees[k].
ed;
19141 SWAP(myrinfo->
id, myedegrees[k].
ed, j);
19142 if (myedegrees[k].ed == 0)
19143 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
19145 myedegrees[k].
pid = from;
19147 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[i] != -1)
19151 for (j=xadj[i]; j<xadj[i+1]; j++) {
19167 if (myrinfo->
ed-myrinfo->
id >= 0 && bndptr[
ii] == -1)
19170 else if (me == to) {
19173 if (myrinfo->
ed-myrinfo->
id < 0 && bndptr[
ii] != -1)
19179 for (k=0; k<myrinfo->
ndegrees; k++) {
19180 if (myedegrees[k].pid == from) {
19181 if (myedegrees[k].ed == adjwgt[j])
19182 myedegrees[k] = myedegrees[--myrinfo->
ndegrees];
19184 myedegrees[k].
ed -= adjwgt[j];
19192 for (k=0; k<myrinfo->
ndegrees; k++) {
19193 if (myedegrees[k].pid == to) {
19194 myedegrees[k].
ed += adjwgt[j];
19200 myedegrees[myrinfo->
ndegrees++].
ed = adjwgt[j];
19210 graph->
nbnd = nbnd;
19261 printf(
"\nTiming Information -------------------------------------------------");
19267 printf(
"\n Construct Separator: \t %7.3f",
gettimer(ctrl->
SepTmr));
19275 printf(
"\n********************************************************************\n");
19284 return((
double) clock()/CLOCKS_PER_SEC);
19310 char out1[256], out2[256];
19312 va_start(argp, f_str);
19313 vsprintf(out1, f_str, argp);
19316 sprintf(out2,
"Error! %s", out1);
19318 fprintf(
stdout,
"%s", out2);
19335 return (
int *)
GKmalloc(
sizeof(
int)*n, msg);
19359 return (
float *)
GKmalloc(
sizeof(
float)*n, msg);
19371 return iset(n, ival, (
int *)
GKmalloc(
sizeof(
int)*n, msg));
19398 ptr = (
void *)malloc(nbytes);
19400 errexit(
"***Memory allocation failed for %s. Requested size: %d bytes", msg, nbytes);
19418 va_start(plist, ptr1);
19421 while ((ptr = va_arg(plist,
void **)) !=
LTERM) {
19438 for (i=0; i<n; i++)
19452 for (i=0; i<n; i++)
19466 for (i=0; i<n; i++)
19481 for (i=1; i<n; i++)
19482 max = (
x[i] >
x[max] ? i : max);
19495 for (i=1; i<n; i++)
19496 max = (
x[i] >
x[max] ? i : max);
19509 for (i=incx; i<n; i+=incx)
19510 max = (
x[i] >
x[max] ? i : max);
19524 for (i=1; i<n; i++)
19525 max = (
x[i] >
x[max] ? i : max);
19546 for (i=2; i<n; i++) {
19547 if (
x[i] >
x[max1]) {
19551 else if (
x[i] >
x[max2])
19566 for (i=1; i<n; i++)
19567 min = (
x[i] <
x[min] ? i : min);
19580 for (i=1; i<n; i++)
19581 min = (
x[i] <
x[min] ? i : min);
19594 for (i=0; i<n; i++)
19608 for (i=0; i<n; i++,
x+=incx) {
19621 for (n--; n>=0; n--)
19633 for (i=0; i<n; i++)
19646 for (i=0; i<n; i++)
19660 for (i=0; i<n; i++)
19674 for (i=0; i<n; i++,
x+=incx)
19687 for (i=0; i<n; i++)
19700 for (i = 0; i<n; i++)
19701 partial += v[i] * v[i];
19703 return sqrt(partial);
19716 for (i = 0; i<n; i++)
19717 partial +=
x[i] * y[i];
19730 for (i=0; i<n; i++,
x+=incx, y+=incy)
19748 for (i=0; i<n; i++)
19755 for (i=0; i<n; i+=16) {
19772 for (; a%2 != 1; a = a>>1);
19773 return (a > 1 ? 0 : 1);
19803 for (i=1; a > 1; i++, a = a>>1);
#define RTYPE_KWAYRANDOM_MCONN
#define MATCH_SBHEM_INFNORM
#define MATCH_SHEBM_ONENORM
#define ORDER_UNBALANCE_FRACTION
#define COARSEN_FRACTION2
#define MATCH_SHEBM_INFNORM
#define MATCH_SBHEM_ONENORM
#define COMPRESSION_FRACTION
#define MALLOC_CHECK(ptr)
#define INC_DEC(a, b, val)
#define BNDInsert(nbnd, bndind, bndptr, vtx)
#define ASSERTP(expr, msg)
#define BNDDelete(nbnd, bndind, bndptr, vtx)
#define RandomInRangeFast(u)
#define IFSET(a, flag, cmd)
void METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void MlevelNestedDissection(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx)
void Balance2Way(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void SetUpSplitGraph(GraphType *graph, GraphType *sgraph, int snvtxs, int snedges)
void iintsort(int n, int *base)
int MocIsHBalanced(int ncon, int nparts, float *npwgts, float *ubvec)
void METIS_WPartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void SelectQueue2(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, PQueueType queues[MAXNCON][2], float *maxwgt)
int idxamax(int n, idxtype *x)
void Change2CNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy)
void METIS_PARTMESHDUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void METIS_PARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
int MCMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float ubfactor, int fpart)
int mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker)
GraphType * Coarsen2Way(CtrlType *ctrl, GraphType *graph)
void MocInit2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts)
int PQueueInsert(PQueueType *queue, int node, int gain)
void InitTimers(CtrlType *ctrl)
void SplitGraphPart(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph)
void metis_meshtodual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
int PQueueGetMax(PQueueType *queue)
void genmmd(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *invp, idxtype *perm, int delta, idxtype *head, idxtype *qsize, idxtype *list, idxtype *marker, int maxint, int *ncsub)
int AreAllHVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit)
void InitGraph(GraphType *graph)
int CheckNodePartitionParams(GraphType *graph)
void PQueueReset(PQueueType *queue)
void METIS_NodeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *options, int *sepsize, idxtype *part)
void metis_nodewnd_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts)
void metis_meshtodual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void metis_wpartgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
void MinCover(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *cover, int *csize)
void metis_partgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void GrowBisectionNode(CtrlType *ctrl, GraphType *graph, float ubfactor)
int AreAnyVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx)
void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag)
void EliminateVolComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
int WspaceAvail(CtrlType *ctrl)
void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *ubvec)
void metis_wpartgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void RandomPermute(int n, idxtype *p, int flag)
void MocInit2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
int AreAllHVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit)
void METIS_NODEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void metis_edgend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
int AreAllVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
void METIS_PARTMESHNODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void Allocate2WayNodePartitionMemory(CtrlType *ctrl, GraphType *graph)
void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void metis_meshtodual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
int idxamin(int n, idxtype *x)
void METIS_mCPartGraphKway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
void MlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void METIS_WPARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void HEXNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
void metis_estimatememory_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
void iidxsort(int n, idxtype *base)
void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
int * ismalloc(int n, int ival, char *msg)
GraphType * CreateGraph(void)
void ChangeMesh2FNumbering(int n, idxtype *mesh, int nvtxs, idxtype *xadj, idxtype *adjncy)
void ikeyvalsort(int n, KeyValueType *base)
void FM_2WayNodeRefine_OneSided(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
void METIS_EDGEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
int IsHBalanceBetterTT(int ncon, int nparts, float *pt1, float *pt2, float *vwgt, float *ubvec)
int IsHBalanceBetterFT(int ncon, int nparts, float *pfrom, float *pto, float *vwgt, float *ubvec)
void mmdelm(int mdeg_node, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint, int tag)
int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff)
int CheckBnd2(GraphType *graph)
void ComputeKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
void Random_KWayVolRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
void AllocateVolKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
void MCHMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
void metis_partgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
void metis_partgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize)
void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor)
void metis_edgend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
void Change2FNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vector)
void MocInit2WayPartition(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
void fwspacefree(CtrlType *ctrl, int n)
GraphType * SetUpCoarseGraph(GraphType *graph, int cnvtxs, int dovsize)
void Greedy_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
void sscale(int n, float alpha, float *x)
void FreeWorkSpace(CtrlType *ctrl, GraphType *graph)
void MCMatch_RM(CtrlType *ctrl, GraphType *graph)
void metis_nodend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void MlevelNodeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void metis_nodend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void MinCover_Decompose(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *mate, idxtype *cover, int *csize)
void TRINODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
void metis_estimatememory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
void MoveGroupMConn(CtrlType *ctrl, GraphType *graph, idxtype *ndoms, idxtype *pmat, int nparts, int to, int nind, idxtype *ind)
int MCHMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *ubvec, int fpart)
void Match_RM(CtrlType *ctrl, GraphType *graph)
void Random_KWayVolRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
void EliminateVolSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts)
void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, float *orgubvec, int npasses)
void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
void MCMatch_HEM(CtrlType *ctrl, GraphType *graph)
void TETNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
int IsConnected2(GraphType *graph, int report)
void Greedy_KWayVolBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
int SelectQueueOneWay2(int ncon, float *pto, PQueueType queues[MAXNCON][2], float *ubvec)
int ComputeCoarseGraphSize(int nvtxs, idxtype *xadj, idxtype *adjncy, int cnvtxs, idxtype *cmap, idxtype *match, idxtype *perm)
void MocBalance2Way(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor)
void METIS_MESHTONODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void metis_nodewnd__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
int PQueueSeeMax(PQueueType *queue)
void metis_partmeshdual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
int ComputeCut(GraphType *graph, idxtype *where)
void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, idxtype *adjncy, float *nvwgt, idxtype *adjwgt)
void METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void metis_wpartgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
void MCMatch_SHEM(CtrlType *ctrl, GraphType *graph)
void metis_mcpartgraphrecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void idxadd(int n, idxtype *x, idxtype *y)
void METIS_MESHTODUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void METIS_PARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void errexit(char *f_str,...)
int PQueueUpdate(PQueueType *queue, int node, int oldgain, int newgain)
void PQueueUpdateUp(PQueueType *queue, int node, int oldgain, int newgain)
void METIS_MCPARTGRAPHRECURSIVE(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void RandomBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
int samax(int n, float *x)
void Greedy_KWayEdgeBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
void ConstructSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor)
void CheckVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
void METIS_mCHPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *ubvec, int *options, int *edgecut, idxtype *part)
int ComputeMaxNodeGain(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt)
void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void AllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
void METIS_PARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
void METIS_mCPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void PQueueFree(CtrlType *ctrl, PQueueType *queue)
void MocInit2WayPartition2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
void Match_SHEM(CtrlType *ctrl, GraphType *graph)
void PrintSubDomainGraph(GraphType *graph, int nparts, idxtype *where)
void METIS_NodeNDP(int nvtxs, idxtype *xadj, idxtype *adjncy, int npes, int *options, idxtype *perm, idxtype *iperm, idxtype *sizes)
void Allocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
int SelectQueueOneWay(int ncon, float *npwgts, float *tpwgts, int from, PQueueType queues[MAXNCON][2])
int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind)
void MinCover_RowDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
void Greedy_KWayVolBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
void PQueueInit(CtrlType *ctrl, PQueueType *queue, int maxnodes, int maxgain)
void METIS_WPARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
float sdot(int n, float *x, float *y)
void FM_2WayNodeRefine(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
int MlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor)
void metis_wpartgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph)
void MlevelNodeBisectionMultiple(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void METIS_MeshToDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void ComputeVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
void metis_nodend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void metis_partgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
idxtype * idxmalloc(int n, char *msg)
void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm)
void metis_meshtonodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void QUADNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
void ComputeSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms)
void GENDUALMETIS(int nelmnts, int nvtxs, int etype, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy)
void metis_partgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
int CheckBnd(GraphType *graph)
void metis_partgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void ComputeVolKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
void METIS_ESTIMATEMEMORY(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
void metis_mcpartgraphkway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
void metis_partmeshnodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void Greedy_KWayEdgeBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses)
int IsSeparable(GraphType *graph)
int idxsum_strd(int n, idxtype *x, int incx)
void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag)
void metis_nodewnd(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void metis_mcpartgraphkway__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
int idxamax_strd(int n, idxtype *x, int incx)
void SelectQueue3(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, PQueueType queues[MAXNCON][2], float *maxwgt)
int PQueueGetSize(PQueueType *queue)
void METIS_WPartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
void METIS_PartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
int idxsum(int n, idxtype *x)
void EliminateComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
int * iset(int n, int val, int *x)
void MocGeneral2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor)
void GKfree(void **ptr1,...)
void METIS_NodeWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
float ComputeElementBalance(int ne, int nparts, idxtype *where)
idxtype * idxset(int n, idxtype val, idxtype *x)
void MCMatch_SHEBM(CtrlType *ctrl, GraphType *graph, int norm)
void MocGrowBisectionNew2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
void MinCover_ColDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag)
GraphType * MCCoarsen2Way(CtrlType *ctrl, GraphType *graph)
int charsum(int n, char *x)
void Random_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
void Init2WayPartition(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void MlevelNestedDissectionP(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx, int npes, int cpos, idxtype *sizes)
void FM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, int *tpwgts, int npasses)
void ChangeMesh2CNumbering(int n, idxtype *mesh)
int CheckRInfo(RInfoType *rinfo)
void RandomizeGraph(GraphType *graph)
void Change2FNumbering2(int nvtxs, idxtype *xadj, idxtype *adjncy)
void SelectQueue(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, PQueueType queues[MAXNCON][2])
void metis_wpartgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void METIS_PartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
int samax2(int n, float *x)
float ComputeLoadImbalance(int ncon, int nparts, float *npwgts, float *tpwgts)
void METIS_MeshToNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void metis_wpartgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
float BetterVBalance(int ncon, int norm, float *vwgt, float *u1wgt, float *u2wgt)
void METIS_EdgeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *options, int *sepsize, idxtype *part)
int PQueueDelete(PQueueType *queue, int node, int gain)
void ComputePartitionInfo(GraphType *graph, int nparts, idxtype *where)
void ComputeVolKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
void METIS_mCHPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, float *nvwgt, idxtype *adjwgt, int *nparts, float *ubvec, int *options, int *edgecut, idxtype *part)
void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, float *ubvec, int npasses)
int SplitGraphOrderCC(CtrlType *ctrl, GraphType *graph, GraphType *sgraphs, int ncmps, idxtype *cptr, idxtype *cind)
float Compute2WayHLoadImbalance(int ncon, float *npwgts, float *tpwgts)
void ComputeHKWayLoadImbalance(int ncon, int nparts, float *npwgts, float *lbvec)
void MocBalance2Way2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
int IsConnectedSubdomain(CtrlType *ctrl, GraphType *graph, int pid, int report)
void ComputeKWayVolGains(CtrlType *ctrl, GraphType *graph, int nparts)
void FM_2WayNodeRefine2(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses)
void ConstructMinCoverSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor)
float * sset(int n, float val, float *x)
idxtype * idxwspacemalloc(CtrlType *ctrl, int n)
int MinCover_Augment(idxtype *xadj, idxtype *adjncy, int col, idxtype *mate, idxtype *flag, idxtype *level, int maxlevel)
void metis_partmeshnodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void RefineVolKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
void CompressGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *cptr, idxtype *cind)
void METIS_WPartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void Project2WayPartition(CtrlType *ctrl, GraphType *graph)
int samin(int n, float *x)
void metis_mcpartgraphkway_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
void METIS_NODEWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void KWayVolUpdate(CtrlType *ctrl, GraphType *graph, int v, int from, int to, idxtype *marker, idxtype *phtable, idxtype *updind)
void * GKmalloc(int nbytes, char *msg)
void Match_RM_NVW(CtrlType *ctrl, GraphType *graph)
void metis_partmeshnodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void General2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts)
void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy)
int MlevelVolKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor)
void PrintTimers(CtrlType *ctrl)
int AreAllVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit)
float ssum_strd(int n, float *x, int incx)
void InitRandom(int seed)
void METIS_EstimateMemory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
float * fwspacemalloc(CtrlType *ctrl, int n)
void METIS_MCPARTGRAPHKWAY(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
int IsBetter2wayBalance(int ncon, float *newbal, float *oldbal, float *ubvec)
void Compute2WayPartitionParams(CtrlType *ctrl, GraphType *graph)
int CheckHeap(PQueueType *queue)
void METIS_EdgeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void MocFM_2WayEdgeRefine2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *orgubvec, int npasses)
void metis_mcpartgraphrecursive_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void METIS_WPARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
void FM_2WayNodeBalance(CtrlType *ctrl, GraphType *graph, float ubfactor)
void MocGeneral2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
void metis_meshtonodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
void MCMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
void Compute2WayHLoadImbalanceVec(int ncon, float *npwgts, float *tpwgts, float *lbvec)
void ComputeKWayVolume(GraphType *graph, int nupd, idxtype *updind, idxtype *marker, idxtype *phtable)
void metis_estimatememory__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes)
void METIS_WPartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void PruneGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *iperm, float factor)
idxtype * idxsmalloc(int n, idxtype ival, char *msg)
int MCMlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *rubvec)
void ikeysort(int n, KeyValueType *base)
float * fmalloc(int n, char *msg)
int ComputeVolume(GraphType *graph, idxtype *where)
void ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec)
void Compute2WayNodePartitionParams(CtrlType *ctrl, GraphType *graph)
void SplitGraphOrder(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph)
void idxwspacefree(CtrlType *ctrl, int n)
int IsConnected(CtrlType *ctrl, GraphType *graph, int report)
void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm)
float snorm2(int n, float *v)
int MlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor, int fpart)
void FreeGraph(GraphType *graph)
void EliminateSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts)
void MMDOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx)
void Project2WayNodePartition(CtrlType *ctrl, GraphType *graph)
void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph)
void RefineKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
void metis_partgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void BucketSortKeysInc(int n, int max, idxtype *keys, idxtype *tperm, idxtype *perm)
void Random_KWayEdgeRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor)
void metis_edgend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm)
void Bnd2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts)
void MocRefine2Way2(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float *ubvec)
void METIS_mCPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, float *nvwgt, idxtype *adjwgt, int *nparts, int *options, int *edgecut, idxtype *part)
void ProjectVolKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
void MoveGroup(CtrlType *ctrl, GraphType *graph, int nparts, int to, int gid, idxtype *ptr, idxtype *ind)
void ComputeVolSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms)
void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts)
void metis_partmeshdual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
float ssum(int n, float *x)
void metis_wpartgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
int * imalloc(int n, char *msg)
void metis_partmeshdual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void ProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts)
void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses)
void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, float ubfactor)
void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg, idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint, int *tag)
void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
void InitSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor)
void MocGrowBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
void GrowBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor)
void ChangeMesh2FNumbering2(int n, idxtype *mesh, int ne, int nn, idxtype *epart, idxtype *npart)
void Refine2WayNode(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float ubfactor)
int PQueueGetKey(PQueueType *queue)
void Match_HEM(CtrlType *ctrl, GraphType *graph)
void metis_wpartgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
void metis_mcpartgraphrecursive__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void METIS_PartMeshDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart)
void ConstructMinCoverSeparator0(CtrlType *ctrl, GraphType *graph, float ubfactor)
void ComputePartitionInfoBipartite(GraphType *graph, int nparts, idxtype *where)
void ReAdjustMemory(GraphType *graph, GraphType *cgraph, int dovsize)
int AreAllVwgtsBelowFast(int ncon, float *vwgt1, float *vwgt2, float limit)
void MocRandomBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor)
void FM_2WayNodeRefineEqWgt(CtrlType *ctrl, GraphType *graph, int npasses)
void MocGrowBisection2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec)
int AreAllBelow(int ncon, float *v1, float *v2)
void Change2FNumberingOrder(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *v1, idxtype *v2)
int IsBalanced(idxtype *pwgts, int nparts, float *tpwgts, float ubfactor)
void metis_wpartgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part)
void saxpy(int n, float alpha, float *x, int incx, float *y, int incy)
void EstimateCFraction(int nvtxs, idxtype *xadj, idxtype *adjncy, float *vfraction, float *efraction)
int CheckNodeBnd(GraphType *graph, int onbnd)
void metis_partgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part)
void metis_partgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part)
void ComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts)
void ComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts)
void metis_meshtonodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy)
integer(kind=inttype) istart
integer(kind=inttype) iend
integer(kind=inttype) jstart
real(kind=realtype), dimension(:, :, :), pointer p
integer(kind=inttype), dimension(:, :, :), pointer status
real(kind=realtype), dimension(:, :, :, :), pointer x
integer(kind=inttype), parameter imax
integer(kind=inttype), parameter imin
integer(kind=inttype), dimension(:), allocatable part
integer(kind=inttype) function delta(val1, val2)
int CheckGraph(GraphType *)
struct ListNodeType ListNodeType
struct ListNodeType * next
struct ListNodeType * prev
struct graphdef * coarser