Changeset 586


Ignore:
Timestamp:
May 29, 2011 7:25:38 AM (9 years ago)
Author:
fmargot
Message:

Couenne/src/main/BonCouenne.cpp: add ifdef FM_RES for storing results of
several runs; Best value found and required tolearance now printed at the
end of the run.

Couenne/src/branch/CouenneChooseStrong.hpp: add minDepthPrint_ to the class;
add method gutsOfSetupList() to the class.

Couenne/src/branch/CouenneChooseStrong.cpp: add minDepthPrint_ to the class;
complete rewrite of CouenneChooseStrong::chooseVariable(), treating carefully
OsiSimpleInteger? objects to avoid inconsistant branching; new version is used
only if FM_MOD is defined, otherwise the older version is used (for comparison
purposes); add method gutsOfSetupList() to give the option of selecting objects
according to priority and usefulness more precisely than
Bonmin::BonChooseVariable::setupList(); add ifdef FM_SORT_STRONG
to activate sorting when FM_MOD is set. Add debugging ifdefs TRACE_STRONG
and TRACE_STRONG2.

Couenne/src/branch/doStrongBranching.cpp: Modif. doStrongBranching() to
make sure that OsiSimpleInteger? objects for which the branching point is
outside the current solver bounds do not enlarge the feasible set when branched
on; make sure that bounds from solver and from problem are intersected.
Add debugging ifdefs TRACE_STRONG and TRACE_STRONG2.

Couenne/src/problem/CouenneProblem.hpp/cpp: add lastPrioSort_ and corresp.
set/get methods.

Couenne/src/problem/CouenneProblemConstructors.hpp: add lastPrioSort_.

Location:
trunk/Couenne/src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Couenne/src/branch/CouenneChooseStrong.cpp

    r577 r586  
    2020
    2121//#define TRACE_STRONG
     22//#define TRACE_STRONG2
     23//#define FM_MOD
     24//#define FM_SORT_STRONG
     25//#define OLD_STYLE
    2226
    2327using namespace Couenne;
     
    4852    setTrustStrongForSolution (s == "yes");
    4953    setTrustStrongForBound    (s == "yes");
     54
     55    minDepthPrint_ = -1;
    5056  }
    5157
     
    5763    estimateProduct_  (rhs.estimateProduct_),
    5864    jnlst_            (rhs.jnlst_),
    59     branchtime_       (rhs.branchtime_)
     65    branchtime_       (rhs.branchtime_),
     66    minDepthPrint_    (rhs.minDepthPrint_)
    6067  {}
    6168
     
    8087      jnlst_           = rhs.jnlst_;
    8188      branchtime_      = rhs.branchtime_;
     89      minDepthPrint_   = rhs.minDepthPrint_;
    8290    }
    8391    return *this;
     
    98106     If we have a solution then we can pick up from goodObjectiveValue() and goodSolution()
    99107  */
     108#ifdef FM_MOD
     109/*******************************************************************/
    100110  int CouenneChooseStrong::chooseVariable (OsiSolverInterface * solver,
    101111                                           OsiBranchingInformation *info,
     
    112122       info -> upper_);
    113123
     124#ifdef TRACE_STRONG2
     125    int pv = -1;
     126    if(info->depth_ > minDepthPrint_) {
     127      if(pv > -1) {
     128        printf("CCS: beg: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     129               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     130        printf("CCS: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     131               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     132        printf("CCS: problem: lb: %10.4f  ub: %10.4f\n",
     133               problem_->Lb(pv), problem_->Ub(pv));
     134      }
     135    }
     136 #endif                                                                         
     137
    114138    int retval;
     139
     140    //int retval = BonChooseVariable::chooseVariable (solver, info, fixVariables);
     141
     142    // COPY of Bonmin starts here ////////////////////////////////////////////
     143
     144    // We assume here that chooseVariable is called once at the very
     145    // beginning with fixVariables set to true.  This is then the root
     146    // node.
     147
     148    bool isRoot = isRootNode(info);
     149    int numberStrong = numberStrong_;
     150    if (isRoot) {
     151      numberStrong = CoinMax(numberStrong_, numberStrongRoot_);
     152    }
     153    if (numberUnsatisfied_) {
     154      int cardIndForPseudo = 0, *indForPseudo = new int[numberUnsatisfied_];
     155      OsiObject ** object = solver->objects();
     156      const double* upTotalChange = pseudoCosts_.upTotalChange();
     157      const double* downTotalChange = pseudoCosts_.downTotalChange();
     158      const int* upNumber = pseudoCosts_.upNumber();
     159      const int* downNumber = pseudoCosts_.downNumber();
     160      int numberBeforeTrusted = pseudoCosts_.numberBeforeTrusted();
     161      int numberLeft = CoinMin(numberStrong -numberStrongDone_,numberUnsatisfied_);
     162      results_.clear();
     163      int returnCode = 0;
     164      int returnCodeSB = 0;
     165      bestObjectIndex_ = -1;
     166      bestWhichWay_ = -1;
     167      firstForcedObjectIndex_ = -1;
     168      firstForcedWhichWay_ =-1;
     169      double bestTrusted=-COIN_DBL_MAX;
     170      for (int i=0;i<numberLeft;i++) {
     171        int iObject = list_[i];
     172        if (numberBeforeTrusted == 0||
     173            i < minNumberStrongBranch_ ||
     174            (
     175              only_pseudo_when_trusted_ && number_not_trusted_>0 ) ||
     176              ( !isRoot && (upNumber[iObject]<numberBeforeTrusted ||
     177                          downNumber[iObject]<numberBeforeTrusted ))||
     178              ( isRoot && (!upNumber[iObject] && !downNumber[iObject])) ) {
     179         
     180#ifdef TRACE_STRONG
     181          if(info->depth_ > minDepthPrint_) {
     182            printf("Push object %d for strong branch\n", iObject);
     183          }
     184#endif
     185          results_.push_back(Bonmin::HotInfo(solver, info,
     186                                object, iObject));
     187        }
     188        else {
     189
     190#ifdef TRACE_STRONG
     191          if(info->depth_ > minDepthPrint_) {
     192            printf("Use pseudo cost for object %d\n", iObject);
     193          }
     194#endif
     195          indForPseudo[cardIndForPseudo] = iObject;
     196          cardIndForPseudo++;
     197        }
     198      }
     199
     200      int numberFixed=0;
     201
     202      if (results_.size() > 0) {
     203
     204        // do strong branching //////////////////////////////////////////////////
     205        returnCodeSB = doStrongBranching (solver, info, results_.size(), 1);
     206
     207        if (bb_log_level_>=3) {
     208          const char* stat_msg[] = {"NOTDON", "FEAS", "INFEAS", "NOFINI"};
     209          message(SB_HEADER)<<CoinMessageEol;
     210          for (unsigned int i = 0; i< results_.size(); i++) {
     211            double up_change = results_[i].upChange();
     212            double down_change = results_[i].downChange();
     213            int up_status = results_[i].upStatus();
     214            int down_status = results_[i].downStatus();
     215            message(SB_RES)<<(int) i<<stat_msg[down_status+1]<<down_change
     216            <<stat_msg[up_status+1]<< up_change<< CoinMessageEol;
     217          }
     218        }
     219
     220        if (returnCodeSB >= 0 && returnCodeSB <= 2) { // 1, 2: some can be fixed
     221          if(returnCodeSB > 0) {
     222            returnCode = 4; // no bestObject yet
     223          }
     224          else {
     225            returnCode = 0;
     226          }
     227          const double prec = problem_->getFeasTol();
     228
     229          for (unsigned int i=0;i < results_.size (); i++) {
     230
     231            if((results_[i].upStatus() < 0) || (results_[i].downStatus() < 0))
     232              continue;
     233
     234
     235            if((results_[i].upStatus() < 0) || (results_[i].downStatus() < 0)) {
     236              continue;
     237            }
     238
     239            int iObject = results_[i].whichObject();
     240
     241            ///////////////////////////////////////////////////////////////////
     242
     243            double upEstimate;
     244
     245            if (results_[i].upStatus()!=1) {
     246              assert (results_[i].upStatus()>=0);
     247              upEstimate = results_[i].upChange();
     248            }
     249            else {
     250              // infeasible - just say expensive
     251              if (info->cutoff_<1.0e50)
     252                upEstimate = 2.0*(info->cutoff_-info->objectiveValue_);
     253              else
     254                upEstimate = 2.0*fabs(info->objectiveValue_);
     255              if (firstForcedObjectIndex_ <0) {
     256                // first fixed variable
     257                firstForcedObjectIndex_ = iObject;
     258                firstForcedWhichWay_ =0;
     259              }
     260
     261              numberFixed++;
     262              if (fixVariables) {
     263                bool needBranch = true;
     264                const OsiObject * obj = object[iObject];
     265                CouenneObject *co = dynamic_cast <CouenneObject *>(object[iObject]);
     266                OsiSimpleInteger *simpl = dynamic_cast <OsiSimpleInteger *>(object[iObject]);
     267               int vInd = -1;
     268                if(co) {
     269                  vInd = co->Reference()->Index();
     270                }
     271                else {
     272                  vInd = obj->columnNumber();
     273                }
     274                if((vInd >= 0) && (simpl)) {
     275                  needBranch = false;
     276                  double nearest = floor(info->solution_[vInd] + 0.5);
     277                  if(nearest > 0.5) {
     278                    nearest = 1 - nearest;
     279                  }
     280                                                                               
     281                  if((nearest > info->integerTolerance_) &&
     282                     (solver->getColUpper()[vInd] > solver->getColLower()[vInd]\
     283 + prec)) {
     284                    needBranch = true;
     285                  }
     286                }
     287                if(needBranch) {
     288                  OsiBranchingObject * branch = obj -> createBranch (solver, info, 0);
     289                  branch -> branch (solver);
     290                  delete branch;
     291                }
     292              }
     293            }
     294
     295            ///////////////////////////////////////////////////////////////////
     296
     297            double downEstimate;
     298
     299            if (results_[i].downStatus()!=1) {
     300              assert (results_[i].downStatus()>=0);
     301              downEstimate = results_[i].downChange();
     302            }
     303            else {
     304              // infeasible - just say expensive
     305              if (info->cutoff_<1.0e50)
     306                downEstimate = 2.0*(info->cutoff_-info->objectiveValue_);
     307              else
     308                downEstimate = 2.0*fabs(info->objectiveValue_);
     309              if (firstForcedObjectIndex_ <0) {
     310                firstForcedObjectIndex_ = iObject;
     311                firstForcedWhichWay_ =1;
     312              }
     313              numberFixed++;
     314              if (fixVariables) {
     315                bool needBranch = true;
     316                const OsiObject * obj = object[iObject];
     317                CouenneObject *co = dynamic_cast <CouenneObject *>(object[iObject]);
     318                OsiSimpleInteger *simpl = dynamic_cast <OsiSimpleInteger *>(object[iObject]);
     319                int vInd = -1;
     320                if(co) {
     321                  vInd = co->Reference()->Index();
     322                }
     323                else {
     324                  vInd = obj->columnNumber();
     325                }
     326                if((vInd >= 0) && (simpl)) {
     327                  needBranch = false;
     328                  double nearest = floor(info->solution_[vInd] + 0.5);
     329                  if(nearest > 0.5) {
     330                    nearest = 1 - nearest;
     331                  }
     332                                                                               
     333                  if((nearest > info->integerTolerance_) &&
     334                     (solver->getColUpper()[vInd] > solver->getColLower()[vInd]\
     335 + prec)) {
     336                    needBranch = true;
     337                  }
     338                }
     339                if(needBranch) {
     340                  OsiBranchingObject * branch = obj -> createBranch (solver, info, 1);
     341                  branch -> branch (solver);
     342                  delete branch;
     343                }
     344              }
     345            }
     346
     347            double
     348              MAXMIN_CRITERION = maxminCrit (info),
     349              minVal, maxVal, value;
     350
     351            if (downEstimate < upEstimate) {
     352              minVal = downEstimate;
     353              maxVal = upEstimate;
     354            } else {
     355              minVal = upEstimate;
     356              maxVal = downEstimate;
     357            }
     358
     359            value =
     360              estimateProduct_ ?
     361              ((estProdEps + minVal) * maxVal) :
     362              (       MAXMIN_CRITERION  * minVal +
     363               (1.0 - MAXMIN_CRITERION) * maxVal);
     364
     365            if (value>bestTrusted) {
     366              bestTrusted = value;
     367              bestObjectIndex_ = iObject;
     368              bestWhichWay_ = upEstimate>downEstimate ? 0 : 1;
     369              // but override if there is a preferred way
     370              const OsiObject * obj = object[iObject];
     371              if (obj->preferredWay()>=0&&obj->infeasibility())
     372                bestWhichWay_ = obj->preferredWay();
     373              if(returnCodeSB) { // 1 or 2
     374                returnCode = 2;
     375              }
     376            }
     377          }
     378        }
     379        else { // returnCodeSB is -1 or 3
     380          if (returnCodeSB == 3) { // max time - just choose one
     381            if(bestObjectIndex_ < 0) {
     382              bestObjectIndex_ = list_[0];
     383              bestWhichWay_ = 0;
     384              returnCode = 0;
     385            }
     386          }
     387          else {
     388            returnCode = -1;
     389          }
     390        }
     391#ifdef OLD_STYLE
     392        if(bestObjectIndex_ < 0) {
     393          bestObjectIndex_ = list_[0];
     394        }
     395        cardIndForPseudo = 0; // do not scan other vars using pseudo costs
     396#endif
     397      }
     398
     399      if(returnCodeSB != -1) { 
     400                  // if returnCodeSB == -1 (i.e. problem is infeasible)
     401                  // no need to scan objects with pseudocosts
     402        const double *solverUb = solver->getColUpper();
     403        const double *solverLb = solver->getColLower();
     404        const double prec = problem_->getFeasTol();
     405       
     406        // to keep best object skipped on basis of bounds and branching value
     407        int bestObjectIndex2 = -1;
     408        int bestWhichWay2 = 0;
     409        double bestTrusted2 = -COIN_DBL_MAX;
     410       
     411        for(int ips=0; ips<cardIndForPseudo; ips++) {
     412          int iObject = list_[ips];
     413          const OsiObject * obj = object[iObject];
     414          double
     415            upEstimate       = (upTotalChange[iObject]*obj->upEstimate())/upNumber[iObject],
     416            downEstimate     = (downTotalChange[iObject]*obj->downEstimate())/downNumber[iObject],
     417            MAXMIN_CRITERION = maxminCrit (info),
     418            minVal, maxVal, value;
     419         
     420          if (downEstimate < upEstimate) {
     421            minVal = downEstimate;
     422            maxVal = upEstimate;
     423          } else {
     424            minVal = upEstimate;
     425            maxVal = downEstimate;
     426          }
     427         
     428          value =
     429            estimateProduct_ ?
     430            ((estProdEps + minVal) * maxVal) :
     431            (       MAXMIN_CRITERION  * minVal +
     432                    (1.0 - MAXMIN_CRITERION) * maxVal);
     433         
     434         
     435          // skip OsiSimpleInteger objects with variable fixed or
     436          // branching value outside bounds
     437          bool skipIt = false;
     438          CouenneObject *co = dynamic_cast <CouenneObject *>(object[iObject]);
     439          OsiSimpleInteger *simpl = dynamic_cast <OsiSimpleInteger *>(object[iObject]);
     440          int vInd = -1;
     441          if(co) {
     442            vInd = co->Reference()->Index();
     443          }
     444          else {
     445            vInd = obj->columnNumber();
     446          }
     447          if(simpl && (vInd >= 0)) {
     448            double vUb = solverUb[vInd];
     449            double vLb = solverLb[vInd];
     450            double vSol = info->solution_[vInd];
     451            if((vSol < vLb + prec) || (vSol > vUb - prec) || (vUb-vLb < prec)) {
     452              skipIt = true;
     453              numberFixed++;
     454            }
     455          }
     456         
     457          if(skipIt) {
     458            if (value > bestTrusted2) {
     459              bestObjectIndex2 = iObject;
     460              bestWhichWay2 = upEstimate>downEstimate ? 0 : 1;
     461              bestTrusted2 = value;
     462            }
     463#ifdef TRACE_STRONG
     464            if(info->depth_ > minDepthPrint_) {
     465              printf("Object %d skip pseudocost\n", iObject);
     466            }
     467#endif
     468          }
     469          else {
     470            if (value > bestTrusted) {
     471              bestObjectIndex_ = iObject;
     472              bestWhichWay_ = upEstimate>downEstimate ? 0 : 1;
     473              bestTrusted = value;
     474              returnCode = (returnCode ? 3 : 0); // if returnCode was 2 or 3
     475                                                 // it becomes 3
     476            }
     477#ifdef TRACE_STRONG
     478            if(info->depth_ > minDepthPrint_) {
     479              printf("Object %d use pseudocost\n", iObject);
     480            }
     481#endif
     482          }
     483        }
     484   
     485        delete[] indForPseudo;
     486
     487        if((bestObjectIndex_ < 0) && (bestObjectIndex2 >= 0)) {
     488          bestObjectIndex_ = bestObjectIndex2;
     489          bestWhichWay_ = bestWhichWay2;
     490          bestTrusted = bestTrusted2;
     491          returnCode = 4;
     492        }
     493      }
     494
     495      int objectVarInd = -1;
     496      if(bestObjectIndex_ >= 0) {
     497        OsiObject * obj = object[bestObjectIndex_];
     498        obj->setWhichWay(bestWhichWay_);
     499        CouenneObject *co =  dynamic_cast <CouenneObject *>(object[bestObjectIndex_]);
     500        if(co) {
     501          objectVarInd = co->Reference()->Index();
     502        }
     503        else {
     504          objectVarInd = obj->columnNumber();
     505        }
     506
     507        message(BRANCH_VAR)<<bestObjectIndex_<< bestWhichWay_ <<CoinMessageEol;
     508
     509#ifdef TRACE_STRONG
     510        if(info->depth_ > minDepthPrint_) {
     511          if(objectVarInd >= 0) {
     512            double vUb = solver->getColUpper()[objectVarInd];
     513            double vLb = solver->getColLower()[objectVarInd];
     514            double vSolI = info->solution_[objectVarInd];
     515            double vSolS = solver->getColSolution()[objectVarInd];
     516            printf("Branch on object %d (var: %d): solInfo: %10.4f  SolSolver: %10.4f low: %10.4f  up: %10.4f\n",
     517                   bestObjectIndex_, objectVarInd, vSolI, vSolS, vLb, vUb);
     518          }
     519          else {
     520            printf("Branch on object %d (var: -1)\n", bestObjectIndex_);
     521          }
     522        }
     523#endif
     524      }
     525      message(CHOSEN_VAR)<<bestObjectIndex_<<CoinMessageEol;
     526
     527      if (numberFixed==numberUnsatisfied_&&numberFixed)
     528        returnCode=4;
     529
     530      if((returnCode == 2) || (returnCode == 3)) {
     531        if((objectVarInd > -1) &&
     532           (solver->getColUpper()[objectVarInd] < solver->getColLower()[objectVarInd] + problem_->getFeasTol())) {
     533          // Can occur: two objects for same var, first scanned object
     534          // has both branches feasible and is saved as bestObjectIndex_,
     535          // second scanned object fixes the variable
     536          returnCode = 4;
     537        }
     538      }
     539      retval = returnCode;
     540    }
     541    else {
     542      retval = 1;
     543    }
     544
     545    // COPY of Bonmin ends here //////////////////////////////////////////////
     546
     547
     548#ifdef TRACE_STRONG2
     549    if(info->depth_ > minDepthPrint_) {
     550      if(pv > -1) {
     551        printf("CCS: end: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     552               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     553        printf("CCS: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     554               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     555        printf("CCS: problem: lb: %10.4f  ub: %10.4f\n",
     556               problem_->Lb(pv), problem_->Ub(pv));
     557      }
     558      printf("retval: %d\n", retval);
     559    }
     560#endif
     561 
     562    problem_ -> domain () -> pop ();
     563
     564    return retval;
     565  }
     566/*******************************************************************/
     567#else /* not FM_MOD */
     568  int CouenneChooseStrong::chooseVariable (OsiSolverInterface * solver,
     569                                           OsiBranchingInformation *info,
     570                                           bool fixVariables) {
     571
     572    /// Note: had to copy code from
     573    /// BonChooseVariable::chooseVariable() in order to test product
     574    /// thing
     575
     576    problem_ -> domain () -> push
     577      (problem_ -> nVars (),
     578       info -> solution_,
     579       info -> lower_,
     580       info -> upper_);
     581
     582    int retval;
     583
     584#ifdef TRACE_STRONG2
     585    int pv = -1;
     586    if(info->depth_ > minDepthPrint_) {
     587      if(pv > -1) {
     588        printf("CCS: beg: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     589               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     590        printf("CCS: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     591               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     592        printf("CCS: problem: lb: %10.4f  ub: %10.4f\n",
     593               problem_->Lb(pv), problem_->Ub(pv));
     594      }
     595    }
     596#endif
    115597
    116598    //int retval = BonChooseVariable::chooseVariable (solver, info, fixVariables);
     
    150632                          downNumber[iObject]<numberBeforeTrusted ))||
    151633              ( isRoot && (!upNumber[iObject] && !downNumber[iObject])) ) {
    152          
     634
    153635#ifdef TRACE_STRONG
    154           printf("Push object %d for strong branch\n", iObject);
    155 #endif
    156 
     636          if(info->depth_ > minDepthPrint_) {
     637            printf("Push object %d for strong branch\n", iObject);
     638          }
     639#endif
    157640          results_.push_back(Bonmin::HotInfo(solver, info,
    158                                 solver->objects(), iObject));
     641                                             solver->objects(), iObject));
    159642        }
    160643        else {
     644
     645#ifdef TRACE_STRONG
     646          if(info->depth_ > minDepthPrint_) {
     647            printf("Use pseudo cost for object %d\n", iObject);
     648          }
     649#endif
     650
    161651          const OsiObject * obj = solver->object(iObject);
    162 
    163 #ifdef TRACE_STRONG
    164           printf("Use pseudo cost for object %d\n", iObject);
    165 #endif
    166 
    167652          double
    168653            upEstimate       = (upTotalChange[iObject]*obj->upEstimate())/upNumber[iObject],
     
    192677        }
    193678      }
     679
    194680      int numberFixed=0;
     681
    195682      if (results_.size() > 0) {
    196683
     
    210697          }
    211698        }
     699
    212700        if (returnCode >= 0 &&
    213701            returnCode <= 2) {
     702
    214703          if (returnCode)
    215704            returnCode = (bestObjectIndex_>=0) ? 3 : 4;
    216           for (unsigned int i=0;i < results_.size();i++) {
     705
     706          for (unsigned int i=0;i < results_.size (); i++) {
     707
     708            if((results_[i].upStatus() < 0) || (results_[i].downStatus() < 0))
     709              continue;
     710
     711
     712            if((results_[i].upStatus() < 0) || (results_[i].downStatus() < 0)) {
     713              continue;
     714            }
     715
    217716            int iObject = results_[i].whichObject();
    218 
    219             // UP ESTIMATE ////////////////////////////////////////
     717           
     718            ///////////////////////////////////////////////////////////////////
    220719
    221720            double upEstimate;
     721
    222722            if (results_[i].upStatus()!=1) {
    223               assert (results_[i].upStatus()>=0);
     723              assert (results_[i].upStatus()>=0);
    224724              upEstimate = results_[i].upChange();
    225725            }
     
    235735                firstForcedWhichWay_ =0;
    236736              }
     737
    237738              numberFixed++;
     739
    238740              if (fixVariables) {
    239                 const OsiObject * obj = solver->object(iObject);
    240                 OsiBranchingObject * branch = obj->createBranch(solver,info,0);
    241                 branch->branch(solver);
    242                 delete branch;
     741
     742                const OsiObject * obj = solver->objects()[iObject];
     743                OsiBranchingObject * branch = obj -> createBranch (solver, info, 0);
     744                branch -> branch (solver);
     745                delete branch;
    243746              }
    244747            }
    245748
    246             // DOWN ESTIMATE /////////////////////////////////////
     749            ///////////////////////////////////////////////////////////////////
    247750
    248751            double downEstimate;
     752
    249753            if (results_[i].downStatus()!=1) {
    250               assert (results_[i].downStatus()>=0);
    251               downEstimate = results_[i].downChange();
     754              assert (results_[i].downStatus()>=0);
     755              downEstimate = results_[i].downChange();
    252756            }
    253757            else {
     
    263767              numberFixed++;
    264768              if (fixVariables) {
    265                 const OsiObject * obj = solver->object(iObject);
    266                 OsiBranchingObject * branch = obj->createBranch(solver,info,1);
    267                 branch->branch(solver);
    268                 delete branch;
     769
     770                const OsiObject * obj = solver->objects()[iObject];
     771                OsiBranchingObject * branch = obj -> createBranch (solver, info, 1);
     772                branch -> branch (solver);
     773                delete branch;
    269774              }
    270775            }
    271776
    272777            double
    273               MAXMIN_CRITERION = maxminCrit(info),           
     778              MAXMIN_CRITERION = maxminCrit (info),
    274779              minVal, maxVal, value;
    275780
     
    311816        bestObjectIndex_=list_[0];
    312817      }
    313 
    314       if ( bestObjectIndex_ >=0 ) {
     818   
     819      if(bestObjectIndex_ >=0) {
    315820        OsiObject * obj = solver->objects()[bestObjectIndex_];
    316821        obj->setWhichWay(bestWhichWay_);
    317         message(BRANCH_VAR)<<obj->columnNumber()<< bestWhichWay_ <<CoinMessageEol;
     822        message(BRANCH_VAR)<<bestObjectIndex_<< bestWhichWay_ <<CoinMessageEol;
     823        CouenneObject *co =  dynamic_cast <CouenneObject *>(solver->objects()[bestObjectIndex_]);
     824
     825        int objectInd = -1;
     826        if(co) {
     827          objectInd = co->Reference()->Index();
     828        }
     829        else {
     830          objectInd = obj->columnNumber();
     831        }
     832
     833#ifdef TRACE_STRONG
     834        if(info->depth_ > minDepthPrint_) {
     835          if(objectInd >= 0) {
     836            double vUb = solver->getColUpper()[objectInd];                     
     837            double vLb = solver->getColLower()[objectInd];                     
     838            double vSolI = info->solution_[objectInd];                         
     839            double vSolS = solver->getColSolution()[objectInd];                 
     840            printf("Branch on object %d (var: %d): solInfo: %10.4f  SolSolver: \
     841%10.4f low: %10.4f  up: %10.4f\n",                                             
     842                   bestObjectIndex_, objectInd, vSolI, vSolS, vLb, vUb);       
     843          }
     844          else {
     845            printf("Branch on object %d (var: -1)\n", bestObjectIndex_);           
     846          }
     847        }
     848#endif
     849
    318850      }
    319851
     
    330862    // COPY of Bonmin ends here //////////////////////////////////////////////
    331863
     864#ifdef TRACE_STRONG2
     865    if(info->depth_ > minDepthPrint_) {
     866      if(pv > -1) {
     867        printf("CCS: end: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     868               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     869        printf("CCS: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     870               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     871        printf("CCS: problem: lb: %10.4f  ub: %10.4f\n",
     872               problem_->Lb(pv), problem_->Ub(pv));
     873      }                                                   
     874      printf("retval: %d\n", retval);
     875    }
     876#endif
    332877    problem_ -> domain () -> pop ();
    333878
    334879    return retval;
    335   }
    336 
     880    }
     881#endif /* not FM_MOD */
    337882
    338883  // Sets up strong list and clears all if initialize is true.
    339884  // Returns number of infeasibilities.
    340885  int CouenneChooseStrong::setupList (OsiBranchingInformation *info, bool initialize) {
    341 
    342886    static bool warned = false;
    343887
     
    363907#endif
    364908
     909
    365910    jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
    366911                      "----------------- (strong) setup list\n");
     
    372917    }
    373918
     919    OsiObject ** object = info->solver_->objects();
     920    int numberObjects = info->solver_->numberObjects();
     921
    374922#ifdef TRACE_STRONG
    375     printObjViol(info);
    376 #endif
    377 
    378     // call Bonmin's setuplist
    379     int retval = Bonmin::BonChooseVariable::setupList (info, initialize);
    380 
    381     if (!retval) { // No branching is possible
    382 
     923    if(info->depth_ > minDepthPrint_) {
     924      printObjViol(info);
     925    }
     926#endif
     927
     928    int retval = gutsOfSetupList(info, initialize);
     929
     930    if(retval == 0) { // No branching is possible
    383931      double ckObj = info->objectiveValue_;
    384 
    385       if (!(problem_ -> checkNLP (info -> solution_, ckObj, true))) {
    386 
    387         if (!warned) {
    388           printf ("CouenneChooseStrong::setupList() -- Warning: checkNLP returns infeasible, no branching object selected\n");
    389           warned = true;
    390         }
    391         //exit (1);
    392       }
    393     }
    394 
    395     jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
    396                       "----------------- (strong) setup list done - %d infeasibilities\n", retval);
    397 
    398 
    399     if(retval == 0) { // No branching is possible
    400       double ckObj = 0;
    401932
    402933#ifdef FM_CHECKNLP2
     
    407938                               problem_->getFeasTol()))) {
    408939                                // false for NOT stopping at first violation
    409         printf("CouenneChooseStrong::setupList(): ### WARNING: checkNLP2() returns infeasible, no branching object selected\n");
     940        if (!warned) {
     941          printf("CouenneChooseStrong::setupList(): ### WARNING: checkNLP2() returns infeasible, no branching object selected\n");
     942          warned = true;
     943        }
    410944      }
    411945#else /* not FM_CHECKNLP2 */
    412946      if(!(problem_->checkNLP(info->solution_, ckObj, true))) {
    413         printf("CouenneChooseStrong::setupList(): ### WARNING: checkNLP() returns infeasible, no branching object selected\n");
     947        if (!warned) {
     948          printf("CouenneChooseStrong::setupList(): ### WARNING: checkNLP() returns infeasible, no branching object selected\n");
     949          warned = true;
     950        }
    414951      }
    415952#endif /* not FM_CHECKNLP2 */
     
    426963
    427964#ifdef TRACE_STRONG
    428     printf("Strong list: (obj_ind var_ind priority useful)\n");
    429     printf("numberStrong: %d  numberStrongRoot: %d  retval: %d\n",
    430            numberStrong_, numberStrongRoot_, retval);
    431 
    432     OsiObject ** object = info->solver_->objects();
    433 
    434     for(int i=0; i<retval; i++) {
    435       CouenneObject *co =  dynamic_cast <CouenneObject *> (object[list_[i]]);
    436       int objectInd = -1;
    437       if(co) {
    438         objectInd = co->Reference()->Index();
    439       }
    440       else {
    441         objectInd = object[list_[i]]->columnNumber();
    442       }
    443       printf(" (%d %d %d %6.4f)", list_[i], objectInd,
    444              object[list_[i]]->priority(), useful_[i]);
    445     }
    446     printf("\n");
    447 #endif
    448 
     965    if(info->depth_ > minDepthPrint_) {
     966      printf("Strong list: (obj_ind var_ind priority useful)\n");
     967      printf("numberStrong: %d  numberStrongRoot: %d  retval: %d\n",
     968             numberStrong_, numberStrongRoot_, retval);
     969      for(int i=0; i<retval; i++) {
     970        CouenneObject *co =  dynamic_cast <CouenneObject *>(object[list_[i]]);
     971        int objectInd = -1;
     972        if(co) {
     973          objectInd = co->Reference()->Index();
     974        }
     975        else {
     976          objectInd = object[list_[i]]->columnNumber();
     977        }
     978        printf(" (%d %d %d %6.4f)", list_[i], objectInd,
     979               object[list_[i]]->priority(), useful_[i]);
     980      }
     981      printf("\n");
     982    }
     983#endif
     984 
     985
     986    jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
     987                      "----------------- (strong) setup list done - %d infeasibilities\n", retval);
    449988
    450989    problem_ -> domain () -> pop ();
     
    452991  }
    453992
    454 
     993/****************************************************************************/
     994// Copied from BonChooseVariable.cpp and modified slightly
     995  int CouenneChooseStrong::gutsOfSetupList(OsiBranchingInformation *info,
     996                                      bool initialize)
     997  {
     998    if (numberBeforeTrustedList_ < 0) {
     999      number_not_trusted_ = 1;
     1000      printf("CouenneChooseStrong::gutsOfSetupList(): Did not think we were using this; Please double check ...\n");
     1001      exit(1);
     1002      return OsiChooseVariable::setupList(info, initialize);
     1003    }
     1004    if (initialize) {
     1005      status_=-2;
     1006      delete [] goodSolution_;
     1007      bestObjectIndex_=-1;
     1008      numberStrongDone_=0;
     1009      numberStrongIterations_ = 0;
     1010      numberStrongFixed_ = 0;
     1011      goodSolution_ = NULL;
     1012      goodObjectiveValue_ = COIN_DBL_MAX;
     1013      number_not_trusted_=0;
     1014    }
     1015    else {
     1016      throw CoinError(CNAME,"setupList","Should not be called with initialize==false");
     1017    }
     1018    numberOnList_=0;
     1019    numberUnsatisfied_=0;
     1020    int numberObjects = solver_->numberObjects();
     1021    assert (numberObjects);
     1022    if (numberObjects>pseudoCosts_.numberObjects()) {
     1023      //std::cout<<"Number objects "<<numberObjects<<std::endl;
     1024      //AW : How could that ever happen?
     1025      //PB : It happens for instance when SOS constraints are added. They are added after the creation of this.
     1026      //   assert(false && "Right now, all old content is deleted!");
     1027      // redo useful arrays
     1028      int saveNumberBeforeTrusted = pseudoCosts_.numberBeforeTrusted();
     1029      pseudoCosts_.initialize(numberObjects);
     1030      pseudoCosts_.setNumberBeforeTrusted(saveNumberBeforeTrusted);
     1031    }
     1032    double check = -COIN_DBL_MAX;
     1033    int checkIndex=0;
     1034    int bestPriority=COIN_INT_MAX;
     1035    int putOther = numberObjects;
     1036    int i;
     1037
     1038#ifdef FM_SORT_STRONG
     1039    int numStr = numberStrong_;
     1040    if(isRootNode(info)) {
     1041      numStr = numberStrongRoot_;
     1042    }
     1043    int maximumStrong = CoinMin(numStr, numberObjects) ;
     1044    int lastPrio = problem_->getLastPrioSort();
     1045    int card_vPriority = 0;
     1046    int posEnd_vPriority = numberObjects;
     1047    double *vPriority = new double[numberObjects];
     1048#else /* not FM_SORT_STRONG */
     1049    int maximumStrong = CoinMin(CoinMax(numberStrong_,numberStrongRoot_),
     1050        numberObjects) ;
     1051    for (i=0;i<numberObjects;i++) {
     1052      list_[i]=-1;
     1053      useful_[i]=0.0;
     1054    }
     1055    // We make a second list for most fractional variables
     1056    int* list2 = NULL;
     1057    double* useful2 = NULL;
     1058    double check2 = -COIN_DBL_MAX;
     1059    int checkIndex2=0;
     1060    int max_most_fra = setup_pseudo_frac_ > 0. ? (int)floor(setup_pseudo_frac_*(double)maximumStrong): 0;
     1061    if (setup_pseudo_frac_ > 0.) {
     1062      max_most_fra = CoinMax(1, max_most_fra);
     1063    }
     1064    if (max_most_fra) {
     1065      list2 = new int[max_most_fra];
     1066      useful2 = new double[max_most_fra];
     1067      for (i=0;i<max_most_fra;i++) {
     1068        list2[i]=-1;
     1069        useful2[i]=0.0;
     1070      }
     1071    }
     1072#endif /* not FM_SORT_STRONG */
     1073
     1074#ifdef FM_CHECK
     1075    const double* upTotalChange = pseudoCosts_.upTotalChange();
     1076    const double* downTotalChange = pseudoCosts_.downTotalChange();
     1077    int pseudoNum = pseudoCosts_.numberObjects();
     1078    for(i=0; i<pseudoNum; i++) {
     1079      if(isnan(upTotalChange[i]) || isinf(upTotalChange[i])) {
     1080        printf("CouenneChooseStrong::gutsOfSetupList(): upTotalChange[%d]: not a number or infinite\n", i);
     1081        exit(1);
     1082      }
     1083      if(isnan(downTotalChange[i]) || isinf(downTotalChange[i])) {
     1084        printf("CouenneChooseStrong::gutsOfSetupList(): downTotalChange[%d]: not a number or infinite\n", i);
     1085        exit(1);
     1086      }
     1087    }
     1088#endif
     1089
     1090    OsiObject ** object = info->solver_->objects();
     1091    double upMultiplier, downMultiplier;
     1092    computeMultipliers(upMultiplier, downMultiplier);
     1093
     1094    // Say feasible
     1095    bool feasible = true;
     1096    const double MAXMIN_CRITERION = maxminCrit(info);
     1097
     1098    bool firstPass = false; // not important; useful for making two
     1099                            // passes, picking different objects
     1100    while(numberOnList_ == 0) {
     1101      for(i=0;i<numberObjects;i++) {
     1102        int way;
     1103        double value = object[i]->infeasibility(info, way);
     1104        double lbForInfeas = 0.0;
     1105        if(value > lbForInfeas) {
     1106          numberUnsatisfied_++;
     1107          if(value >= 1e50) {
     1108            // infeasible
     1109            feasible=false;
     1110            break;
     1111          }
     1112          int priorityLevel = object[i]->priority();
     1113
     1114#ifdef FM_SORT_STRONG
     1115          if(priorityLevel > lastPrio) {
     1116            posEnd_vPriority--;
     1117            vPriority[posEnd_vPriority] = priorityLevel;
     1118            list_[posEnd_vPriority] = i;
     1119          }
     1120          else {
     1121            vPriority[card_vPriority] = priorityLevel;
     1122            list_[card_vPriority] = i;
     1123            card_vPriority++;
     1124          }
     1125#else /* not FM_SORT_STRONG */
     1126          // Better priority? Flush choices.
     1127          if(priorityLevel < bestPriority) {
     1128            for (int j=maximumStrong-1; j>=0; j--) {
     1129              if(list_[j] >= 0) {
     1130                int iObject = list_[j];
     1131                list_[j]=-1;
     1132                useful_[j]=0.0;
     1133                list_[--putOther]=iObject;
     1134              }
     1135            }
     1136            maximumStrong = CoinMin(maximumStrong,putOther);
     1137            bestPriority = priorityLevel;
     1138            check=-COIN_DBL_MAX;
     1139            checkIndex=0;
     1140            check2=-COIN_DBL_MAX;
     1141            checkIndex2=0;
     1142            number_not_trusted_=0;
     1143            if(max_most_fra > 0) {
     1144              for(int j=0; j<max_most_fra; j++) {
     1145                list2[j]=-1;
     1146                useful2[j]=0.0;
     1147              }
     1148            }
     1149          }
     1150          if(priorityLevel == bestPriority) {
     1151            // Modify value
     1152            double value2;
     1153            value = computeUsefulness(MAXMIN_CRITERION,
     1154                                      upMultiplier, downMultiplier, value,
     1155                                      object[i], i, value2);
     1156            if(value > check) {
     1157              //add to list
     1158              int iObject = list_[checkIndex];
     1159              if(iObject >= 0) {
     1160                assert (list_[putOther-1]<0);
     1161                list_[--putOther]=iObject;  // to end
     1162              }
     1163              list_[checkIndex]=i;
     1164              assert (checkIndex<putOther);
     1165              useful_[checkIndex]=value;
     1166              // find worst
     1167              check=COIN_DBL_MAX;
     1168              maximumStrong = CoinMin(maximumStrong,putOther);
     1169              for (int j=0; j<maximumStrong; j++) {
     1170                if(list_[j]>=0) {
     1171                  if (useful_[j]<check) {
     1172                    check=useful_[j];
     1173                    checkIndex=j;
     1174                  }
     1175                }
     1176                else {
     1177                  check=0.0;
     1178                  checkIndex = j;
     1179                  break;
     1180                }
     1181              }
     1182            }
     1183            else {
     1184              // to end
     1185              assert (list_[putOther-1]<0);
     1186              list_[--putOther]=i;
     1187              maximumStrong = CoinMin(maximumStrong,putOther);
     1188            }
     1189            if(max_most_fra > 0 && value2 > check2) {
     1190              // add to list of integer infeasibilities
     1191              number_not_trusted_++;
     1192              list2[checkIndex2]=i;
     1193              useful2[checkIndex2]=value2;
     1194              // find worst
     1195              check2=COIN_DBL_MAX;
     1196              for(int j=0; j<max_most_fra; j++) {
     1197                if(list2[j] >= 0) {
     1198                  if(useful2[j] < check2) {
     1199                    check2=useful2[j];
     1200                    checkIndex2=j;
     1201                  }
     1202                }
     1203                else {
     1204                  check2=0.0;
     1205                  checkIndex2 = j;
     1206                  break;
     1207                }
     1208              }
     1209            }
     1210          }
     1211          else {
     1212            // worse priority
     1213            // to end
     1214            assert (list_[putOther-1]<0);
     1215            list_[--putOther]=i;
     1216            maximumStrong = CoinMin(maximumStrong,putOther);
     1217          }
     1218#endif /* not FM_SORT_STRONG */
     1219        }
     1220      }
     1221
     1222#ifdef FM_SORT_STRONG
     1223
     1224#ifdef FM_CHECK
     1225      if(card_vPriority - posEnd_vPriority + numberObjects != numberUnsatisfied_) {
     1226        printf("CouenneChooseStrong::gutsOfSetupList(): ### ERROR: card_vPriority: %d  posEnd_vPriority: %d  numberUnsatisfied: %d numberObjects: %d\n",
     1227               card_vPriority, posEnd_vPriority, numberUnsatisfied_, numberObjects);
     1228        exit(1);
     1229      }
     1230#endif
     1231
     1232      numberOnList_ = 0;
     1233      if(feasible) {
     1234        int card_smallerThanPrio = card_vPriority;
     1235        if(posEnd_vPriority > card_vPriority) {
     1236          for(i=posEnd_vPriority; i<numberObjects; i++) {
     1237            list_[card_vPriority] = list_[i];
     1238            list_[i] = -1;
     1239            vPriority[card_vPriority] = vPriority[i];
     1240            card_vPriority++;
     1241          }
     1242        }
     1243        else {
     1244          card_vPriority = numberUnsatisfied_;
     1245        }
     1246        // correct bounds if card_smallThanPrio >= maximumStrong
     1247        int sortFrom = 0;
     1248        int sortUpTo = card_smallerThanPrio;
     1249        if(card_smallerThanPrio < maximumStrong) {
     1250          sortFrom = card_smallerThanPrio;
     1251          sortUpTo = card_vPriority;
     1252        }
     1253        if(card_vPriority > 0) {
     1254          numberOnList_ = card_vPriority;
     1255          bool alwaysSort = false;
     1256          if(alwaysSort) {
     1257            sortFrom = 0;
     1258            sortUpTo = card_vPriority;
     1259          }
     1260          if((sortUpTo > maximumStrong) || alwaysSort){
     1261            // sort list_[card_sortFrom..card_sortUpTo-1] according to priority
     1262            CoinSort_2(vPriority + sortFrom, vPriority + sortUpTo,
     1263                       list_ + sortFrom);
     1264          }
     1265          for(i=0; i<card_vPriority; i++) {
     1266            int indObj = list_[i];
     1267            double value, value2;
     1268            value = computeUsefulness(MAXMIN_CRITERION,
     1269                                      upMultiplier, downMultiplier, value,
     1270                                      object[indObj], indObj, value2);
     1271
     1272#ifdef OLD_USEFULLNESS
     1273            useful_[i] = -value;
     1274#else
     1275            if ((sortCrit_ & 1) == 0) {
     1276              useful_[i] = -value;
     1277            }
     1278            else {
     1279              useful_[i] = value;
     1280            }
     1281#endif
     1282          }
     1283       
     1284          if(sortUpTo > maximumStrong) {
     1285            // compute from, upto such that
     1286            // vPriority[k] == vPriority[maximumStrong] for k in [from..upto-1]
     1287            int from = maximumStrong-1, upto = maximumStrong;
     1288            int msPrio = vPriority[maximumStrong-1];
     1289            problem_->setLastPrioSort(msPrio);
     1290            while((from > -1) && (vPriority[from] == msPrio)) {
     1291              from--;
     1292            }
     1293            from++;
     1294            while((upto < sortUpTo) && (vPriority[upto] == msPrio)) {
     1295              upto++;
     1296            }
     1297            // sort list[from]..list[upto-1] according to
     1298            // useful_[from]..useful_[upto-1]
     1299            CoinSort_2(useful_+from, useful_+upto, list_+from);
     1300          }
     1301        }
     1302      }
     1303      else {
     1304        numberUnsatisfied_ = -1;
     1305      }
     1306#else /* not FM_SORT_STRONG */
     1307      // Get list
     1308      numberOnList_=0;
     1309      if (feasible) {
     1310        maximumStrong = CoinMin(maximumStrong,putOther);
     1311        for (i=0;i<maximumStrong;i++) {
     1312          if (list_[i]>=0) {
     1313#ifdef OLD_USEFULLNESS
     1314            list_[numberOnList_]=list_[i];
     1315            useful_[numberOnList_++]=-useful_[i];
     1316           
     1317#else
     1318            list_[numberOnList_]=list_[i];
     1319            if ((sortCrit_ & 1) == 0) {
     1320              useful_[numberOnList_++]=-useful_[i];
     1321            }
     1322            else useful_[numberOnList_++] = useful_[i];
     1323#endif
     1324            message(CANDIDATE_LIST2)<<numberOnList_-1
     1325                                    <<list_[numberOnList_-1]<<numberOnList_-1<<useful_[numberOnList_-1]
     1326                                    <<CoinMessageEol;
     1327          }
     1328        }
     1329        if (numberOnList_) {
     1330          int tmp_on_list = 0;
     1331          if (max_most_fra > 0 && numberOnList_ >= maximumStrong) {
     1332            // If we want to force non-trusted in the list, give them huge
     1333            // weight here
     1334            number_not_trusted_=0;
     1335            for (i=0;i<max_most_fra;i++) {
     1336              if (list2[i]>=0) {
     1337                list2[number_not_trusted_] = list2[i];
     1338                useful2[number_not_trusted_++] = useful2[i];
     1339                message(CANDIDATE_LIST3)<<number_not_trusted_-1
     1340                                        <<list2[number_not_trusted_-1]<<number_not_trusted_-1
     1341                                        <<useful2[number_not_trusted_-1]<<CoinMessageEol;
     1342              }
     1343            }
     1344            if (number_not_trusted_) {
     1345              CoinSort_2(list_,list_+numberOnList_,useful_);
     1346              CoinSort_2(list2,list2+number_not_trusted_,useful2);
     1347              int i1=0;
     1348              int i2=0;
     1349              for (i=0; i<numberObjects; i++) {
     1350                bool found1 = (list_[i1]==i);
     1351                bool found2 = (list2[i2]==i);
     1352                if (found1 && found2) {
     1353                  useful_[i1] = -1e150*(1.+useful2[i2]);
     1354                  list2[i2] = -1;
     1355                }
     1356                if (found1) i1++;
     1357                if (found2) i2++;
     1358                if (i2==max_most_fra) break;
     1359              }
     1360              for (i=0; i<number_not_trusted_; i++) {
     1361                if (list2[i] >= 0) {
     1362                  list_[numberOnList_+tmp_on_list] = list2[i];
     1363                  useful_[numberOnList_+tmp_on_list] = -1e150*(1.+useful2[i]);
     1364                  tmp_on_list++;
     1365                }
     1366              }
     1367            }
     1368          }
     1369          // Sort
     1370          CoinSort_2(useful_,useful_+numberOnList_+tmp_on_list,list_);
     1371          // move others
     1372          i = numberOnList_;
     1373          for (;putOther<numberObjects;putOther++)
     1374            list_[i++]=list_[putOther];
     1375          assert (i==numberUnsatisfied_);
     1376          if (!CoinMax(numberStrong_,numberStrongRoot_))
     1377            numberOnList_=0;
     1378        }
     1379      }
     1380      else {
     1381        // not feasible
     1382        numberUnsatisfied_=-1;
     1383      }
     1384#endif /* not FM_SORT_STRONG */
     1385
     1386      if(!firstPass) {
     1387        break;
     1388      }
     1389      firstPass = false;
     1390    } /* while(numberOnList_ == 0) */
     1391
     1392#ifdef TRACE_STRONG
     1393      printf("numberStrong_: %d   maximumStrong: %d\n",
     1394             numberStrong_, maximumStrong);
     1395#endif
     1396
     1397#ifdef FM_SORT_STRONG
     1398      delete [] vPriority;
     1399#else  /* not FM_SORT_STRONG */
     1400    delete [] list2;
     1401    delete [] useful2;
     1402#endif /* not FM_SORT_STRONG */
     1403
     1404    // Get rid of any shadow prices info
     1405    info->defaultDual_ = -1.0; // switch off
     1406    delete [] info->usefulRegion_;
     1407    delete [] info->indexRegion_;
     1408
     1409    int way;
     1410    if (bb_log_level_>3) {
     1411      //for (int i=0; i<Min(numberUnsatisfied_,numberStrong_); i++)
     1412      for (int i=0; i<numberOnList_; i++){
     1413        message(CANDIDATE_LIST)<<i<< list_[i]<< i<< useful_[i]
     1414        <<object[list_[i]]->infeasibility(info,way)
     1415        <<CoinMessageEol;
     1416      }
     1417    }
     1418    return numberUnsatisfied_;
     1419  }
     1420
     1421/****************************************************************************/
    4551422  /// Add list of options to be read from file ////////////////////////////////////////
    4561423  void CouenneChooseStrong::registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions) {
     
    5211488    double minPosViol = 1e50;
    5221489    for(int i=0; i<numberObjects; i++) {
     1490      CouenneObject *co =  dynamic_cast <CouenneObject *>(object[i]);
     1491      int indVar = -1;
     1492      if(co) {
     1493        indVar = co->Reference()->Index();
     1494      }
     1495      else {
     1496        indVar = object[i]->columnNumber();
     1497      }
    5231498      int way;
    5241499      double value = object[i]->infeasibility(info,way);
    525       int indVar = object[i]->columnNumber();
    5261500      maxViol = (value > maxViol ? value : maxViol);
    5271501      if(value > 0.0) {
  • trunk/Couenne/src/branch/CouenneChooseStrong.hpp

    r575 r586  
    4343  /// Returns number of infeasibilities.
    4444  virtual int setupList (OsiBranchingInformation *info, bool initialize);
     45
     46  // actually setting up the list
     47  int gutsOfSetupList(OsiBranchingInformation *info, bool initialize);
    4548
    4649  /**  This is a utility function which does strong branching on a
     
    115118  /// total time spent in strong branching
    116119  double branchtime_;
     120
     121  // For debugging
     122  int minDepthPrint_;
    117123};
    118124
  • trunk/Couenne/src/branch/doStrongBranching.cpp

    r556 r586  
    1717#include "CouenneBranchingObject.hpp"
    1818
     19//#define TRACE_STRONG
     20//#define TRACE_STRONG2
     21
    1922using namespace Couenne;
    2023
     
    6366     3 - returning because max time
    6467*/
    65 int CouenneChooseStrong::doStrongBranching (OsiSolverInterface *solver,
    66                                             OsiBranchingInformation *info,
    67                                             int numberToDo, int returnCriterion) {
    68 
    69   // // print info at the beginning
    70   // printf ("beginning of doSB\n");
    71   // for (int i=0; i< problem_ -> nVars (); i++) {
    72   //   printf ("x_%-3d @%6g[%6g,%5g] ", i,
    73   //          info -> solution_ [i],
    74   //          info -> lower_ [i],
    75   //          info -> upper_ [i]);
    76   //   if (i && !(i%5)) printf ("\n");
    77   // }
    78 
    79   jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
    80                     "\n-\n------- CCS: trying %d objects:\n", numberToDo);
    81 
    82   //solver -> doingResolve () = false; // turns off setCutoff and restoreUnused
    83 
    84   int numberColumns = solver -> getNumCols ();
    85 
    86   solver -> markHotStart (); // save current LP point
    87 
    88   const double
    89     *lower = info -> lower_,
    90     *upper = info -> upper_;
    91 
    92   double
    93     *saveLower = CoinCopyOfArray (info -> lower_, numberColumns),
    94     *saveUpper = CoinCopyOfArray (info -> upper_, numberColumns),
    95 
    96     *Lower0 = NULL,
    97     *Upper0 = NULL,
    98 
    99     *oldLower  = new double [numberColumns],
    100     *oldUpper  = new double [numberColumns],
    101 
    102     *lpSol     = NULL,
    103     timeStart = CoinCpuTime ();
    104 
    105   if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
    106     Lower0 = CoinCopyOfArray (info -> lower_, numberColumns); // delete afterwards
    107     Upper0 = CoinCopyOfArray (info -> upper_, numberColumns);
     68  int CouenneChooseStrong::doStrongBranching (OsiSolverInterface *solver,
     69                                              OsiBranchingInformation *info,
     70                                              int numberToDo, int returnCriterion) {
     71
     72#ifdef TRACE_STRONG2
     73    int pv = -1;
     74    if(info->depth_ > minDepthPrint_) {
     75      if(pv > -1) {
     76        printf("doSB: beg: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     77               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     78        printf("doSB: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     79               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     80        printf("doSB: problem: lb: %10.4f  ub: %10.4f\n",
     81               problem_->Lb(pv), problem_->Ub(pv));
     82      }
     83    }
     84#endif
     85
     86    jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING,
     87                      "\n-\n------- CCS: trying %d objects:\n", numberToDo);
     88
     89    //solver -> doingResolve () = false; // turns off setCutoff and restoreUnused
     90
     91    int numberColumns = solver -> getNumCols ();
     92
     93    solver -> markHotStart (); // save current LP point
     94
     95    // save initial bounds
     96    const double
     97      *initLower = info -> lower_,
     98      *initUpper = info -> upper_;
     99
     100    // save intersection of bounds obtained by branching on all objects
     101    double
     102      *saveLower = CoinCopyOfArray (info -> lower_, numberColumns),
     103      *saveUpper = CoinCopyOfArray (info -> upper_, numberColumns),
     104
     105      *Lower0 = NULL,
     106      *Upper0 = NULL,
     107
     108      // save union of bounds on both branches of one object;
     109      // reset to (current) saveLower when branching on a new object
     110      *unionLower  = new double [numberColumns],
     111      *unionUpper  = new double [numberColumns],
     112
     113      *lpSol     = NULL,
     114       timeStart = CoinCpuTime ();
     115
     116    if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
     117      Lower0 = CoinCopyOfArray (info -> lower_, numberColumns); // delete afterwards
     118      Upper0 = CoinCopyOfArray (info -> upper_, numberColumns);
     119    }
     120
     121    // LP solution for distance
     122    if (pseudoUpdateLP_)
     123      lpSol = CoinCopyOfArray (info -> solution_, numberColumns);
     124
     125    // provide Couenne problem with point/bounds contained in info
     126    // problem_ -> domain () -> push
     127    //   (problem_ -> nVars (),
     128    //    info -> solution_,
     129    //    info -> lower_,
     130    //    info -> upper_);
     131
     132    Bonmin::HotInfo * results = results_ ();
     133
     134    int returnCode = 0, iDo = 0;
     135
     136    for (iDo = 0; iDo < numberToDo; iDo++) {
     137
     138      Bonmin::HotInfo * result = results_ () + iDo; // retrieve i-th object to test
     139
     140      OsiObject *Object = solver_ -> objects () [result -> whichObject ()];
     141
     142      // TODO: apply isCuttable()     
     143
     144      // TODO: set a cutoff for dual bound in dual simplex
     145      //       do the same for primal based on SB's alpha
     146
     147      // For now just 2 way
     148      OsiBranchingObject * branch = result -> branchingObject ();
     149      assert (branch->numberBranches()==2);
     150
     151      CouenneBranchingObject *cb = dynamic_cast <CouenneBranchingObject *> (branch);
     152
     153      if (cb) cb -> setSimulate (true);
     154
     155      int
     156        status0 = -1,
     157        status1 = -1;
     158
     159      ///////////////////////////////////////////////////////////////////////////
     160
     161      /* Try the first direction.  Each subsequent call to branch()
     162         performs the specified branch and advances the branch object
     163         state to the next branch alternative. */
     164
     165      bool isInf0 = false;
     166      bool isInf1 = false;
     167
     168      double indUb = 0, indLb = 0;
     169      CouenneObject *CouObj = dynamic_cast <CouenneObject *> (Object);
     170      OsiSimpleInteger *simpl = dynamic_cast <OsiSimpleInteger *>(solver_->objects()[result->whichObject ()]);
     171      // if OsiSimpleInteger Object with branching point outside
     172      // current solver bound interval, one branch must
     173      // be set as infeasible, otherwise bounds are enlarged
     174      // in one branch
     175      int objVarIndex = -1;
     176      if(CouObj) {
     177        objVarIndex = CouObj->Reference()->Index();
     178      }
     179      else {
     180        objVarIndex = Object->columnNumber();
     181      }
     182      if(simpl) {
     183        if(objVarIndex >= 0) {
     184          indUb = solver->getColUpper()[objVarIndex];
     185          indLb = solver->getColLower()[objVarIndex];
     186          if(info->solution_[objVarIndex] < indLb) {
     187            isInf0 = true;
     188          }
     189          if(info->solution_[objVarIndex] > indUb) {
     190            isInf1 = true;
     191          }
     192        }
     193      }
     194
     195      status0 = simulateBranch (Object, info, branch, solver, result, -1);
     196      if(isInf0) {
     197        status0 = 1; // branch was known to be infeasible
     198        result->setDownStatus(1);
     199      }
     200
     201      // save current bounds as tightened by the down branch; will be           
     202      // used below to update global bounding box in solver                     
     203      // if status0 == 1 unionLower will be ignored below                         
     204      CoinCopyN (solver->getColLower(), numberColumns, unionLower);
     205      CoinCopyN (solver->getColUpper(), numberColumns, unionUpper);
     206
     207      // Restore pre-left-branch bounds in solver and problem
     208      for (int j=0; j<numberColumns; j++) {
     209        if(problem_->Lb(j) > unionLower[j]) {
     210          unionLower[j] = problem_->Lb(j);
     211        }
     212        if(problem_->Ub(j) < unionLower[j]) {
     213          unionLower[j] = problem_->Ub(j);
     214        }
     215
     216        solver->setColLower(j, saveLower [j]);
     217        solver->setColUpper (j, saveUpper [j]);
     218        problem_ -> Lb (j) = saveLower [j];
     219        problem_ -> Ub (j) = saveUpper [j];
     220      }
     221
     222      /* second direction */
     223
     224      status1 = simulateBranch (Object, info, branch, solver, result, +1);
     225      if(isInf1) {
     226        status1 = 1; // branch was known to be infeasible
     227        result->setUpStatus(1);
     228      }
     229
     230#ifdef TRACE_STRONG
     231      if(info->depth_ > minDepthPrint_) {
     232        printf("Strong on object %d: status0: %d  status1: %d\n",
     233               result->whichObject(), status0, status1);
     234      }
     235#endif
     236
     237      ///////////////////////////////////////////////////////////////////////////
     238
     239      jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "-------\n");
     240
     241      if (cb)
     242        cb -> setSimulate (false);
     243
     244      /////////////////////////////////////////////////////////////////////////////
     245
     246      bool tightened = false;
     247
     248      t_chg_bounds *chg_bds = new t_chg_bounds [numberColumns];
     249
     250      const double *sLb = solver->getColLower();
     251      const double *sUb = solver->getColUpper();
     252
     253      if(status1 != 1) { // feasible
     254        if(status0 != 1) { // feasible; take union of both branches
     255          for (int j=0; j<numberColumns; j++) {
     256            double maxLb = (problem_->Lb(j) < sLb[j] ? sLb[j] : problem_->Lb(j));
     257            double minUb = (problem_->Ub(j) < sUb[j] ? problem_->Ub(j) : sUb[j]);
     258            problem_->Lb(j) = (unionLower[j] > maxLb ? maxLb : unionLower [j]);
     259            problem_->Ub(j) = (unionUpper[j] < minUb ? minUb : unionUpper [j]);
     260          }
     261        }
     262        else { // keep current bounds; best of problem_ and solver
     263          for (int j=0; j<numberColumns; j++) {
     264            problem_->Lb(j) = (problem_->Lb(j) < sLb[j] ? sLb[j] : problem_->Lb(j));
     265            problem_->Ub(j) = (problem_->Ub(j) < sUb[j] ? problem_->Ub(j) : sUb[j]);
     266          }
     267        }
     268      }
     269      else { // branch 1 infeasible
     270        if(status0 != 1) { // feasible; otherwise both branches are infeasible 
     271                           // keep current inconsistant bounds in solver       
     272          for (int j=0; j<numberColumns; j++) {                                 
     273            problem_->Lb (j) = unionLower [j];                                 
     274            problem_->Ub (j) = unionUpper [j];                                 
     275          }                                                                     
     276        }                                                                       
     277      }                                                                         
     278
     279      if((status0 == 1) && (status1 == 1)) {
     280        tightened = false;
     281
     282        // make sure that bounds in solver proves problem is
     283        // infeasible
     284        double lbVar0 = solver->getColLower()[0];
     285        if(lbVar0 < 1) {
     286          solver->setColLower(0, 1);
     287          solver->setColUpper(0, 0);
     288        }
     289        else {
     290          solver->setColUpper(0, lbVar0-1);
     291        }
     292      }
     293      else {
     294        for (int j=0; j<numberColumns; j++) {
     295          if (problem_ -> Lb (j) > initLower [j] + COUENNE_EPS) {
     296            chg_bds [j].setLower (t_chg_bounds::CHANGED);
     297            tightened = true;
     298          }
     299         
     300          if (problem_ -> Ub (j) < initUpper [j] - COUENNE_EPS) {
     301            chg_bds [j].setUpper (t_chg_bounds::CHANGED);
     302            tightened = true;
     303          }
     304        }
     305      }
     306      if (tightened &&                     // have tighter bounds
     307          (problem_ -> doFBBT ()) &&       // selected FBBT
     308          !(problem_ -> btCore (chg_bds))) // tighten again on root
     309
     310        status0 = status1 = 1;             // if returns false, problem is infeasible
     311
     312      delete [] chg_bds;
     313
     314
     315      if((status0 != 1) || (status1 != 1)) {
     316
     317        // set new bounding box as the possibly tightened one (a subset
     318        // of the initial)
     319        for (int j=0; j<numberColumns; j++) {
     320          solver -> setColLower (j, saveLower [j] = problem_ -> Lb (j));
     321          solver -> setColUpper (j, saveUpper [j] = problem_ -> Ub (j));
     322        }
     323      }
     324
     325      /*
     326        End of evaluation for this candidate object. Possibilities are:
     327
     328        * Both sides below cutoff; this variable is a candidate for
     329          branching.
     330
     331        * Both sides infeasible or above the objective cutoff: no
     332          further action here. Break from the evaluation loop and
     333          assume the node will be purged by the caller.
     334
     335        * One side feasible and below cutoff: Install the branch
     336          (i.e., fix the variable). Possibly break from the evaluation
     337          loop and assume the node will be reoptimised by the caller.
     338      */
     339
     340      if (status0 == 1 &&
     341          status1 == 1) { // infeasible
     342        returnCode=-1;
     343        break; // exit loop
     344      } else if (status0==1 || status1==1) {
     345        numberStrongFixed_++;
     346        if (!returnCriterion) {
     347          returnCode=1;
     348        } else {
     349          returnCode=2;
     350          break;
     351        }
     352      }
     353
     354      bool hitMaxTime = ( CoinCpuTime()-timeStart > info->timeRemaining_);
     355      if (hitMaxTime) {
     356        returnCode=3;
     357        break;
     358      }
     359    } // end loop /***********************************/
     360
     361    if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
     362      printf ("tightened bounds: ");
     363      // create union of bounding box from both branching directions
     364      for (int j=0; j<numberColumns; j++) {
     365     
     366        if (problem_ -> Lb (j) > Lower0 [j]) printf ("l%d (%g-->%g) ", j,Lower0[j], problem_->Lb (j));
     367        if (problem_ -> Ub (j) < Upper0 [j]) printf ("u%d (%g-->%g) ", j,Upper0[j], problem_->Ub (j));
     368      }
     369
     370      delete [] Lower0;
     371      delete [] Upper0;
     372    }
     373
     374    //problem_ -> domain () -> pop (); // discard current point/bounds from problem
     375
     376    delete [] lpSol;
     377
     378    jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "----------------------done\n\n\n");
     379
     380#ifdef TRACE_STRONG2
     381    if(info->depth_ > minDepthPrint_) {
     382      if(pv > -1) {
     383        printf("doSB: beg: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     384               pv, solver->getColSolution()[pv], solver->getColLower()[pv], solver->getColUpper()[pv]);
     385        printf("doSB: info: x[%d]: %10.4f  lb: %10.4f  ub: %10.4f\n",
     386               pv, info->solution_[pv], info->lower_[pv], info->upper_[pv]);
     387        printf("doSB: problem: lb: %10.4f  ub: %10.4f\n",
     388               problem_->Lb(pv), problem_->Ub(pv));
     389      }
     390    }
     391#endif
     392
     393    if (iDo < numberToDo) iDo++; // exited due to infeasibility
     394    assert (iDo <= (int) results_.size());
     395    results_.resize (iDo);
     396
     397    delete [] unionLower;
     398    delete [] unionUpper;
     399
     400    delete [] saveLower;
     401    delete [] saveUpper;
     402
     403    solver -> unmarkHotStart ();     // Delete the snapshot
     404
     405    //solver -> doingResolve () = true;
     406    branchtime_ += CoinCpuTime () - timeStart;
     407
     408    return returnCode;
    108409  }
    109 
    110   // LP solution for distance
    111   if (pseudoUpdateLP_)
    112     lpSol = CoinCopyOfArray (info -> solution_, numberColumns);
    113 
    114   // provide Couenne problem with point/bounds contained in info
    115   // problem_ -> domain () -> push
    116   //   (problem_ -> nVars (),
    117   //    info -> solution_,
    118   //    info -> lower_,
    119   //    info -> upper_);
    120 
    121   int returnCode = 0, iDo = 0;
    122 
    123   Bonmin::HotInfo * results = results_ ();
    124 
    125   for (;iDo < numberToDo; iDo++) {
    126 
    127     Bonmin::HotInfo * result = results + iDo; // retrieve i-th object to test
    128 
    129     OsiObject *Object = solver_ -> objects () [result -> whichObject ()];
    130 
    131     // TODO: apply isCuttable ()
    132 
    133     // TODO: set a cutoff for dual bound in dual simplex
    134     //       do the same for primal based on SB's alpha
    135 
    136     // For now just 2 way
    137     OsiBranchingObject * branch = result -> branchingObject ();
    138     assert (branch->numberBranches()==2);
    139 
    140     CouenneBranchingObject *cb = dynamic_cast <CouenneBranchingObject *> (branch);
    141     if (cb) cb -> setSimulate (true);
    142 
    143     int
    144       status0 = -1,
    145       status1 = -1;
    146 
    147     ///////////////////////////////////////////////////////////////////////////
    148 
    149     /* Try the first direction.  Each subsequent call to branch()
    150        performs the specified branch and advances the branch object
    151        state to the next branch alternative. */
    152 
    153     status0 = simulateBranch (Object, info, branch, solver, result, -1);
    154 
    155     // save current bounds as tightened by the down branch; will be
    156     // used below to update global bounding box in solver
    157     CoinCopyN (problem_ -> Lb (), numberColumns, oldLower);
    158     CoinCopyN (problem_ -> Ub (), numberColumns, oldUpper);
    159 
    160     // Restore pre-left-branch bounds in solver
    161     for (int j=0; j<numberColumns; j++) {
    162 
    163       if (saveLower [j] != lower [j]) solver -> setColLower (j, saveLower [j]);
    164       if (saveUpper [j] != upper [j]) solver -> setColUpper (j, saveUpper [j]);
    165 
    166       problem_ -> Lb (j) = saveLower [j];
    167       problem_ -> Ub (j) = saveUpper [j];
    168     }
    169 
    170     status1 = simulateBranch (Object, info, branch, solver, result, +1);
    171 
    172     ///////////////////////////////////////////////////////////////////////////
    173 
    174     if (cb) cb -> setSimulate (false);
    175 
    176     /////////////////////////////////////////////////////////////////////////////
    177 
    178     bool tightened = false;
    179 
    180     t_chg_bounds *chg_bds = new t_chg_bounds [numberColumns];
    181 
    182     // extend problem_'s bounding box to include downbranch's tightened
    183     for (int j=0; j<numberColumns; j++) {
    184 
    185       if (oldLower [j] < problem_ -> Lb (j)) problem_ -> Lb (j) = oldLower [j];
    186       if (oldUpper [j] > problem_ -> Ub (j)) problem_ -> Ub (j) = oldUpper [j];
    187 
    188       if (problem_ -> Lb (j) > lower [j] + COUENNE_EPS) {
    189         chg_bds [j].setLower (t_chg_bounds::CHANGED);
    190         tightened = true;
    191       }
    192 
    193       if (problem_ -> Ub (j) < upper [j] - COUENNE_EPS) {
    194         chg_bds [j].setUpper (t_chg_bounds::CHANGED);
    195         tightened = true;
    196       }
    197     }
    198 
    199     // at this point, problem_'s bounds are a tightening of the union
    200     // of the two nodes and should be kept for the caller,
    201     // CouenneChooseStrong::chooseVariable()
    202 
    203     if (tightened &&                     // have tighter bounds
    204         (problem_ -> doFBBT ()) &&       // selected FBBT
    205         !(problem_ -> btCore (chg_bds))) // tighten again on root
    206 
    207       status0 = status1 = 1;               // if returns false, problem is infeasible
    208 
    209     delete [] chg_bds;
    210 
    211     // set new bounding box as the possibly tightened one (a subset
    212     // of the initial)
    213     for (int j=0; j<numberColumns; j++) {
    214       solver -> setColLower (j, saveLower [j] = problem_ -> Lb (j));
    215       solver -> setColUpper (j, saveUpper [j] = problem_ -> Ub (j));
    216     }
    217 
    218     /*
    219       End of evaluation for this candidate object. Possibilities are:
    220 
    221       * Both sides below cutoff; this variable is a candidate for
    222       branching.
    223 
    224       * Both sides infeasible or above the objective cutoff: no
    225       further action here. Break from the evaluation loop and
    226       assume the node will be purged by the caller.
    227 
    228       * One side feasible and below cutoff: Install the branch
    229       (i.e., fix the variable). Possibly break from the evaluation
    230       loop and assume the node will be reoptimised by the caller.
    231     */
    232 
    233     if (status0 == 1 &&
    234         status1 == 1) { // infeasible
    235       returnCode=-1;
    236       break; // exit loop
    237     } else if (status0==1 || status1==1) {
    238       numberStrongFixed_++;
    239       if (!returnCriterion) {
    240         returnCode=1;
    241       } else {
    242         returnCode=2;
    243         break;
    244       }
    245     }
    246 
    247     bool hitMaxTime = ( CoinCpuTime()-timeStart > info->timeRemaining_);
    248     if (hitMaxTime) {
    249       returnCode=3;
    250       break;
    251     }
    252   } // end loop /***********************************/
    253  
    254 
    255   if (jnlst_ -> ProduceOutput (J_DETAILED, J_BRANCHING)) {
    256     printf ("tightened bounds: ");
    257     // create union of bounding box from both branching directions
    258     for (int j=0; j<numberColumns; j++) {
    259      
    260       if (problem_ -> Lb (j) > Lower0 [j]) printf ("l%d (%g-->%g) ", j,Lower0[j], problem_->Lb (j));
    261       if (problem_ -> Ub (j) < Upper0 [j]) printf ("u%d (%g-->%g) ", j,Upper0[j], problem_->Ub (j));
    262     }
    263 
    264     delete [] Lower0;
    265     delete [] Upper0;
    266   }
    267 
    268   //problem_ -> domain () -> pop (); // discard current point/bounds from problem
    269 
    270   delete [] lpSol;
    271 
    272   jnlst_ -> Printf (J_ITERSUMMARY, J_BRANCHING, "----------------------done\n\n\n");
    273 
    274   if (iDo < numberToDo) iDo++; // exited due to infeasibility
    275   assert (iDo <= (int) results_.size());
    276   results_.resize (iDo);
    277 
    278   delete [] oldLower;
    279   delete [] oldUpper;
    280 
    281   delete [] saveLower;
    282   delete [] saveUpper;
    283 
    284   solver -> unmarkHotStart ();     // Delete the snapshot
    285 
    286   //solver -> doingResolve () = true;
    287   branchtime_ += CoinCpuTime () - timeStart;
    288 
    289   // // print info at the beginning
    290   // printf ("end of doSB\n");
    291   // for (int i=0; i< problem_ -> nVars (); i++) {
    292   //   printf ("x_%-3d @%5g[%5g,%5g] ", i,
    293   //          info -> solution_ [i],
    294   //          info -> lower_ [i],
    295   //          info -> upper_ [i]);
    296   //   if (i && !(i%5)) printf ("\n");
    297   // }
    298 
    299   return returnCode;
    300 }
    301 
    302410
    303411// Do one side of strong branching
  • trunk/Couenne/src/main/BonCouenne.cpp

    r577 r586  
    6666  }
    6767}
     68
     69//#define FM_FRES
    6870
    6971int main (int argc, char *argv[]) {
     
    277279      switch (retcomp) {
    278280      case -1: printf("No solution found\n"); break;
    279       case 0: printf("Best solution found by Cbc\n"); break;
    280       case 1: printf("Best solution found by Couenne\n"); break;
     281      case 0: printf("Best solution found by Cbc  Value: %10.4f  Tolerance: %10g\n", modCbcSolVal, modCbcSolMaxViol); break;
     282      case 1: printf("Best solution found by Couenne  Value: %10.4f  Tolerance: %10g\n", modCouenneSolVal, modCouenneSolMaxViol); break;
    281283      default: break; // never happens
    282284      }
     
    296298#endif /* FM_TRACE_OPTSOL */
    297299
     300#ifdef FM_FRES
     301    if(cp != NULL) {
     302      FILE *f_res = fopen("fres.xxx", "a");
     303      char *pbName, shortName[256]; 
     304     
     305      pbName = strdup(cp -> problemName ().c_str ());
     306      char *f_name_pos = strrchr(pbName, '/');
     307      if(f_name_pos != NULL) {
     308        strcpy(shortName, &(f_name_pos[1]));
     309      }
     310      else {
     311        strcpy(shortName, pbName);
     312      }
     313     
     314      fprintf(f_res, "%20s %10.4f", shortName, cbcLb);
     315      if(foundSol) {
     316        fprintf(f_res, " %10.4f", printObj);
     317      }
     318      else {
     319        fprintf(f_res, "         *");
     320      }
     321      fprintf(f_res, " %10d %10.4f\n", bb.numNodes (),
     322              CoinCpuTime () - time_start);
     323      fclose(f_res);
     324    }
     325#endif
    298326
    299327    // retrieve test value to check
  • trunk/Couenne/src/problem/CouenneProblem.cpp

    r549 r586  
    251251{return ConstPtr (jnlst_);}
    252252
     253// set lastPrioSort_
     254void CouenneProblem::setLastPrioSort(int givenLastPS) {
     255  lastPrioSort_ = givenLastPS;
     256}
  • trunk/Couenne/src/problem/CouenneProblem.hpp

    r573 r586  
    290290  int nUnusedOriginals_;
    291291
     292  // to speedup sorting operations in strong branching
     293  int lastPrioSort_;
     294
    292295  // to record best solution found
    293296  struct Couenne::CouenneRecordBestSol *recBSol;
     
    763766
    764767public:
     768
     769  inline int getLastPrioSort() const {return lastPrioSort_;};
     770  void setLastPrioSort(int givenLastPS);
     771
    765772  inline CouenneRecordBestSol *getRecordBestSol() const {return recBSol;};
    766773
  • trunk/Couenne/src/problem/CouenneProblemConstructors.cpp

    r573 r586  
    105105
    106106  recBSol = new struct Couenne::CouenneRecordBestSol();
    107 
     107  lastPrioSort_ = 1000000;
    108108}
    109109
     
    191191
    192192  recBSol = new CouenneRecordBestSol(*(p.recBSol));
     193  lastPrioSort_ = p.lastPrioSort_;
    193194}
    194195
Note: See TracChangeset for help on using the changeset viewer.