コード例 #1
0
ファイル: BonNWayChoose.cpp プロジェクト: coin-or/Bonmin
  /* Choose a variable
     Returns -
     -1 Node is infeasible
     0  Normal termination - we have a candidate
     1  All looks satisfied - no candidate
     2  We can change the bound on a variable - but we also have a strong branching candidate
     3  We can change the bound on a variable - but we have a non-strong branching candidate
     4  We can change the bound on a variable - no other candidates
     We can pick up branch from whichObject() and whichWay()
     We can pick up a forced branch (can change bound) from whichForcedObject() and whichForcedWay()
     If we have a solution then we can pick up from goodObjectiveValue() and goodSolution()
  */
  int
  BonNWayChoose::chooseVariable(
    OsiSolverInterface * solver,
    OsiBranchingInformation *info,
    bool fixVariables)
  {
    if(!numberUnsatisfied_) return 1;//Node is feasible


    double cutoff = info->cutoff_;
    double obj_val = info->objectiveValue_;
    if(info->depth_ > br_depth_ &&  ( (- useful_[0]   > pseudocost_trust_value_ )|| num_eval_[list_[0] - start_nway_] >= 18) ){
      const double * lower = info->lower_;
      const double * upper = info->upper_;


      // See if quick variable fixing can be done
      int n_fixed = 0;
      if(do_fixings_ > 1){
         for(int i = 0 ; i < numberUnsatisfied_ ; i++){
            int iObject = list_[i];
            int nwayIndex = iObject - start_nway_;
            const BonNWayObject * nway = ASSERTED_CAST<const BonNWayObject *>(solver->object(iObject));

            size_t n = nway->numberMembers();
            const int * vars = nway->members();
            for(size_t  j = 0 ; j < n ; j++){
              int iCol = vars[j];
              if(upper[iCol] < lower[iCol] + 0.5) continue;//variable already fixed to lower buund
              if(bounds_[nwayIndex][j] > cutoff){//It can be fixed
                 solver->setColUpper(iCol, lower[iCol]);
                 n_fixed ++;
              }
            }
         }
        if(n_fixed && log_ > 1)
          printf("NWAY: Fixed %i variables\n", n_fixed);
      }

      assert(bounds_.size() == unit_changes_.size());
      assert(unit_changes_.size() == info->solver_->numberObjects() - start_nway_);
      //Just take the most usefull
      bestObjectIndex_ = list_[0];
      bestWhichWay_ = 1; 
      OsiObject * obj = solver->objects()[bestObjectIndex_];
      obj->setWhichWay(bestWhichWay_);

      if(log_ > 1){
        printf("level %i branch on %i bound %g usefullness %g.\n",
               info->depth_, bestObjectIndex_ - start_nway_, obj_val, - useful_[0]);
      }
      if(n_fixed) return 2;
      return 0;
     }


    if(log_ > 0)
      printf("Restarting strong branching loop....\n\n");

    numberStrongIterations_ = 0;
    numberStrongDone_ = 0;
    int numberLeft = numberOnList_;//Always do full strong at root
    int returnCode=0;
    bestObjectIndex_ = -1;
    bestWhichWay_ = -1;
    firstForcedObjectIndex_ = -1;
    firstForcedWhichWay_ =-1;
    double best_score = -COIN_DBL_MAX;
    int bestPriority=0;

    int n = solver->getNumCols();
    std::vector<double> saveLower(n);
    std::vector<double> saveUpper(n);
    std::copy(info->lower_, info->lower_ + n, saveLower.begin());
    std::copy(info->upper_, info->upper_ + n, saveUpper.begin());


    solver->markHotStart();
    for (int i=0;i<numberLeft;i++) {
      int iObject = list_[i];
      const int objectPriority = solver->object(iObject)->priority();
      if (objectPriority >= bestPriority){
             bestPriority = objectPriority;
      }
      else break;
      double score;
      int r_val = doStrongBranching(solver, info, iObject, saveLower.data(),
                                     saveUpper.data(), score);
      if(r_val == -1) {
         if(log_ > 0)
           std::cout<<"This is Infeasible"<<std::endl;
         returnCode = -1;
         break;
      }

      if(do_fixings_ > 1 && r_val == 1 && info->depth_ == 0) returnCode=2;
      //Compute Score
      if(log_ > 0)
        printf("Usefullness from strong branching on %i : %g\n", iObject - start_nway_, score);
      if(score > best_score){//We have a winner
        best_score = score;
        bestObjectIndex_ = iObject;
        bestWhichWay_ = 0;
      }
      if (r_val==3) {
          returnCode = 3;
          // max time - just choose one
          if(bestObjectIndex_ < 0){
            bestObjectIndex_ = list_[0];
            bestWhichWay_ = 0;
          }
          break;
        }
    }
    solver->unmarkHotStart();
    return returnCode;
  }
コード例 #2
0
ファイル: OsiChooseVariable.cpp プロジェクト: sednanref/tesis
/* Choose a variable
   Returns - 
   -1 Node is infeasible
   0  Normal termination - we have a candidate
   1  All looks satisfied - no candidate
   2  We can change the bound on a variable - but we also have a strong branching candidate
   3  We can change the bound on a variable - but we have a non-strong branching candidate
   4  We can change the bound on a variable - no other candidates
   We can pick up branch from whichObject() and whichWay()
   We can pick up a forced branch (can change bound) from whichForcedObject() and whichForcedWay()
   If we have a solution then we can pick up from goodObjectiveValue() and goodSolution()
*/
int 
OsiChooseStrong::chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables)
{
  if (numberUnsatisfied_) {
    const double* upTotalChange = pseudoCosts_.upTotalChange();
    const double* downTotalChange = pseudoCosts_.downTotalChange();
    const int* upNumber = pseudoCosts_.upNumber();
    const int* downNumber = pseudoCosts_.downNumber();
    int numberBeforeTrusted = pseudoCosts_.numberBeforeTrusted();
    // Somehow we can get here with it 0 !
    if (!numberBeforeTrusted) {
      numberBeforeTrusted=5;
      pseudoCosts_.setNumberBeforeTrusted(numberBeforeTrusted);
    }

    int numberLeft = CoinMin(numberStrong_-numberStrongDone_,numberUnsatisfied_);
    int numberToDo=0;
    resetResults(numberLeft);
    int returnCode=0;
    bestObjectIndex_ = -1;
    bestWhichWay_ = -1;
    firstForcedObjectIndex_ = -1;
    firstForcedWhichWay_ =-1;
    double bestTrusted=-COIN_DBL_MAX;
    for (int i=0;i<numberLeft;i++) {
      int iObject = list_[i];
      if (upNumber[iObject]<numberBeforeTrusted||downNumber[iObject]<numberBeforeTrusted) {
	results_[numberToDo++] = OsiHotInfo(solver, info,
					    solver->objects(), iObject);
      } else {
	const OsiObject * obj = solver->object(iObject);
	double upEstimate = (upTotalChange[iObject]*obj->upEstimate())/upNumber[iObject];
	double downEstimate = (downTotalChange[iObject]*obj->downEstimate())/downNumber[iObject];
	double value = MAXMIN_CRITERION*CoinMin(upEstimate,downEstimate) + (1.0-MAXMIN_CRITERION)*CoinMax(upEstimate,downEstimate);
	if (value > bestTrusted) {
	  bestObjectIndex_=iObject;
	  bestWhichWay_ = upEstimate>downEstimate ? 0 : 1;
	  bestTrusted = value;
	}
      }
    }
    int numberFixed=0;
    if (numberToDo) {
      returnCode = doStrongBranching(solver, info, numberToDo, 1);
      if (returnCode>=0&&returnCode<=2) {
	if (returnCode) {
	  returnCode=4;
	  if (bestObjectIndex_>=0)
	    returnCode=3;
	}
	for (int i=0;i<numResults_;i++) {
	  int iObject = results_[i].whichObject();
	  double upEstimate;
	  if (results_[i].upStatus()!=1) {
	    assert (results_[i].upStatus()>=0);
	    upEstimate = results_[i].upChange();
	  } else {
	    // infeasible - just say expensive
	    if (info->cutoff_<1.0e50)
	      upEstimate = 2.0*(info->cutoff_-info->objectiveValue_);
	    else
	      upEstimate = 2.0*fabs(info->objectiveValue_);
	    if (firstForcedObjectIndex_ <0) {
	      firstForcedObjectIndex_ = iObject;
	      firstForcedWhichWay_ =0;
	    }
	    numberFixed++;
	    if (fixVariables) {
	      const OsiObject * obj = solver->object(iObject);
	      OsiBranchingObject * branch = obj->createBranch(solver,info,0);
	      branch->branch(solver);
	      delete branch;
	    }
	  }
	  double downEstimate;
	  if (results_[i].downStatus()!=1) {
	    assert (results_[i].downStatus()>=0);
	    downEstimate = results_[i].downChange();
	  } else {
	    // infeasible - just say expensive
	    if (info->cutoff_<1.0e50)
	      downEstimate = 2.0*(info->cutoff_-info->objectiveValue_);
	    else
	      downEstimate = 2.0*fabs(info->objectiveValue_);
	    if (firstForcedObjectIndex_ <0) {
	      firstForcedObjectIndex_ = iObject;
	      firstForcedWhichWay_ =1;
	    }
	    numberFixed++;
	    if (fixVariables) {
	      const OsiObject * obj = solver->object(iObject);
	      OsiBranchingObject * branch = obj->createBranch(solver,info,1);
	      branch->branch(solver);
	      delete branch;
	    }
	  }
	  double value = MAXMIN_CRITERION*CoinMin(upEstimate,downEstimate) + (1.0-MAXMIN_CRITERION)*CoinMax(upEstimate,downEstimate);
	  if (value>bestTrusted) {
	    bestTrusted = value;
	    bestObjectIndex_ = iObject;
	    bestWhichWay_ = upEstimate>downEstimate ? 0 : 1;
	    // but override if there is a preferred way
	    const OsiObject * obj = solver->object(iObject);
	    if (obj->preferredWay()>=0&&obj->infeasibility())
	      bestWhichWay_ = obj->preferredWay();
	    if (returnCode)
	      returnCode=2;
	  }
	}
      } else if (returnCode==3) {
	// max time - just choose one
	bestObjectIndex_ = list_[0];
	bestWhichWay_ = 0;
	returnCode=0;
      }
    } else {
      bestObjectIndex_=list_[0];
    }
    if ( bestObjectIndex_ >=0 ) {
      OsiObject * obj = solver->objects()[bestObjectIndex_];
      obj->setWhichWay(	bestWhichWay_);
    }
    if (numberFixed==numberUnsatisfied_&&numberFixed)
      returnCode=4;
    return returnCode;
  } else {
    return 1;
  }
}