00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <metis.h>
00014
00015
00016
00017
00018
00019
00020 void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts,
00021 floattype *orgubvec, int npasses)
00022 {
00023 int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same;
00024 int from, me, to, oldcut, gain;
00025 idxtype *xadj, *adjncy, *adjwgt;
00026 idxtype *where, *perm, *bndptr, *bndind;
00027 EDegreeType *myedegrees;
00028 RInfoType *myrinfo;
00029 floattype *npwgts, *nvwgt, *minwgt, *maxwgt, maxlb, minlb, ubvec[MAXNCON], tvec[MAXNCON];
00030
00031 nvtxs = graph->nvtxs;
00032 ncon = graph->ncon;
00033 xadj = graph->xadj;
00034 adjncy = graph->adjncy;
00035 adjwgt = graph->adjwgt;
00036
00037 bndptr = graph->bndptr;
00038 bndind = graph->bndind;
00039
00040 where = graph->where;
00041 npwgts = graph->npwgts;
00042
00043
00044 minwgt = fwspacemalloc(ctrl, nparts*ncon);
00045 maxwgt = fwspacemalloc(ctrl, nparts*ncon);
00046
00047
00048 maxlb = minlb = orgubvec[0];
00049 for (i=1; i<ncon; i++) {
00050 minlb = (orgubvec[i] < minlb ? orgubvec[i] : minlb);
00051 maxlb = (orgubvec[i] > maxlb ? orgubvec[i] : maxlb);
00052 }
00053 same = (fabs(maxlb-minlb) < .01 ? 1 : 0);
00054
00055
00056
00057 ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec);
00058 for (i=0; i<ncon; i++)
00059 ubvec[i] = amax(ubvec[i], orgubvec[i]);
00060
00061 if (!same) {
00062 for (i=0; i<nparts; i++) {
00063 for (j=0; j<ncon; j++) {
00064 maxwgt[i*ncon+j] = ubvec[j]/nparts;
00065 minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);
00066 }
00067 }
00068 }
00069 else {
00070 maxlb = ubvec[0];
00071 for (i=1; i<ncon; i++)
00072 maxlb = (ubvec[i] > maxlb ? ubvec[i] : maxlb);
00073
00074 for (i=0; i<nparts; i++) {
00075 for (j=0; j<ncon; j++) {
00076 maxwgt[i*ncon+j] = maxlb/nparts;
00077 minwgt[i*ncon+j] = 1.0/(maxlb*nparts);
00078 }
00079 }
00080 }
00081
00082
00083 perm = idxwspacemalloc(ctrl, nvtxs);
00084
00085 if (ctrl->dbglvl&DBG_REFINE) {
00086 printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
00087 npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],
00088 graph->nvtxs, graph->nbnd, graph->mincut);
00089 ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
00090 for (i=0; i<ncon; i++)
00091 printf("%.3f ", tvec[i]);
00092 printf("\n");
00093 }
00094
00095 for (pass=0; pass<npasses; pass++) {
00096 ASSERT(ComputeCut(graph, where) == graph->mincut);
00097
00098 oldcut = graph->mincut;
00099 nbnd = graph->nbnd;
00100
00101 RandomPermute(nbnd, perm, 1);
00102 for (nmoves=iii=0; iii<graph->nbnd; iii++) {
00103 ii = perm[iii];
00104 if (ii >= nbnd)
00105 continue;
00106 i = bndind[ii];
00107
00108 myrinfo = graph->rinfo+i;
00109
00110 if (myrinfo->ed >= myrinfo->id) {
00111 from = where[i];
00112 nvwgt = graph->nvwgt+i*ncon;
00113
00114 if (myrinfo->id > 0 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))
00115 continue;
00116
00117 myedegrees = myrinfo->edegrees;
00118 myndegrees = myrinfo->ndegrees;
00119
00120 for (k=0; k<myndegrees; k++) {
00121 to = myedegrees[k].pid;
00122 gain = myedegrees[k].ed - myrinfo->id;
00123 if (gain >= 0 &&
00124 (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) ||
00125 IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)))
00126 break;
00127 }
00128 if (k == myndegrees)
00129 continue;
00130
00131 for (j=k+1; j<myndegrees; j++) {
00132 to = myedegrees[j].pid;
00133 if ((myedegrees[j].ed > myedegrees[k].ed &&
00134 (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) ||
00135 IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) ||
00136 (myedegrees[j].ed == myedegrees[k].ed &&
00137 IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec)))
00138 k = j;
00139 }
00140
00141 to = myedegrees[k].pid;
00142
00143 if (myedegrees[k].ed-myrinfo->id == 0
00144 && !IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)
00145 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon))
00146 continue;
00147
00148
00149
00150
00151 graph->mincut -= myedegrees[k].ed-myrinfo->id;
00152
00153 IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
00154
00155
00156 saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
00157 saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
00158 where[i] = to;
00159 myrinfo->ed += myrinfo->id-myedegrees[k].ed;
00160 SWAP(myrinfo->id, myedegrees[k].ed, j);
00161 if (myedegrees[k].ed == 0)
00162 myedegrees[k] = myedegrees[--myrinfo->ndegrees];
00163 else
00164 myedegrees[k].pid = from;
00165
00166 if (myrinfo->ed-myrinfo->id < 0)
00167 BNDDelete(nbnd, bndind, bndptr, i);
00168
00169
00170 for (j=xadj[i]; j<xadj[i+1]; j++) {
00171 ii = adjncy[j];
00172 me = where[ii];
00173
00174 myrinfo = graph->rinfo+ii;
00175 if (myrinfo->edegrees == NULL) {
00176 myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
00177 ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
00178 }
00179 myedegrees = myrinfo->edegrees;
00180
00181 ASSERT(CheckRInfo(myrinfo));
00182
00183 if (me == from) {
00184 INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
00185
00186 if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)
00187 BNDInsert(nbnd, bndind, bndptr, ii);
00188 }
00189 else if (me == to) {
00190 INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
00191
00192 if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)
00193 BNDDelete(nbnd, bndind, bndptr, ii);
00194 }
00195
00196
00197 if (me != from) {
00198 for (k=0; k<myrinfo->ndegrees; k++) {
00199 if (myedegrees[k].pid == from) {
00200 if (myedegrees[k].ed == adjwgt[j])
00201 myedegrees[k] = myedegrees[--myrinfo->ndegrees];
00202 else
00203 myedegrees[k].ed -= adjwgt[j];
00204 break;
00205 }
00206 }
00207 }
00208
00209
00210 if (me != to) {
00211 for (k=0; k<myrinfo->ndegrees; k++) {
00212 if (myedegrees[k].pid == to) {
00213 myedegrees[k].ed += adjwgt[j];
00214 break;
00215 }
00216 }
00217 if (k == myrinfo->ndegrees) {
00218 myedegrees[myrinfo->ndegrees].pid = to;
00219 myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
00220 }
00221 }
00222
00223 ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
00224 ASSERT(CheckRInfo(myrinfo));
00225
00226 }
00227 nmoves++;
00228 }
00229 }
00230
00231 graph->nbnd = nbnd;
00232
00233 if (ctrl->dbglvl&DBG_REFINE) {
00234 printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
00235 npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],
00236 nbnd, nmoves, graph->mincut);
00237 ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
00238 for (i=0; i<ncon; i++)
00239 printf("%.3f ", tvec[i]);
00240 printf("\n");
00241 }
00242
00243 if (graph->mincut == oldcut)
00244 break;
00245 }
00246
00247 fwspacefree(ctrl, ncon*nparts);
00248 fwspacefree(ctrl, ncon*nparts);
00249 idxwspacefree(ctrl, nvtxs);
00250 }
00251
00252
00253
00254
00255
00256
00257 void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts,
00258 floattype *ubvec, int npasses)
00259 {
00260 int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves;
00261 int from, me, to, oldcut;
00262 idxtype *xadj, *adjncy, *adjwgt;
00263 idxtype *where, *perm, *bndptr, *bndind, *moved;
00264 EDegreeType *myedegrees;
00265 RInfoType *myrinfo;
00266 PQueueType queue;
00267 floattype *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[MAXNCON];
00268
00269 nvtxs = graph->nvtxs;
00270 ncon = graph->ncon;
00271 xadj = graph->xadj;
00272 adjncy = graph->adjncy;
00273 adjwgt = graph->adjwgt;
00274
00275 bndind = graph->bndind;
00276 bndptr = graph->bndptr;
00277
00278 where = graph->where;
00279 npwgts = graph->npwgts;
00280
00281
00282 minwgt = fwspacemalloc(ctrl, ncon*nparts);
00283 maxwgt = fwspacemalloc(ctrl, ncon*nparts);
00284
00285 for (i=0; i<nparts; i++) {
00286 for (j=0; j<ncon; j++) {
00287 maxwgt[i*ncon+j] = ubvec[j]/nparts;
00288 minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);
00289 }
00290 }
00291
00292 perm = idxwspacemalloc(ctrl, nvtxs);
00293 moved = idxwspacemalloc(ctrl, nvtxs);
00294
00295 PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);
00296
00297 if (ctrl->dbglvl&DBG_REFINE) {
00298 printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",
00299 npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],
00300 graph->nvtxs, graph->nbnd, graph->mincut);
00301 ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
00302 for (i=0; i<ncon; i++)
00303 printf("%.3f ", tvec[i]);
00304 printf("[B]\n");
00305 }
00306
00307
00308 for (pass=0; pass<npasses; pass++) {
00309 ASSERT(ComputeCut(graph, where) == graph->mincut);
00310
00311
00312 if (MocIsHBalanced(ncon, nparts, npwgts, ubvec))
00313 break;
00314
00315 PQueueReset(&queue);
00316 idxset(nvtxs, -1, moved);
00317
00318 oldcut = graph->mincut;
00319 nbnd = graph->nbnd;
00320
00321 RandomPermute(nbnd, perm, 1);
00322 for (ii=0; ii<nbnd; ii++) {
00323 i = bndind[perm[ii]];
00324 PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);
00325 moved[i] = 2;
00326 }
00327
00328 nmoves = 0;
00329 for (;;) {
00330 if ((i = PQueueGetMax(&queue)) == -1)
00331 break;
00332 moved[i] = 1;
00333
00334 myrinfo = graph->rinfo+i;
00335 from = where[i];
00336 nvwgt = graph->nvwgt+i*ncon;
00337
00338 if (AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))
00339 continue;
00340
00341 myedegrees = myrinfo->edegrees;
00342 myndegrees = myrinfo->ndegrees;
00343
00344 for (k=0; k<myndegrees; k++) {
00345 to = myedegrees[k].pid;
00346 if (IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))
00347 break;
00348 }
00349 if (k == myndegrees)
00350 continue;
00351
00352 for (j=k+1; j<myndegrees; j++) {
00353 to = myedegrees[j].pid;
00354 if (IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec))
00355 k = j;
00356 }
00357
00358 to = myedegrees[k].pid;
00359
00360 j = 0;
00361 if (!AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon))
00362 j++;
00363 if (myedegrees[k].ed-myrinfo->id >= 0)
00364 j++;
00365 if (!AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) &&
00366 AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon))
00367 j++;
00368 if (j == 0)
00369 continue;
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 graph->mincut -= myedegrees[k].ed-myrinfo->id;
00382
00383 IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));
00384
00385
00386 saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);
00387 saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);
00388 where[i] = to;
00389 myrinfo->ed += myrinfo->id-myedegrees[k].ed;
00390 SWAP(myrinfo->id, myedegrees[k].ed, j);
00391 if (myedegrees[k].ed == 0)
00392 myedegrees[k] = myedegrees[--myrinfo->ndegrees];
00393 else
00394 myedegrees[k].pid = from;
00395
00396 if (myrinfo->ed == 0)
00397 BNDDelete(nbnd, bndind, bndptr, i);
00398
00399
00400 for (j=xadj[i]; j<xadj[i+1]; j++) {
00401 ii = adjncy[j];
00402 me = where[ii];
00403
00404 myrinfo = graph->rinfo+ii;
00405 if (myrinfo->edegrees == NULL) {
00406 myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;
00407 ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];
00408 }
00409 myedegrees = myrinfo->edegrees;
00410
00411 ASSERT(CheckRInfo(myrinfo));
00412
00413 oldgain = (myrinfo->ed-myrinfo->id);
00414
00415 if (me == from) {
00416 INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);
00417
00418 if (myrinfo->ed > 0 && bndptr[ii] == -1)
00419 BNDInsert(nbnd, bndind, bndptr, ii);
00420 }
00421 else if (me == to) {
00422 INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);
00423
00424 if (myrinfo->ed == 0 && bndptr[ii] != -1)
00425 BNDDelete(nbnd, bndind, bndptr, ii);
00426 }
00427
00428
00429 if (me != from) {
00430 for (k=0; k<myrinfo->ndegrees; k++) {
00431 if (myedegrees[k].pid == from) {
00432 if (myedegrees[k].ed == adjwgt[j])
00433 myedegrees[k] = myedegrees[--myrinfo->ndegrees];
00434 else
00435 myedegrees[k].ed -= adjwgt[j];
00436 break;
00437 }
00438 }
00439 }
00440
00441
00442 if (me != to) {
00443 for (k=0; k<myrinfo->ndegrees; k++) {
00444 if (myedegrees[k].pid == to) {
00445 myedegrees[k].ed += adjwgt[j];
00446 break;
00447 }
00448 }
00449 if (k == myrinfo->ndegrees) {
00450 myedegrees[myrinfo->ndegrees].pid = to;
00451 myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];
00452 }
00453 }
00454
00455
00456
00457 if (me == to || me == from) {
00458 gain = myrinfo->ed-myrinfo->id;
00459 if (moved[ii] == 2) {
00460 if (myrinfo->ed > 0)
00461 PQueueUpdate(&queue, ii, oldgain, gain);
00462 else {
00463 PQueueDelete(&queue, ii, oldgain);
00464 moved[ii] = -1;
00465 }
00466 }
00467 else if (moved[ii] == -1 && myrinfo->ed > 0) {
00468 PQueueInsert(&queue, ii, gain);
00469 moved[ii] = 2;
00470 }
00471 }
00472
00473 ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);
00474 ASSERT(CheckRInfo(myrinfo));
00475 }
00476 nmoves++;
00477 }
00478
00479 graph->nbnd = nbnd;
00480
00481 if (ctrl->dbglvl&DBG_REFINE) {
00482 printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",
00483 npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],
00484 nbnd, nmoves, graph->mincut);
00485 ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);
00486 for (i=0; i<ncon; i++)
00487 printf("%.3f ", tvec[i]);
00488 printf("\n");
00489 }
00490
00491 if (nmoves == 0)
00492 break;
00493 }
00494
00495 PQueueFree(ctrl, &queue);
00496
00497 fwspacefree(ctrl, ncon*nparts);
00498 fwspacefree(ctrl, ncon*nparts);
00499 idxwspacefree(ctrl, nvtxs);
00500 idxwspacefree(ctrl, nvtxs);
00501
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 int AreAllHVwgtsBelow(int ncon, floattype alpha, floattype *vwgt1, floattype beta, floattype *vwgt2, floattype *limit)
00513 {
00514 int i;
00515
00516 for (i=0; i<ncon; i++)
00517 if (alpha*vwgt1[i] + beta*vwgt2[i] > limit[i])
00518 return 0;
00519
00520 return 1;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 int AreAllHVwgtsAbove(int ncon, floattype alpha, floattype *vwgt1, floattype beta, floattype *vwgt2, floattype *limit)
00530 {
00531 int i;
00532
00533 for (i=0; i<ncon; i++)
00534 if (alpha*vwgt1[i] + beta*vwgt2[i] < limit[i])
00535 return 0;
00536
00537 return 1;
00538 }
00539
00540
00541
00542
00543
00544
00545 void ComputeHKWayLoadImbalance(int ncon, int nparts, floattype *npwgts, floattype *lbvec)
00546 {
00547 int i, j;
00548 floattype max;
00549
00550 for (i=0; i<ncon; i++) {
00551 max = 0.0;
00552 for (j=0; j<nparts; j++) {
00553 if (npwgts[j*ncon+i] > max)
00554 max = npwgts[j*ncon+i];
00555 }
00556
00557 lbvec[i] = max*nparts;
00558 }
00559 }
00560
00561
00562
00563
00564
00565 int MocIsHBalanced(int ncon, int nparts, floattype *npwgts, floattype *ubvec)
00566 {
00567 int i, j;
00568 floattype max;
00569
00570 for (i=0; i<ncon; i++) {
00571 max = 0.0;
00572 for (j=0; j<nparts; j++) {
00573 if (npwgts[j*ncon+i] > max)
00574 max = npwgts[j*ncon+i];
00575 }
00576
00577 if (ubvec[i] < max*nparts)
00578 return 0;
00579 }
00580
00581 return 1;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 int IsHBalanceBetterFT(int ncon, int nparts, floattype *pfrom, floattype *pto, floattype *vwgt, floattype *ubvec)
00594 {
00595 int i, j, k;
00596 floattype blb1=0.0, alb1=0.0, sblb=0.0, salb=0.0;
00597 floattype blb2=0.0, alb2=0.0;
00598 floattype temp;
00599
00600 for (i=0; i<ncon; i++) {
00601 temp = amax(pfrom[i], pto[i])*nparts/ubvec[i];
00602 if (blb1 < temp) {
00603 blb2 = blb1;
00604 blb1 = temp;
00605 }
00606 else if (blb2 < temp)
00607 blb2 = temp;
00608 sblb += temp;
00609
00610 temp = amax(pfrom[i]-vwgt[i], pto[i]+vwgt[i])*nparts/ubvec[i];
00611 if (alb1 < temp) {
00612 alb2 = alb1;
00613 alb1 = temp;
00614 }
00615 else if (alb2 < temp)
00616 alb2 = temp;
00617 salb += temp;
00618 }
00619
00620 if (alb1 < blb1)
00621 return 1;
00622 if (blb1 < alb1)
00623 return 0;
00624 if (alb2 < blb2)
00625 return 1;
00626 if (blb2 < alb2)
00627 return 0;
00628
00629 return salb < sblb;
00630
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 int IsHBalanceBetterTT(int ncon, int nparts, floattype *pt1, floattype *pt2, floattype *vwgt, floattype *ubvec)
00642 {
00643 int i;
00644 floattype m11=0.0, m12=0.0, m21=0.0, m22=0.0, sm1=0.0, sm2=0.0, temp;
00645
00646 for (i=0; i<ncon; i++) {
00647 temp = (pt1[i]+vwgt[i])*nparts/ubvec[i];
00648 if (m11 < temp) {
00649 m12 = m11;
00650 m11 = temp;
00651 }
00652 else if (m12 < temp)
00653 m12 = temp;
00654 sm1 += temp;
00655
00656 temp = (pt2[i]+vwgt[i])*nparts/ubvec[i];
00657 if (m21 < temp) {
00658 m22 = m21;
00659 m21 = temp;
00660 }
00661 else if (m22 < temp)
00662 m22 = temp;
00663 sm2 += temp;
00664 }
00665
00666 if (m21 < m11)
00667 return 1;
00668 if (m21 > m11)
00669 return 0;
00670 if (m22 < m12)
00671 return 1;
00672 if (m22 > m12)
00673 return 0;
00674
00675 return sm2 < sm1;
00676 }
00677