예제 #1
0
// Creates a branching object
CbcBranchingObject * 
CbcSimpleIntegerFixed::createBranch(OsiSolverInterface * solver,
					    const OsiBranchingInformation * info, int way)  
{
  const double * solution = model_->testSolution();
  const double * lower = solver->getColLower();
  const double * upper = solver->getColUpper();
  double value = solution[columnNumber_];
  value = CoinMax(value, lower[columnNumber_]);
  value = CoinMin(value, upper[columnNumber_]);
  assert (upper[columnNumber_]>lower[columnNumber_]);
  if (!model_->hotstartSolution()) {
    double nearest = floor(value+0.5);
    double integerTolerance = 
    model_->getDblParam(CbcModel::CbcIntegerTolerance);
    if (fabs(value-nearest)<integerTolerance) {
      // adjust value
      if (nearest!=upper[columnNumber_])
	value = nearest+2.0*integerTolerance;
      else
	value = nearest-2.0*integerTolerance;
    }
  } else {
    const double * hotstartSolution = model_->hotstartSolution();
    double targetValue = hotstartSolution[columnNumber_];
    if (way>0)
      value = targetValue-0.1;
    else
      value = targetValue+0.1;
  }
  CbcBranchingObject * branch = new CbcIntegerBranchingObject(model_,columnNumber_,way,
					     value);
  branch->setOriginalObject(this);
  return branch;
}
예제 #2
0
CbcBranchingObject *
CbcNWay::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * /*info*/, int /*way*/)
{
    int numberFree = 0;
    int j;

    //OsiSolverInterface * solver = model_->solver();
    const double * solution = model_->testSolution();
    const double * lower = solver->getColLower();
    const double * upper = solver->getColUpper();
    int * list = new int[numberMembers_];
    double * sort = new double[numberMembers_];

    for (j = 0; j < numberMembers_; j++) {
        int iColumn = members_[j];
        double value = solution[iColumn];
        value = CoinMax(value, lower[iColumn]);
        value = CoinMin(value, upper[iColumn]);
        if (upper[iColumn] > lower[iColumn]) {
            double distance = upper[iColumn] - value;
            list[numberFree] = j;
            sort[numberFree++] = distance;
        }
    }
    assert (numberFree);
    // sort
    CoinSort_2(sort, sort + numberFree, list);
    // create object
    CbcBranchingObject * branch;
    branch = new CbcNWayBranchingObject(model_, this, numberFree, list);
    branch->setOriginalObject(this);
    delete [] list;
    delete [] sort;
    return branch;
}
예제 #3
0
int
CbcBranchDefaultDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
                                      int numberUnsatisfied,
                                      double * changeUp, int * numberInfeasibilitiesUp,
                                      double * changeDown, int * numberInfeasibilitiesDown,
                                      double objectiveValue)
{

    int bestWay = 0;
    int whichObject = -1;
    if (numberObjects) {
        CbcModel * model = cbcModel();
        // at continuous
        //double continuousObjective = model->getContinuousObjective();
        //int continuousInfeasibilities = model->getContinuousInfeasibilities();

        // average cost to get rid of infeasibility
        //double averageCostPerInfeasibility =
        //(objectiveValue-continuousObjective)/
        //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
        /* beforeSolution is :
           0 - before any solution
           n - n heuristic solutions but no branched one
           -1 - branched solution found
        */
        int numberSolutions = model->getSolutionCount();
        double cutoff = model->getCutoff();
        int method = 0;
        int i;
        if (numberSolutions) {
            int numberHeuristic = model->getNumberHeuristicSolutions();
            if (numberHeuristic < numberSolutions) {
                method = 1;
            } else {
                method = 2;
                // look further
                for ( i = 0 ; i < numberObjects ; i++) {
                    int numberNext = numberInfeasibilitiesUp[i];

                    if (numberNext < numberUnsatisfied) {
                        int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
                        double perUnsatisfied = changeUp[i] / static_cast<double> (numberUp);
                        double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
                        if (estimatedObjective < cutoff)
                            method = 3;
                    }
                    numberNext = numberInfeasibilitiesDown[i];
                    if (numberNext < numberUnsatisfied) {
                        int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
                        double perUnsatisfied = changeDown[i] / static_cast<double> (numberDown);
                        double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
                        if (estimatedObjective < cutoff)
                            method = 3;
                    }
                }
            }
            method = 2;
        } else {
            method = 0;
        }
        // Uncomment next to force method 4
        //method=4;

	// FIXME This should be an enum.  It will be easier to
	// understand in the code than numbers.
        /* Methods :
           0 - fewest infeasibilities
           1 - largest min change in objective
           2 - as 1 but use sum of changes if min close
           3 - predicted best solution
           4 - take cheapest up branch if infeasibilities same
        */
        int bestNumber = COIN_INT_MAX;
        double bestCriterion = -1.0e50;
        double alternativeCriterion = -1.0;
        double bestEstimate = 1.0e100;
        switch (method) {
        case 0:
            // could add in depth as well
            for ( i = 0 ; i < numberObjects ; i++) {
                int thisNumber = CoinMin(numberInfeasibilitiesUp[i], numberInfeasibilitiesDown[i]);
                if (thisNumber <= bestNumber) {
                    int betterWay = 0;
                    if (numberInfeasibilitiesUp[i] < numberInfeasibilitiesDown[i]) {
                        if (numberInfeasibilitiesUp[i] < bestNumber) {
                            betterWay = 1;
                        } else {
                            if (changeUp[i] < bestCriterion)
                                betterWay = 1;
                        }
                    } else if (numberInfeasibilitiesUp[i] > numberInfeasibilitiesDown[i]) {
                        if (numberInfeasibilitiesDown[i] < bestNumber) {
                            betterWay = -1;
                        } else {
                            if (changeDown[i] < bestCriterion)
                                betterWay = -1;
                        }
                    } else {
                        // up and down have same number
                        bool better = false;
                        if (numberInfeasibilitiesUp[i] < bestNumber) {
                            better = true;
                        } else if (numberInfeasibilitiesUp[i] == bestNumber) {
                            if (CoinMin(changeUp[i], changeDown[i]) < bestCriterion)
                                better = true;;
                        }
                        if (better) {
                            // see which way
                            if (changeUp[i] <= changeDown[i])
                                betterWay = 1;
                            else
                                betterWay = -1;
                        }
                    }
                    if (betterWay) {
                        bestCriterion = CoinMin(changeUp[i], changeDown[i]);
                        bestNumber = thisNumber;
                        whichObject = i;
                        bestWay = betterWay;
                    }
                }
            }
            break;
        case 1:
            for ( i = 0 ; i < numberObjects ; i++) {
                int betterWay = 0;
                if (changeUp[i] <= changeDown[i]) {
                    if (changeUp[i] > bestCriterion)
                        betterWay = 1;
                } else {
                    if (changeDown[i] > bestCriterion)
                        betterWay = -1;
                }
                if (betterWay) {
                    bestCriterion = CoinMin(changeUp[i], changeDown[i]);
                    whichObject = i;
                    bestWay = betterWay;
                }
            }
            break;
        case 2:
            for ( i = 0 ; i < numberObjects ; i++) {
                double change = CoinMin(changeUp[i], changeDown[i]);
                double sum = changeUp[i] + changeDown[i];
                bool take = false;
                if (change > 1.1*bestCriterion)
                    take = true;
                else if (change > 0.9*bestCriterion && sum + change > bestCriterion + alternativeCriterion)
                    take = true;
                if (take) {
                    if (changeUp[i] <= changeDown[i]) {
                        if (changeUp[i] > bestCriterion)
                            bestWay = 1;
                    } else {
                        if (changeDown[i] > bestCriterion)
                            bestWay = -1;
                    }
                    bestCriterion = change;
                    alternativeCriterion = sum;
                    whichObject = i;
                }
            }
            break;
        case 3:
            for ( i = 0 ; i < numberObjects ; i++) {
                int numberNext = numberInfeasibilitiesUp[i];

                if (numberNext < numberUnsatisfied) {
                    int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
                    double perUnsatisfied = changeUp[i] / static_cast<double> (numberUp);
                    double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
                    if (estimatedObjective < bestEstimate) {
                        bestEstimate = estimatedObjective;
                        bestWay = 1;
                        whichObject = i;
                    }
                }
                numberNext = numberInfeasibilitiesDown[i];
                if (numberNext < numberUnsatisfied) {
                    int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
                    double perUnsatisfied = changeDown[i] / static_cast<double> (numberDown);
                    double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
                    if (estimatedObjective < bestEstimate) {
                        bestEstimate = estimatedObjective;
                        bestWay = -1;
                        whichObject = i;
                    }
                }
            }
            break;
        case 4:
            // if number infeas same then cheapest up
            // first get best number or when going down
            // now choose smallest change up amongst equal number infeas
            for ( i = 0 ; i < numberObjects ; i++) {
                int thisNumber = CoinMin(numberInfeasibilitiesUp[i], numberInfeasibilitiesDown[i]);
                if (thisNumber <= bestNumber) {
                    int betterWay = 0;
                    if (numberInfeasibilitiesUp[i] < numberInfeasibilitiesDown[i]) {
                        if (numberInfeasibilitiesUp[i] < bestNumber) {
                            betterWay = 1;
                        } else {
                            if (changeUp[i] < bestCriterion)
                                betterWay = 1;
                        }
                    } else if (numberInfeasibilitiesUp[i] > numberInfeasibilitiesDown[i]) {
                        if (numberInfeasibilitiesDown[i] < bestNumber) {
                            betterWay = -1;
                        } else {
                            if (changeDown[i] < bestCriterion)
                                betterWay = -1;
                        }
                    } else {
                        // up and down have same number
                        bool better = false;
                        if (numberInfeasibilitiesUp[i] < bestNumber) {
                            better = true;
                        } else if (numberInfeasibilitiesUp[i] == bestNumber) {
                            if (CoinMin(changeUp[i], changeDown[i]) < bestCriterion)
                                better = true;;
                        }
                        if (better) {
                            // see which way
                            if (changeUp[i] <= changeDown[i])
                                betterWay = 1;
                            else
                                betterWay = -1;
                        }
                    }
                    if (betterWay) {
                        bestCriterion = CoinMin(changeUp[i], changeDown[i]);
                        bestNumber = thisNumber;
                        whichObject = i;
                        bestWay = betterWay;
                    }
                }
            }
            bestCriterion = 1.0e50;
            for ( i = 0 ; i < numberObjects ; i++) {
                int thisNumber = numberInfeasibilitiesUp[i];
                if (thisNumber == bestNumber && changeUp) {
                    if (changeUp[i] < bestCriterion) {
                        bestCriterion = changeUp[i];
                        whichObject = i;
                        bestWay = 1;
                    }
                }
            }
            break;
        }
        // set way in best
        if (whichObject >= 0) {
            CbcBranchingObject * bestObject = objects[whichObject];
            if (bestObject->object() && bestObject->object()->preferredWay())
                bestWay = bestObject->object()->preferredWay();
            bestObject->way(bestWay);
        } else {
	  COIN_DETAIL_PRINT(printf("debug\n"));
        }
    }
    return whichObject;
}