示例#1
0
void ParQGHandler::linearizeObj_()
{
  ObjectivePtr o = minlp_->getObjective();
  FunctionType fType = o->getFunctionType();
  if (!o) {
    assert(!"need objective in QG!");
  } else if (fType != Linear && fType != Constant) {
    oNl_ = true;
    FunctionPtr f;
    VariablePtr vPtr;
    ObjectiveType objType = o->getObjectiveType();
    LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
    for (VariableConstIterator viter=rel_->varsBegin(); viter!=rel_->varsEnd();
         ++viter) {
      vPtr = *viter;
      if (vPtr->getName() == "eta") {
        assert(o->getObjectiveType()==Minimize);
        rel_->removeObjective();
        lf->addTerm(vPtr, 1.0);
        f = (FunctionPtr) new Function(lf);
        rel_->newObjective(f, 0.0, objType);
        objVar_ = vPtr;
        break;
      }
    }
  }
  return;
}
示例#2
0
void Transformer::copyLinear_(ConstProblemPtr p, ProblemPtr newp)
{
  FunctionPtr f;
  LinearFunctionPtr newlf;
  ConstConstraintPtr c;
  ConstraintPtr newc;
  ObjectivePtr obj;

  // copy linear constraints.
  for (ConstraintConstIterator it=p->consBegin(); it!=p->consEnd(); ++it) {
    c = *it;
    if (Linear==c->getFunction()->getType()) {
      // create a clone of this linear function.
      newlf = c->getLinearFunction()->cloneWithVars(newp->varsBegin());
      f = (FunctionPtr) new Function(newlf);
      newc = newp->newConstraint(f, c->getLb(), c->getUb());
      lHandler_->addConstraint(newc);
    }
  }

  // copy linear objective.
  obj = p->getObjective();

  if (!obj) {
    f.reset();
    newp_->newObjective(f, 0.0, Minimize);
  } else {
    switch (obj->getFunctionType()) {
    case (Constant):
      f = FunctionPtr(); // NULL
      newp->newObjective(f, obj->getConstant(), obj->getObjectiveType(),
                         obj->getName());
      break;
    case (Linear):
      newlf = obj->getFunction()->getLinearFunction()->
      cloneWithVars(newp->varsBegin());
      f = (FunctionPtr) new Function(newlf); 
      newp->newObjective(f, obj->getConstant(), obj->getObjectiveType(),
                         obj->getName());
      break;
    default:
      break;
    }
  }
}
示例#3
0
void Transformer::makeObjLin_()
{
  ObjectivePtr obj;
  assert(p_);
  assert(newp_);

  obj = p_->getObjective();
  if (!obj) {
    return;
  }
  
  if (obj->getFunctionType() != Linear && obj->getFunctionType() != Constant) {
    VariablePtr eta = newp_->newVariable(VarTran);
    FunctionPtr etaf;
    FunctionPtr f = obj->getFunction();
    LinearFunctionPtr lz = LinearFunctionPtr(new LinearFunction());
    LinearFunctionPtr lz2;
    ObjectiveType otype = obj->getObjectiveType();
    ConstraintPtr objcon;

    lz->addTerm(eta, -1.0);
    f->add(lz);
    
    if (otype == Minimize) {
      //XXX Do you want to keep track of the objective constraint?
      objcon = newp_->newConstraint(f, -INFINITY, 0.0);
      if (lHandler_) {
        lHandler_->addConstraint(objcon);
      }
    } else {
      objcon = newp_->newConstraint(f, 0.0, INFINITY);
      if (lHandler_) {
        lHandler_->addConstraint(objcon);
      }
    }

    lz2 = (LinearFunctionPtr) new LinearFunction();
    lz2->addTerm(eta, 1.0);
    etaf = (FunctionPtr) new Function(lz2);

    newp_->newObjective(etaf, obj->getConstant(), otype);
  }
}
示例#4
0
void ParQGHandler::setObjVar()
{
  ObjectivePtr o = minlp_->getObjective();
  FunctionType fType = o->getFunctionType();
  if (!o) {
    assert(!"need objective in QG!");
  } else if (fType != Linear && fType != Constant) {
    oNl_ = true;
    VariablePtr vPtr;
    for (VariableConstIterator viter=rel_->varsBegin(); viter!=rel_->varsEnd();
         ++viter) {
      vPtr = *viter;
      if (vPtr->getName() == "eta") {
        assert(o->getObjectiveType()==Minimize);
        objVar_ = vPtr;
        break;
      }
    }
  }
  return;
}
示例#5
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;
}