18 #define FM_SORT_STRONG
19 #define FM_SEC_SORT_USEFUL
20 #define USE_NOT_TRUSTED
28 using namespace Ipopt;
29 using namespace Couenne;
49 return (one -> priority_ < two -> priority_ ||
50 ((one -> priority_ == two -> priority_) &&
51 (one -> value_ > two -> value_)));
89 int CouenneChooseStrong::gutsOfSetupList(OsiBranchingInformation *
info,
92 if (numberBeforeTrustedList_ < 0) {
93 number_not_trusted_ = 1;
94 printf(
"CouenneChooseStrong::gutsOfSetupList(): Did not think we were using this; Please double check ...\n");
96 return OsiChooseVariable::setupList(info, initialize);
100 delete [] goodSolution_;
103 numberStrongIterations_ = 0;
104 numberStrongFixed_ = 0;
105 goodSolution_ = NULL;
106 goodObjectiveValue_ = COIN_DBL_MAX;
107 number_not_trusted_=0;
110 throw CoinError(CNAME,
"setupList",
"Should not be called with initialize==false");
113 numberUnsatisfied_=0;
114 int numberObjects = solver_->numberObjects();
115 assert (numberObjects);
116 if (numberObjects>pseudoCosts_.numberObjects()) {
122 int saveNumberBeforeTrusted = pseudoCosts_.numberBeforeTrusted();
123 pseudoCosts_.initialize(numberObjects);
124 pseudoCosts_.setNumberBeforeTrusted(saveNumberBeforeTrusted);
127 int bestPriority = COIN_INT_MAX;
130 #ifdef FM_SORT_STRONG
131 int numStr = numberStrong_;
132 if(isRootNode(info)) {
133 numStr = numberStrongRoot_;
135 int maximumStrong = CoinMin(numStr, numberObjects) ;
136 int lastPrio = problem_->getLastPrioSort();
137 int card_vPriority = 0;
138 int posEnd_vPriority = numberObjects;
139 double *vPriority =
new double [numberObjects];
140 double *infeasVal =
new double [numberObjects];
141 int max_most_fra = setup_pseudo_frac_ > 0. ? (
int)floor(setup_pseudo_frac_*(
double)maximumStrong): 0;
142 if (setup_pseudo_frac_ > 0.) {
143 max_most_fra = CoinMax(1, max_most_fra);
147 int putOther = numberObjects;
148 double check = -COIN_DBL_MAX;
150 int maximumStrong = CoinMin(CoinMax(numberStrong_,numberStrongRoot_),
152 for (
int i=0;i<numberObjects;i++) {
158 double* useful2 = NULL;
159 double check2 = -COIN_DBL_MAX;
161 int max_most_fra = setup_pseudo_frac_ > 0. ? (
int)floor(setup_pseudo_frac_*(
double)maximumStrong): 0;
162 if (setup_pseudo_frac_ > 0.) {
163 max_most_fra = CoinMax(1, max_most_fra);
166 list2 =
new int[max_most_fra];
167 useful2 =
new double[max_most_fra];
168 for (
int i=0;i<max_most_fra;i++) {
176 const double* upTotalChange = pseudoCosts_.upTotalChange();
177 const double* downTotalChange = pseudoCosts_.downTotalChange();
178 int pseudoNum = pseudoCosts_.numberObjects();
179 for(
int i=0; i<pseudoNum; i++) {
180 if(isnan(upTotalChange[i]) || isinf(upTotalChange[i])) {
181 printf(
"CouenneChooseStrong::gutsOfSetupList(): upTotalChange[%d]: not a number or infinite\n", i);
184 if(isnan(downTotalChange[i]) || isinf(downTotalChange[i])) {
185 printf(
"CouenneChooseStrong::gutsOfSetupList(): downTotalChange[%d]: not a number or infinite\n", i);
191 double upMultiplier, downMultiplier;
192 computeMultipliers (upMultiplier, downMultiplier);
195 bool feasible =
true;
196 const double MAXMIN_CRITERION = maxminCrit(info);
198 OsiObject **objectOrig = info -> solver_ -> objects ();
200 std::vector <int> objectInd;
202 numberObjects = info -> solver_ -> numberObjects ();
225 bool useOrbitalBranching = problem_ -> orbitalBranching ();
227 if (useOrbitalBranching) {
229 int n = problem_ -> nVars ();
236 std::vector<std::vector<int> > *orbits = problem_ -> getNtyInfo () -> getOrbits ();
240 bool nonTrivialOrbits =
false;
242 for (std::vector <std::vector<int> >::iterator i = orbits -> begin ();
243 i != orbits ->
end (); ++i)
245 if (i -> size () >= 2) {
246 nonTrivialOrbits =
true;
254 if (nonTrivialOrbits) {
261 int *varObj =
new int [
n];
263 CoinFillN (varObj, n, -1);
265 for (
unsigned int i = 0; i < numberObjects; i++) {
267 int indVar = objectOrig [i] -> columnNumber ();
280 for (std::vector <std::vector<int> >::iterator i = orbits -> begin ();
281 i != orbits ->
end (); ++i) {
283 int orbSize = i -> size ();
290 int orbVar = (*i) [0];
295 if ((varObj [orbVar] >= 0) &&
296 (objectOrig [varObj [orbVar]] -> checkInfeasibility (info) >
COUENNE_EPS))
297 objectInd.push_back (varObj [orbVar]);
309 std::vector <struct objStrongPri *> orbitObj;
312 minPri = COIN_INT_MAX,
313 maxPri = -COIN_INT_MAX;
316 minValue = COIN_DBL_MAX,
317 maxValue = -COIN_DBL_MAX;
319 for (std::vector<int>::iterator
j = i -> begin ();
320 j != i ->
end (); ++
j)
322 if ((*
j < n) && (*
j >= 0)) {
324 int objInd = varObj [*
j];
329 int pri = objectOrig [objInd] -> priority ();
331 if (pri < minPri) minPri = pri;
332 if (pri > maxPri) maxPri = pri;
336 infeas = objectOrig [objInd] -> checkInfeasibility (info),
338 value = computeUsefulness (MAXMIN_CRITERION,
339 upMultiplier, downMultiplier, infeas,
340 objectOrig [objInd], objInd,
343 if (value < minValue) minValue = infeas;
344 if (value > maxValue) maxValue = infeas;
354 orbitObj. push_back (obj);
361 std::sort (orbitObj.begin (), orbitObj.end (),
compStrongPri);
367 for (std::vector <struct objStrongPri *>::iterator
j = orbitObj. begin ();
368 j != orbitObj.
end (); ++
j) {
382 for (std::vector <struct objStrongPri *>::iterator
j = orbitObj. begin ();
383 j != orbitObj.
end (); ++
j)
387 numberObjects = objectInd.size ();
411 bool firstPass =
false;
414 OsiObject **
object = info -> solver_ -> objects ();
416 while (numberOnList_ == 0) {
418 for (
unsigned int i = 0; i < numberObjects; i++) {
420 int indexObj = ((objectInd.size () > 0) && (i < objectInd.size ())) ? objectInd [i] : i;
424 double value =
object [indexObj] -> infeasibility (info, way);
428 #ifdef FM_SORT_STRONG
429 infeasVal[i] = value;
432 double lbForInfeas = 0.0;
433 if(value > lbForInfeas) {
434 numberUnsatisfied_++;
440 int priorityLevel =
object[indexObj]->priority();
442 #ifdef FM_SORT_STRONG
443 if(priorityLevel < bestPriority) {
444 bestPriority = priorityLevel;
446 if(priorityLevel > lastPrio) {
448 vPriority[posEnd_vPriority] = priorityLevel;
449 list_[posEnd_vPriority] = indexObj;
452 vPriority[card_vPriority] = priorityLevel;
453 list_[card_vPriority] = indexObj;
458 if(priorityLevel < bestPriority) {
459 for (
int j=maximumStrong-1;
j>=0;
j--) {
461 int iObject = list_[
j];
464 list_[--putOther]=iObject;
467 maximumStrong = CoinMin(maximumStrong,putOther);
468 bestPriority = priorityLevel;
469 check = -COIN_DBL_MAX;
471 check2 = -COIN_DBL_MAX;
473 number_not_trusted_ = 0;
474 if(max_most_fra > 0) {
475 for(
int j=0;
j<max_most_fra;
j++) {
481 if(priorityLevel == bestPriority) {
484 value = computeUsefulness(MAXMIN_CRITERION,
485 upMultiplier, downMultiplier, value,
486 object[indexObj], indexObj, value2);
489 int iObject = list_[checkIndex];
491 assert (list_[putOther-1]<0);
492 list_[--putOther]=iObject;
494 list_[checkIndex]= indexObj;
495 assert (checkIndex<putOther);
496 useful_[checkIndex]=value;
499 maximumStrong = CoinMin(maximumStrong,putOther);
500 for (
int j=0;
j<maximumStrong;
j++) {
502 if (useful_[
j]<check) {
516 assert (list_[putOther-1]<0);
517 list_[--putOther] = indexObj;
518 maximumStrong = CoinMin(maximumStrong,putOther);
521 if((max_most_fra > 0) && (value2 > check2)) {
523 number_not_trusted_++;
524 list2[checkIndex2] = indexObj;
525 useful2[checkIndex2]=value2;
528 for(
int j=0;
j<max_most_fra;
j++) {
530 if(useful2[
j] < check2) {
546 assert (list_[putOther-1]<0);
547 list_[--putOther]= indexObj;
548 maximumStrong = CoinMin(maximumStrong,putOther);
554 #ifdef FM_SORT_STRONG
557 if(card_vPriority - posEnd_vPriority + numberObjects != numberUnsatisfied_) {
558 printf(
"CouenneChooseStrong::gutsOfSetupList(): ### ERROR: card_vPriority: %d posEnd_vPriority: %d numberUnsatisfied: %d numberObjects: %d\n",
559 card_vPriority, posEnd_vPriority, numberUnsatisfied_, numberObjects);
566 int card_smallerThanPrio = card_vPriority;
567 if(posEnd_vPriority > card_vPriority) {
568 for(
int i=posEnd_vPriority; i<numberObjects; i++) {
569 list_[card_vPriority] = list_[i];
571 vPriority[card_vPriority] = vPriority[i];
576 card_vPriority = numberUnsatisfied_;
580 int sortUpTo = card_smallerThanPrio;
581 if(card_smallerThanPrio < maximumStrong) {
582 sortFrom = card_smallerThanPrio;
583 sortUpTo = card_vPriority;
585 if(card_vPriority > 0) {
586 numberOnList_ = (card_vPriority < maximumStrong ? card_vPriority : maximumStrong);
588 #ifdef FM_ALWAYS_SORT
589 bool alwaysSort =
true;
591 bool alwaysSort =
false;
595 sortUpTo = card_vPriority;
597 if((sortUpTo > maximumStrong) || alwaysSort){
599 CoinSort_2(vPriority + sortFrom, vPriority + sortUpTo,
602 for(
int i=0; i<card_vPriority; i++) {
603 int indObj = list_[i];
604 double value = 0, value2;
605 value = computeUsefulness(MAXMIN_CRITERION,
606 upMultiplier, downMultiplier, value,
607 object[indObj], indObj, value2);
609 #ifdef OLD_USEFULLNESS
612 if ((sortCrit_ & 1) == 0) {
620 #ifdef USE_NOT_TRUSTED
621 if(value2 < -COIN_DBL_MAX / 10) {
622 infeasVal[i] = -COIN_DBL_MAX;
627 #ifdef USE_NOT_TRUSTED
629 if((card_vPriority > maximumStrong) &&
630 (vPriority[maximumStrong] < bestPriority +
COUENNE_EPS)) {
634 int *fracInd =
new int[card_vPriority];
636 double *fracVal =
new double[card_vPriority];
639 for(
int i=0; i<card_vPriority; i++) {
642 if(infeasVal[i] > -COIN_DBL_MAX/10) {
643 fracInd[cardFrac] = i;
644 fracVal[cardFrac] = -infeasVal[i];
650 if(max_most_fra > 0) {
653 if(cardFrac > max_most_fra) {
654 CoinSort_2(fracVal, fracVal+cardFrac, fracInd);
656 for(
int i=0; i<cardFrac; i++) {
657 useful_[fracInd[i]] =
658 -1e150*(1. + infeasVal[fracInd[i]]);
669 number_not_trusted_++;
670 if(i == max_most_fra - 1) {
683 #ifdef FM_SEC_SORT_USEFUL
684 CoinSort_2(useful_, useful_ + card_vPriority, list_);
686 #ifdef FM_ALWAYS_SORT
687 int from = 0, upto = 1;
688 while(upto < card_vPriority) {
689 while(vPriority[upto] == vPriority[from]) {
691 if(upto == card_vPriority) {
695 CoinSort_2(useful_+from, useful_+upto, list_+from);
700 if(sortUpTo > maximumStrong) {
703 int from = maximumStrong-1, upto = maximumStrong;
704 int msPrio = vPriority[maximumStrong-1];
705 problem_->setLastPrioSort(msPrio);
706 while((from > -1) && (vPriority[from] == msPrio)) {
710 while((upto < sortUpTo) && (vPriority[upto] == msPrio)) {
715 CoinSort_2(useful_+from, useful_+upto, list_+from);
722 double ckPrio = (card_vPriority < numberUnsatisfied_ ?
723 vPriority[card_vPriority] : 100000);
724 double ckUse = (card_vPriority < numberUnsatisfied_ ?
725 useful_[card_vPriority] : 100000);
726 for(
int i=0; i<card_vPriority; i++) {
727 int indObj = list_[i];
728 if(
object[indObj]->priority() > ckPrio + 1
e-3) {
729 printf(
"CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->priority(): %d > ckPrio: %d\n",
730 indObj,
object[indObj]->priority(), ckPrio);
733 if(fabs(
object[indObj]->priority() - ckPrio) < 1
e-3) {
734 if(useful_[i] > ckUse + 1
e-3) {
735 printf(
"CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->useful: %f > ckUse: %d\n",
736 indObj, useful_[i], ckUse);
741 for(
int i=card_vPriority; i<numberUnsatisfied_; i++) {
742 int indObj = list_[i];
743 if(
object[indObj]->priority() < ckPrio - 1
e-3) {
744 printf(
"CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->priority(): %d < ckPrio: %d\n",
745 indObj,
object[indObj]->priority(), ckPrio);
748 if(fabs(
object[indObj]->priority() - ckPrio) < 1
e-3) {
749 if(useful_[i] < ckUse - 1
e-3) {
750 printf(
"CouenneChooseStrong::gutsOfSetupList(): ### ERROR: object[%d]->useful: %f < ckUse: %d\n",
751 indObj, useful_[i], ckUse);
760 numberUnsatisfied_ = -1;
766 maximumStrong = CoinMin(maximumStrong,putOther);
767 for (
int i=0;i<maximumStrong;i++) {
769 #ifdef OLD_USEFULLNESS
770 list_[numberOnList_]=list_[i];
771 useful_[numberOnList_++]=-useful_[i];
774 list_[numberOnList_]=list_[i];
775 if ((sortCrit_ & 1) == 0) {
776 useful_[numberOnList_++]=-useful_[i];
778 else useful_[numberOnList_++] = useful_[i];
780 message(CANDIDATE_LIST2)<<numberOnList_-1
781 <<list_[numberOnList_-1]<<numberOnList_-1<<useful_[numberOnList_-1]
787 if (max_most_fra > 0 && numberOnList_ >= maximumStrong) {
790 number_not_trusted_=0;
791 for (
int i=0;i<max_most_fra;i++) {
793 list2[number_not_trusted_] = list2[i];
794 useful2[number_not_trusted_++] = useful2[i];
795 message(CANDIDATE_LIST3)<<number_not_trusted_-1
796 <<list2[number_not_trusted_-1]<<number_not_trusted_-1
797 <<useful2[number_not_trusted_-1]<<CoinMessageEol;
800 if (number_not_trusted_) {
801 CoinSort_2(list_,list_+numberOnList_,useful_);
802 CoinSort_2(list2,list2+number_not_trusted_,useful2);
805 for (
int i=0; i<numberObjects; i++) {
806 bool found1 = (list_[i1]==i);
807 bool found2 = (list2[i2]==i);
808 if (found1 && found2) {
810 #ifdef OLD_USEFULLNESS
811 useful_[i1] = 1e150*(1.+useful2[i2]);
813 useful_[i1] = -1e150*(1.+useful2[i2]);
819 if (i2==max_most_fra)
break;
821 for (
int i=0; i<number_not_trusted_; i++) {
823 list_[numberOnList_+tmp_on_list] = list2[i];
825 #ifdef OLD_USEFULLNESS
826 useful_[numberOnList_+tmp_on_list] = 1e150*(1.+useful2[i]);
828 useful_[numberOnList_+tmp_on_list] = -1e150*(1.+useful2[i]);
836 CoinSort_2(useful_,useful_+numberOnList_+tmp_on_list,list_);
838 int i = numberOnList_;
839 for (;putOther<numberObjects;putOther++)
840 list_[i++]=list_[putOther];
841 assert (i==numberUnsatisfied_);
842 if (!CoinMax(numberStrong_,numberStrongRoot_))
848 numberUnsatisfied_=-1;
861 if(problem_->doPrint_) {
862 printf(
"numberStrong_: %d maximumStrong: %d\n",
863 numberStrong_, maximumStrong);
867 #ifdef FM_SORT_STRONG
876 info->defaultDual_ = -1.0;
877 delete [] info->usefulRegion_;
878 delete [] info->indexRegion_;
881 if (bb_log_level_>3) {
883 for (
int i=0; i<numberOnList_; i++){
884 message(CANDIDATE_LIST)<<i<< list_[i]<< i<< useful_[i]
885 <<
object[list_[i]]->infeasibility(info,way)
899 if(numberUnsatisfied_ == -1) {
902 return numberOnList_;
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real fint fint fint fint * info
bool compStrongPri(struct objStrongPri *one, struct objStrongPri *two)
void fint fint fint real fint real real real real real real real real real * e
double CouNumber
main number type in Couenne
const CouNumber estProdEps