00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qs_config.h"
00026 #include "stddefs.h"
00027 #include "mpf_qsopt.h"
00028 #include "mpf_lpdefs.h"
00029 #include "mpf_fct.h"
00030 #include "mpf_price.h"
00031 #include "mpf_basis.h"
00032 #include "mpf_iqsutil.h"
00033 #include "mpf_dstruct.h"
00034 #ifdef USEDMALLOC
00035 #include "dmalloc.h"
00036 #endif
00037
00038 #define mpf_MULTIP 1
00039 #define mpf_PRICE_DEBUG 0
00040
00041 static void mpf_update_d_scaleinf (
00042 mpf_price_info * const p,
00043 mpf_heap * const h,
00044 int const j,
00045 mpf_t inf,
00046 int const prule),
00047 mpf_update_p_scaleinf (
00048 mpf_price_info * const p,
00049 mpf_heap * const h,
00050 int const i,
00051 mpf_t inf,
00052 int const prule);
00053
00054 static void mpf_compute_dualI_inf (
00055 mpf_lpinfo * const lp,
00056 int const j,
00057 mpf_t * const inf),
00058 mpf_compute_dualII_inf (
00059 mpf_lpinfo * const lp,
00060 int const j,
00061 mpf_t * const inf),
00062 mpf_compute_primalI_inf (
00063 mpf_lpinfo * const lp,
00064 int const i,
00065 mpf_t * const inf),
00066 mpf_compute_primalII_inf (
00067 mpf_lpinfo * const lp,
00068 int const i,
00069 mpf_t * const inf);
00070
00071 void mpf_ILLprice_free_heap (
00072 mpf_price_info * const pinf)
00073 {
00074 mpf_ILLheap_free (&(pinf->h));
00075 }
00076
00077 int mpf_ILLprice_build_heap (
00078 mpf_price_info * const pinf,
00079 int const nkeys,
00080 mpf_t * keylist)
00081 {
00082 mpf_ILLheap_init (&(pinf->h));
00083 mpf_EGlpNumSet (pinf->htrigger,
00084 1.0 +
00085 (double) nkeys / (PARAM_HEAP_RATIO * mpf_ILLutil_our_log2 (nkeys)));
00086 return mpf_ILLheap_build (&(pinf->h), nkeys, keylist);
00087 }
00088
00089 int mpf_ILLprice_test_for_heap (
00090 mpf_lpinfo * const lp,
00091 mpf_price_info * const pinf,
00092 int const nkeys,
00093 mpf_t * keylist,
00094 int const algo,
00095 int const upd)
00096 {
00097 mpf_heap *const h = &(pinf->h);
00098 int rval = 0;
00099 mpf_t ravg;
00100
00101 if (upd != 0)
00102 {
00103 mpf_EGlpNumInitVar (ravg);
00104 if (algo == PRIMAL_SIMPLEX)
00105 mpf_EGlpNumCopy (ravg, lp->cnts->za_ravg);
00106 else
00107 mpf_EGlpNumCopy (ravg, lp->cnts->y_ravg);
00108 if (mpf_EGlpNumIsLeq (ravg, pinf->htrigger))
00109 pinf->hineff--;
00110 else
00111 {
00112 mpf_EGlpNumDivUiTo (ravg, 2U);
00113 if (mpf_EGlpNumIsLess (pinf->htrigger, ravg))
00114 pinf->hineff++;
00115 }
00116 mpf_EGlpNumClearVar (ravg);
00117 }
00118 if (h->hexist == 0 && pinf->hineff <= 0)
00119 {
00120 rval = mpf_ILLprice_build_heap (pinf, nkeys, keylist);
00121 CHECKRVALG (rval, CLEANUP);
00122 }
00123 else if (h->hexist != 0 && pinf->hineff >= PARAM_HEAP_UTRIGGER)
00124 {
00125 mpf_ILLprice_free_heap (pinf);
00126
00127
00128
00129
00130
00131 }
00132
00133 CLEANUP:
00134 if (rval)
00135 mpf_ILLprice_free_heap (pinf);
00136 return rval;
00137 }
00138
00139 void mpf_ILLprice_init_pricing_info (
00140 mpf_price_info * const pinf)
00141 {
00142 pinf->p_strategy = -1;
00143 pinf->d_strategy = -1;
00144 pinf->pI_price = -1;
00145 pinf->pII_price = -1;
00146 pinf->dI_price = -1;
00147 pinf->dII_price = -1;
00148 pinf->cur_price = -1;
00149 pinf->p_scaleinf = 0;
00150 pinf->d_scaleinf = 0;
00151 pinf->pdinfo.norms = 0;
00152 pinf->pdinfo.refframe = 0;
00153 pinf->psinfo.norms = 0;
00154 pinf->ddinfo.norms = 0;
00155 pinf->ddinfo.refframe = 0;
00156 pinf->dsinfo.norms = 0;
00157 pinf->dmpinfo.gstart = pinf->pmpinfo.gstart = 0;
00158 pinf->dmpinfo.gshift = pinf->pmpinfo.gshift = 0;
00159 pinf->dmpinfo.gsize = pinf->pmpinfo.gsize = 0;
00160 pinf->dmpinfo.bucket = pinf->pmpinfo.bucket = 0;
00161 pinf->dmpinfo.perm = pinf->pmpinfo.perm = 0;
00162 pinf->dmpinfo.infeas = pinf->pmpinfo.infeas = 0;
00163 mpf_ILLheap_init (&(pinf->h));
00164 mpf_EGlpNumZero (pinf->htrigger);
00165 pinf->hineff = 0;
00166 }
00167
00168 void mpf_ILLprice_free_pricing_info (
00169 mpf_price_info * const pinf)
00170 {
00171 mpf_EGlpNumFreeArray (pinf->p_scaleinf);
00172 mpf_EGlpNumFreeArray (pinf->d_scaleinf);
00173 mpf_EGlpNumFreeArray (pinf->pdinfo.norms);
00174 ILL_IFFREE (pinf->pdinfo.refframe, int);
00175 mpf_EGlpNumFreeArray (pinf->psinfo.norms);
00176 mpf_EGlpNumFreeArray (pinf->ddinfo.norms);
00177 ILL_IFFREE (pinf->ddinfo.refframe, int);
00178 mpf_EGlpNumFreeArray (pinf->dsinfo.norms);
00179
00180 mpf_ILLprice_free_mpartial_info (&(pinf->pmpinfo));
00181 mpf_ILLprice_free_mpartial_info (&(pinf->dmpinfo));
00182 mpf_ILLprice_free_heap (pinf);
00183 }
00184
00185 int mpf_ILLprice_build_pricing_info (
00186 mpf_lpinfo * const lp,
00187 mpf_price_info * const pinf,
00188 int const phase)
00189 {
00190 int rval = 0;
00191 int p_price = -1;
00192 int d_price = -1;
00193
00194 switch (phase)
00195 {
00196 case PRIMAL_PHASEI:
00197 p_price = pinf->pI_price;
00198 break;
00199 case PRIMAL_PHASEII:
00200 p_price = pinf->pII_price;
00201 break;
00202 case DUAL_PHASEI:
00203 d_price = pinf->dI_price;
00204 break;
00205 case DUAL_PHASEII:
00206 d_price = pinf->dII_price;
00207 break;
00208 }
00209
00210 if (p_price != -1)
00211 {
00212 pinf->cur_price = p_price;
00213
00214 if (p_price == QS_PRICE_PDANTZIG || p_price == QS_PRICE_PDEVEX ||
00215 p_price == QS_PRICE_PSTEEP)
00216 {
00217 pinf->p_strategy = COMPLETE_PRICING;
00218 mpf_EGlpNumFreeArray (pinf->d_scaleinf);
00219 pinf->d_scaleinf = mpf_EGlpNumAllocArray (lp->nnbasic);
00220 }
00221 else if (p_price == QS_PRICE_PMULTPARTIAL)
00222 pinf->p_strategy = MULTI_PART_PRICING;
00223
00224 switch (p_price)
00225 {
00226 case QS_PRICE_PDEVEX:
00227 if (pinf->pdinfo.norms)
00228 return rval;
00229 rval = mpf_ILLprice_build_pdevex_norms (lp, &(pinf->pdinfo), 0);
00230 CHECKRVALG(rval,CLEANUP);
00231 break;
00232 case QS_PRICE_PSTEEP:
00233 if (pinf->psinfo.norms)
00234 return rval;
00235 rval = mpf_ILLprice_build_psteep_norms (lp, &(pinf->psinfo));
00236 CHECKRVALG(rval,CLEANUP);
00237 break;
00238 case QS_PRICE_PMULTPARTIAL:
00239 rval = mpf_ILLprice_build_mpartial_info (lp, pinf, COL_PRICING);
00240 CHECKRVALG(rval,CLEANUP);
00241 break;
00242 }
00243 }
00244 else if (d_price != -1)
00245 {
00246 pinf->cur_price = d_price;
00247
00248 if (d_price == QS_PRICE_DDANTZIG || d_price == QS_PRICE_DSTEEP ||
00249 d_price == QS_PRICE_DDEVEX)
00250 {
00251 pinf->d_strategy = COMPLETE_PRICING;
00252 mpf_EGlpNumFreeArray (pinf->p_scaleinf);
00253 pinf->p_scaleinf = mpf_EGlpNumAllocArray (lp->nrows);
00254 }
00255 else if (d_price == QS_PRICE_DMULTPARTIAL)
00256 pinf->d_strategy = MULTI_PART_PRICING;
00257
00258 switch (d_price)
00259 {
00260 case QS_PRICE_DSTEEP:
00261 if (pinf->dsinfo.norms)
00262 return rval;
00263 rval = mpf_ILLprice_build_dsteep_norms (lp, &(pinf->dsinfo));
00264 CHECKRVALG(rval,CLEANUP);
00265 break;
00266 case QS_PRICE_DMULTPARTIAL:
00267 rval = mpf_ILLprice_build_mpartial_info (lp, pinf, ROW_PRICING);
00268 CHECKRVALG(rval,CLEANUP);
00269 break;
00270 case QS_PRICE_DDEVEX:
00271 if (pinf->ddinfo.norms)
00272 return rval;
00273 rval = mpf_ILLprice_build_ddevex_norms (lp, &(pinf->ddinfo), 0);
00274 CHECKRVALG(rval,CLEANUP);
00275 break;
00276 }
00277 }
00278
00279 CLEANUP:
00280 if (rval)
00281 mpf_ILLprice_free_pricing_info (pinf);
00282 EG_RETURN(rval);
00283 }
00284
00285 int mpf_ILLprice_update_pricing_info (
00286 mpf_lpinfo * const lp,
00287 mpf_price_info * const pinf,
00288 int const phase,
00289 mpf_svector * const wz,
00290 int const eindex,
00291 int const lindex,
00292 mpf_t y)
00293 {
00294 int rval = 0;
00295 int p_price = -1;
00296 int d_price = -1;
00297
00298 switch (phase)
00299 {
00300 case PRIMAL_PHASEI:
00301 p_price = pinf->pI_price;
00302 break;
00303 case PRIMAL_PHASEII:
00304 p_price = pinf->pII_price;
00305 break;
00306 case DUAL_PHASEI:
00307 d_price = pinf->dI_price;
00308 break;
00309 case DUAL_PHASEII:
00310 d_price = pinf->dII_price;
00311 break;
00312 }
00313
00314 if (p_price != -1)
00315 {
00316 if (p_price == QS_PRICE_PDEVEX)
00317 {
00318 rval = mpf_ILLprice_update_pdevex_norms (lp, &(pinf->pdinfo), eindex, y);
00319 CHECKRVALG(rval,CLEANUP);
00320 }
00321 else if (p_price == QS_PRICE_PSTEEP)
00322 mpf_ILLprice_update_psteep_norms (lp, &(pinf->psinfo), wz, eindex, y);
00323 }
00324 else if (d_price != -1)
00325 {
00326 if (d_price == QS_PRICE_DSTEEP)
00327 mpf_ILLprice_update_dsteep_norms (lp, &(pinf->dsinfo), wz, lindex, y);
00328 else if (d_price == QS_PRICE_DDEVEX)
00329 {
00330 rval = mpf_ILLprice_update_ddevex_norms (lp, &(pinf->ddinfo), lindex, y);
00331 CHECKRVALG(rval,CLEANUP);
00332 }
00333 }
00334 CLEANUP:
00335 EG_RETURN(rval);
00336 }
00337
00338 int mpf_ILLprice_get_price (
00339 mpf_price_info * const p,
00340 int const phase)
00341 {
00342 int pri = -1;
00343
00344 switch (phase)
00345 {
00346 case PRIMAL_PHASEI:
00347 return p->pI_price;
00348 case PRIMAL_PHASEII:
00349 return p->pII_price;
00350 case DUAL_PHASEI:
00351 return p->dI_price;
00352 case DUAL_PHASEII:
00353 return p->dII_price;
00354 }
00355 return pri;
00356 }
00357
00358 void mpf_ILLprice_free_mpartial_info (
00359 mpf_mpart_info * p)
00360 {
00361 ILL_IFFREE (p->gstart, int);
00362 ILL_IFFREE (p->gshift, int);
00363 ILL_IFFREE (p->gsize, int);
00364 ILL_IFFREE (p->bucket, int);
00365 mpf_EGlpNumFreeArray (p->infeas);
00366 ILL_IFFREE (p->perm, int);
00367 }
00368
00369 int mpf_ILLprice_build_mpartial_info (
00370 mpf_lpinfo * const lp,
00371 mpf_price_info * const pinf,
00372 int const pricetype)
00373 {
00374 int i = 0;
00375 int rval = 0;
00376 int extra = 0;
00377 int nelems;
00378 mpf_mpart_info *p;
00379
00380 p = (pricetype == COL_PRICING) ? &(pinf->pmpinfo) : &(pinf->dmpinfo);
00381 p->k = 50;
00382 p->cgroup = 0;
00383 nelems = (pricetype == COL_PRICING) ? lp->nnbasic : lp->nrows;
00384
00385 if (nelems % p->k)
00386 extra = nelems - p->k * (nelems / p->k);
00387 p->ngroups = nelems / p->k;
00388 if (extra != 0)
00389 p->ngroups++;
00390
00391 ILL_SAFE_MALLOC (p->gstart, p->ngroups, int);
00392 ILL_SAFE_MALLOC (p->gshift, p->ngroups, int);
00393 ILL_SAFE_MALLOC (p->gsize, p->ngroups, int);
00394 ILL_SAFE_MALLOC (p->bucket, 2 * p->k, int);
00395 p->infeas = mpf_EGlpNumAllocArray (2 * p->k);
00396 ILL_SAFE_MALLOC (p->perm, 2 * p->k, int);
00397
00398 p->bsize = 0;
00399
00400 if (extra != 0)
00401 {
00402 p->gstart[0] = 0;
00403 p->gshift[0] = 1;
00404 p->gsize[0] = extra;
00405 for (i = 1; i < p->ngroups; i++)
00406 {
00407 p->gstart[i] = extra + i - 1;
00408 p->gshift[i] = p->ngroups - 1;
00409 p->gsize[i] = p->k;
00410 }
00411 }
00412 else
00413 {
00414 for (i = 0; i < p->ngroups; i++)
00415 {
00416 p->gstart[i] = i;
00417 p->gshift[i] = p->ngroups;
00418 p->gsize[i] = p->k;
00419 }
00420 }
00421
00422 CLEANUP:
00423 if (rval)
00424 mpf_ILLprice_free_mpartial_info (p);
00425 EG_RETURN(rval);
00426 }
00427
00428 void mpf_ILLprice_init_mpartial_price (
00429 mpf_lpinfo * const lp,
00430 mpf_price_info * const pinf,
00431 int const phase,
00432 int const pricetype)
00433 {
00434 int i;
00435 mpf_mpart_info *p;
00436
00437 p = (pricetype == COL_PRICING) ? &(pinf->pmpinfo) : &(pinf->dmpinfo);
00438 p->bsize = 0;
00439 i = p->cgroup;
00440 do
00441 {
00442 mpf_ILLprice_mpartial_group (lp, p, phase, i, pricetype);
00443 i = (i + 1) % p->ngroups;
00444 } while (i != p->cgroup && p->bsize <= p->k);
00445 p->cgroup = i;
00446 }
00447
00448 void mpf_ILLprice_update_mpartial_price (
00449 mpf_lpinfo * const lp,
00450 mpf_price_info * const pinf,
00451 int const phase,
00452 int const pricetype)
00453 {
00454 int i = 0;
00455 int csize = 0;
00456 mpf_t infeas;
00457 mpf_mpart_info *p;
00458 mpf_price_res pr;
00459
00460 p = (pricetype == COL_PRICING) ? &(pinf->pmpinfo) : &(pinf->dmpinfo);
00461 mpf_EGlpNumInitVar (pr.dinfeas);
00462 mpf_EGlpNumInitVar (pr.pinfeas);
00463 mpf_EGlpNumInitVar (infeas);
00464
00465 #ifdef mpf_MULTIP
00466 i = 0;
00467 while (i < p->bsize)
00468 {
00469 if (pricetype == COL_PRICING)
00470 {
00471 mpf_ILLprice_column (lp, p->bucket[i], phase, &pr);
00472 mpf_EGlpNumCopy (infeas, pr.dinfeas);
00473 }
00474 else
00475 {
00476 mpf_ILLprice_row (lp, p->bucket[i], phase, &pr);
00477 mpf_EGlpNumCopy (infeas, pr.pinfeas);
00478 }
00479 if (!mpf_EGlpNumIsNeqqZero (infeas))
00480 {
00481 p->bucket[i] = p->bucket[p->bsize - 1];
00482 p->bsize--;
00483 }
00484 else
00485 {
00486 mpf_EGlpNumCopy (p->infeas[i], infeas);
00487 i++;
00488 }
00489 }
00490 if (p->bsize > 0)
00491 {
00492 for (i = 0; i < p->bsize; i++)
00493 p->perm[i] = i;
00494 mpf_EGutilPermSort ((size_t) (p->bsize), p->perm,
00495 (const mpf_t * const) p->infeas);
00496
00497 csize = QSMIN (p->bsize, p->k);
00498 for (i = csize - 1; i >= 0; i--)
00499 lp->iwork[p->bucket[p->perm[i]]] = 1;
00500
00501 for (i = 0, csize = 0; i < p->bsize; i++)
00502 if (lp->iwork[p->bucket[i]] == 1)
00503 {
00504 mpf_EGlpNumCopy (p->infeas[csize], p->infeas[i]);
00505 p->bucket[csize] = p->bucket[i];
00506 csize++;
00507 }
00508 p->bsize = csize;
00509 }
00510 #else
00511 p->bsize = 0;
00512 #endif
00513
00514 i = p->cgroup;
00515 do
00516 {
00517 mpf_ILLprice_mpartial_group (lp, p, phase, i, pricetype);
00518 i = (i + 1) % p->ngroups;
00519 } while (i != p->cgroup && p->bsize <= p->k);
00520 p->cgroup = i;
00521
00522 #ifdef mpf_MULTIP
00523 for (i = 0; i < csize; i++)
00524 lp->iwork[p->bucket[i]] = 0;
00525 #endif
00526 mpf_EGlpNumClearVar (infeas);
00527 mpf_EGlpNumClearVar (pr.pinfeas);
00528 mpf_EGlpNumClearVar (pr.dinfeas);
00529 }
00530
00531 void mpf_ILLprice_delete_onempart_price (
00532
00533 mpf_price_info * const pinf,
00534 int const indx,
00535 int const pricetype)
00536 {
00537 int i = 0;
00538 mpf_mpart_info *p;
00539
00540 p = (pricetype == COL_PRICING) ? &(pinf->pmpinfo) : &(pinf->dmpinfo);
00541
00542 for (i = 0; i < p->bsize; i++)
00543 if (p->bucket[i] == indx)
00544 {
00545 p->bucket[i] = p->bucket[p->bsize - 1];
00546 mpf_EGlpNumCopy (p->infeas[i], p->infeas[p->bsize - 1]);
00547 p->bsize--;
00548 break;
00549 }
00550 }
00551
00552 void mpf_ILLprice_mpartial_group (
00553 mpf_lpinfo * const lp,
00554 mpf_mpart_info * const p,
00555 int const phase,
00556 int const g,
00557 int const pricetype)
00558 {
00559 int i, ix;
00560 int gstart = p->gstart[g];
00561 int gsize = p->gsize[g];
00562 int gshift = p->gshift[g];
00563 mpf_t infeas;
00564 mpf_price_res pr;
00565
00566 mpf_EGlpNumInitVar (pr.dinfeas);
00567 mpf_EGlpNumInitVar (pr.pinfeas);
00568 mpf_EGlpNumInitVar (infeas);
00569
00570 for (i = 0, ix = gstart; i < gsize; i++, ix += gshift)
00571 {
00572 #ifdef mpf_MULTIP
00573 if (lp->iwork[ix])
00574 continue;
00575 #endif
00576 if (pricetype == COL_PRICING)
00577 {
00578 mpf_ILLprice_column (lp, ix, phase, &pr);
00579 mpf_EGlpNumCopy (infeas, pr.dinfeas);
00580 }
00581 else
00582 {
00583 mpf_ILLprice_row (lp, ix, phase, &pr);
00584 mpf_EGlpNumCopy (infeas, pr.pinfeas);
00585 }
00586 if (mpf_EGlpNumIsNeqqZero (infeas))
00587 {
00588 mpf_EGlpNumCopy (p->infeas[p->bsize], infeas);
00589 p->bucket[p->bsize] = ix;
00590 p->bsize++;
00591 }
00592 }
00593 mpf_EGlpNumClearVar (infeas);
00594 mpf_EGlpNumClearVar (pr.dinfeas);
00595 mpf_EGlpNumClearVar (pr.pinfeas);
00596 }
00597
00598 void mpf_ILLprice_column (
00599 mpf_lpinfo * const lp,
00600 int const ix,
00601 int const phase,
00602 mpf_price_res * const pr)
00603 {
00604 int i;
00605 int col;
00606 int mcnt;
00607 int mbeg;
00608 mpf_t sum;
00609
00610 mpf_EGlpNumZero (pr->dinfeas);
00611 col = lp->nbaz[ix];
00612 if (lp->vtype[col] == VARTIFICIAL || lp->vtype[col] == VFIXED)
00613 return;
00614 mpf_EGlpNumInitVar (sum);
00615 mpf_EGlpNumZero (sum);
00616 mcnt = lp->matcnt[col];
00617 mbeg = lp->matbeg[col];
00618
00619 if (phase == PRIMAL_PHASEII)
00620 {
00621 for (i = 0; i < mcnt; i++)
00622 mpf_EGlpNumAddInnProdTo (sum, lp->piz[lp->matind[mbeg + i]], lp->matval[mbeg + i]);
00623 mpf_EGlpNumCopyDiff (lp->dz[ix], lp->cz[col], sum);
00624 mpf_compute_dualII_inf (lp, ix, &(pr->dinfeas));
00625 }
00626 else
00627 {
00628 for (i = 0; i < mcnt; i++)
00629 mpf_EGlpNumAddInnProdTo (sum, lp->pIpiz[lp->matind[mbeg + i]], lp->matval[mbeg + i]);
00630 mpf_EGlpNumCopyNeg (lp->pIdz[ix], sum);
00631 mpf_compute_dualI_inf (lp, ix, &(pr->dinfeas));
00632 }
00633 mpf_EGlpNumClearVar (sum);
00634 }
00635
00636 void mpf_ILLprice_row (
00637 mpf_lpinfo * const lp,
00638 int const ix,
00639 int const phase,
00640 mpf_price_res * const pr)
00641 {
00642 if (phase == DUAL_PHASEII)
00643 mpf_compute_primalII_inf (lp, ix, &(pr->pinfeas));
00644 else
00645 mpf_compute_primalI_inf (lp, ix, &(pr->pinfeas));
00646 }
00647
00648 int mpf_ILLprice_build_pdevex_norms (
00649 mpf_lpinfo * const lp,
00650 mpf_p_devex_info * const pdinfo,
00651 int const reinit)
00652 {
00653 int j;
00654 int rval = 0;
00655
00656 if (reinit == 0)
00657 {
00658 pdinfo->ninit = 0;
00659 pdinfo->norms = mpf_EGlpNumAllocArray (lp->nnbasic);
00660 ILL_SAFE_MALLOC (pdinfo->refframe, lp->ncols, int);
00661 }
00662
00663 if (reinit != 0)
00664 pdinfo->ninit++;
00665
00666 for (j = 0; j < lp->ncols; j++)
00667 {
00668 if (lp->vstat[j] == STAT_BASIC)
00669 pdinfo->refframe[j] = 0;
00670 else
00671 {
00672 mpf_EGlpNumOne (pdinfo->norms[lp->vindex[j]]);
00673 pdinfo->refframe[j] = 1;
00674 }
00675 }
00676
00677 CLEANUP:
00678 if (rval)
00679 {
00680 mpf_EGlpNumFreeArray (pdinfo->norms);
00681 ILL_IFFREE (pdinfo->refframe, int);
00682 }
00683 EG_RETURN(rval);
00684 }
00685
00686 int mpf_ILLprice_update_pdevex_norms (
00687 mpf_lpinfo * const lp,
00688 mpf_p_devex_info * const pdinfo,
00689 int const eindex,
00690 mpf_t yl)
00691 {
00692 int i, j;
00693 mpf_t normj;
00694 mpf_t zAj;
00695 mpf_t ntmp, ntmp2;
00696
00697 mpf_EGlpNumInitVar (normj);
00698 mpf_EGlpNumInitVar (zAj);
00699 mpf_EGlpNumInitVar (ntmp);
00700 mpf_EGlpNumInitVar (ntmp2);
00701 mpf_EGlpNumZero (normj);
00702
00703 for (i = 0; i < lp->yjz.nzcnt; i++)
00704 if (pdinfo->refframe[lp->baz[lp->yjz.indx[i]]])
00705 mpf_EGlpNumAddInnProdTo (normj, lp->yjz.coef[i], lp->yjz.coef[i]);
00706
00707 if (pdinfo->refframe[lp->nbaz[eindex]])
00708 mpf_EGlpNumAddTo (normj, mpf_oneLpNum);
00709
00710 mpf_EGlpNumSet(ntmp,1000.0);
00711 mpf_EGlpNumSet(ntmp2,0.001);
00712 mpf_EGlpNumMultTo(ntmp,pdinfo->norms[eindex]);
00713 mpf_EGlpNumMultTo(ntmp2,pdinfo->norms[eindex]);
00714 if (mpf_EGlpNumIsLess (normj, ntmp2) || mpf_EGlpNumIsLess (ntmp, normj))
00715 {
00716 mpf_EGlpNumClearVar (zAj);
00717 mpf_EGlpNumClearVar (normj);
00718 mpf_EGlpNumClearVar (ntmp);
00719 mpf_EGlpNumClearVar (ntmp2);
00720 return mpf_ILLprice_build_pdevex_norms (lp, pdinfo, 1);
00721 }
00722
00723 for (i = 0; i < lp->zA.nzcnt; i++)
00724 {
00725 j = lp->zA.indx[i];
00726 mpf_EGlpNumCopyFrac (zAj, lp->zA.coef[i], yl);
00727 mpf_EGlpNumMultTo (zAj, zAj);
00728 mpf_EGlpNumMultTo (zAj, normj);
00729 if (mpf_EGlpNumIsLess (pdinfo->norms[j], zAj))
00730 mpf_EGlpNumCopy (pdinfo->norms[j], zAj);
00731 }
00732 mpf_EGlpNumDivTo (normj, yl);
00733 mpf_EGlpNumDivTo (normj, yl);
00734 if (mpf_EGlpNumIsLess (normj, mpf_oneLpNum))
00735 mpf_EGlpNumCopy (pdinfo->norms[eindex], mpf_oneLpNum);
00736 else
00737 mpf_EGlpNumCopy (pdinfo->norms[eindex], normj);
00738 mpf_EGlpNumClearVar (zAj);
00739 mpf_EGlpNumClearVar (normj);
00740 mpf_EGlpNumClearVar (ntmp);
00741 mpf_EGlpNumClearVar (ntmp2);
00742 return 0;
00743 }
00744
00745 int mpf_ILLprice_build_psteep_norms (
00746 mpf_lpinfo * const lp,
00747 mpf_p_steep_info * const psinfo)
00748 {
00749 int j;
00750 int rval = 0;
00751 mpf_svector yz;
00752
00753 mpf_ILLsvector_init (&yz);
00754 rval = mpf_ILLsvector_alloc (&yz, lp->nrows);
00755 CHECKRVALG(rval,CLEANUP);
00756 psinfo->norms = mpf_EGlpNumAllocArray (lp->nnbasic);
00757
00758 for (j = 0; j < lp->nnbasic; j++)
00759 {
00760 rval = ILLstring_report (NULL, &lp->O->reporter);
00761 CHECKRVALG(rval,CLEANUP);
00762 mpf_ILLfct_compute_yz (lp, &yz, 0, lp->nbaz[j]);
00763 mpf_EGlpNumInnProd (psinfo->norms[j], yz.coef, yz.coef, (size_t) yz.nzcnt);
00764 mpf_EGlpNumAddTo (psinfo->norms[j], mpf_oneLpNum);
00765 }
00766
00767 CLEANUP:
00768 mpf_ILLsvector_free (&yz);
00769 if (rval)
00770 mpf_EGlpNumFreeArray (psinfo->norms);
00771
00772 EG_RETURN(rval);
00773 }
00774
00775 void mpf_ILLprice_update_psteep_norms (
00776 mpf_lpinfo * const lp,
00777 mpf_p_steep_info * const psinfo,
00778 mpf_svector * const wz,
00779 int const eindex,
00780 mpf_t yl)
00781 {
00782 int i, j, k;
00783 int mcnt, mbeg;
00784 mpf_t normj,ntmp;
00785 mpf_t zAj, wAj;
00786 mpf_t *v = 0;
00787
00788 mpf_EGlpNumInitVar (normj);
00789 mpf_EGlpNumInitVar (zAj);
00790 mpf_EGlpNumInitVar (ntmp);
00791 mpf_EGlpNumInitVar (wAj);
00792 mpf_EGlpNumInnProd (normj, lp->yjz.coef, lp->yjz.coef, (size_t) (lp->yjz.nzcnt));
00793 mpf_EGlpNumAddTo (normj, mpf_oneLpNum);
00794
00795 #if 0
00796 Bico - remove warnings for dist
00797 if (fabs ((normj - psinfo->norms[eindex]) / normj) > 1000.0 )
00798 {
00799 printf ("warning: incorrect norm values\n");
00800 printf ("anorm = %.6f, pnorm = %.6f\n", normj, psinfo->norms[eindex]);
00801 fflush (stdout);
00802 }
00803 #endif
00804
00805 mpf_ILLfct_load_workvector (lp, wz);
00806 v = lp->work.coef;
00807
00808 for (k = 0; k < lp->zA.nzcnt; k++)
00809 {
00810 j = lp->zA.indx[k];
00811 mpf_EGlpNumCopy (zAj, lp->zA.coef[k]);
00812 mpf_EGlpNumZero (wAj);
00813 mcnt = lp->matcnt[lp->nbaz[j]];
00814 mbeg = lp->matbeg[lp->nbaz[j]];
00815 for (i = 0; i < mcnt; i++)
00816 mpf_EGlpNumAddInnProdTo (wAj, lp->matval[mbeg + i], v[lp->matind[mbeg + i]]);
00817
00818
00819 mpf_EGlpNumCopy(ntmp,zAj);
00820 mpf_EGlpNumMultTo(ntmp,normj);
00821 mpf_EGlpNumDivTo(ntmp,yl);
00822 mpf_EGlpNumSubTo(ntmp,wAj);
00823 mpf_EGlpNumSubTo(ntmp,wAj);
00824 mpf_EGlpNumMultTo(ntmp,zAj);
00825 mpf_EGlpNumDivTo(ntmp,yl);
00826
00827 mpf_EGlpNumAddTo(psinfo->norms[j],ntmp);
00828 if (mpf_EGlpNumIsLess (psinfo->norms[j], mpf_oneLpNum))
00829 mpf_EGlpNumOne (psinfo->norms[j]);
00830 }
00831
00832 mpf_EGlpNumCopyFrac (psinfo->norms[eindex], normj, yl);
00833 mpf_EGlpNumDivTo (psinfo->norms[eindex], yl);
00834 if (mpf_EGlpNumIsLess (psinfo->norms[eindex], mpf_oneLpNum))
00835 mpf_EGlpNumOne (psinfo->norms[eindex]);
00836
00837 mpf_ILLfct_zero_workvector (lp);
00838 mpf_EGlpNumClearVar (wAj);
00839 mpf_EGlpNumClearVar (zAj);
00840 mpf_EGlpNumClearVar (normj);
00841 mpf_EGlpNumClearVar (ntmp);
00842 }
00843
00844 int mpf_ILLprice_build_ddevex_norms (
00845 mpf_lpinfo * const lp,
00846 mpf_d_devex_info * const ddinfo,
00847 int const reinit)
00848 {
00849 int i;
00850 int rval = 0;
00851
00852 if (reinit == 0)
00853 {
00854 ddinfo->ninit = 0;
00855 ddinfo->norms = mpf_EGlpNumAllocArray (lp->nrows);
00856 ILL_SAFE_MALLOC (ddinfo->refframe, lp->ncols, int);
00857 }
00858 if (reinit != 0)
00859 ddinfo->ninit++;
00860
00861 for (i = 0; i < lp->ncols; i++)
00862 ddinfo->refframe[i] = (lp->vstat[i] == STAT_BASIC) ? 1 : 0;
00863
00864 for (i = 0; i < lp->nrows; i++)
00865 mpf_EGlpNumOne (ddinfo->norms[i]);
00866
00867 CLEANUP:
00868 if (rval)
00869 {
00870 mpf_EGlpNumFreeArray (ddinfo->norms);
00871 ILL_IFFREE (ddinfo->refframe, int);
00872 }
00873 EG_RETURN(rval);
00874 }
00875
00876 int mpf_ILLprice_update_ddevex_norms (
00877 mpf_lpinfo * const lp,
00878 mpf_d_devex_info * const ddinfo,
00879 int const lindex,
00880 mpf_t yl)
00881 {
00882 int i, r;
00883 mpf_t normi;
00884 mpf_t yr;
00885 mpf_t ntmp,ntmp2;
00886
00887 mpf_EGlpNumInitVar (ntmp);
00888 mpf_EGlpNumInitVar (ntmp2);
00889 mpf_EGlpNumInitVar (normi);
00890 mpf_EGlpNumInitVar (yr);
00891 mpf_EGlpNumZero (normi);
00892
00893 for (i = 0; i < lp->zA.nzcnt; i++)
00894 if (ddinfo->refframe[lp->nbaz[lp->zA.indx[i]]])
00895 mpf_EGlpNumAddInnProdTo (normi, lp->zA.coef[i], lp->zA.coef[i]);
00896
00897 if (ddinfo->refframe[lp->baz[lindex]])
00898 mpf_EGlpNumAddTo (normi, mpf_oneLpNum);
00899
00900 mpf_EGlpNumSet(ntmp,1000.0);
00901 mpf_EGlpNumSet(ntmp2,0.001);
00902 mpf_EGlpNumMultTo(ntmp,ddinfo->norms[lindex]);
00903 mpf_EGlpNumMultTo(ntmp2,ddinfo->norms[lindex]);
00904 if (mpf_EGlpNumIsLess(normi, ntmp2) || mpf_EGlpNumIsLess(ntmp, normi))
00905 {
00906 mpf_EGlpNumClearVar (normi);
00907 mpf_EGlpNumClearVar (yr);
00908 mpf_EGlpNumClearVar (ntmp);
00909 mpf_EGlpNumClearVar (ntmp2);
00910 return mpf_ILLprice_build_ddevex_norms (lp, ddinfo, 1);
00911 }
00912
00913 for (i = 0; i < lp->yjz.nzcnt; i++)
00914 {
00915 r = lp->yjz.indx[i];
00916 mpf_EGlpNumCopy(yr, lp->yjz.coef[i]);
00917 mpf_EGlpNumCopy(ntmp,yr);
00918 mpf_EGlpNumMultTo(ntmp,yr);
00919 mpf_EGlpNumMultTo(ntmp,normi);
00920 mpf_EGlpNumDivTo(ntmp,yl);
00921 mpf_EGlpNumDivTo(ntmp,yl);
00922 if (mpf_EGlpNumIsLess (ddinfo->norms[r], ntmp))
00923 mpf_EGlpNumCopy (ddinfo->norms[r], ntmp);
00924 }
00925 mpf_EGlpNumCopy (ddinfo->norms[lindex], normi);
00926 mpf_EGlpNumDivTo(ddinfo->norms[lindex], yl);
00927 mpf_EGlpNumDivTo(ddinfo->norms[lindex], yl);
00928 if (mpf_EGlpNumIsLess (ddinfo->norms[lindex], mpf_oneLpNum))
00929 mpf_EGlpNumOne (ddinfo->norms[lindex]);
00930 mpf_EGlpNumClearVar (normi);
00931 mpf_EGlpNumClearVar (yr);
00932 mpf_EGlpNumClearVar (ntmp);
00933 mpf_EGlpNumClearVar (ntmp2);
00934 return 0;
00935 }
00936
00937 int mpf_ILLprice_build_dsteep_norms (
00938 mpf_lpinfo * const lp,
00939 mpf_d_steep_info * const dsinfo)
00940 {
00941 int i;
00942 int rval = 0;
00943 mpf_svector z;
00944
00945 mpf_ILLsvector_init (&z);
00946 rval = mpf_ILLsvector_alloc (&z, lp->nrows);
00947 CHECKRVALG(rval,CLEANUP);
00948 dsinfo->norms = mpf_EGlpNumAllocArray (lp->nrows);
00949
00950 for (i = 0; i < lp->nrows; i++)
00951 {
00952 rval = ILLstring_report (NULL, &lp->O->reporter);
00953 CHECKRVALG(rval,CLEANUP);
00954
00955 mpf_ILLfct_compute_zz (lp, &z, i);
00956
00957 mpf_EGlpNumInnProd (dsinfo->norms[i], z.coef, z.coef, (size_t) z.nzcnt);
00958 if (mpf_EGlpNumIsLess (dsinfo->norms[i], mpf_PARAM_MIN_DNORM))
00959 mpf_EGlpNumCopy (dsinfo->norms[i], mpf_PARAM_MIN_DNORM);
00960 }
00961
00962 CLEANUP:
00963 mpf_ILLsvector_free (&z);
00964 if (rval)
00965 mpf_EGlpNumFreeArray (dsinfo->norms);
00966
00967 EG_RETURN(rval);
00968 }
00969
00970 int mpf_ILLprice_get_dsteep_norms (
00971 mpf_lpinfo * const lp,
00972 int const count,
00973 int *const rowind,
00974 mpf_t * const norms)
00975 {
00976 int i;
00977 int rval = 0;
00978 mpf_svector z;
00979
00980 mpf_ILLsvector_init (&z);
00981 rval = mpf_ILLsvector_alloc (&z, lp->nrows);
00982 CHECKRVALG(rval,CLEANUP);
00983
00984 for (i = 0; i < count; i++)
00985 {
00986 mpf_ILLfct_compute_zz (lp, &z, rowind[i]);
00987 mpf_EGlpNumInnProd (norms[i], z.coef, z.coef, (size_t) z.nzcnt);
00988 }
00989
00990 CLEANUP:
00991 mpf_ILLsvector_free (&z);
00992 EG_RETURN(rval);
00993 }
00994
00995 void mpf_ILLprice_update_dsteep_norms (
00996 mpf_lpinfo * const lp,
00997 mpf_d_steep_info * const dsinfo,
00998 mpf_svector * const wz,
00999 int const lindex,
01000 mpf_t yl)
01001 {
01002 int i, k;
01003 mpf_t yij;
01004 mpf_t norml;
01005 mpf_t *v = 0;
01006 mpf_t ntmp;
01007
01008 mpf_EGlpNumInitVar (ntmp);
01009 mpf_EGlpNumInitVar (norml);
01010 mpf_EGlpNumInitVar (yij);
01011 mpf_EGlpNumInnProd (norml, lp->zz.coef, lp->zz.coef, (size_t) (lp->zz.nzcnt));
01012
01013 #if 0
01014 Bico - remove warnings for dist
01015 if (fabs ((norml - dsinfo->norms[lindex]) / norml) > 1000.0 )
01016 {
01017 printf ("warning: incorrect dnorm values\n");
01018 printf ("anorm = %.6f, pnorm = %.6f\n", norml, dsinfo->norms[lindex]);
01019 fflush (stdout);
01020 }
01021 #endif
01022
01023 mpf_ILLfct_load_workvector (lp, wz);
01024 v = lp->work.coef;
01025
01026 for (k = 0; k < lp->yjz.nzcnt; k++)
01027 {
01028 i = lp->yjz.indx[k];
01029 mpf_EGlpNumCopy (yij, lp->yjz.coef[k]);
01030
01031 mpf_EGlpNumCopy(ntmp,yij);
01032 mpf_EGlpNumMultTo(ntmp,norml);
01033 mpf_EGlpNumDivTo(ntmp,yl);
01034 mpf_EGlpNumSubTo(ntmp,v[i]);
01035 mpf_EGlpNumSubTo(ntmp,v[i]);
01036 mpf_EGlpNumMultTo (ntmp, yij);
01037 mpf_EGlpNumDivTo (ntmp, yl);
01038
01039 mpf_EGlpNumAddTo(dsinfo->norms[i], ntmp);
01040 if (mpf_EGlpNumIsLess (dsinfo->norms[i], mpf_PARAM_MIN_DNORM))
01041 mpf_EGlpNumCopy (dsinfo->norms[i], mpf_PARAM_MIN_DNORM);
01042 }
01043 mpf_EGlpNumCopyFrac (dsinfo->norms[lindex], norml, yl);
01044 mpf_EGlpNumDivTo (dsinfo->norms[lindex], yl);
01045 if (mpf_EGlpNumIsLess (dsinfo->norms[lindex], mpf_PARAM_MIN_DNORM))
01046 mpf_EGlpNumCopy (dsinfo->norms[lindex], mpf_PARAM_MIN_DNORM);
01047
01048 mpf_ILLfct_zero_workvector (lp);
01049 mpf_EGlpNumClearVar (norml);
01050 mpf_EGlpNumClearVar (ntmp);
01051 mpf_EGlpNumClearVar (yij);
01052 }
01053
01054 static void mpf_update_d_scaleinf (
01055 mpf_price_info * const p,
01056 mpf_heap * const h,
01057 int const j,
01058 mpf_t inf,
01059 int const prule)
01060 {
01061 if (!mpf_EGlpNumIsNeqqZero (inf))
01062 {
01063 mpf_EGlpNumZero (p->d_scaleinf[j]);
01064 if (h->hexist != 0 && h->loc[j] != -1)
01065 mpf_ILLheap_delete (h, j);
01066 }
01067 else
01068 {
01069 if (prule == QS_PRICE_PDANTZIG)
01070 mpf_EGlpNumCopy (p->d_scaleinf[j], inf);
01071 else if (prule == QS_PRICE_PDEVEX)
01072 mpf_EGlpNumCopySqrOver (p->d_scaleinf[j], inf, p->pdinfo.norms[j]);
01073 else if (prule == QS_PRICE_PSTEEP)
01074 mpf_EGlpNumCopySqrOver (p->d_scaleinf[j], inf, p->psinfo.norms[j]);
01075
01076 if (h->hexist != 0)
01077 {
01078 if (h->loc[j] == -1)
01079 mpf_ILLheap_insert (h, j);
01080 else
01081 mpf_ILLheap_modify (h, j);
01082 }
01083 }
01084 }
01085
01086 static void mpf_compute_dualI_inf (
01087 mpf_lpinfo * const lp,
01088 const int j,
01089 mpf_t * const inf)
01090 {
01091 int col = lp->nbaz[j];
01092 int vt = lp->vtype[col];
01093 int vs = lp->vstat[col];
01094 mpf_t*dj = &(lp->pIdz[j]);
01095 mpf_t*ftol = &(lp->tol->id_tol);
01096 mpf_EGlpNumZero (*inf);
01097 if (vt != VARTIFICIAL && vt != VFIXED)
01098 {
01099 if( mpf_EGlpNumIsSumLess(*dj,*ftol,mpf_zeroLpNum) && (vs == STAT_LOWER || vs == STAT_ZERO))
01100 mpf_EGlpNumCopyNeg(*inf,*dj);
01101 else if (mpf_EGlpNumIsLess(*ftol, *dj) && (vs == STAT_UPPER || vs == STAT_ZERO))
01102 mpf_EGlpNumCopy (*inf, *dj);
01103 }
01104 }
01105
01106 static void mpf_compute_dualII_inf (
01107 mpf_lpinfo * const lp,
01108 int const j,
01109 mpf_t * const inf)
01110 {
01111 int col = lp->nbaz[j];
01112 int vt = lp->vtype[col];
01113 int vs = lp->vstat[col];
01114 mpf_t*dj = &(lp->dz[j]);
01115 mpf_t*ftol = &(lp->tol->dfeas_tol);
01116 mpf_EGlpNumZero (*inf);
01117 if (vt != VARTIFICIAL && vt != VFIXED)
01118 {
01119 if( mpf_EGlpNumIsSumLess(*dj,*ftol,mpf_zeroLpNum) && (vs == STAT_LOWER || vs == STAT_ZERO))
01120 mpf_EGlpNumCopyNeg(*inf,*dj);
01121 else if (mpf_EGlpNumIsLess(*ftol,*dj) && (vs == STAT_UPPER || vs == STAT_ZERO))
01122 mpf_EGlpNumCopy (*inf, *dj);
01123 }
01124 }
01125
01126 void mpf_ILLprice_compute_dual_inf (
01127 mpf_lpinfo * const lp,
01128 mpf_price_info * const p,
01129 int *const ix,
01130 int const icnt,
01131 int const phase)
01132 {
01133 int i;
01134 int price;
01135 mpf_t inf;
01136 mpf_heap *h = &(p->h);
01137
01138 price = (phase == PRIMAL_PHASEI) ? p->pI_price : p->pII_price;
01139 mpf_EGlpNumInitVar (inf);
01140 mpf_EGlpNumZero (inf);
01141
01142 if (phase == PRIMAL_PHASEI)
01143 {
01144 if (ix == NULL)
01145 for (i = 0; i < lp->nnbasic; i++)
01146 {
01147 mpf_compute_dualI_inf (lp, i, &(inf));
01148 mpf_update_d_scaleinf (p, h, i, inf, price);
01149 }
01150 else
01151 for (i = 0; i < icnt; i++)
01152 {
01153 mpf_compute_dualI_inf (lp, ix[i], &(inf));
01154 mpf_update_d_scaleinf (p, h, ix[i], inf, price);
01155 }
01156 }
01157 else if (phase == PRIMAL_PHASEII)
01158 {
01159 if (ix == NULL)
01160 for (i = 0; i < lp->nnbasic; i++)
01161 {
01162 mpf_compute_dualII_inf (lp, i, &inf);
01163 mpf_update_d_scaleinf (p, h, i, inf, price);
01164 }
01165 else
01166 for (i = 0; i < icnt; i++)
01167 {
01168 mpf_compute_dualII_inf (lp, ix[i], &inf);
01169 mpf_update_d_scaleinf (p, h, ix[i], inf, price);
01170 }
01171 }
01172 mpf_EGlpNumClearVar (inf);
01173 }
01174
01175 void mpf_ILLprice_primal (
01176 mpf_lpinfo * const lp,
01177 mpf_price_info * const pinf,
01178 mpf_price_res * const pr,
01179 int const phase)
01180 {
01181 int j, vs;
01182 mpf_t d_e, d_max;
01183 mpf_t *ftol = &(lp->tol->dfeas_tol);
01184 mpf_heap *const h = &(pinf->h);
01185
01186 mpf_EGlpNumInitVar (d_e);
01187 mpf_EGlpNumInitVar (d_max);
01188 pr->eindex = -1;
01189 mpf_EGlpNumZero(d_max);
01190
01191 #if USEHEAP > 0
01192 mpf_ILLprice_test_for_heap (lp, pinf, lp->nnbasic, pinf->d_scaleinf,
01193 PRIMAL_SIMPLEX, 1);
01194 #endif
01195
01196 if (pinf->p_strategy == COMPLETE_PRICING)
01197 {
01198 if (h->hexist)
01199 {
01200 pr->eindex = mpf_ILLheap_findmin (h);
01201 if (pr->eindex != -1)
01202 mpf_ILLheap_delete (h, pr->eindex);
01203 }
01204 else
01205 {
01206 for (j = 0; j < lp->nnbasic; j++)
01207 {
01208 if (mpf_EGlpNumIsLess (d_max, pinf->d_scaleinf[j]))
01209 {
01210 mpf_EGlpNumCopy (d_max, pinf->d_scaleinf[j]);
01211 pr->eindex = j;
01212 }
01213 }
01214 }
01215 }
01216 else if (pinf->p_strategy == MULTI_PART_PRICING)
01217 {
01218 for (j = 0; j < pinf->pmpinfo.bsize; j++)
01219 {
01220 if (mpf_EGlpNumIsLess (d_max, pinf->pmpinfo.infeas[j]))
01221 {
01222 mpf_EGlpNumCopy (d_max, pinf->pmpinfo.infeas[j]);
01223 pr->eindex = pinf->pmpinfo.bucket[j];
01224 }
01225 }
01226 }
01227
01228 if (pr->eindex < 0)
01229 pr->price_stat = PRICE_OPTIMAL;
01230 else
01231 {
01232 if (phase == PRIMAL_PHASEI)
01233 mpf_EGlpNumCopy (d_e, lp->pIdz[pr->eindex]);
01234 else
01235 mpf_EGlpNumCopy (d_e, lp->dz[pr->eindex]);
01236 vs = lp->vstat[lp->nbaz[pr->eindex]];
01237
01238 pr->price_stat = PRICE_NONOPTIMAL;
01239 if (vs == STAT_UPPER || (vs == STAT_ZERO && mpf_EGlpNumIsLess (*ftol, d_e)))
01240 pr->dir = VDECREASE;
01241 else
01242 pr->dir = VINCREASE;
01243 }
01244 mpf_EGlpNumClearVar (d_e);
01245 mpf_EGlpNumClearVar (d_max);
01246 }
01247
01248 static void mpf_update_p_scaleinf (
01249 mpf_price_info * const p,
01250 mpf_heap * const h,
01251 int const i,
01252 mpf_t inf,
01253 int const prule)
01254 {
01255 if (!mpf_EGlpNumIsNeqqZero (inf))
01256 {
01257 mpf_EGlpNumZero (p->p_scaleinf[i]);
01258 if (h->hexist != 0 && h->loc[i] != -1)
01259 mpf_ILLheap_delete (h, i);
01260 }
01261 else
01262 {
01263 if (prule == QS_PRICE_DDANTZIG)
01264 mpf_EGlpNumCopy (p->p_scaleinf[i], inf);
01265 else if (prule == QS_PRICE_DSTEEP)
01266 mpf_EGlpNumCopySqrOver (p->p_scaleinf[i], inf, p->dsinfo.norms[i]);
01267 else if (prule == QS_PRICE_DDEVEX)
01268 mpf_EGlpNumCopySqrOver (p->p_scaleinf[i], inf, p->ddinfo.norms[i]);
01269
01270 if (h->hexist != 0)
01271 {
01272 if (h->loc[i] == -1)
01273 mpf_ILLheap_insert (h, i);
01274 else
01275 mpf_ILLheap_modify (h, i);
01276 }
01277 }
01278 }
01279
01280 static void mpf_compute_primalI_inf (
01281 mpf_lpinfo * const lp,
01282 int const i,
01283 mpf_t * const inf)
01284 {
01285 int const col = lp->baz[i];
01286 mpf_t*x = &(lp->xbz[i]);
01287 mpf_t*l = &(lp->lz[col]);
01288 mpf_t*u = &(lp->uz[col]);
01289 mpf_t*ftol = &(lp->tol->ip_tol);
01290 mpf_EGlpNumZero (*inf);
01291
01292 if (mpf_EGlpNumIsLess (*ftol, *x) && mpf_EGlpNumIsNeqq (*u, mpf_INFTY))
01293 mpf_EGlpNumCopy (*inf, *x);
01294 else if (mpf_EGlpNumIsNeqq (*l, mpf_NINFTY) && mpf_EGlpNumIsSumLess (*x, *ftol,mpf_zeroLpNum))
01295 mpf_EGlpNumCopy (*inf, *x);
01296 }
01297
01298 static void mpf_compute_primalII_inf (
01299 mpf_lpinfo * const lp,
01300 int const i,
01301 mpf_t * const inf)
01302 {
01303 int const col = lp->baz[i];
01304 mpf_t*x = &(lp->xbz[i]);
01305 mpf_t*l = &(lp->lz[col]);
01306 mpf_t*u = &(lp->uz[col]);
01307 mpf_t*ftol = &(lp->tol->pfeas_tol);
01308 mpf_EGlpNumZero (*inf);
01309
01310 if (mpf_EGlpNumIsNeqq (*u, mpf_INFTY) && mpf_EGlpNumIsSumLess (*u, *ftol, *x))
01311 mpf_EGlpNumCopyDiff (*inf, *x, *u);
01312 else if (mpf_EGlpNumIsNeqq (*l, mpf_NINFTY) && mpf_EGlpNumIsSumLess (*x, *ftol, *l))
01313 mpf_EGlpNumCopyDiff (*inf, *l, *x);
01314 }
01315
01316 void mpf_ILLprice_compute_primal_inf (
01317 mpf_lpinfo * const lp,
01318 mpf_price_info * const p,
01319 int *const ix,
01320 int const icnt,
01321 int const phase)
01322 {
01323 int i;
01324 int price;
01325 mpf_t inf;
01326 mpf_heap *h = &(p->h);
01327
01328 price = (phase == DUAL_PHASEI) ? p->dI_price : p->dII_price;
01329 mpf_EGlpNumInitVar (inf);
01330 mpf_EGlpNumZero (inf);
01331
01332 if (phase == DUAL_PHASEI)
01333 {
01334 if (ix == NULL)
01335 for (i = 0; i < lp->nrows; i++)
01336 {
01337 mpf_compute_primalI_inf (lp, i, &inf);
01338 mpf_update_p_scaleinf (p, h, i, inf, price);
01339 }
01340 else
01341 for (i = 0; i < icnt; i++)
01342 {
01343 mpf_compute_primalI_inf (lp, ix[i], &inf);
01344 mpf_update_p_scaleinf (p, h, ix[i], inf, price);
01345 }
01346 }
01347 else if (phase == DUAL_PHASEII)
01348 {
01349 if (ix == NULL)
01350 for (i = 0; i < lp->nrows; i++)
01351 {
01352 mpf_compute_primalII_inf (lp, i, &inf);
01353 mpf_update_p_scaleinf (p, h, i, inf, price);
01354 }
01355 else
01356 for (i = 0; i < icnt; i++)
01357 {
01358 mpf_compute_primalII_inf (lp, ix[i], &inf);
01359 mpf_update_p_scaleinf (p, h, ix[i], inf, price);
01360 }
01361 }
01362 mpf_EGlpNumClearVar (inf);
01363 }
01364
01365 void mpf_ILLprice_dual (
01366 mpf_lpinfo * const lp,
01367 mpf_price_info * const pinf,
01368 int const phase,
01369 mpf_price_res * const pr)
01370 {
01371 int i;
01372 mpf_t p_max;
01373 mpf_t ubound;
01374 mpf_t*ftol = &(lp->tol->pfeas_tol);
01375 mpf_heap *const h = &(pinf->h);
01376
01377 mpf_EGlpNumInitVar (p_max);
01378 mpf_EGlpNumInitVar (ubound);
01379 pr->lindex = -1;
01380 mpf_EGlpNumZero(p_max);
01381
01382 #if USEHEAP > 0
01383 mpf_ILLprice_test_for_heap (lp, pinf, lp->nrows, pinf->p_scaleinf, DUAL_SIMPLEX,
01384 1);
01385 #endif
01386
01387 if (pinf->d_strategy == COMPLETE_PRICING)
01388 {
01389 if (h->hexist)
01390 {
01391 pr->lindex = mpf_ILLheap_findmin (h);
01392 if (pr->lindex != -1)
01393 mpf_ILLheap_delete (h, pr->lindex);
01394 }
01395 else
01396 {
01397 for (i = 0; i < lp->nrows; i++)
01398 {
01399 if (mpf_EGlpNumIsLess (p_max, pinf->p_scaleinf[i]))
01400 {
01401 mpf_EGlpNumCopy (p_max, pinf->p_scaleinf[i]);
01402 pr->lindex = i;
01403 }
01404 }
01405 }
01406 }
01407 else if (pinf->d_strategy == MULTI_PART_PRICING)
01408 {
01409 for (i = 0; i < pinf->dmpinfo.bsize; i++)
01410 {
01411 if (mpf_EGlpNumIsLess (p_max, pinf->dmpinfo.infeas[i]))
01412 {
01413 mpf_EGlpNumCopy (p_max, pinf->dmpinfo.infeas[i]);
01414 pr->lindex = pinf->dmpinfo.bucket[i];
01415 }
01416 }
01417 }
01418
01419 if (pr->lindex < 0)
01420 pr->price_stat = PRICE_OPTIMAL;
01421 else
01422 {
01423 pr->price_stat = NONOPTIMAL;
01424
01425 if (mpf_EGlpNumIsNeqq (lp->uz[lp->baz[pr->lindex]], mpf_INFTY))
01426 {
01427 if (phase == DUAL_PHASEI)
01428 mpf_EGlpNumZero(ubound);
01429 else
01430 mpf_EGlpNumCopy(ubound,lp->uz[lp->baz[pr->lindex]]);
01431 if (mpf_EGlpNumIsSumLess (*ftol, ubound, lp->xbz[pr->lindex]))
01432 pr->lvstat = STAT_UPPER;
01433 else
01434 pr->lvstat = STAT_LOWER;
01435 }
01436 else
01437 pr->lvstat = STAT_LOWER;
01438 }
01439 mpf_EGlpNumClearVar (p_max);
01440 mpf_EGlpNumClearVar (ubound);
01441 }
01442
01443 int mpf_ILLprice_get_rownorms (
01444 mpf_lpinfo * const lp,
01445 mpf_price_info * const pinf,
01446 mpf_t * const rnorms)
01447 {
01448 int rval = 0;
01449 int i;
01450
01451 if (pinf->dsinfo.norms == NULL)
01452 {
01453 rval = mpf_ILLprice_build_dsteep_norms (lp, &(pinf->dsinfo));
01454 CHECKRVALG(rval,CLEANUP);
01455 }
01456 for (i = 0; i < lp->nrows; i++)
01457 mpf_EGlpNumCopy (rnorms[i], pinf->dsinfo.norms[i]);
01458
01459 CLEANUP:
01460 if (rval)
01461 mpf_EGlpNumFreeArray (pinf->dsinfo.norms);
01462
01463 return rval;
01464 }
01465
01466 int mpf_ILLprice_get_colnorms (
01467 mpf_lpinfo * const lp,
01468 mpf_price_info * const pinf,
01469 mpf_t * const cnorms)
01470 {
01471 int rval = 0;
01472 int i, j;
01473
01474 if (pinf->psinfo.norms == NULL)
01475 {
01476 rval = mpf_ILLprice_build_psteep_norms (lp, &(pinf->psinfo));
01477 CHECKRVALG(rval,CLEANUP);
01478 }
01479 for (i = 0; i < lp->nrows; i++)
01480 mpf_EGlpNumZero (cnorms[lp->baz[i]]);
01481 for (j = 0; j < lp->nnbasic; j++)
01482 mpf_EGlpNumCopy (cnorms[lp->nbaz[j]], pinf->psinfo.norms[j]);
01483
01484 CLEANUP:
01485 if (rval)
01486 mpf_EGlpNumFreeArray (pinf->psinfo.norms);
01487
01488 return rval;
01489 }
01490
01491 int mpf_ILLprice_get_newnorms (
01492 mpf_lpinfo * const lp,
01493 int const nelems,
01494 mpf_t * const norms,
01495 int *const matcnt,
01496 int *const matbeg,
01497 int *const matind,
01498 mpf_t * const matval,
01499 int const option)
01500 {
01501 int i, j;
01502 int rval = 0;
01503 mpf_svector a;
01504 mpf_svector y;
01505
01506 mpf_ILLsvector_init (&y);
01507 rval = mpf_ILLsvector_alloc (&y, lp->nrows);
01508 CHECKRVALG(rval,CLEANUP);
01509
01510 for (j = 0; j < nelems; j++)
01511 {
01512 a.nzcnt = matcnt[j];
01513 a.indx = &(matind[matbeg[j]]);
01514 a.coef = &(matval[matbeg[j]]);
01515
01516 if (option == COLUMN_SOLVE)
01517 mpf_ILLbasis_column_solve (lp, &a, &y);
01518 else
01519 mpf_ILLbasis_row_solve (lp, &a, &y);
01520
01521 mpf_EGlpNumOne (norms[j]);
01522 for (i = 0; i < y.nzcnt; i++)
01523 mpf_EGlpNumAddInnProdTo (norms[j], y.coef[i], y.coef[i]);
01524 }
01525
01526 CLEANUP:
01527 mpf_ILLsvector_free (&y);
01528 EG_RETURN(rval);
01529 }
01530
01531 int mpf_ILLprice_get_new_rownorms (
01532 mpf_lpinfo * const lp,
01533 int const newrows,
01534 mpf_t * const rnorms,
01535 int *const rmatcnt,
01536 int *const rmatbeg,
01537 int *const rmatind,
01538 mpf_t * const rmatval)
01539 {
01540 return mpf_ILLprice_get_newnorms (lp, newrows, rnorms, rmatcnt, rmatbeg, rmatind,
01541 rmatval, ROW_SOLVE);
01542 }
01543
01544 int mpf_ILLprice_get_new_colnorms (
01545 mpf_lpinfo * const lp,
01546 int const newrows,
01547 mpf_t * const rnorms,
01548 int *const matcnt,
01549 int *const matbeg,
01550 int *const matind,
01551 mpf_t * const matval)
01552 {
01553 return mpf_ILLprice_get_newnorms (lp, newrows, rnorms, matcnt, matbeg, matind,
01554 matval, COLUMN_SOLVE);
01555 }
01556
01557 int mpf_ILLprice_load_rownorms (
01558 mpf_lpinfo * const lp,
01559 mpf_t * const rnorms,
01560 mpf_price_info * const pinf)
01561 {
01562 int i;
01563 int rval = 0;
01564
01565 mpf_EGlpNumFreeArray (pinf->dsinfo.norms);
01566 pinf->dsinfo.norms = mpf_EGlpNumAllocArray (lp->nrows);
01567
01568 for (i = 0; i < lp->nrows; i++)
01569 {
01570 mpf_EGlpNumCopy (pinf->dsinfo.norms[i], rnorms[i]);
01571 if (mpf_EGlpNumIsLess (pinf->dsinfo.norms[i], mpf_PARAM_MIN_DNORM))
01572 mpf_EGlpNumCopy (pinf->dsinfo.norms[i], mpf_PARAM_MIN_DNORM);
01573 }
01574
01575 EG_RETURN(rval);
01576 }
01577
01578 int mpf_ILLprice_load_colnorms (
01579 mpf_lpinfo * const lp,
01580 mpf_t * const cnorms,
01581 mpf_price_info * const pinf)
01582 {
01583 int j;
01584 int rval = 0;
01585
01586 mpf_EGlpNumFreeArray (pinf->psinfo.norms);
01587 pinf->psinfo.norms = mpf_EGlpNumAllocArray (lp->nnbasic);
01588
01589 for (j = 0; j < lp->nnbasic; j++)
01590 {
01591 mpf_EGlpNumCopy (pinf->psinfo.norms[j], cnorms[lp->nbaz[j]]);
01592 if (mpf_EGlpNumIsLess (pinf->psinfo.norms[j], mpf_oneLpNum))
01593 mpf_EGlpNumOne (pinf->psinfo.norms[j]);
01594 }
01595
01596 EG_RETURN(rval);
01597 }
01598
01599 #if mpf_PRICE_DEBUG > 0
01600 void mpf_test_dsteep_norms (
01601 mpf_lpinfo * lp,
01602 mpf_price_info * p)
01603 {
01604 int i, errn = 0;
01605 mpf_t *pn = mpf_EGlpNumAllocArray(lp->nrows);
01606 mpf_t err, diff;
01607 mpf_EGlpNumZero (err);
01608
01609 mpf_EGlpNumInitVar (err);
01610 mpf_EGlpNumInitVar (diff);
01611
01612 mpf_ILLprice_get_dsteep_norms (lp, lp->yjz.nzcnt, lp->yjz.indx, pn);
01613 for (i = 0; i < lp->yjz.nzcnt; i++)
01614 {
01615 mpf_EGlpNumCopyDiff (diff, pn[i], p->dsinfo.norms[lp->yjz.indx[i]]);
01616 mpf_EGlpNumCopyAbs(diff,diff);
01617 if (mpf_EGlpNumIsLess (mpf_PFEAS_TOLER, diff))
01618 {
01619 errn++;
01620 mpf_EGlpNumAddTo (err, diff);
01621 mpf_EGlpNumCopy (p->dsinfo.norms[lp->yjz.indx[i]], pn[i]);
01622 }
01623 }
01624 if (errn)
01625 printf ("%d: dnorm errn = %d, err = %.6f\n", lp->cnts->tot_iter, errn,
01626 mpf_EGlpNumToLf (err));
01627 mpf_EGlpNumFreeArray (pn);
01628 mpf_EGlpNumClearVar (diff);
01629 mpf_EGlpNumClearVar (err);
01630 }
01631 #endif