Example #1
0
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;
}
Example #2
0
//! main routine implementing outer approximation
int main(int argc, char** argv)
{
  //! Declaration of Variables ============================================
  //! interface to AMPL (NULL):
  MINOTAUR_AMPL::AMPLInterfacePtr iface = MINOTAUR_AMPL::AMPLInterfacePtr();  
  MINOTAUR_AMPL::JacobianPtr jPtr;            //! Jacobian read from AMPL
  MINOTAUR_AMPL::HessianOfLagPtr hPtr;        //! Hessian read from AMPL

  //! environment, timers, options:
  EnvPtr env = (EnvPtr) new Environment();
  TimerFactory *tFactory = new TimerFactory();     
  Timer *timer=tFactory->getTimer();
  OptionDBPtr options;                        //! AMPL and MINOTAUR options

  //! problem pointers (MINLP, NLP, MILP):
  ProblemPtr minlp;                           //! MINLP instance to be solved
  ProblemPtr milp;                            //! MILP master problem

  //! solver pointers, including status
  FilterSQPEngine e(env);                     //! NLP engine: FilterSQP
  EngineStatus status;

  //! pointers to manipulate variables & constraints
  VariablePtr v, objVar;                      //! variable pointer (objective)
  ObjectivePtr objFun;                        //! remember objective function pt.

  //! local variables
  Double *x, *xsoln;
  Double *lobnd, *upbnd;
  Double objfLo = -INFINITY, objfUp = INFINITY, objfNLP, objfMIP;
  Double tol = 1E-2;
  Int    feasibleNLP = 0, iterOA = 1, n;
  // ======================================================================

  //! start the timer
  timer->start();

  //! make sure solver is used correctly
  if (argc < 2) {
    usage();
    return -1;
  }

  //! add AMPL options & flags to environment: flags (options without values)
  options = env->getOptions();
  add_ampl_flags(options);
  env->readOptions(argc, argv);                  //! parse options
  if (!checkUserOK(options,env)) goto CLEANUP;   //! check if user needs help

  //! read MINLP from AMPL & create Hessian/Jacobian for NLP solves
  iface = (MINOTAUR_AMPL::AMPLInterfacePtr) new MINOTAUR_AMPL::AMPLInterface(env);
  minlp = iface->readInstance(options->findString("problem_file")->getValue(),false);
  jPtr  = (MINOTAUR_AMPL::JacobianPtr)      new MINOTAUR_AMPL::Jacobian(iface);
  hPtr  = (MINOTAUR_AMPL::HessianOfLagPtr)  new MINOTAUR_AMPL::HessianOfLag(iface);
  minlp->setJacobian(jPtr);
  minlp->setHessian(hPtr);
    
  //! Display number of constraints and variables, and MINLP problem
  minlp->calculateSize();
  n = minlp->getNumVars();
  std::cout << "No. of vars, cons = " << minlp->getNumVars() 
            << minlp->getNumCons() << std::endl;
  std::cout << std::endl << "The MINLP problem is: " << std::endl;
  minlp->write(std::cout);

  //! load the MINLP into the NLP solver (FilterSQP)
  e.load(minlp);

  //! get initial point & save original bounds
  x     = new Double[n];
  xsoln = new Double[n];
  lobnd = new Double[n];
  upbnd = new Double[n];
  std::copy(iface->getInitialPoint(),iface->getInitialPoint()+n,x);
  for (VariableConstIterator i=minlp->varsBegin(); i!=minlp->varsEnd(); ++i) {
    v = *i;
    lobnd[v->getId()] = v->getLb();
    upbnd[v->getId()] = v->getUb();
  }

  //! initialize the MILP master problem by copying variables & linear c/s
  milp   = (ProblemPtr) new Problem();
  objFun = minlp->getObjective();
  objVar = VariablePtr();
  initMaster(minlp, milp, objVar, objFun, x);

  while ((objfLo <= objfUp)&&(iterOA<4)){

    std::cout << "Iteration " << iterOA << std::endl 
              << "===============" << std::endl << std::endl;

    //! set-up and solve NLP(y) with fixed integers
    solveNLP(minlp, e, x, objfNLP, feasibleNLP, n);
    std::cout << "Solved NLP " << iterOA << "  objective = " << objfNLP 
              << "  NLPfeasible = " << feasibleNLP << std::endl;
    if (feasibleNLP && (objfNLP-tol < objfUp)) {
      objfUp = objfNLP - tol;
      std::copy(x,x+n,xsoln);
    }
        
    //! update MILP master problem by adding outer approximations
    updateMaster(minlp, milp, objVar, objFun, objfUp, x, n);

    //! solve MILP master problem
    solveMaster(env, milp, x, &objfMIP, n);
    objfLo = objfMIP;

    iterOA = iterOA + 1;

  } // end while (objfLo <= objfUp) 

  //! output final result & timing
  std::cout << std::endl << "END outer-approximation: f(x) = " << objfUp 
            << "   time used = " << timer->query() << std::endl;

CLEANUP:
  //! free storage 
   delete timer;
   delete tFactory;
   if (minlp) {
     minlp->clear();
     delete [] x;
     delete [] xsoln;
     delete [] lobnd;
     delete [] upbnd;
   }
   if (milp) {
     milp->clear();
   }
  return 0;
} // end outer approximation main