diff --git a/src/MibSBilevel.cpp b/src/MibSBilevel.cpp index bcd08cb7..a83d1103 100644 --- a/src/MibSBilevel.cpp +++ b/src/MibSBilevel.cpp @@ -57,15 +57,19 @@ MibSBilevel::createBilevel(CoinPackedVector* sol, (model_->MibSPar_->entry(MibSParams::branchStrategy)); bool solveSecondLevelEveryIteration(model_->MibSPar_->entry - (MibSParams::solveSecondLevelEveryIteration) == PARAM_ON); + (MibSParams::solveSecondLevelEveryIteration) == PARAM_ON); + bool solveSecondLevelEveryIterationRoot(model_->MibSPar_->entry + (MibSParams::solveSecondLevelEveryIterationRoot) == PARAM_ON); bool solveSecondLevelWhenXYVarsInt(model_->MibSPar_->entry - (MibSParams::solveSecondLevelWhenXYVarsInt) == PARAM_ON); + (MibSParams::solveSecondLevelWhenXYVarsInt) == PARAM_ON); bool solveSecondLevelWhenXVarsInt(model_->MibSPar_->entry - (MibSParams::solveSecondLevelWhenXVarsInt) == PARAM_ON); + (MibSParams::solveSecondLevelWhenXVarsInt) == PARAM_ON); + bool solveSecondLevelWhenYVarsInt(model_->MibSPar_->entry + (MibSParams::solveSecondLevelWhenYVarsInt) == PARAM_ON); bool solveSecondLevelWhenLVarsInt(model_->MibSPar_->entry - (MibSParams::solveSecondLevelWhenLVarsInt) == PARAM_ON); + (MibSParams::solveSecondLevelWhenLVarsInt) == PARAM_ON); bool solveSecondLevelWhenLVarsFixed(model_->MibSPar_->entry - (MibSParams::solveSecondLevelWhenLVarsFixed) == PARAM_ON); + (MibSParams::solveSecondLevelWhenLVarsFixed) == PARAM_ON); int cutStrategy(model_->MibSPar_->entry (MibSParams::cutStrategy)); @@ -239,11 +243,14 @@ MibSBilevel::createBilevel(CoinPackedVector* sol, isLinkVarsFixed_) || (branchPar == MibSBranchingStrategyFractional && isIntegral_) || (solveSecondLevelEveryIteration) || + (solveSecondLevelEveryIterationRoot && + model_->activeNode_->getDepth() == 0) || (solveSecondLevelWhenXYVarsInt && isIntegral_) || (solveSecondLevelWhenXVarsInt && isUpperIntegral_) || + (solveSecondLevelWhenYVarsInt && isLowerIntegral_) || (solveSecondLevelWhenLVarsInt && isLinkVarsIntegral_) || (solveSecondLevelWhenLVarsFixed && isLinkVarsFixed_ )))){ - storeSol = checkBilevelFeasibility(mibs->isRoot_); + storeSol = checkBilevelFeasibility(mibs->isRoot_); } } @@ -420,6 +427,7 @@ MibSBilevel::checkBilevelFeasibility(bool isRoot) }else{ startTimeVF = model_->broker_->subTreeTimer().getTime(); lSolver->branchAndBound(); + //lSolver->writeLp("water"); model_->timerVF_ += model_->broker_->subTreeTimer().getTime() - startTimeVF; } diff --git a/src/MibSConstants.hpp b/src/MibSConstants.hpp index 05dd7104..6436a87c 100644 --- a/src/MibSConstants.hpp +++ b/src/MibSConstants.hpp @@ -98,6 +98,30 @@ enum MibSBilevelFreeSetTypeISIC{ //############################################################################# +enum MibSIDICGenStrategy{ + MibSIDICGenStrategyNotSet = -1, + MibSIDICGenStrategyAlways, + MibSIDICGenStrategyAlwaysRoot, + MibSIDICGenStrategyXYInt, + MibSIDICGenStrategyLInt, + MibSIDICGenStrategyYInt, + MibSIDICGenStrategyYLInt +}; + +//############################################################################# + +enum MibSISICGenStrategy{ + MibSISICGenStrategyNotSet = -1, + MibSISICGenStrategyAlways, + MibSISICGenStrategyAlwaysRoot, + MibSISICGenStrategyXYInt, + MibSISICGenStrategyLInt, + MibSISICGenStrategyYInt, + MibSISICGenStrategyYLInt, +}; + +//############################################################################# + enum MibSRelaxTypeParamBoundCut{ MibSRelaxTypeParamBoundCutLP = 0, MibSRelaxTypeParamBoundCutMIP diff --git a/src/MibSCutGenerator.cpp b/src/MibSCutGenerator.cpp index ea80ddb8..5fd3968d 100644 --- a/src/MibSCutGenerator.cpp +++ b/src/MibSCutGenerator.cpp @@ -302,14 +302,13 @@ MibSCutGenerator::feasibilityCuts(BcpsConstraintPool &conPool) = localModel_->MibSPar_->entry(MibSParams::useValFuncCut); if(useIntegerNoGoodCut && !useValFuncCut){ - return bilevelFeasCut1(conPool) ? true : false; + return bilevelFeasCut1(conPool); } else if(!useIntegerNoGoodCut && useValFuncCut){ - return bilevelFeasCut2(conPool) ? true : false; + return bilevelFeasCut2(conPool); } else if(useIntegerNoGoodCut && useValFuncCut){ - return ((bilevelFeasCut1(conPool) ? true : false) || - (bilevelFeasCut2(conPool) ? true : false)); + return (bilevelFeasCut1(conPool) + bilevelFeasCut2(conPool)); } else{ //std::cout << "No MIBS Cuts generated" << std::endl; @@ -828,7 +827,7 @@ MibSCutGenerator::findLowerLevelSolImprovingSolutionIC(double *uselessIneqs, double infinity(oSolver->getInfinity()); int i, j; int index(0), cntInt(0); - double lObjVal(0.0), value(0.0); + double lObjVal(0.0); int uCols(localModel_->getUpperDim()); int lCols(localModel_->getLowerDim()); int lRows(localModel_->getLowerRowNum()); @@ -5870,22 +5869,26 @@ MibSCutGenerator::generateConstraints(BcpsConstraintPool &conPool) int useBendersBinaryCut = localModel_->MibSPar_->entry(MibSParams::useBendersBinaryCut); - int useFractionalCuts = - localModel_->MibSPar_->entry(MibSParams::useFractionalCuts); + int IDICGenStrategy = + localModel_->MibSPar_->entry(MibSParams::IDICGenStrategy); - int useFractionalCutsRootOnly = - localModel_->MibSPar_->entry(MibSParams::useFractionalCutsRootOnly); + int ISICGenStrategy = + localModel_->MibSPar_->entry(MibSParams::ISICGenStrategy); double relaxedObjVal = localModel_->bS_->getLowerObj( localModel_->solver()->getColSolution(), localModel_->getLowerObjSense()); bool haveSecondLevelSol = ((useLinkingSolutionPool == PARAM_ON && + bS->isLinkVarsIntegral_ && bS->tagInSeenLinkingPool_ != MibSLinkingPoolTagIsNotSet && bS->tagInSeenLinkingPool_ != MibSLinkingPoolTagLowerIsInfeasible) || - (useLinkingSolutionPool != PARAM_ON && + ((useLinkingSolutionPool != PARAM_ON || + !bS->isLinkVarsIntegral_) && bS->isLowerSolved_ != false && bS->isProvenOptimal_ != false)); + + int returnVal(0); if ((useBoundCut) && (localModel_->boundingPass_ <= 1)){ @@ -5951,27 +5954,43 @@ MibSCutGenerator::generateConstraints(BcpsConstraintPool &conPool) int bendersInterdictionCutType = localModel_->MibSPar_->entry(MibSParams::bendersInterdictionCutType); if(bendersInterdictionCutType == MibSBendersInterdictionCutTypeJustOneCut){ - numCuts += bendersInterdictionOneCut(conPool, + returnVal = bendersInterdictionOneCut(conPool, bS->optLowerSolutionOrd_); } else{ - numCuts += bendersInterdictionMultipleCuts(conPool); - } + returnVal = bendersInterdictionMultipleCuts(conPool); + } + numCuts += returnVal; + localModel_->counterBendersInterdict_ += returnVal; } if (useImprovingSolutionIC == PARAM_ON){ cutType = MibSIntersectionCutImprovingSolution; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterXYIntISIC_++; + }else{ + localModel_->counterXYIntISICFail_++; + } + numCuts += returnVal; } if (useImprovingDirectionIC == PARAM_ON){ cutType = MibSIntersectionCutImprovingDirection; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterXYIntIDIC_++; + }else{ + localModel_->counterXYIntIDICFail_++; + } + numCuts += returnVal; } if (useHypercubeIC == PARAM_ON){ cutType = MibSIntersectionCutHypercube; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + localModel_->counterHypercubeIC_ += returnVal; + numCuts += returnVal; } if (useTenderIC == PARAM_ON){ @@ -5985,15 +6004,21 @@ MibSCutGenerator::generateConstraints(BcpsConstraintPool &conPool) } if (useGeneralizedNoGoodCut == PARAM_ON){ - numCuts += generalizedNoGoodCut(conPool); + returnVal = generalizedNoGoodCut(conPool); + localModel_->counterGeneralizedNoGood_ += returnVal; + numCuts += returnVal; } if (useBendersBinaryCut == PARAM_ON && relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_){ - numCuts += bendersBinaryCut(conPool); + returnVal = bendersBinaryCut(conPool); + localModel_->counterBendersBinary_ += returnVal; + numCuts += returnVal; } - numCuts += feasibilityCuts(conPool) ? true : false; + returnVal = feasibilityCuts(conPool); + localModel_->counterBendersInterdict_ += returnVal; + numCuts += returnVal; //This return value indicates whether the relaxation needs to be re-solved //and should always be false (see BlisTreeNode.cpp) @@ -6005,38 +6030,66 @@ MibSCutGenerator::generateConstraints(BcpsConstraintPool &conPool) int bendersInterdictionCutType = localModel_->MibSPar_->entry(MibSParams::bendersInterdictionCutType); if(bendersInterdictionCutType == MibSBendersInterdictionCutTypeJustOneCut){ - numCuts += bendersInterdictionOneCut(conPool, - bS->optLowerSolutionOrd_); + returnVal = bendersInterdictionOneCut(conPool, + bS->optLowerSolutionOrd_); + }else{ + returnVal = bendersInterdictionMultipleCuts(conPool); } - else{ - numCuts += bendersInterdictionMultipleCuts(conPool); - } + localModel_->counterBendersInterdict_ += returnVal; + numCuts += returnVal; } - if (useImprovingSolutionIC == PARAM_ON && ((haveSecondLevelSol && - relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_) || - localModel_->MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == 1)){ - cutType = MibSIntersectionCutImprovingSolution; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); - } - - if (useFractionalCuts && useImprovingDirectionIC == PARAM_ON){ + if (useImprovingDirectionIC == PARAM_ON && + (IDICGenStrategy == MibSIDICGenStrategyLInt || + IDICGenStrategy == MibSIDICGenStrategyYLInt || + IDICGenStrategy == MibSIDICGenStrategyAlways || + (IDICGenStrategy == MibSIDICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))){ cutType = MibSIntersectionCutImprovingDirection; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterLIntIDIC_++; + }else{ + localModel_->counterLIntIDICFail_++; + } + numCuts += returnVal; + } + if (useImprovingSolutionIC == PARAM_ON && + ((haveSecondLevelSol && + relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_) || + (localModel_->MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == + MibSBilevelFreeSetTypeISICWithNewLLSol)) && + (ISICGenStrategy == MibSISICGenStrategyLInt || + ISICGenStrategy == MibSISICGenStrategyYLInt || + ISICGenStrategy == MibSISICGenStrategyAlways || + (ISICGenStrategy == MibSISICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))){ + cutType = MibSIntersectionCutImprovingSolution; + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterLIntISIC_++; + }else{ + localModel_->counterLIntISICFail_++; + } + numCuts += returnVal; } - if (useHypercubeIC == PARAM_ON && haveSecondLevelSol){ cutType = MibSIntersectionCutHypercube; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + localModel_->counterHypercubeIC_ += returnVal; + numCuts += returnVal; } - if (localModel_->allUpperBin_){ //problem with binary UL variables and integer LL variables if (useGeneralizedNoGoodCut == PARAM_ON){ - numCuts += generalizedNoGoodCut(conPool); + returnVal = generalizedNoGoodCut(conPool); + localModel_->counterGeneralizedNoGood_ += returnVal; + numCuts += returnVal; } if (useBendersBinaryCut == PARAM_ON && relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_){ - numCuts += bendersBinaryCut(conPool); + returnVal = bendersBinaryCut(conPool); + localModel_->counterBendersBinary_ += returnVal; + numCuts += returnVal; } } @@ -6044,19 +6097,71 @@ MibSCutGenerator::generateConstraints(BcpsConstraintPool &conPool) //and should always be false (see BlisTreeNode.cpp) return (false); - }else if (bS->isLowerIntegral_ && - (useFractionalCuts || - (useFractionalCutsRootOnly && - localModel_->activeNode_->getDepth() == 0))){ - if (useImprovingDirectionIC == PARAM_ON){ + }else if (bS->isLowerIntegral_){ + if (useImprovingDirectionIC == PARAM_ON && + (IDICGenStrategy == MibSIDICGenStrategyYInt || + IDICGenStrategy == MibSIDICGenStrategyYLInt || + IDICGenStrategy == MibSIDICGenStrategyAlways || + (IDICGenStrategy == MibSIDICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))){ cutType = MibSIntersectionCutImprovingDirection; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterYIntIDIC_++; + }else{ + localModel_->counterYIntIDICFail_++; + } + numCuts += returnVal; } - if (useImprovingSolutionIC == PARAM_ON && ((haveSecondLevelSol && + if (useImprovingSolutionIC == PARAM_ON && + ((haveSecondLevelSol && relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_) || - localModel_->MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == 1)){ + (localModel_->MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == + MibSBilevelFreeSetTypeISICWithNewLLSol && + (ISICGenStrategy == MibSISICGenStrategyYInt || + ISICGenStrategy == MibSISICGenStrategyYLInt || + ISICGenStrategy == MibSISICGenStrategyAlways || + (ISICGenStrategy == MibSISICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))))){ cutType = MibSIntersectionCutImprovingSolution; - numCuts += intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterYIntISIC_++; + }else{ + localModel_->counterYIntISICFail_++; + } + numCuts += returnVal; + } + }else{ + if (useImprovingDirectionIC == PARAM_ON && + (IDICGenStrategy == MibSIDICGenStrategyAlways || + (IDICGenStrategy == MibSIDICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))){ + cutType = MibSIntersectionCutImprovingDirection; + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterFracIDIC_++; + }else{ + localModel_->counterFracIDICFail_++; + } + numCuts += returnVal; + } + if (useImprovingSolutionIC == PARAM_ON && + ((haveSecondLevelSol && + relaxedObjVal > localModel_->bS_->objVal_ + localModel_->etol_) || + (localModel_->MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == + MibSBilevelFreeSetTypeISICWithNewLLSol && + (ISICGenStrategy == MibSIDICGenStrategyAlways || + (ISICGenStrategy == MibSIDICGenStrategyAlwaysRoot && + localModel_->activeNode_->getDepth() == 0))))){ + cutType = MibSIntersectionCutImprovingSolution; + returnVal = intersectionCuts(conPool, bS->optLowerSolutionOrd_, cutType); + if (returnVal){ + localModel_->counterFracISIC_++; + }else{ + localModel_->counterFracISICFail_++; + } + numCuts += returnVal; } } diff --git a/src/MibSModel.cpp b/src/MibSModel.cpp index cda009e5..22c464b9 100644 --- a/src/MibSModel.cpp +++ b/src/MibSModel.cpp @@ -143,6 +143,27 @@ MibSModel::initialize() objAlignment_ = 0; counterVF_ = 0; counterUB_ = 0; + counterXYIntIDIC_ = 0; + counterLIntIDIC_ = 0; + counterYIntIDIC_ = 0; + counterFracIDIC_ = 0; + counterXYIntIDICFail_ = 0; + counterLIntIDICFail_ = 0; + counterYIntIDICFail_ = 0; + counterFracIDICFail_ = 0; + counterXYIntISIC_ = 0; + counterLIntISIC_ = 0; + counterYIntISIC_ = 0; + counterFracISIC_ = 0; + counterXYIntISICFail_ = 0; + counterLIntISICFail_ = 0; + counterYIntISICFail_ = 0; + counterFracISICFail_ = 0; + counterBendersInterdict_ = 0; + counterHypercubeIC_ = 0; + counterGeneralizedNoGood_ = 0; + counterBendersBinary_ = 0; + counterIntegerNoGood_ = 0; timerVF_ = 0.0; timerUB_ = 0.0; countIteration_ = 0; @@ -3933,7 +3954,12 @@ MibSModel::adjustParameters() } } if (MibSPar_->entry(MibSParams::useImprovingDirectionIC) == PARAM_ON){ - defaultCutIsOn = true; + defaultCutIsOn = true; + if (MibSPar_->entry(MibSParams::IDICGenStrategy) == + MibSIDICGenStrategyNotSet){ + MibSPar()->setEntry(MibSParams::IDICGenStrategy, + MibSIDICGenStrategyAlways); + } } //Param: "MibS_useImprovingSolutionIC" @@ -3945,7 +3971,10 @@ MibSModel::adjustParameters() paramValue = MibSPar_->entry(MibSParams::useImprovingSolutionIC); if (paramValue == PARAM_NOTSET){ - if (lowerRowSignsConsistent_ == false || upperRowSignsConsistent_ == false){ + if (lowerRowSignsConsistent_ == false || upperRowSignsConsistent_ == false || + isPureInteger_ == false || isLowerCoeffInt_ == false || + (MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == + MibSBilevelFreeSetTypeISICWithNewLLSol && isLowerObjInt_ == false)){ MibSPar()->setEntry(MibSParams::useImprovingSolutionIC, PARAM_OFF); }else{ MibSPar()->setEntry(MibSParams::useImprovingSolutionIC, PARAM_ON); @@ -3958,8 +3987,8 @@ MibSModel::adjustParameters() std::cout << std::endl; MibSPar()->setEntry(MibSParams::useImprovingSolutionIC, PARAM_OFF); } - if (MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == 1 && - isLowerObjInt_ == false){ + if (MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == + MibSBilevelFreeSetTypeISICWithNewLLSol && isLowerObjInt_ == false){ std::cout << "The improving solution intersection cut (type II) are " << "only valid for problems with integer lower-level " << "objective coefficients."; @@ -3967,6 +3996,31 @@ MibSModel::adjustParameters() MibSPar()->setEntry(MibSParams::useImprovingSolutionIC, PARAM_OFF); } } + if (MibSPar_->entry(MibSParams::useImprovingSolutionIC) == PARAM_ON){ + switch (MibSPar_->entry(MibSParams::ISICGenStrategy)) { + case MibSISICGenStrategyNotSet: + MibSPar()->setEntry(MibSParams::ISICGenStrategy, MibSISICGenStrategyLInt); + case MibSISICGenStrategyLInt: + MibSPar()->setEntry(MibSParams::solveSecondLevelWhenLVarsInt, 1); + break; + case MibSISICGenStrategyXYInt: + MibSPar()->setEntry(MibSParams::solveSecondLevelWhenXYVarsInt, 1); + break; + case MibSISICGenStrategyYInt: + MibSPar()->setEntry(MibSParams::solveSecondLevelWhenYVarsInt, 1); + break; + case MibSISICGenStrategyYLInt: + MibSPar()->setEntry(MibSParams::solveSecondLevelWhenYVarsInt, 1); + MibSPar()->setEntry(MibSParams::solveSecondLevelWhenLVarsInt, 1); + break; + case MibSISICGenStrategyAlways: + MibSPar()->setEntry(MibSParams::solveSecondLevelEveryIteration, 1); + break; + case MibSISICGenStrategyAlwaysRoot: + MibSPar()->setEntry(MibSParams::solveSecondLevelEveryIterationRoot, 1); + break; + } + } //Param: "MibS_useHyperCubeIC" if ((turnOffDefaultCuts == true) && @@ -4155,36 +4209,76 @@ MibSModel::printProblemInfo(){ if (MibSPar_->entry(MibSParams::useImprovingSolutionIC) == PARAM_ON){ if (MibSPar_->entry(MibSParams::bilevelFreeSetTypeISIC) == MibSBilevelFreeSetTypeISICWithLLOptSol){ - std::cout << "Improving solution intersection cut generator (Type I) is on." << std::endl; + std::cout << "Improving solution intersection cut generator " + << "(Type I) is on." << std::endl; }else{ - std::cout << "Improving solution intersection cut generator (Type II) is on." << std::endl; + std::cout << "Improving solution intersection cut generator " + << "(Type II) is on." << std::endl; } + switch (MibSPar_->entry(MibSParams::ISICGenStrategy)){ + case MibSISICGenStrategyLInt: + std::cout << "ISICs will be used to separate solutions " + << "with integer linking variables." << std::endl; + break; + case MibSISICGenStrategyYInt: + std::cout << "ISICs will be used to separate solutions " + << "with integer lower-level variables." << std::endl; + break; + case MibSISICGenStrategyYLInt: + std::cout << "ISICs will be used to separate solutions " + << "with integer linking or lower-level variables." << std::endl; + break; + case MibSISICGenStrategyXYInt: + std::cout << "ISICs will be used to separate only solutions " + << "that are fully integer." << std::endl; + break; + case MibSISICGenStrategyAlwaysRoot: + std::cout << "ISICs will be used to separate fractional solutions " + << "only in the root node." << std::endl; + break; + case MibSISICGenStrategyAlways: + std::cout << "ISICs will be used to separate all solutions." + << std::endl; + break; + } } if (MibSPar_->entry(MibSParams::useImprovingDirectionIC) == PARAM_ON){ - std::cout << "Improving direction intersection cut generator is on." << std::endl; + std::cout << "Improving direction intersection cut generator is on." + << std::endl; + switch (MibSPar_->entry(MibSParams::IDICGenStrategy)){ + case MibSIDICGenStrategyLInt: + std::cout << "IDICs will be used to separate solutions " + << "with integer linking variables." << std::endl; + break; + case MibSIDICGenStrategyYInt: + std::cout << "IDICs will be used to separate solutions " + << "with integer lower-level variables." << std::endl; + break; + case MibSIDICGenStrategyYLInt: + std::cout << "IDICs will be used to separate solutions " + << "with integer linking or lower-level variables." << std::endl; + break; + case MibSIDICGenStrategyXYInt: + std::cout << "IDICs will be used to separate only solutions " + << "that are fully integer." << std::endl; + break; + case MibSIDICGenStrategyAlwaysRoot: + std::cout << "IDICs will be used to separate fractional solutions " + << "only in the root node." << std::endl; + break; + case MibSIDICGenStrategyAlways: + std::cout << "IDICs will be used to separate all solutions." + << std::endl; + break; + } } if (MibSPar_->entry(MibSParams::useHypercubeIC) == PARAM_ON){ - std::cout << "Hypercube intersection cut generator is on." << std::endl; + std::cout << "Hypercube intersection cut generator is on." + << std::endl; } - if (MibSPar_->entry(MibSParams::useImprovingSolutionIC) == PARAM_ON || - MibSPar_->entry(MibSParams::useImprovingDirectionIC) == PARAM_ON){ - - if (MibSPar_->entry(MibSParams::useFractionalCutsRootOnly) == 1){ - std::cout << "Fractional solutions will be seperated in the root node." << std::endl; - MibSPar_->setEntry(MibSParams::useFractionalCuts, 0); - } - if (MibSPar_->entry(MibSParams::useFractionalCuts) == 1){ - std::cout << "Fractional solutions will be separated using intersection cuts." - << std::endl; - }else{ - std::cout << "Only integer solutions will be separated using intersection cuts." - << std::endl; - } - } - if (MibSPar_->entry(MibSParams::solveSecondLevelEveryIteration) == PARAM_OFF && MibSPar_->entry(MibSParams::solveSecondLevelWhenXYVarsInt) == diff --git a/src/MibSModel.hpp b/src/MibSModel.hpp index 6e764a4b..51067e0f 100644 --- a/src/MibSModel.hpp +++ b/src/MibSModel.hpp @@ -114,6 +114,69 @@ class MibSModel : public BlisModel { /** Number of (UB) solved **/ int counterUB_; + /** Number of IDICs generated when solution is fully integer **/ + int counterXYIntIDIC_; + + /** Number of IDICs generated when linking variables are integer **/ + int counterLIntIDIC_; + + /** Number of IDICs generated when lower-level is integer **/ + int counterYIntIDIC_; + + /** Number of IDICs generated when solutions is fractional **/ + int counterFracIDIC_; + + /** Number of IDIC fails when solution is fully integer **/ + int counterXYIntIDICFail_; + + /** Number of IDIC fails when linking variables are integer **/ + int counterLIntIDICFail_; + + /** Number of IDIC fails when lower-level is integer **/ + int counterYIntIDICFail_; + + /** Number of IDIC fails when solutions is fractional **/ + int counterFracIDICFail_; + + /** Number of ISICs generated when solution is fully integer **/ + int counterXYIntISIC_; + + /** Number of ISICs generated when linking variables are integer **/ + int counterLIntISIC_; + + /** Number of ISICs generated when lower-level is integer **/ + int counterYIntISIC_; + + /** Number of ISICs generated when solutions is fractional **/ + int counterFracISIC_; + + /** Number of ISIC fails when solution is fully integer **/ + int counterXYIntISICFail_; + + /** Number of ISIC fails when linking variables are integer **/ + int counterLIntISICFail_; + + /** Number of ISIC fails when lower-level is integer **/ + int counterYIntISICFail_; + + /** Number of ISIC fails when solutions is fractional**/ + int counterFracISICFail_; + + /** Number of Benders Interdiction cuts generated **/ + int counterBendersInterdict_; + + /** Number of Hypercube Intersection cuts generated **/ + int counterHypercubeIC_; + + /** Number of Generalized No Good cuts generated **/ + int counterGeneralizedNoGood_; + + /** Number of Benders Binary cuts generated **/ + int counterBendersBinary_; + + /** Number of Integer No Good cuts generated **/ + int counterIntegerNoGood_; + /** Time for solving (VF) **/ double timerVF_; diff --git a/src/MibSParams.cpp b/src/MibSParams.cpp index a7710ff7..4c5359ae 100644 --- a/src/MibSParams.cpp +++ b/src/MibSParams.cpp @@ -177,12 +177,21 @@ MibSParams::createKeywordList() { keys_.push_back(make_pair(std::string("MibS_useTypeIC"), AlpsParameter(AlpsIntPar, useImprovingSolutionIC))); + keys_.push_back(make_pair(std::string("MibS_ISICGenStrategy"), + AlpsParameter(AlpsIntPar, ISICGenStrategy))); + keys_.push_back(make_pair(std::string("MibS_useImprovingDirectionIC"), AlpsParameter(AlpsIntPar, useImprovingDirectionIC))); //legacy parameter name keys_.push_back(make_pair(std::string("MibS_useTypeWatermelon"), AlpsParameter(AlpsIntPar, useImprovingDirectionIC))); + keys_.push_back(make_pair(std::string("MibS_IDICGenStrategy"), + AlpsParameter(AlpsIntPar, IDICGenStrategy))); + + keys_.push_back(make_pair(std::string("MibS_useTypeWatermelon"), + AlpsParameter(AlpsIntPar, useImprovingDirectionIC))); + keys_.push_back(make_pair(std::string("MibS_useHypercubeIC"), AlpsParameter(AlpsIntPar, useHypercubeIC))); @@ -195,23 +204,23 @@ MibSParams::createKeywordList() { keys_.push_back(make_pair(std::string("MibS_bilevelFreeSetTypeISIC"), AlpsParameter(AlpsIntPar, bilevelFreeSetTypeISIC))); - keys_.push_back(make_pair(std::string("MibS_useFractionalCuts"), - AlpsParameter(AlpsIntPar, useFractionalCuts))); - - keys_.push_back(make_pair(std::string("MibS_useFractionalCutsRootOnly"), - AlpsParameter(AlpsIntPar, - useFractionalCutsRootOnly))); - //solve lower-level Parameters keys_.push_back(make_pair(std::string("MibS_solveSecondLevelEveryIteration"), AlpsParameter(AlpsIntPar, solveSecondLevelEveryIteration))); + keys_.push_back(make_pair(std::string("MibS_solveSecondLevelEveryIterationRoot"), + AlpsParameter(AlpsIntPar, + solveSecondLevelEveryIterationRoot))); + keys_.push_back(make_pair(std::string("MibS_solveSecondLevelWhenXYVarsInt"), AlpsParameter(AlpsIntPar, solveSecondLevelWhenXYVarsInt))); keys_.push_back(make_pair(std::string("MibS_solveSecondLevelWhenXVarsInt"), AlpsParameter(AlpsIntPar, solveSecondLevelWhenXVarsInt))); + keys_.push_back(make_pair(std::string("MibS_solveSecondLevelWhenYVarsInt"), + AlpsParameter(AlpsIntPar, solveSecondLevelWhenYVarsInt))); + keys_.push_back(make_pair(std::string("MibS_solveSecondLevelWhenLVarsInt"), AlpsParameter(AlpsIntPar, solveSecondLevelWhenLVarsInt))); @@ -376,26 +385,30 @@ MibSParams::setDefaultEntries() { setEntry(useImprovingSolutionIC, PARAM_NOTSET); + setEntry(ISICGenStrategy, MibSISICGenStrategyNotSet); + setEntry(useImprovingDirectionIC, PARAM_NOTSET); + setEntry(IDICGenStrategy, MibSIDICGenStrategyNotSet); + setEntry(useHypercubeIC, PARAM_NOTSET); setEntry(useTenderIC, PARAM_NOTSET); setEntry(useHybridIC, PARAM_NOTSET); - setEntry(useFractionalCuts, 1); - - setEntry(useFractionalCutsRootOnly, 0); - setEntry(bilevelFreeSetTypeISIC, MibSBilevelFreeSetTypeISICWithLLOptSol); setEntry(solveSecondLevelEveryIteration, PARAM_OFF); + setEntry(solveSecondLevelEveryIterationRoot, PARAM_OFF); + setEntry(solveSecondLevelWhenXYVarsInt, PARAM_ON); setEntry(solveSecondLevelWhenXVarsInt, PARAM_OFF); + setEntry(solveSecondLevelWhenYVarsInt, PARAM_OFF); + setEntry(solveSecondLevelWhenLVarsInt, PARAM_OFF); setEntry(solveSecondLevelWhenLVarsFixed, PARAM_ON); diff --git a/src/MibSParams.hpp b/src/MibSParams.hpp index 9d168670..cf5a7d3c 100644 --- a/src/MibSParams.hpp +++ b/src/MibSParams.hpp @@ -71,16 +71,18 @@ class MibSParams : public AlpsParameterSet { useBendersInterdictionCut, bendersInterdictionCutType, useImprovingSolutionIC, + ISICGenStrategy, + bilevelFreeSetTypeISIC, useImprovingDirectionIC, + IDICGenStrategy, useHypercubeIC, useTenderIC, useHybridIC, - useFractionalCuts, - useFractionalCutsRootOnly, - bilevelFreeSetTypeISIC, solveSecondLevelEveryIteration, + solveSecondLevelEveryIterationRoot, solveSecondLevelWhenXYVarsInt, solveSecondLevelWhenXVarsInt, + solveSecondLevelWhenYVarsInt, solveSecondLevelWhenLVarsInt, solveSecondLevelWhenLVarsFixed, computeBestUBWhenXVarsInt, diff --git a/src/MibSSolution.cpp b/src/MibSSolution.cpp index 5914462d..2ad7a540 100644 --- a/src/MibSSolution.cpp +++ b/src/MibSSolution.cpp @@ -166,11 +166,88 @@ MibSSolution::print(std::ostream& os) const } } - if(&os == &std::cout){ - std::cout << "Number of problems (VF) solved = " << localModel_->counterVF_ << std::endl; - std::cout << "Number of problems (UB) solved = " << localModel_->counterUB_ << std::endl; - std::cout << "Time for solving problem (VF) = " << localModel_->timerVF_ << std::endl; - std::cout << "Time for solving problem (UB) = " << localModel_->timerUB_ << std::endl; + int useBendersInterdictionCut = + localModel_->MibSPar_->entry(MibSParams::useBendersInterdictionCut); + int useImprovingSolutionIC = + localModel_->MibSPar_->entry(MibSParams::useImprovingSolutionIC); + int useImprovingDirectionIC = + localModel_->MibSPar_->entry(MibSParams::useImprovingDirectionIC); + int useHypercubeIC = + localModel_->MibSPar_->entry(MibSParams::useHypercubeIC); + int useGeneralizedNoGoodCut = + localModel_->MibSPar_->entry(MibSParams::useGeneralizedNoGoodCut); + int useBendersBinaryCut + = localModel_->MibSPar_->entry(MibSParams::useBendersBinaryCut); + int useIntegerNoGoodCut + = localModel_->MibSPar_->entry(MibSParams::useIntegerNoGoodCut); + + os << "Number of problems (VF) solved = " << localModel_->counterVF_ + << std::endl + << "Number of problems (UB) solved = " << localModel_->counterUB_ + << std::endl + << "Time for solving problem (VF) = " << localModel_->timerVF_ + << std::endl + << "Time for solving problem (UB) = " << localModel_->timerUB_ + << std::endl; + if (useBendersInterdictionCut){ + os << "Number of Benders Interdiction Cuts Generated: " + << localModel_->counterBendersInterdict_ << std::endl; + } + if (useHypercubeIC){ + os << "Number of Hypercube Intersection Cuts Generated: " + << localModel_->counterHypercubeIC_ << std::endl; + } + if (useGeneralizedNoGoodCut){ + os << "Number of Generalized No Good Cuts Generated: " + << localModel_->counterGeneralizedNoGood_ << std::endl; + } + if (useBendersBinaryCut){ + os << "Number of Benders Binary Cuts Generated: " + << localModel_->counterBendersBinary_ << std::endl; + } + if (useIntegerNoGoodCut){ + os << "Number of Integer No Good Cuts Generated: " + << localModel_->counterIntegerNoGood_ << std::endl; + } + if (useImprovingDirectionIC){ + os << "Number of IDICs Generated:" << std::endl + << " Full Int IDIC: " << localModel_->counterXYIntIDIC_ + << std::endl + << " Linking Int IDIC: " << localModel_->counterLIntIDIC_ + << std::endl + << " Second-level Int IDIC: " << localModel_->counterYIntIDIC_ + << std::endl + << " Fractional IDIC: " << localModel_->counterFracIDIC_ + << std::endl + << "Number of IDIC Generation Failures:" << std::endl + << " Full Int IDIC (Fail): " << localModel_->counterXYIntIDICFail_ + << std::endl + << " Linking Int IDIC (Fail): " << localModel_->counterLIntIDICFail_ + << std::endl + << " Second-level Int IDIC (Fail): " << localModel_->counterYIntIDICFail_ + << std::endl + << " Fractional IDIC (Fail): " << localModel_->counterFracIDICFail_ + << std::endl; + } + if (useImprovingSolutionIC){ + os << "Number of ISICs Generated:" << std::endl + << " Full Int ISIC: " << localModel_->counterXYIntISIC_ + << std::endl + << " Linking Int ISIC: " << localModel_->counterLIntISIC_ + << std::endl + << " Second-level Int ISIC: " << localModel_->counterYIntISIC_ + << std::endl + << " Fractional ISIC: " << localModel_->counterFracISIC_ + << std::endl + << "Number of ISIC Generation Failures:" << std::endl + << " Full Int ISIC (Fail): " << localModel_->counterXYIntISICFail_ + << std::endl + << " Linking Int ISIC (Fail): " << localModel_->counterLIntISICFail_ + << std::endl + << " Second-level Int ISIC (Fail): " << localModel_->counterYIntISICFail_ + << std::endl + << " Fractional ISIC (Fail): " << localModel_->counterFracISICFail_ + << std::endl; } }