void AMPLOsiUT::testOsiBnB() { EnvPtr env = (EnvPtr) new Environment(); char file_name[] = "instances/milp"; HandlerVector handlers; ReliabilityBrancherPtr br; EnginePtr e; int err = 0; env->startTimer(err); ProblemPtr p = iface_->readInstance(file_name); BranchAndBound *bab = new BranchAndBound(env, p); IntVarHandlerPtr v_hand = (IntVarHandlerPtr) new IntVarHandler(env, p); LinearHandlerPtr l_hand = (LinearHandlerPtr) new LinearHandler(env, p); handlers.push_back(v_hand); handlers.push_back(l_hand); v_hand->setModFlags(false, true); l_hand->setModFlags(false, true); EngineFactory efac(env); e = efac.getLPEngine(); PCBProcessorPtr nproc = (PCBProcessorPtr) new PCBProcessor(env, e, handlers); br= (ReliabilityBrancherPtr) new ReliabilityBrancher(env, handlers); br->setEngine(e); nproc->setBrancher(br); bab->setNodeProcessor(nproc); NodeIncRelaxerPtr nr = (NodeIncRelaxerPtr) new NodeIncRelaxer(env, handlers); bab->setNodeRelaxer(nr); nr->setEngine(e); nr->setModFlag(false); p->setNativeDer(); bab->shouldCreateRoot(true); bab->setLogLevel(LogNone); bab->solve(); CPPUNIT_ASSERT(bab->getUb() == 1.0); delete bab; }
int main(int argc, char* argv[]) { EnvPtr env = (EnvPtr) new Environment(); OptionDBPtr options; MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr(); ProblemPtr inst; SolutionPtr sol, sol2; double obj_sense =1.0; // jacobian is read from AMPL interface and passed on to branch-and-bound JacobianPtr jPtr; // hessian is read from AMPL interface and passed on to branch-and-bound MINOTAUR_AMPL::AMPLHessianPtr hPtr; // the branch-and-bound BranchAndBound *bab = 0; PresolverPtr pres; EngineFactory *efac; const std::string me("qg: "); BrancherPtr br = BrancherPtr(); // NULL PCBProcessorPtr nproc; NodeIncRelaxerPtr nr; //handlers HandlerVector handlers; IntVarHandlerPtr vHand; LinearHandlerPtr lHand; QGAdvHandlerPtr qgHand; RCHandlerPtr rcHand; //engines EnginePtr nlp_e; EnginePtr proj_nlp_e; EnginePtr l1proj_nlp_e; LPEnginePtr lin_e; // lp engine LoggerPtr logger_ = (LoggerPtr) new Logger(LogInfo); VarVector *orig_v=0; int err = 0; // start timing. env->startTimer(err); if (err) { goto CLEANUP; } setInitialOptions(env); iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env, "qg"); // parse options env->readOptions(argc, argv); options = env->getOptions(); options->findString("interface_type")->setValue("AMPL"); if (0!=showInfo(env)) { goto CLEANUP; } loadProblem(env, iface, inst, &obj_sense); // Initialize engines nlp_e = getNLPEngine(env, inst); //Engine for Original problem efac = new EngineFactory(env); lin_e = efac->getLPEngine(); // lp engine delete efac; // get presolver. orig_v = new VarVector(inst->varsBegin(), inst->varsEnd()); pres = presolve(env, inst, iface->getNumDefs(), handlers); handlers.clear(); if (Finished != pres->getStatus() && NotStarted != pres->getStatus()) { env->getLogger()->msgStream(LogInfo) << me << "status of presolve: " << getSolveStatusString(pres->getStatus()) << std::endl; writeSol(env, orig_v, pres, SolutionPtr(), pres->getStatus(), iface); writeBnbStatus(env, bab, obj_sense); goto CLEANUP; } if (options->findBool("solve")->getValue()==true) { if (true==options->findBool("use_native_cgraph")->getValue()) { inst->setNativeDer(); } // Initialize the handlers for branch-and-cut lHand = (LinearHandlerPtr) new LinearHandler(env, inst); lHand->setModFlags(false, true); handlers.push_back(lHand); assert(lHand); vHand = (IntVarHandlerPtr) new IntVarHandler(env, inst); vHand->setModFlags(false, true); handlers.push_back(vHand); assert(vHand); // Use of perspective handler is user choice if (env->getOptions()->findBool("perspective")->getValue() == true) { PerspCutHandlerPtr pcHand = (PerspCutHandlerPtr) new PerspCutHandler(env, inst); pcHand->findPRCons(); if (pcHand->getStatus()) { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e, pcHand); } else { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e); } } else { qgHand = (QGAdvHandlerPtr) new QGAdvHandler(env, inst, nlp_e); } qgHand->setModFlags(false, true); handlers.push_back(qgHand); assert(qgHand); if (options->findBool("rc_fix")->getValue()) { rcHand = (RCHandlerPtr) new RCHandler(env); rcHand->setModFlags(false, true); handlers.push_back(rcHand); assert(rcHand); } // report name env->getLogger()->msgStream(LogExtraInfo) << me << "handlers used:" << std::endl; for (HandlerIterator h = handlers.begin(); h != handlers.end(); ++h) { env->getLogger()->msgStream(LogExtraInfo) << me << (*h)->getName() << std::endl; } // Only store bound-changes of relaxation (not problem) nr = (NodeIncRelaxerPtr) new NodeIncRelaxer(env, handlers); nr->setModFlag(false); nr->setEngine(lin_e); nproc = (PCBProcessorPtr) new PCBProcessor(env, lin_e, handlers); if (env->getOptions()->findString("brancher")->getValue() == "rel") { ReliabilityBrancherPtr rel_br = (ReliabilityBrancherPtr) new ReliabilityBrancher(env, handlers); rel_br->setEngine(lin_e); nproc->setBrancher(rel_br); br = rel_br; } else if (env->getOptions()->findString("brancher")->getValue() == "maxvio") { MaxVioBrancherPtr mbr = (MaxVioBrancherPtr) new MaxVioBrancher(env, handlers); nproc->setBrancher(mbr); br = mbr; } else if (env->getOptions()->findString("brancher")->getValue() == "lex") { LexicoBrancherPtr lbr = (LexicoBrancherPtr) new LexicoBrancher(env, handlers); br = lbr; } nproc->setBrancher(br); env->getLogger()->msgStream(LogExtraInfo) << me << "brancher used = " << br->getName() << std::endl; bab = new BranchAndBound(env, inst); bab->setNodeRelaxer(nr); bab->setNodeProcessor(nproc); bab->shouldCreateRoot(true); // start solving bab->solve(); bab->writeStats(env->getLogger()->msgStream(LogExtraInfo)); //bab->writeStats(std::cout); nlp_e->writeStats(env->getLogger()->msgStream(LogExtraInfo)); lin_e->writeStats(env->getLogger()->msgStream(LogExtraInfo)); for (HandlerVector::iterator it=handlers.begin(); it!=handlers.end(); ++it) { //(*it)->writeStats(std::cout); (*it)->writeStats(env->getLogger()->msgStream(LogExtraInfo)); } writeSol(env, orig_v, pres, bab->getSolution(), bab->getStatus(), iface); writeBnbStatus(env, bab, obj_sense); } CLEANUP: if (iface) { delete iface; } if (orig_v) { delete orig_v; } if (bab) { delete bab; } return 0; }
int main() { // Generate output. ofstream output; output.open("numknapcov.txt"); // Generate input. ifstream input; input.open("list.txt"); // Check if input is opened succesfully. if (input.is_open() == false) { cerr << "Input file read error." << endl; output << "Input file read error." << endl; exit(0); } /********************************************************************************/ // Headers for output data. output << "Statistics of knapsack cover cuts applied to root relaxation." << endl; output << "problem " << "vars " << "cons " << "lincons " << "knapcons " << "knapcov " << "knaps " << "totalcuts " << "cuts " << "violknapcuts " << "initobj " << "endobj " << "gapclosed " << "timeinit " << "timecut " << "timemod" << endl; /********************************************************************************/ // loop to test all problems in list.txt while (input.good()) { // problem name string pname; getline(input, pname); // At the end of file just exit from loop. if (pname.empty()) { break; } cout << "Problem considered is: " << pname << endl; // Real stuff begins. // Ampl interface, jacobian and hessian. MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr(); JacobianPtr jPtr; //! Jacobian read from AMPL HessianOfLagPtr hPtr; //! Hessian read from AMPL // environment, timers and options: EnvPtr env = (EnvPtr) new Environment(); OptionDBPtr options; // problem to be solved. ProblemPtr minlp; // solver pointers, including status. FilterSQPEngine e(env); EngineStatus status; // Presolver. PresolverPtr pres; // give parameters. UInt argc2 = 2; std::string arg1 = "bnb"; std::string arg2 = pname; char** argv2 = new char* [2]; argv2[0] = &arg1[0]; argv2[1] = &arg2[0]; // Default options env->getOptions()->findBool("presolve")->setValue(false); env->getOptions()->findBool("use_native_cgraph")->setValue(true); env->getOptions()->findBool("nl_presolve")->setValue(false); // parse options env->readOptions(argc2, argv2); options = env->getOptions(); options->findString("interface_type")->setValue("AMPL"); // read minlp from AMPL. iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env); minlp = iface->readInstance(pname); // Timer is obtained. Timer * timer = env->getNewTimer(); // Nonlinearize objective function. Bool MIPCONSIDERED = false; if (MIPCONSIDERED == true) { ObjectivePtr initobjfun = minlp->getObjective(); if (initobjfun->getObjectiveType() == Maximize) { cerr << "Objective type is Maximize, change it to Minimize." << endl; exit(0); } LinearFunctionPtr lfinitobj = initobjfun->getLinearFunction(); // NonlinearFunctionPtr nlfobj = (NonlinearFunctionPtr) new NonlinearFunction(); CGraphPtr nlfobj = (CGraphPtr) new CGraph(); logobj(lfinitobj, nlfobj); FunctionPtr logobjfun = (FunctionPtr) new Function(nlfobj); ObjectiveType otyp = Minimize; minlp->changeObj(logobjfun, 0); } minlp->calculateSize(); minlp->prepareForSolve(); // Change format of problem to be suitable for Minotaur. HandlerVector handlers; // Use presolver to standardize problem. //pres = (PresolverPtr) new Presolver(minlp, env, handlers); //pres->standardize(); minlp->calculateSize(); minlp->prepareForSolve(); minlp->setJacobian(jPtr); minlp->setHessian(hPtr); minlp->setNativeDer(); minlp->calculateSize(); minlp->prepareForSolve(); minlp->setNativeDer(); //minlp->write(std::cout); /**************************************************************/ // Given problem statistics . // Number of variables. UInt numvars = minlp->getNumVars(); // number of constraints. UInt numcons = minlp->getNumCons(); // linear constraints. UInt numlin = minlp->getNumLinCons(); /*************************************************************/ // set option for engine to resolve to solve NLP repeatedly. // Probbaly does nothing. e.setOptionsForRepeatedSolve(); // load problem. e.load(minlp); // Solve problem. timer->start(); status = e.solve(); /********************************************************************/ // Solution time of relaxation. Double timeinit = timer->query(); timer->stop(); // Solution objective value Double initobj = e.getSolutionValue(); /********************************************************************/ std::cout << "Relaxation objective value = " << initobj << std::endl; // Get solution from engine. ConstSolutionPtr sol = e.getSolution(); // Construct relaxation. RelaxationPtr rel = (RelaxationPtr) new Relaxation(minlp); // Time for cut generation. timer->start(); // Generate kanpsack cover cuts. CoverCutGeneratorPtr knapgen = (CoverCutGeneratorPtr) new CoverCutGenerator(rel, sol, env); /*******************************************************************/ Double timecut = timer->query(); timer->stop(); /*******************************************************************/ // Get statistics of cut generator. ConstCovCutGenStatsPtr knapstats = knapgen->getStats(); /*******************************************************************/ // Knapsack cut generator statistics. // knapsack constraints. UInt numknap = (knapgen->getKnapsackList())->getNumKnaps(); // knapsacks that has cover sets. UInt numknapcov = knapgen->getNumCons(); // knapsack subproblems solved, i.e number of lifting subproblems solved. UInt knaps = knapstats->knaps; // cover cuts including duplicates. UInt totalcuts = knapstats->totalcuts; // cuts without duplicates. UInt numknapcuts = knapstats->cuts; // violated cuts. UInt violknapcuts = knapstats->violated; /*******************************************************************/ std::cout << "Number of knapsack cover cuts to be applied is: " << knapstats->violated << std::endl; // Get the violated cuts from generator. CutVector knapcuts = knapgen->getViolatedCutList(); // Iterators for cuts CutVectorConstIter it; CutVectorConstIter begin = knapcuts.begin(); CutVectorConstIter end = knapcuts.end(); // Apply the cuts to the problem. // Violation list. DoubleVector knapviols = knapgen->getViolList(); UInt curknap = 0; Double maxviol = 0.0; for (it=begin; it!=end; ++it) { std::cout << "Violation obtained from this constraint is: " << knapviols[curknap] << std::endl; ConstraintPtr newcons = rel->newConstraint((*it)->getFunction(), (*it)->getLb(), (*it)->getUb()); if (maxviol < knapviols[curknap]) { maxviol = knapviols[curknap]; } // add constraint to engine does not do anything. // Thus, we add constraint to the relaxation and reload it to engine. // e.addConstraint(newcons); } /*******************************************************************/ // Solution time of knapsack cover cuts added problem. Double timemod = 0.0; // Objective value after adding knapsack cover cuts. Double endobj = 0.0; // Gap closed by using knapsack cover cuts. Double gapknap = 0.0; /*******************************************************************/ if (violknapcuts >= 1) { // Reload problem to engine. // Check if we should reload the modified problem. e.clear(); const Double * xupdated; if (WARMSTART == 1) { // Set initial point as the solution of root solution. xupdated = sol->getPrimal(); rel->setInitialPoint(xupdated); } // Load the modified problem. e.load(rel); // warmstart continues. if (WARMSTART == 1) { // Before presolve, we set initial primal and // dual solutions as the root solution. SolutionPtr solupdated = (SolutionPtr) new Solution(initobj, xupdated, rel); // Create new dual solution. const Double * dualofvars = sol->getDualOfVars(); solupdated->setDualOfVars(dualofvars); const Double * initdualofcons = sol->getDualOfCons(); UInt numconsupdated = rel->getNumCons(); Double * dualofcons = new Double[numconsupdated]; memcpy(dualofcons, initdualofcons, numcons*sizeof(Double)); for (UInt indexx = numcons; indexx < numconsupdated; ++indexx) { dualofcons[indexx] = 0.0; } solupdated->setDualOfCons(dualofcons); FilterWSPtr warmstart = (FilterWSPtr) new FilterSQPWarmStart(); warmstart->setPoint(solupdated); e.loadFromWarmStart(warmstart); delete [] dualofcons; } // Solution time after adding knapsack cover cuts to relaxation. timer->start(); // Resolve the problem. e.solve(); /*******************************************************************/ // Solution time of knapsack cover cuts added problem. timemod = timer->query(); timer->stop(); // Objective value after adding knapsack cover cuts. endobj = e.getSolutionValue(); // Gap closed by using knapsack cover cuts. gapknap = (endobj-initobj)/fabs(initobj) * 100; /*******************************************************************/ } else { /*******************************************************************/ // Solution time of knapsack cover cuts added problem. timemod = timeinit; // Objective value after adding knapsack cover cuts. endobj = initobj; // Gap closed by using knapsack cover cuts. gapknap = 0.0; /*******************************************************************/ } std::cout << "Objective value of relaxation after adding cuts: " << endobj << std::endl; cout << pname << " " << numvars << " " << numcons << " " << numlin << " " << numknap << " " << numknapcov << " " << knaps << " " << totalcuts << " " << numknapcuts << " " << violknapcuts << std::fixed << std::setprecision(2) << " " << initobj << " " << endobj << " " << gapknap << " " << timeinit << " " << timecut << " " << timemod << endl; if (numknap >= 1) { // Save output data. output << pname << " " << numvars << " " << numcons << " " << numlin << " " << numknap << " " << numknapcov << " " << knaps << " " << totalcuts << " " << numknapcuts << " " << violknapcuts << std::fixed << std::setprecision(2) << " " << initobj << " " << endobj << " " << gapknap << " " << timeinit << " " << timecut << " " << timemod << endl; } delete iface; delete [] argv2; } output.close(); input.close(); return 0; }