00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CouenneObject.hpp"
00013 #include "BonChooseVariable.hpp"
00014 #include "CouenneChooseStrong.hpp"
00015 #include "CouenneProblem.hpp"
00016
00017
00018 #define FM_SORT_STRONG
00019 #define FM_SEC_SORT_USEFUL
00020 #define USE_NOT_TRUSTED
00021
00022
00023
00024
00025
00026
00027
00028 using namespace Ipopt;
00029 using namespace Couenne;
00030
00031 const CouNumber estProdEps = 1e-6;
00032
00033 #ifdef COIN_HAS_NTY
00034 #include "Nauty.h"
00035 #endif
00036
00037
00038
00039 struct objStrongPri {
00040
00041 int objIndex_;
00042
00043 int priority_;
00044 double value_;
00045 };
00046
00047 inline bool compStrongPri (struct objStrongPri *one, struct objStrongPri *two) {
00048
00049 return (one -> priority_ < two -> priority_ ||
00050 ((one -> priority_ == two -> priority_) &&
00051 (one -> value_ > two -> value_)));
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 int CouenneChooseStrong::gutsOfSetupList(OsiBranchingInformation *info,
00090 bool initialize)
00091 {
00092 if (numberBeforeTrustedList_ < 0) {
00093 number_not_trusted_ = 1;
00094 printf("CouenneChooseStrong::gutsOfSetupList(): Did not think we were using this; Please double check ...\n");
00095 exit(1);
00096 return OsiChooseVariable::setupList(info, initialize);
00097 }
00098 if (initialize) {
00099 status_=-2;
00100 delete [] goodSolution_;
00101 bestObjectIndex_=-1;
00102 numberStrongDone_=0;
00103 numberStrongIterations_ = 0;
00104 numberStrongFixed_ = 0;
00105 goodSolution_ = NULL;
00106 goodObjectiveValue_ = COIN_DBL_MAX;
00107 number_not_trusted_=0;
00108 }
00109 else {
00110 throw CoinError(CNAME,"setupList","Should not be called with initialize==false");
00111 }
00112 numberOnList_=0;
00113 numberUnsatisfied_=0;
00114 int numberObjects = solver_->numberObjects();
00115 assert (numberObjects);
00116 if (numberObjects>pseudoCosts_.numberObjects()) {
00117
00118
00119
00120
00121
00122 int saveNumberBeforeTrusted = pseudoCosts_.numberBeforeTrusted();
00123 pseudoCosts_.initialize(numberObjects);
00124 pseudoCosts_.setNumberBeforeTrusted(saveNumberBeforeTrusted);
00125 }
00126
00127 int bestPriority = COIN_INT_MAX;
00128
00129
00130 #ifdef FM_SORT_STRONG
00131 int numStr = numberStrong_;
00132 if(isRootNode(info)) {
00133 numStr = numberStrongRoot_;
00134 }
00135 int maximumStrong = CoinMin(numStr, numberObjects) ;
00136 int lastPrio = problem_->getLastPrioSort();
00137 int card_vPriority = 0;
00138 int posEnd_vPriority = numberObjects;
00139 double *vPriority = new double [numberObjects];
00140 double *infeasVal = new double [numberObjects];
00141 int max_most_fra = setup_pseudo_frac_ > 0. ? (int)floor(setup_pseudo_frac_*(double)maximumStrong): 0;
00142 if (setup_pseudo_frac_ > 0.) {
00143 max_most_fra = CoinMax(1, max_most_fra);
00144 }
00145 #else
00146
00147 int putOther = numberObjects;
00148 double check = -COIN_DBL_MAX;
00149 int checkIndex = 0;
00150 int maximumStrong = CoinMin(CoinMax(numberStrong_,numberStrongRoot_),
00151 numberObjects) ;
00152 for (int i=0;i<numberObjects;i++) {
00153 list_[i]=-1;
00154 useful_[i]=0.0;
00155 }
00156
00157 int* list2 = NULL;
00158 double* useful2 = NULL;
00159 double check2 = -COIN_DBL_MAX;
00160 int checkIndex2=0;
00161 int max_most_fra = setup_pseudo_frac_ > 0. ? (int)floor(setup_pseudo_frac_*(double)maximumStrong): 0;
00162 if (setup_pseudo_frac_ > 0.) {
00163 max_most_fra = CoinMax(1, max_most_fra);
00164 }
00165 if (max_most_fra) {
00166 list2 = new int[max_most_fra];
00167 useful2 = new double[max_most_fra];
00168 for (int i=0;i<max_most_fra;i++) {
00169 list2[i]=-1;
00170 useful2[i]=0.0;
00171 }
00172 }
00173 #endif
00174
00175 #ifdef FM_CHECK
00176 const double* upTotalChange = pseudoCosts_.upTotalChange();
00177 const double* downTotalChange = pseudoCosts_.downTotalChange();
00178 int pseudoNum = pseudoCosts_.numberObjects();
00179 for(int i=0; i<pseudoNum; i++) {
00180 if(isnan(upTotalChange[i]) || isinf(upTotalChange[i])) {
00181 printf("CouenneChooseStrong::gutsOfSetupList(): upTotalChange[%d]: not a number or infinite\n", i);
00182 exit(1);
00183 }
00184 if(isnan(downTotalChange[i]) || isinf(downTotalChange[i])) {
00185 printf("CouenneChooseStrong::gutsOfSetupList(): downTotalChange[%d]: not a number or infinite\n", i);
00186 exit(1);
00187 }
00188 }
00189 #endif
00190
00191 double upMultiplier, downMultiplier;
00192 computeMultipliers (upMultiplier, downMultiplier);
00193
00194
00195 bool feasible = true;
00196 const double MAXMIN_CRITERION = maxminCrit(info);
00197
00198 OsiObject **objectOrig = info -> solver_ -> objects ();
00199
00200 std::vector <int> objectInd;
00201
00202 numberObjects = info -> solver_ -> numberObjects ();
00203
00204
00205
00206
00207
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 #ifdef COIN_HAS_NTY
00224
00225 bool useOrbitalBranching = problem_ -> orbitalBranching ();
00226
00227 if (useOrbitalBranching) {
00228
00229 int n = problem_ -> nVars ();
00230
00231
00232
00233
00234
00235
00236 std::vector<std::vector<int> > *orbits = problem_ -> getNtyInfo () -> getOrbits ();
00237
00238
00239
00240 bool nonTrivialOrbits = false;
00241
00242 for (std::vector <std::vector<int> >::iterator i = orbits -> begin ();
00243 i != orbits -> end (); ++i)
00244
00245 if (i -> size () >= 2) {
00246 nonTrivialOrbits = true;
00247 break;
00248 }
00249
00250
00251
00252
00253
00254 if (nonTrivialOrbits) {
00255
00256
00257
00258
00259
00260
00261 int *varObj = new int [n];
00262
00263 CoinFillN (varObj, n, -1);
00264
00265 for (unsigned int i = 0; i < numberObjects; i++) {
00266
00267 int indVar = objectOrig [i] -> columnNumber ();
00268
00269 if ((indVar >= 0) &&
00270 (indVar < n))
00271 varObj [indVar] = i;
00272
00273
00274 }
00275
00276
00277
00278
00279
00280 for (std::vector <std::vector<int> >::iterator i = orbits -> begin ();
00281 i != orbits -> end (); ++i) {
00282
00283 int orbSize = i -> size ();
00284
00285 if (orbSize <= 0)
00286 continue;
00287
00288 if (orbSize == 1) {
00289
00290 int orbVar = (*i) [0];
00291
00292 if ((orbVar < n) &&
00293 (orbVar >= 0)) {
00294
00295 if ((varObj [orbVar] >= 0) &&
00296 (objectOrig [varObj [orbVar]] -> checkInfeasibility (info) > COUENNE_EPS))
00297 objectInd.push_back (varObj [orbVar]);
00298
00299
00300
00301
00302 continue;
00303 }
00304 }
00305
00306
00307
00308
00309 std::vector <struct objStrongPri *> orbitObj;
00310
00311 int
00312 minPri = COIN_INT_MAX,
00313 maxPri = -COIN_INT_MAX;
00314
00315 double
00316 minValue = COIN_DBL_MAX,
00317 maxValue = -COIN_DBL_MAX;
00318
00319 for (std::vector<int>::iterator j = i -> begin ();
00320 j != i -> end (); ++j)
00321
00322 if ((*j < n) && (*j >= 0)) {
00323
00324 int objInd = varObj [*j];
00325
00326 if (objInd < 0)
00327 continue;
00328
00329 int pri = objectOrig [objInd] -> priority ();
00330
00331 if (pri < minPri) minPri = pri;
00332 if (pri > maxPri) maxPri = pri;
00333
00334 double
00335 newValue,
00336 infeas = objectOrig [objInd] -> checkInfeasibility (info),
00337
00338 value = computeUsefulness (MAXMIN_CRITERION,
00339 upMultiplier, downMultiplier, infeas,
00340 objectOrig [objInd], objInd,
00341 newValue);
00342
00343 if (value < minValue) minValue = infeas;
00344 if (value > maxValue) maxValue = infeas;
00345
00346
00347
00348 struct objStrongPri *obj = new struct objStrongPri;
00349
00350 obj -> objIndex_ = objInd;
00351 obj -> priority_ = pri;
00352 obj -> value_ = infeas;
00353
00354 orbitObj. push_back (obj);
00355 }
00356
00357
00358
00359
00360 if (minPri < maxPri)
00361 std::sort (orbitObj.begin (), orbitObj.end (), compStrongPri);
00362
00363
00364
00365
00366
00367 for (std::vector <struct objStrongPri *>::iterator j = orbitObj. begin ();
00368 j != orbitObj. end (); ++j) {
00369
00370
00371
00372 if ((*j) -> value_ > COUENNE_EPS) {
00373
00374
00375
00376
00377 objectInd.push_back ((*j) -> objIndex_);
00378 break;
00379 }
00380 }
00381
00382 for (std::vector <struct objStrongPri *>::iterator j = orbitObj. begin ();
00383 j != orbitObj. end (); ++j)
00384 delete (*j);
00385 }
00386
00387 numberObjects = objectInd.size ();
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 delete [] varObj;
00407 }
00408 }
00409 #endif
00410
00411 bool firstPass = false;
00412
00413
00414 OsiObject **object = info -> solver_ -> objects ();
00415
00416 while (numberOnList_ == 0) {
00417
00418 for (unsigned int i = 0; i < numberObjects; i++) {
00419
00420 int indexObj = ((objectInd.size () > 0) && (i < objectInd.size ())) ? objectInd [i] : i;
00421
00422 int way;
00423
00424 double value = object [indexObj] -> infeasibility (info, way);
00425
00426
00427
00428 #ifdef FM_SORT_STRONG
00429 infeasVal[i] = value;
00430 #endif
00431
00432 double lbForInfeas = 0.0;
00433 if(value > lbForInfeas) {
00434 numberUnsatisfied_++;
00435 if(value >= 1e50) {
00436
00437 feasible=false;
00438 break;
00439 }
00440 int priorityLevel = object[indexObj]->priority();
00441
00442 #ifdef FM_SORT_STRONG
00443 if(priorityLevel < bestPriority) {
00444 bestPriority = priorityLevel;
00445 }
00446 if(priorityLevel > lastPrio) {
00447 posEnd_vPriority--;
00448 vPriority[posEnd_vPriority] = priorityLevel;
00449 list_[posEnd_vPriority] = indexObj;
00450 }
00451 else {
00452 vPriority[card_vPriority] = priorityLevel;
00453 list_[card_vPriority] = indexObj;
00454 card_vPriority++;
00455 }
00456 #else
00457
00458 if(priorityLevel < bestPriority) {
00459 for (int j=maximumStrong-1; j>=0; j--) {
00460 if(list_[j] >= 0) {
00461 int iObject = list_[j];
00462 list_[j]=-1;
00463 useful_[j]=0.0;
00464 list_[--putOther]=iObject;
00465 }
00466 }
00467 maximumStrong = CoinMin(maximumStrong,putOther);
00468 bestPriority = priorityLevel;
00469 check = -COIN_DBL_MAX;
00470 checkIndex = 0;
00471 check2 = -COIN_DBL_MAX;
00472 checkIndex2 = 0;
00473 number_not_trusted_ = 0;
00474 if(max_most_fra > 0) {
00475 for(int j=0; j<max_most_fra; j++) {
00476 list2[j]=-1;
00477 useful2[j]=0.0;
00478 }
00479 }
00480 }
00481 if(priorityLevel == bestPriority) {
00482
00483 double value2;
00484 value = computeUsefulness(MAXMIN_CRITERION,
00485 upMultiplier, downMultiplier, value,
00486 object[indexObj], indexObj, value2);
00487 if(value > check) {
00488
00489 int iObject = list_[checkIndex];
00490 if(iObject >= 0) {
00491 assert (list_[putOther-1]<0);
00492 list_[--putOther]=iObject;
00493 }
00494 list_[checkIndex]= indexObj;
00495 assert (checkIndex<putOther);
00496 useful_[checkIndex]=value;
00497
00498 check=COIN_DBL_MAX;
00499 maximumStrong = CoinMin(maximumStrong,putOther);
00500 for (int j=0; j<maximumStrong; j++) {
00501 if(list_[j]>=0) {
00502 if (useful_[j]<check) {
00503 check=useful_[j];
00504 checkIndex=j;
00505 }
00506 }
00507 else {
00508 check=0.0;
00509 checkIndex = j;
00510 break;
00511 }
00512 }
00513 }
00514 else {
00515
00516 assert (list_[putOther-1]<0);
00517 list_[--putOther] = indexObj;
00518 maximumStrong = CoinMin(maximumStrong,putOther);
00519 }
00520
00521 if((max_most_fra > 0) && (value2 > check2)) {
00522
00523 number_not_trusted_++;
00524 list2[checkIndex2] = indexObj;
00525 useful2[checkIndex2]=value2;
00526
00527 check2=COIN_DBL_MAX;
00528 for(int j=0; j<max_most_fra; j++) {
00529 if(list2[j] >= 0) {
00530 if(useful2[j] < check2) {
00531 check2=useful2[j];
00532 checkIndex2=j;
00533 }
00534 }
00535 else {
00536 check2=0.0;
00537 checkIndex2 = j;
00538 break;
00539 }
00540 }
00541 }
00542 }
00543 else {
00544
00545
00546 assert (list_[putOther-1]<0);
00547 list_[--putOther]= indexObj;
00548 maximumStrong = CoinMin(maximumStrong,putOther);
00549 }
00550 #endif
00551 }
00552 }
00553
00554 #ifdef FM_SORT_STRONG
00555
00556 #ifdef FM_CHECK
00557 if(card_vPriority - posEnd_vPriority + numberObjects != numberUnsatisfied_) {
00558 printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: card_vPriority: %d posEnd_vPriority: %d numberUnsatisfied: %d numberObjects: %d\n",
00559 card_vPriority, posEnd_vPriority, numberUnsatisfied_, numberObjects);
00560 exit(1);
00561 }
00562 #endif
00563
00564 numberOnList_ = 0;
00565 if(feasible) {
00566 int card_smallerThanPrio = card_vPriority;
00567 if(posEnd_vPriority > card_vPriority) {
00568 for(int i=posEnd_vPriority; i<numberObjects; i++) {
00569 list_[card_vPriority] = list_[i];
00570 list_[i] = -1;
00571 vPriority[card_vPriority] = vPriority[i];
00572 card_vPriority++;
00573 }
00574 }
00575 else {
00576 card_vPriority = numberUnsatisfied_;
00577 }
00578
00579 int sortFrom = 0;
00580 int sortUpTo = card_smallerThanPrio;
00581 if(card_smallerThanPrio < maximumStrong) {
00582 sortFrom = card_smallerThanPrio;
00583 sortUpTo = card_vPriority;
00584 }
00585 if(card_vPriority > 0) {
00586 numberOnList_ = (card_vPriority < maximumStrong ? card_vPriority : maximumStrong);
00587
00588 #ifdef FM_ALWAYS_SORT
00589 bool alwaysSort = true;
00590 #else
00591 bool alwaysSort = false;
00592 #endif
00593 if(alwaysSort) {
00594 sortFrom = 0;
00595 sortUpTo = card_vPriority;
00596 }
00597 if((sortUpTo > maximumStrong) || alwaysSort){
00598
00599 CoinSort_2(vPriority + sortFrom, vPriority + sortUpTo,
00600 list_ + sortFrom);
00601 }
00602 for(int i=0; i<card_vPriority; i++) {
00603 int indObj = list_[i];
00604 double value = 0, value2;
00605 value = computeUsefulness(MAXMIN_CRITERION,
00606 upMultiplier, downMultiplier, value,
00607 object[indObj], indObj, value2);
00608
00609 #ifdef OLD_USEFULLNESS
00610 useful_[i] = -value;
00611 #else
00612 if ((sortCrit_ & 1) == 0) {
00613 useful_[i] = -value;
00614 }
00615 else {
00616 useful_[i] = value;
00617 }
00618 #endif
00619
00620 #ifdef USE_NOT_TRUSTED
00621 if(value2 < -COIN_DBL_MAX / 10) {
00622 infeasVal[i] = -COIN_DBL_MAX;
00623 }
00624 #endif
00625 }
00626
00627 #ifdef USE_NOT_TRUSTED
00628
00629 if((card_vPriority > maximumStrong) &&
00630 (vPriority[maximumStrong] < bestPriority + COUENNE_EPS)) {
00631
00632
00633 int cardFrac = 0;
00634 int *fracInd = new int[card_vPriority];
00635
00636 double *fracVal = new double[card_vPriority];
00637
00638
00639 for(int i=0; i<card_vPriority; i++) {
00640
00641 if(vPriority[i] < bestPriority + COUENNE_EPS) {
00642 if(infeasVal[i] > -COIN_DBL_MAX/10) {
00643 fracInd[cardFrac] = i;
00644 fracVal[cardFrac] = -infeasVal[i];
00645 cardFrac++;
00646 }
00647 }
00648 }
00649
00650 if(max_most_fra > 0) {
00651
00652
00653 if(cardFrac > max_most_fra) {
00654 CoinSort_2(fracVal, fracVal+cardFrac, fracInd);
00655 }
00656 for(int i=0; i<cardFrac; i++) {
00657 useful_[fracInd[i]] =
00658 -1e150*(1. + infeasVal[fracInd[i]]);
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 number_not_trusted_++;
00670 if(i == max_most_fra - 1) {
00671 break;
00672 }
00673 }
00674 }
00675 delete[] fracInd;
00676 delete[] fracVal;
00677 }
00678 #endif
00679 }
00680
00681
00682
00683 #ifdef FM_SEC_SORT_USEFUL
00684 CoinSort_2(useful_, useful_ + card_vPriority, list_);
00685 #else
00686 #ifdef FM_ALWAYS_SORT
00687 int from = 0, upto = 1;
00688 while(upto < card_vPriority) {
00689 while(vPriority[upto] == vPriority[from]) {
00690 upto++;
00691 if(upto == card_vPriority) {
00692 break;
00693 }
00694 }
00695 CoinSort_2(useful_+from, useful_+upto, list_+from);
00696 from = upto;
00697 upto = from+1;
00698 }
00699 #else
00700 if(sortUpTo > maximumStrong) {
00701
00702
00703 int from = maximumStrong-1, upto = maximumStrong;
00704 int msPrio = vPriority[maximumStrong-1];
00705 problem_->setLastPrioSort(msPrio);
00706 while((from > -1) && (vPriority[from] == msPrio)) {
00707 from--;
00708 }
00709 from++;
00710 while((upto < sortUpTo) && (vPriority[upto] == msPrio)) {
00711 upto++;
00712 }
00713
00714
00715 CoinSort_2(useful_+from, useful_+upto, list_+from);
00716 }
00717
00718 #endif
00719
00720 #ifdef FM_CHECK
00721
00722 double ckPrio = (card_vPriority < numberUnsatisfied_ ?
00723 vPriority[card_vPriority] : 100000);
00724 double ckUse = (card_vPriority < numberUnsatisfied_ ?
00725 useful_[card_vPriority] : 100000);
00726 for(int i=0; i<card_vPriority; i++) {
00727 int indObj = list_[i];
00728 if(object[indObj]->priority() > ckPrio + 1e-3) {
00729 printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->priority(): %d > ckPrio: %d\n",
00730 indObj, object[indObj]->priority(), ckPrio);
00731 exit(1);
00732 }
00733 if(fabs(object[indObj]->priority() - ckPrio) < 1e-3) {
00734 if(useful_[i] > ckUse + 1e-3) {
00735 printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->useful: %f > ckUse: %d\n",
00736 indObj, useful_[i], ckUse);
00737 exit(1);
00738 }
00739 }
00740 }
00741 for(int i=card_vPriority; i<numberUnsatisfied_; i++) {
00742 int indObj = list_[i];
00743 if(object[indObj]->priority() < ckPrio - 1e-3) {
00744 printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->priority(): %d < ckPrio: %d\n",
00745 indObj, object[indObj]->priority(), ckPrio);
00746 exit(1);
00747 }
00748 if(fabs(object[indObj]->priority() - ckPrio) < 1e-3) {
00749 if(useful_[i] < ckUse - 1e-3) {
00750 printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->useful: %f < ckUse: %d\n",
00751 indObj, useful_[i], ckUse);
00752 exit(1);
00753 }
00754 }
00755 }
00756 #endif
00757 #endif
00758 }
00759 else {
00760 numberUnsatisfied_ = -1;
00761 }
00762 #else
00763
00764 numberOnList_=0;
00765 if (feasible) {
00766 maximumStrong = CoinMin(maximumStrong,putOther);
00767 for (int i=0;i<maximumStrong;i++) {
00768 if (list_[i]>=0) {
00769 #ifdef OLD_USEFULLNESS
00770 list_[numberOnList_]=list_[i];
00771 useful_[numberOnList_++]=-useful_[i];
00772
00773 #else
00774 list_[numberOnList_]=list_[i];
00775 if ((sortCrit_ & 1) == 0) {
00776 useful_[numberOnList_++]=-useful_[i];
00777 }
00778 else useful_[numberOnList_++] = useful_[i];
00779 #endif
00780 message(CANDIDATE_LIST2)<<numberOnList_-1
00781 <<list_[numberOnList_-1]<<numberOnList_-1<<useful_[numberOnList_-1]
00782 <<CoinMessageEol;
00783 }
00784 }
00785 if (numberOnList_) {
00786 int tmp_on_list = 0;
00787 if (max_most_fra > 0 && numberOnList_ >= maximumStrong) {
00788
00789
00790 number_not_trusted_=0;
00791 for (int i=0;i<max_most_fra;i++) {
00792 if (list2[i]>=0) {
00793 list2[number_not_trusted_] = list2[i];
00794 useful2[number_not_trusted_++] = useful2[i];
00795 message(CANDIDATE_LIST3)<<number_not_trusted_-1
00796 <<list2[number_not_trusted_-1]<<number_not_trusted_-1
00797 <<useful2[number_not_trusted_-1]<<CoinMessageEol;
00798 }
00799 }
00800 if (number_not_trusted_) {
00801 CoinSort_2(list_,list_+numberOnList_,useful_);
00802 CoinSort_2(list2,list2+number_not_trusted_,useful2);
00803 int i1=0;
00804 int i2=0;
00805 for (int i=0; i<numberObjects; i++) {
00806 bool found1 = (list_[i1]==i);
00807 bool found2 = (list2[i2]==i);
00808 if (found1 && found2) {
00809
00810 #ifdef OLD_USEFULLNESS
00811 useful_[i1] = 1e150*(1.+useful2[i2]);
00812 #else
00813 useful_[i1] = -1e150*(1.+useful2[i2]);
00814 #endif
00815 list2[i2] = -1;
00816 }
00817 if (found1) i1++;
00818 if (found2) i2++;
00819 if (i2==max_most_fra) break;
00820 }
00821 for (int i=0; i<number_not_trusted_; i++) {
00822 if (list2[i] >= 0) {
00823 list_[numberOnList_+tmp_on_list] = list2[i];
00824
00825 #ifdef OLD_USEFULLNESS
00826 useful_[numberOnList_+tmp_on_list] = 1e150*(1.+useful2[i]);
00827 #else
00828 useful_[numberOnList_+tmp_on_list] = -1e150*(1.+useful2[i]);
00829 #endif
00830 tmp_on_list++;
00831 }
00832 }
00833 }
00834 }
00835
00836 CoinSort_2(useful_,useful_+numberOnList_+tmp_on_list,list_);
00837
00838 int i = numberOnList_;
00839 for (;putOther<numberObjects;putOther++)
00840 list_[i++]=list_[putOther];
00841 assert (i==numberUnsatisfied_);
00842 if (!CoinMax(numberStrong_,numberStrongRoot_))
00843 numberOnList_=0;
00844 }
00845 }
00846 else {
00847
00848 numberUnsatisfied_=-1;
00849 }
00850 #endif
00851
00852 if(!firstPass) {
00853
00854
00855 break;
00856 }
00857 firstPass = false;
00858 }
00859
00860 #ifdef TRACE_STRONG
00861 if(problem_->doPrint_) {
00862 printf("numberStrong_: %d maximumStrong: %d\n",
00863 numberStrong_, maximumStrong);
00864 }
00865 #endif
00866
00867 #ifdef FM_SORT_STRONG
00868 delete [] vPriority;
00869 delete [] infeasVal;
00870 #else
00871 delete [] list2;
00872 delete [] useful2;
00873 #endif
00874
00875
00876 info->defaultDual_ = -1.0;
00877 delete [] info->usefulRegion_;
00878 delete [] info->indexRegion_;
00879
00880 int way;
00881 if (bb_log_level_>3) {
00882
00883 for (int i=0; i<numberOnList_; i++){
00884 message(CANDIDATE_LIST)<<i<< list_[i]<< i<< useful_[i]
00885 <<object[list_[i]]->infeasibility(info,way)
00886
00887 <<CoinMessageEol;
00888 }
00889 }
00890
00891 #ifdef COIN_HAS_NTY
00892
00893
00894
00895 #endif
00896
00897
00898
00899 if(numberUnsatisfied_ == -1) {
00900 return(-1);
00901 }
00902 return numberOnList_;
00903 }
00904