예제 #1
0
bool SOS1Handler::isFeasible(ConstSolutionPtr sol, RelaxationPtr rel, bool &,
                             double &)
{
  SOSPtr sos;
  bool isfeas = true;
  int nz;
  const double* x = sol->getPrimal();

  for (SOSConstIterator siter=rel->sos1Begin(); siter!=rel->sos1End();
       ++siter) {
    sos = *siter;
    nz = 0;
    for (VariableConstIterator viter = sos->varsBegin(); viter!=sos->varsEnd();
         ++viter) {
      if (x[(*viter)->getIndex()]>zTol_) {
        ++nz;
        if (nz>1) {
          isfeas = false;
          break;
        }
      }
    }
    if (false == isfeas) {
      break;
    }
  }

#if SPEW
  logger_->msgStream(LogDebug) << me_ << "isFeasible = " << isfeas
                               << std::endl;
#endif
  return isfeas;
}
void
MultilinearTermsHandler::relaxNodeInc(NodePtr node,
                                      RelaxationPtr relaxation, bool *isInfeasible)
{
  *isInfeasible = false;

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  std::cout << "MultilinearTermsHandler::relaxNodeInc.  Node: ";
  node->write(std::cout);
  std::cout << "Initial Relaxation: ";
  relaxation->write(std::cout);
#endif

  ModVector mods;
  handleXDefConstraints_(relaxation, relaxNodeInc_Call, mods);
  handleZDefConstraints_(relaxation, relaxNodeInc_Call, mods);
  
  ModificationConstIterator it;
  for (it = mods.begin(); it != mods.end(); ++it) {
    node->addRMod(*it);
  }

#if defined(DEBUG_MULTILINEARTERMS_HANDLER) 
  std::cout << "MultilinearTermsHandler::relaxNodeInc.  Final relaxation:" << std::endl;
  relaxation->write(std::cout);
#endif

}
예제 #3
0
void ParQGHandler::separate(ConstSolutionPtr sol, NodePtr , RelaxationPtr rel,
                         CutManager *cutMan, SolutionPoolPtr s_pool, ModVector &,
                         ModVector &, bool *sol_found, SeparationStatus *status)
{
  double val;
  VariableType v_type;
  VariableConstIterator v_iter;
  const double *x = sol->getPrimal();
  *status = SepaContinue;

  for (v_iter = rel->varsBegin(); v_iter != rel->varsEnd(); ++v_iter) {
    v_type = (*v_iter)->getType();
    if (v_type == Binary || v_type == Integer) {
      val = x[(*v_iter)->getIndex()];
      if (fabs(val - floor(val+0.5)) > intTol_) {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << "variable " <<
          (*v_iter)->getName() << " has fractional value = " << val <<
          std::endl;
#endif
        return;
      }
    }
  }
  cutIntSol_(sol, cutMan, s_pool, sol_found, status);
  return;
}
// This chunk of code adds
// z_t = \sum_{k=1}^{2 |V_g|} \lambda_k^g, \Prod_{j \in J_t} \chi_j^{g,k}
//   \forall J_t \subseteq V_g
void
MultilinearTermsHandler::handleZDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods)
{
  for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) {
    ConstVariablePtr zt = it->first;
    SetOfVars const &jt = it->second;

    for (UInt gix = 0; gix < groups_.size(); ++gix) {
      SetOfVars &vg = groups_[gix];
       
      if (std::includes(vg.begin(), vg.end(), jt.begin(), jt.end())) { 
        // jt is a subset of vg, add constraint
        LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
        lf->addTerm(zt, -1.0);
        int pix = 0;

        for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); 
             it2 != points_[gix].end(); ++it2) {
          double prodval = 1.0;
          VariablePtr lam = lambdavars_[gix][pix];

          for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) {
            ConstVariablePtr xvar = *jt_it;
            double tmp = varIsAtLowerBoundAtPoint_(xvar, *it2) ? xvar->getLb() : xvar->getUb();
            prodval *= tmp;
          }

          lf->addTerm(lam, prodval);
          ++pix;
        }        
        FunctionPtr f = (FunctionPtr) new Function(lf);

        if (wherefrom == relaxInit_Call) {
          ConstraintPtr c = relaxation->newConstraint(f, 0.0, 0.0);
          zConMap_.insert(std::make_pair(IntVarPtrPair(gix, zt), c));
        }
        else { 
          IntVarPtrPairConstraintMap::iterator pos;
          pos = zConMap_.find(IntVarPtrPair(gix, zt));
          if (pos == zConMap_.end()) {
            assert(0);
          }
          ConstraintPtr c = pos->second;
          //XXX Here you should just check if the constraint really was going to
          //change and do nothing if it doesn't...  (will be faster).
          if (wherefrom == relaxNodeInc_Call) {
            relaxation->changeConstraint(c, lf, 0.0, 0.0);
          }
          LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); 
          mods.push_back(lcmod);
        }
      }
      
    }
  } 


}
void
MultilinearTermsHandler::handleXDefConstraints_(RelaxationPtr relaxation, HandleCallingFunction wherefrom, ModVector &mods)
{
  for (UInt gix = 0; gix < groups_.size(); ++gix) {
    for(SetOfVars::const_iterator it = groups_[gix].begin(); it != groups_[gix].end(); ++it) {
      ConstVariablePtr xvar = *it;
      LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
      lf->addTerm(xvar, -1.0);
      
      int pix = 0;
      for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); it2 != points_[gix].end(); ++it2) {
        VariablePtr lam = lambdavars_[gix][pix];
        double val = varIsAtLowerBoundAtPoint_(xvar, *it2) ? xvar->getLb() : xvar->getUb();
        lf->addTerm(lam, val);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
        std::cout << xvar->getName() << ", lam: " << gix << "," << pix << " value is: " 
                  << val << std::endl;
#endif        
        ++pix;
      }      
      FunctionPtr f = (FunctionPtr) new Function(lf);

      if (wherefrom == relaxInit_Call) {
        ConstraintPtr c = relaxation->newConstraint(f, 0.0, 0.0);
        xConMap_.insert(std::make_pair(IntVarPtrPair(gix, xvar), c));
      }
      else { 
        IntVarPtrPairConstraintMap::iterator pos;
        pos = xConMap_.find(IntVarPtrPair(gix, xvar));
        if (pos == xConMap_.end()) {
          assert(0);
        }
        ConstraintPtr c = pos->second;
        //XXX Here you should just check if the constraint really was going to
        //change and do nothing if it doesn't...  (will be faster).
        if (wherefrom == relaxNodeInc_Call) {
          relaxation->changeConstraint(c, lf, 0.0, 0.0);
        }
        else {
          assert(0);
        }
        LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); 
        mods.push_back(lcmod);
      }      
    }
  }  
  
}
예제 #6
0
void CxUnivarHandler::relaxNodeInc(NodePtr , RelaxationPtr rel, bool *is_inf)
{

#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "CxUnivarHandler::relaxNodeInc.  Current relaxation: "
            << std::endl;
  rel->write(std::cout);
  std::cout << "Current node: " << std::endl;
  node->write(std::cout);
#endif

  // You must apply all modifications to the nodes

  // I think this is all done by branches now.
  //  FALSE -- If you don't branch on a variable, you still need to update the relaxation from
  //  this node

  ModVector mods;
  CxUnivarConstraintIterator dit;   
  for (dit = cons_data_.begin(); dit != cons_data_.end(); ++dit) {
    (*dit)->updateRelax(rel, tmpX_, grad_, mods);
  }

  ModificationConstIterator it;
  for (it = mods.begin(); it != mods.end(); ++it) {
    assert(!"add Mod correctly here.");
    // node->addPMod(*it);
  }

 *is_inf = false;
}
예제 #7
0
/// Creates initial relaxations   
void CxUnivarConstraintData::initRelax(RelaxationPtr rel, DoubleVector& tmpX,
                                       DoubleVector& grad)
{
  // get and set the relaxation relaxation variables that match the original
  // problem variables
  riv_ = rel->getVariable(iv_->getIndex());
  rov_ = rel->getVariable(ov_->getIndex());

  // This isn't used
  ModVector mods;

  // Add secant
  if (sense_ == 'E' || sense_ == 'L') {
    addSecant(rel, riv_, rov_, con_->getFunction(), tmpX, true, mods);
  }

  // Add linearizations 
  // TODO: Make strategy a parameter
  if (sense_ == 'E' || sense_ == 'G') {
    addLin(rel, iv_, ov_, con_->getFunction(), tmpX, grad, true, mods); 
  }

}
예제 #8
0
Branches SOS1Handler::getBranches(BrCandPtr cand, DoubleVector &, 
                                  RelaxationPtr rel, SolutionPoolPtr)
{
  SOSBrCandPtr scand = boost::dynamic_pointer_cast <SOSBrCand> (cand);
  LinModsPtr mod;
  VarBoundModPtr bmod;
  VariablePtr v2;

  BranchPtr branch1, branch2;
  Branches branches = (Branches) new BranchPtrVector();

  branch1 = (BranchPtr) new Branch();
  if (modProb_) {
    mod = (LinModsPtr) new LinMods();
    for (VariableConstIterator vit=scand->lVarsBegin();vit!=scand->lVarsEnd();
         ++vit) {
      v2 = rel->getOriginalVar(*vit);
      if (v2) {
        bmod = (VarBoundModPtr) new VarBoundMod(v2, Upper, 0.0);
        mod->insert(bmod);
      }
    }
    branch1->addPMod(mod);
  }
  if (modRel_) {
    mod = (LinModsPtr) new LinMods();
    for (VariableConstIterator vit=scand->lVarsBegin();vit!=scand->lVarsEnd();
         ++vit) {
      bmod = (VarBoundModPtr) new VarBoundMod(*vit, Upper, 0.0);
      mod->insert(bmod);
    }
    branch1->addRMod(mod);
  }
  branch1->setActivity(scand->getLSum());

  branch2 = (BranchPtr) new Branch();
  if (modProb_) {
    mod = (LinModsPtr) new LinMods();
    for (VariableConstIterator vit=scand->rVarsBegin();vit!=scand->rVarsEnd();
         ++vit) {
      v2 = rel->getOriginalVar(*vit);
      if (v2) {
        bmod = (VarBoundModPtr) new VarBoundMod(v2, Upper, 0.0);
        mod->insert(bmod);
      }
    }
    branch2->addPMod(mod);
  }
  if (modRel_) {
    mod = (LinModsPtr) new LinMods();
    for (VariableConstIterator vit=scand->rVarsBegin();vit!=scand->rVarsEnd();
         ++vit) {
      bmod = (VarBoundModPtr) new VarBoundMod(*vit, Upper, 0.0);
      mod->insert(bmod);
    }
    branch2->addRMod(mod);
  }
  branch2->setActivity(scand->getRSum());

  branches->push_back(branch1);
  branches->push_back(branch2);
  return branches;
}
예제 #9
0
void SOS1Handler::getBranchingCandidates(RelaxationPtr rel, 
                                         const DoubleVector &x,
                                         ModVector &, BrVarCandSet &,
                                         BrCandVector &gencands,
                                         bool &is_inf)
{
  SOSConstIterator siter;
  VariableConstIterator viter;
  VariablePtr var;
  SOSPtr sos;
  double parsum;
  VarVector lvars, rvars;
  int nz;
  double nzsum;
  double nzval;
  SOSBrCandPtr br_can;

  for (siter=rel->sos1Begin(); siter!=rel->sos1End(); ++siter) {
    sos = *siter;
    getNzNumSum_(sos, x, &nz, &nzsum);
    if (nz>1) {
      parsum = 0.0;
      lvars.clear();
      rvars.clear();
      viter = sos->varsBegin();
      for (; viter!=sos->varsEnd(); ++viter) {
        var = *viter;
        if (var->getUb()-var->getLb()>zTol_) {
          nzval = x[var->getIndex()];
          if ((parsum + nzval) < 0.5*nzsum) {
            lvars.push_back(var);
            parsum += nzval;
          } else if (nzval+parsum - nzsum/2 < nzsum/2 - parsum) {
            lvars.push_back(var);
            parsum += nzval;
            ++viter;
            break;
          } else {
            break;
          }
        }
      } 
      for (; viter!=sos->varsEnd(); ++viter) {
        var = *viter;
        if (var->getUb()-var->getLb()>zTol_) {
          rvars.push_back(*viter);
        }
      }
      br_can = (SOSBrCandPtr) new SOSBrCand(sos, lvars, rvars, parsum,
                                            nzsum-parsum);
      br_can->setDir(DownBranch);
      br_can->setScore(20.0*(lvars.size()-1)*(rvars.size()-1));
      
      gencands.push_back(br_can);

#if SPEW
      logger_->msgStream(LogDebug) << me_ << sos->getName() << " is a "
        << " branching candidate." << std::endl
        << me_ << "left branch has variables ";
      for (viter = lvars.begin(); viter!=lvars.end(); ++viter) {
        logger_->msgStream(LogDebug) << (*viter)->getName() << " ";
      }
      logger_->msgStream(LogDebug) << std::endl
                                   << me_ << "left sum = " << parsum
                                   << std::endl
                                   << me_ << "right branch has variables ";
      for (viter = rvars.begin(); viter!=rvars.end(); ++viter) {
        logger_->msgStream(LogDebug) << (*viter)->getName() << " ";
      }
      logger_->msgStream(LogDebug) << std::endl
                                   << me_ << "right sum = " << nzsum - parsum
                                   << std::endl;
#endif

    } else {
#if SPEW
      logger_->msgStream(LogDebug) << me_ << sos->getName() << " is not a "
                                   << " branching candidate." << std::endl;
#endif
    }
  }
  is_inf = false;
}
예제 #10
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;
}
예제 #11
0
Branches RandomBrancher::findBranches(RelaxationPtr rel, NodePtr ,
                                      ConstSolutionPtr sol,
                                      SolutionPoolPtr s_pool,
                                      BrancherStatus & br_status,
                                      ModVector &mods) 
{
  Branches branches;
  DoubleVector x(rel->getNumVars());
  BrVarCandSet cands;      // candidates from which to choose one.
  BrVarCandSet cands2;     // temporary set.
  BrCandVector gencands;
  BrCandVector gencands2;  // temporary set.
  BrCandPtr best_can = BrCandPtr(); // NULL
  bool is_inf = false;

  timer_->start();
  std::copy(sol->getPrimal(), sol->getPrimal()+rel->getNumVars(), x.begin());
  
  ++(stats_->calls);
  br_status = NotModifiedByBrancher;

  for (HandlerIterator h = handlers_.begin(); h != handlers_.end(); ++h) {
    // ask each handler to give some candidates
    (*h)->getBranchingCandidates(rel, x, mods, cands2, gencands2, is_inf);
    for (BrVarCandIter it = cands2.begin(); it != cands2.end(); ++it) {
      (*it)->setHandler(*h);
    }
    for (BrCandVIter it = gencands2.begin(); it != gencands2.end(); ++it) {
      (*it)->setHandler(*h);
    }
    cands.insert(cands2.begin(), cands2.end());
    gencands.insert(gencands.end(), gencands2.begin(), gencands2.end());
    cands2.clear();
    gencands2.clear();
    if (is_inf || mods.size()>0) {
      cands.clear();
      gencands.clear();
      if (is_inf) {
        br_status = PrunedByBrancher;
        stats_->time += timer_->query();
        timer_->stop();
        return branches;
      }
    }
  }

  if (cands.size() > 0) {
    BrVarCandIter it = cands.begin();

    std::advance(it,rand()%cands.size());
    best_can = *(it);
  } else if (gencands.size() > 0) {
    BrCandVIter it = gencands.begin();

    std::advance(it,rand()%gencands.size());
    best_can = *(it);
  }

  if (best_can) {
    best_can->setDir(DownBranch);

    branches = best_can->getHandler()->getBranches(best_can, x, rel, s_pool); 
#if SPEW
    logger_->msgStream(LogDebug) << me_ << "best candidate = "
                                 << best_can->getName() << std::endl;
#endif
  } else {
    assert(!"problem finding candidate in RandomBrancher");
  }

  stats_->time += timer_->query();
  timer_->stop();
  return branches;
}
예제 #12
0
void KnapCovHandler::separate(ConstSolutionPtr sol, NodePtr,
                              RelaxationPtr rel, CutManager * cmanager,
                              SolutionPoolPtr , bool * ,
                              SeparationStatus * status)
{
  // Check integer feasibility of sol, must add cuts if it is not integral.
  numvars_ = minlp_->getNumVars();
  VariableType type;
  const double * x = sol->getPrimal();
  // Is the relaxation solution is integer feasible.
  bool isintfeas = true;
  // Iterators for variables.
  VariableConstIterator it;
  VariableConstIterator begin = rel->varsBegin();
  VariableConstIterator end   = rel->varsEnd();
  // Temporary variable holder.
  ConstVariablePtr var; 
  // Value of variable.
  double value;
  bool separated = false;
  UInt n_added = 0;

  // Check if integrality is satisfied for each integer variable. 
  for (it=begin; it!=end; ++it) {
    var = *it;
    type = var->getType();
    if (type==Binary || type==Integer) {
      value = x[var->getIndex()];
      if (fabs(value - floor(value + 0.5)) > intTol_) {
        isintfeas = false;
        break;
      }
    }
  }

  if (isintfeas ==  false) {
    // We do another check in CoverCutGneerator for integrality, may be we
    // should eliminate it and use the one above.
    // Generate cover cuts from current relaxation.
    CoverCutGeneratorPtr cover = (CoverCutGeneratorPtr) new CoverCutGenerator(rel,sol, env_);
    // Add cuts to the relaxation by using cut manager.
    CutVector violatedcuts = cover->getViolatedCutList();
    CutIterator itc;
    CutIterator beginc = violatedcuts.begin();
    CutIterator endc   = violatedcuts.end();
    
    // Serdar I am not sure if we should add the constraints generated by
    // addCuts to the constraint vector of knapsack cover handler.
    // Currently CutMan2::addCuts does not add the cuts to the relaxation formulation.
    cmanager->addCuts(beginc, endc);
    cmanager->separate(rel, sol, &separated, &n_added);
    if (n_added>0) {
      *status = SepaResolve;
    }
    
    // Update statistics by using return from cover cut generator.
    ConstCovCutGenStatsPtr covstats = cover->getStats();
    // Later put the code below to updateStats function.
    stats_->knaps += covstats->knaps;
    stats_->cuts += covstats->cuts;
    stats_->extended += covstats->extended;
    stats_->simple += covstats->simple;
    stats_->gns += covstats->gns;
    stats_->singlectwo += covstats->singlectwo;    
  }

  
}
예제 #13
0
void CxUnivarConstraintData::addSecant(RelaxationPtr rel,
                                       ConstVariablePtr riv,
                                       ConstVariablePtr rov,
                                       FunctionPtr fn, DoubleVector& tmpX,
                                       bool init, ModVector &mods) 
{

  int error;
  double xlb, xub, fxlb, fxub, m, intercept;
  LinearFunctionPtr lf; 
  FunctionPtr f;

  // First add the secant inequalities based on variable bounds
  xlb = riv->getLb();
  xub = riv->getUb();
	
#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "Adding secant on variable rix index: " << riv->getIndex() 
	    << " rov index: " << rov->getIndex()
	    << " xlb: " << xlb << " xub: " << xub << std::endl;
#endif 
  // no secant if unbounded either way
  if (xlb <= -0.9*INFINITY || xub >= 0.9*INFINITY) {
    std::cout << "Cannot add secant -- bound is infinite" << std::endl;
    return;
  }

  // TODO: Check the error value!
  tmpX[riv->getIndex()] = xlb;
  fxlb =  fn->eval(tmpX, &error);
  tmpX[riv->getIndex()] = xub;
  fxub =  fn->eval(tmpX, &error);
  tmpX[riv->getIndex()] = 0.0;

  // TODO: check/remedy numerical issues in this division
  if (xub - xlb > 10e-7) {
    m = (fxub - fxlb)/(xub - xlb);
  }
  else {
    m = 0.0;
  }

  intercept = fxlb - m*xlb;
  lf = (LinearFunctionPtr) new LinearFunction();
  lf->addTerm(rov, 1.0);
  lf->addTerm(riv, -m);

  // rovar <= m*rivar + intercept 
  if (init) {
     f = (FunctionPtr) new Function(lf);
     secCon_ = rel->newConstraint(f, -INFINITY, intercept);
  }
  else {
    rel->changeConstraint(secCon_, lf, -INFINITY, intercept);
    LinConModPtr lcmod = (LinConModPtr) new LinConMod(secCon_, lf, -INFINITY,
                                                      intercept);
    mods.push_back(lcmod);
  }

  
}
예제 #14
0
void CxUnivarConstraintData::addLin(RelaxationPtr rel, ConstVariablePtr riv,
				    ConstVariablePtr rov, FunctionPtr fn,
                                    DoubleVector& tmpX, DoubleVector& grad,
                                    bool init, ModVector &mods)
{
 
  int error;
  ConstraintPtr cons; 
  double xlb = riv->getLb();
  double xub = riv->getUb();
  double fxlbval=0, fxubval=0, dfxlbval=0, dfxubval=0;
  double tmpxval, fxval, dfxval; 
  LinearFunctionPtr lf; 
  FunctionPtr f;

  // More sophisticated strategies hopefully could be obtained by simply
  // changing this array 
  int npts = 3;
  double xvals[] = {xlb, xub, (xub-xlb)/2.0};

#if defined(DEBUG_CXUNIVARHANDLER)
  std::cout << "Adding linearizations.  rix id: " << riv->getId() 
	    << " rix index: " << riv->getIndex() << " rov id: " << rov->getId() 
	    << " rov index: " << rov->getIndex()
	    << " xlb: " << xlb << " xub: " << xub << std::endl;
#endif
  
  for (int i = 0; i < npts; i++) {

    // Zero out tmpX and grad each time, or else bad things happen
    for (UInt j = 0; j < tmpX.size(); ++j) {
      tmpX[j] = 0.0;
      grad[j] = 0.0;
    }
    
    if (i == 2) {
      // Third linearization point taken to be where first two intersect:
      // x3 = (f'(xub)*xub - f'(xlb)*xlb + f(xlb) - f(xub))/(f'(xub) - f'(xlb))
      // Unless this would put it too close to one of the end points
      if (dfxubval - dfxlbval > 0.0001 || dfxubval - dfxlbval < -0.0001) {
        tmpxval = (dfxubval*xub - dfxlbval*xlb + fxlbval - fxubval)/
                  (dfxubval - dfxlbval);
        if (tmpxval < xlb + (xub-xlb)*0.05) {
          xvals[2] = xlb + (xub-xlb)*0.05;
        }
        else if (tmpxval > xub - (xub-xlb)*0.05) {
          xvals[2] = xub - (xub-xlb)*0.05;
        }
        else {
          xvals[2] = tmpxval;
        }
      }
    }
    tmpX[riv->getIndex()] = xvals[i];
    error = 0;
    fxval =  fn->eval(tmpX, &error);
    fn->evalGradient(&tmpX[0], &grad[0], &error);
#if defined(DEBUG_CXUNIVARHANDLER2)
    for (UInt j = 0; j < tmpX.size(); ++j) {
      std::cout << "x[" << j << "] = " << tmpX[j] << " dfdx[" << j << "] = "
                << grad[j] << std::endl;
    }
#endif
    dfxval = grad[riv->getIndex()];
    if (i == 0) {
       fxlbval = fxval;
       dfxlbval = dfxval; 
    }
    else if (i == 1) {
       fxubval = fxval;
       dfxubval = dfxval; 
    }
    // linearization:  rov >= f(xval) + f'(xval)(riv - xval) 
    //                 rov - f'(xval)*riv >= f(xval) - f'(xval)*xval
    lf = (LinearFunctionPtr) new LinearFunction();
    lf->addTerm(rov, 1.0);
    lf->addTerm(riv, -dfxval);
    if (init) {
        f = (FunctionPtr) new Function(lf);
    	cons = rel->newConstraint(f, fxval - dfxval*xvals[i], INFINITY);
	linCons_.push_back(cons);
    }
    else {
#if defined(DEBUG_CXUNIVARHANDLER)
       std::cout << "Will change 'linearization  ' constraint to have "
                 << "linear function: ";
       lf->write(std::cout);  
       std::cout << std::endl;
#endif

       rel->changeConstraint(linCons_[i], lf, fxval - dfxval*xvals[i], INFINITY); 
       LinConModPtr lcmod = (LinConModPtr) new LinConMod(linCons_[i], lf, 
                                                         fxval -
                                                         dfxval*xvals[i],
                                                         INFINITY); 
       mods.push_back(lcmod);
    }
  }
  tmpX[riv->getIndex()] = 0.0;
  grad[riv->getIndex()] = 0.0;

}
void
MultilinearTermsHandler::relaxInitInc(RelaxationPtr relaxation, bool *)
{

  //  General notes...
  // Use Id to order variables
  // x[v->getIndex()] returns solution.
  
  /*
    0) Create "terms" map using the relaxation variables, not the original
       problem variables
    1) Create groups based on container of terms
    2) Add all lambda variables based on groups.
       (Be sure to keep a container of which constraints are associated with
       which groups)
   */

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  cout << "In MultilinearTermHandler::relaxInitInc()" << endl << " Current Relaxation: " << endl;
  relaxation->write(cout);
  cout << "And current terms: " << endl;

  for(ConstTermIterator it = termsO_.begin(); it != termsO_.end(); ++it) {
    std::cout << "zvar: ";
    it->first->write(std::cout);
    std::cout << "Contains vars: " << std::endl;
    for(SetOfVars::const_iterator it2 = it->second.begin(); 
        it2 != it->second.end(); ++it2) {
      (*it2)->write(cout);
    }
  }
#endif  

  // Copy the original variable pointers into a data structure consisting of 
  //  relaxation variables   (It just makes likfe easier to keep things in 
  //  terms of relaxation variables).
  for (ConstTermIterator it = termsO_.begin(); it != termsO_.end(); ++it) {
    ConstVariablePtr ov = it->first;
    SetOfVars const &ovset = it->second;
    ConstVariablePtr rv = relaxation->getRelaxationVar(ov);
    SetOfVars rvset;
    for(SetOfVars::const_iterator it2 = ovset.begin(); it2 != ovset.end(); ++it2) {
      rvset.insert( relaxation->getRelaxationVar(*it2));
    }
    termsR_.insert(make_pair(rv, rvset));
  }
      
    
  // First we make the groups.

  makeGroups_();

#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  cout << "After making groups: " << endl;

  for (ConstGroupIterator it = groups_.begin(); it != groups_.end(); ++it) {  
    cout << "Group of: " << endl;
    for(set<ConstVariablePtr>::const_iterator it2 = it->begin(); it2 != it->end(); ++it2) {
      (*it2)->write(cout);
    }
  }

  // Just checking groups now.  Stop here.
  //exit(1);
#endif

  /* This chunk of code creates the (powerset) representation 
   * of the extreme points in the groups, adds the lambda variables,
   * and adds the convexity constraints
   */

  lambdavars_.resize(groups_.size());
  for(UInt gix = 0; gix < groups_.size(); ++gix) {    

    LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();

    std::set<SetOfVars> p = powerset_(groups_[gix]);
    int pix = 0;
    for (std::set<SetOfVars>::iterator it2 = p.begin(); it2 != p.end(); ++it2) {
      std::string name;
      std::stringstream name_stream;
      name_stream << "lam_" << gix << "_" << pix;
      name = name_stream.str();
      
      VariablePtr lam;
      lam = relaxation->newVariable(0.0, 1.0, Continuous, name);
      lf->addTerm(lam, 1.0);
#if defined(DEBUG_MULTILINEARTERMS_HANDLER2)
      std::cout << "Adding: " << name << std::endl;
#endif

      lambdavars_[gix].push_back(lam);
      pix++;
    }    
    points_.push_back(p);
    FunctionPtr f = (FunctionPtr) new Function(lf);
    relaxation->newConstraint(f, 1.0, 1.0);
  }  


  ModVector mods;  // Not used in initialization
  handleXDefConstraints_(relaxation, relaxInit_Call, mods);
  handleZDefConstraints_(relaxation, relaxInit_Call, mods);


#if defined(DEBUG_MULTILINEARTERMS_HANDLER)
  std::cout << "In MultilinearTermHandler::relaxInitInc()" << std::endl << " Final Relaxation: " << std::endl;
  relaxation->write(std::cout);
#endif
    
}