Пример #1
0
vector<int> 
MultilinearFormulation::nonlinearVarsInConstraint(const ConstraintPtr c)
{
  set<int> ix;
  const QuadraticFunctionPtr qf = c->getQuadraticFunction();
  const NonlinearFunctionPtr nlf = c->getNonlinearFunction();
  const MultilinearFunction *mlf = dynamic_cast<MultilinearFunction *>(nlf.get());
  
  for(ConstVariablePairGroupIterator it = qf->begin(); it != qf->end(); ++it) {
    ix.insert(it->first.first->getId());
    ix.insert(it->first.second->getId());    
  }

  for(constMultilinearTermContainerIterator it = mlf->termsBegin(); 
      it != mlf->termsEnd();
      ++it) {
    for(set<ConstVariablePtr>::const_iterator it2 = it->second.begin();
        it2 != it->second.end(); ++it2) {
      ix.insert((*it2)->getId());
    }
  }

  vector<int> vix;
  for(set<int>::const_iterator it = ix.begin(); it != ix.end(); ++it) {
    vix.push_back(*it);
  }
  return vix;
  
}
Пример #2
0
VariablePtr Transformer::newVar_(CGraphPtr cg, ProblemPtr newp)
{
  VariablePtr iv;
  VariablePtr ov = VariablePtr(); // NULL
  FunctionPtr f;
  LinearFunctionPtr lf;
  ConstraintPtr cnew;
  assert(cg);

  if (OpSumList!=cg->getOut()->getOp()) {
    ov = yUniExprs_->findY(cg);
  } 

  if (!ov) {
    ov = newp->newVariable(VarTran);
    lf = (LinearFunctionPtr) new LinearFunction();
    lf->addTerm(ov, -1.0);
    f = (FunctionPtr) new Function(lf, cg);
    cnew = newp->newConstraint(f, 0.0, 0.0);
#if SPEW
      logger_->msgStream(LogDebug) << me_ << "added new constraint "
                                   << std::endl;
      cnew->write(logger_->msgStream(LogDebug));
#endif 
    assignHandler_(cg, cnew);

    yUniExprs_->insert(ov, cg);
  }
  return ov;
}
Пример #3
0
VariablePtr Transformer::newVar_(LinearFunctionPtr lf, double d,
                                 ProblemPtr newp)
{
  VariablePtr ov;
  FunctionPtr f;
  ConstraintPtr cnew;

  ov = yLfs_->findY(lf, d);
  if (!ov) {
    LinearFunctionPtr lf2 = lf->clone();
    ov = newp->newVariable(VarTran);
    yLfs_->insert(ov, lf2, d);
    lf->addTerm(ov, -1.0);
    f = (FunctionPtr) new Function(lf);
    cnew = newp->newConstraint(f, -d, -d);
#if SPEW
    logger_->msgStream(LogDebug) << me_ << "added new constraint "
                                 << std::endl;
    cnew->write(logger_->msgStream(LogDebug));
#endif 

    lHandler_->addConstraint(cnew);
  }
  return ov;
}
Пример #4
0
// Constructor, intended for root node
Node::Node(ConstraintPtr constraints)
    : constraints(constraints->clone(true)), // Deep copy
      nodeId(getNextNodeId())
{
    objLowerBound = -INF;
    objUpperBound = INF;
    solLowerBound = std::vector<double>(constraints->getNumVariables(), 0.0);
    solUpperBound = std::vector<double>(constraints->getNumVariables(), 0.0);
    depth = 0;
    parentBranchingVariable = -1; // -1 for root node

    auto bvars = findBranchingVariables(this->constraints);

    // Initialize branching/pseudo costs
    double cost = 1.0;
    for (auto var : bvars)
    {
        if (var->getType() == VariableType::CONTINUOUS)
        {
            // Continuous
            pCostsContinuous.emplace(getVariableIndex(var), cost);
        }
        else
        {
            // Integer
            pCostsInteger.emplace(getVariableIndex(var), 1.0);
        }
    }

    assert(bvars.size() == pCostsInteger.size() + pCostsContinuous.size());
}
Пример #5
0
VariablePtr Transformer::newVar_(VariablePtr iv, double d, ProblemPtr newp)
{
  if (fabs(d)<zTol_) {
    return iv;
  } else {
    LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction();
    VariablePtr ov;
    FunctionPtr f;
    ConstraintPtr cnew;

    ov = yVars_->findY(iv, d);
    if (!ov) {
      ov = newp->newVariable(VarTran);
      yVars_->insert(ov, iv, d);
      lf->addTerm(iv, 1.0);
      lf->addTerm(ov, -1.0);
      f = (FunctionPtr) new Function(lf);
      cnew = newp->newConstraint(f, -d, -d);
#if SPEW
      logger_->msgStream(LogDebug) << me_ << "added new constraint "
                                   << std::endl;
      cnew->write(logger_->msgStream(LogDebug));
#endif 
      lHandler_->addConstraint(cnew);
    }
    return ov;
  }
}
Пример #6
0
ExprPtr UnqualifierSet::unqualify(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds) const {
  Unqualifiers::const_iterator uq = this->uqs.find(cst->name());
  if (uq == this->uqs.end()) {
    throw annotated_error(*e, "Unknown predicate '" + cst->name() + "' can't be unqualified.");
  } else {
    return uq->second->unqualify(tenv, cst, e, ds);
  }
}
Пример #7
0
bool dec(const ConstraintPtr& c, Subtype* st) {
  if (c->name() == SubtypeUnqualifier::constraintName() && c->arguments().size() == 2) {
    st->lower   = c->arguments()[0];
    st->greater = c->arguments()[1];
    return true;
  }
  return false;
}
Пример #8
0
// -----------------------------------------------------------------------------------
void CBCSolver::setUpConstraints(std::vector<ConstraintPtr>& constraints) {
  for (int i = 0; i < constraints.size(); i++) {
    ConstraintPtr c = constraints.at(i);
    pair<double,double> bounds = constraintBounds(c);
    builder_.setRowBounds(i,bounds.first,bounds.second);
    std::map<VariablePtr,double>::iterator it;
    for (it = c->begin(); it != c->end(); it++) {
      builder_.setElement(i,index_[it->first],it->second);
    }
  }
}
Пример #9
0
ConstraintPtr ConstraintBSpline::computeRelaxationConvexHull()
{
    /*
     * Convex combination model:
     *
     * X = [x' y' auxiliary variables]'
     *
     * A = [ I -C ]   b = [ 0 ]
     *     [ 0  1 ]       [ 1 ]
     *
     * AX = b, [lb' 0]' <= X <= [ub' inf]'
     */

    // Consider renaming here (control points matrix was transposed in old implementation)
    int rowsC = bspline.getNumVariables() + 1;
    int colsC = bspline.getNumControlPoints();
    int rowsA = rowsC + 1;
    int colsA = rowsC + colsC;

    DenseMatrix I;
    I.setIdentity(rowsC,rowsC);

    DenseMatrix zeros;
    zeros.setZero(1,rowsC);

    DenseMatrix ones;
    ones.setOnes(1,colsC);

    DenseMatrix A(rowsA, colsA);
    A.block(0,     0,     rowsC, rowsC) = I;
    A.block(0,     rowsC, rowsC, colsC) = -bspline.getControlPoints().transpose();
    A.block(rowsC, 0,     1,     rowsC) = zeros;
    A.block(rowsC, rowsC, 1,     colsC) = ones;

    zeros.setZero(rowsC,1);
    ones.setOnes(1,1);

    DenseVector b(rowsA);
    b.block(0,     0, rowsC, 1) = zeros;
    b.block(rowsC, 0, 1,     1) = ones;

    auto auxVariables = variables;

    // Number of auxiliary variables equals number of control points
    for (int i = 0; i < bspline.getNumControlPoints(); i++)
        auxVariables.push_back(std::make_shared<Variable>(0, 0, 1));

    ConstraintPtr relaxedConstraint = std::make_shared<ConstraintLinear>(auxVariables, A ,b, true);
    relaxedConstraint->setName("B-spline convex hull relaxation");

    return relaxedConstraint;
}
Пример #10
0
// -------------------------------------------------------------
// OptimizerImplementation::p_addToGlobalConstraint
// -------------------------------------------------------------
void 
OptimizerImplementation::p_addToGlobalConstraint(const std::string& name, ExpressionPtr expr)
{
  ConstraintPtr c;
  try {
    c = p_globalConstraints.at(name);
  } catch (const std::out_of_range& e) {
    std::string msg("p_addToGlobalConstraint: Global constraint \"");
    msg += name;
    msg += "\" not defined";
    throw gridpack::Exception(msg);
  }
  c->addToLHS(expr);
}  
Пример #11
0
void ParQGHandler::nlCons()
{
  ConstraintPtr c;
  FunctionType fType;
  
  for (ConstraintConstIterator it=minlp_->consBegin(); it!=minlp_->consEnd();
       ++it) {
    c = *it;
    fType = c->getFunctionType();
    if (fType!=Constant && fType!=Linear) {
      nlCons_.push_back(c);
    }
  }
}
Пример #12
0
ConstraintPtr objectiveCut(ConstraintPtr constraints, double objectiveBound, bool upperCut)
{
    auto allVars = constraints->getVariables();

    std::vector<VariablePtr> vars;

    for (auto var : allVars)
    {
        if (var->getCost() != 0)
            vars.push_back(var);
    }

    DenseMatrix A = DenseMatrix::Zero(1, vars.size());

    int i = 0;
    for (auto var : vars)
    {
        if (upperCut)
            A(0,i++) = var->getCost();
        else
            A(0,i++) = -var->getCost();
    }

    DenseVector b(1);
    if (upperCut)
        b(0) = objectiveBound;
    else
        b(0) = -objectiveBound;

    return std::make_shared<ConstraintLinear>(vars, A, b, false);
}
Пример #13
0
void ParQGHandler::addCut_(const double *nlpx, const double *lpx,
                        ConstraintPtr con, CutManager *cutman,
                        SeparationStatus *status)
{
  int error=0;
  ConstraintPtr newcon;
  std::stringstream sstm;
  double c, lpvio, act, cUb;
  FunctionPtr f = con->getFunction();
  LinearFunctionPtr lf = LinearFunctionPtr();

  act = con->getActivity(nlpx, &error);
  if (error == 0) {
    linearAt_(f, act, nlpx, &c, &lf, &error);
    if (error==0) {
      cUb = con->getUb();
      lpvio = std::max(lf->eval(lpx)-cUb+c, 0.0);
      if ((lpvio>solAbsTol_) &&
          ((cUb-c)==0 || (lpvio>fabs(cUb-c)*solRelTol_))) {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << " linearization of constraint "
          << con->getName() << " violated at LP solution with violation = " <<
          lpvio << ". OA cut added." << std::endl;
#endif
        ++(stats_->cuts);
        sstm << "_OAcut_";
        sstm << stats_->cuts;
        *status = SepaResolve;
        f = (FunctionPtr) new Function(lf);
        newcon = rel_->newConstraint(f, -INFINITY, cUb-c, sstm.str());
        CutPtr cut = (CutPtr) new Cut(minlp_->getNumVars(),f, -INFINITY,
                                      cUb-c, false,false);
        cut->setCons(newcon);
        cutman->addCutToPool(cut);
        return;
      }
    }
  }	else {
    logger_->msgStream(LogError) << me_ << "Constraint not defined at"
      << " this point. "<<  std::endl;
#if SPEW
          logger_->msgStream(LogDebug) << me_ << "constraint " <<
            con->getName() << " not defined at this point." << std::endl;
#endif
  }
  return;
}
Пример #14
0
bool UnqualifierSet::refine(const TEnvPtr& tenv, const ConstraintPtr& cst, MonoTypeUnifier* u, Definitions* ds) {
  bool upd = false;
  Unqualifiers::const_iterator uq = this->uqs.find(cst->name());
  if (uq != this->uqs.end()) {
    upd |= uq->second->refine(tenv, cst, u, ds);
  }
  return upd;
}
Пример #15
0
FunDeps UnqualifierSet::dependencies(const ConstraintPtr& cst) const {
  Unqualifiers::const_iterator uq = this->uqs.find(cst->name());
  if (uq == this->uqs.end()) {
    return FunDeps();
  } else {
    return uq->second->dependencies(cst);
  }
}
Пример #16
0
bool UnqualifierSet::satisfiable(const TEnvPtr& tenv, const ConstraintPtr& cst, Definitions* ds) const {
  Unqualifiers::const_iterator uq = this->uqs.find(cst->name());
  if (uq == this->uqs.end()) {
    return false;
  } else {
    return uq->second->satisfiable(tenv, cst, ds);
  }
}
Пример #17
0
// -----------------------------------------------------------------------------------
std::pair<double,double> CBCSolver::constraintBounds(ConstraintPtr& c) {
  double lval, rval;
  switch(c->equalityRelation()) {
  case Constraint::EQ:
    lval = c->rhs(); rval = c->rhs();
    break;
  case Constraint::GTEQ:
    lval = c->rhs(); rval = COIN_DBL_MAX;
  case Constraint::GT: // explicit fall through
    lval += CONSTRAINT_EPS; 
    break;
  case Constraint::LTEQ:
    lval = COIN_DBL_MAX; rval = c->rhs();
  case Constraint::LT: // explicit fall through
    rval -= CONSTRAINT_EPS; 
    break;
  }
  return pair<double,double>(lval,rval);
}
Пример #18
0
void testConvexRelaxations()
{
    DenseMatrix A(1,3);
    A << 1, 2, 3;

    DenseVector b(1);
    b(0) = 1;

    std::vector<VariablePtr> vars =
    {
        std::make_shared<Variable>(1,0,6),
        std::make_shared<Variable>(2,0,4),
        std::make_shared<Variable>(3,0,2)
    };

    ConstraintPtr lincon1 = std::make_shared<ConstraintLinear>(vars, A, b, true);

    A << 3, 2, 1;
    ConstraintPtr lincon2 = std::make_shared<ConstraintLinear>(vars, A, b, true);

    SPLINTER::DataTable data;
    data.addSample(0,0);
    data.addSample(0.5,0.5);
    data.addSample(1,1);

    SPLINTER::BSpline bs(data, SPLINTER::BSplineType::LINEAR);
    auto bsvars = {vars.at(0), vars.at(1)};
    ConstraintPtr bscon = std::make_shared<ConstraintBSpline>(bsvars, bs, true);

    ConstraintSetPtr cs = std::make_shared<ConstraintSet>();
    cs->add(lincon1);
    cs->add(lincon2);
    cs->add(bscon);

    cout << cs->getVariables() << endl;

    cout << "Relaxed" << endl;

    ConstraintPtr csr = cs->getConvexRelaxation();

    cout << csr->getVariables() << endl;
}
Пример #19
0
std::vector<VariablePtr> findBranchingVariables(ConstraintPtr constraints)
{
    std::vector<VariablePtr> bvars = constraints->getComplicatingVariables();

    auto vars = constraints->getVariables();
    for (auto var : vars)
    {
        if (var->getType() == VariableType::BINARY
            || var->getType() == VariableType::INTEGER)
        {
            // Add to bv if not already there
            if (std::find(bvars.begin(), bvars.end(), var) == bvars.end())
            {
                bvars.push_back(var);
            }
        }
    }

    return bvars;
}
Пример #20
0
void Transformer::assignHandler_(CGraphPtr cg, ConstraintPtr c)
{
  switch (cg->getOut()->getOp()) {
  case OpMult:
  case OpSqr:
    qHandler_->addConstraint(c);
    break;
  default:
    {
    VariablePtr iv;
    VariablePtr ov = VariablePtr();
    LinearFunctionPtr lf = c->getFunction()->getLinearFunction();
    if (lf) {
      assert(lf->getNumTerms()==1);
      ov = lf->termsBegin()->first;
    }
    iv = *(c->getFunction()->getNonlinearFunction()->varsBegin());
    uHandler_->addConstraint(c, iv, ov, 'E');
    }
  }
}
Пример #21
0
ConstraintPtr ConstraintBSpline::computeRelaxationHyperrectangle()
{
    /*
     * Hyperrectangle model:
     *
     * X =   [x' y']'
     *
     * A =   [-I ]   b = [-lb ]
     *       [ I ]       [ ub ]
     *
     * AX <= b
     */

    //    cout << "computeRelaxationSimpleBounds" << endl;

    int dim = controlPoints.rows();
    assert(dim == (int)variables.size());

    DenseVector minControlPoints = controlPoints.rowwise().minCoeff();
    DenseVector maxControlPoints = controlPoints.rowwise().maxCoeff();

    DenseMatrix Idim;
    Idim.setIdentity(dim,dim);

    DenseMatrix A(2*dim, dim);
    A.block(0,0, dim, dim) = - Idim;
    A.block(dim,0, dim, dim) = Idim;

    DenseVector b(2*dim);

    b.block(0,0, dim, 1) = - minControlPoints;
    b.block(dim,0, dim, 1) = maxControlPoints;

    ConstraintPtr relaxedConstraint = std::make_shared<ConstraintLinear>(variables, A ,b, false);
    relaxedConstraint->setName("B-spline hypercube relaxation (linear)");

    return relaxedConstraint;
}
Пример #22
0
void Constraints::load (xmlNodePtr _node, bool overwrite)
{
	for (xmlNodePtr cons = _node->children; cons != NULL; cons = cons->next)
	{
		if (cons->type == XML_COMMENT_NODE)
			continue;
	  	ConstraintPtr con;
		Constraints::iterator candidate = find (std::string ((const char *) cons->name));
		// found existing constrain - if commanded to not overwrite, do not overwrite it
		if (candidate != end ())
		{
			if (overwrite == false)
				continue;
			con = candidate->second;
		}
		else 
		{
			Constraint *cp = createConstraint ((const char *) cons->name);
			if (cp == NULL)
				throw XmlUnexpectedNode (cons);
			con = ConstraintPtr (cp);
		}
		try
		{
			con->load (cons);
		}
		catch (XmlError er)
		{
			con.null ();
			throw er;
		}
		if (candidate == end ())
		{
			(*this)[std::string (con->getName ())] = con;
		}
	}
}
Пример #23
0
bool OBBT::doTightening(ConstraintPtr constraints)
{
    // Get convex relaxation
    ConstraintPtr convexConstraints = constraints->getConvexRelaxation();

    assert(convexConstraints != nullptr);
    assert(convexConstraints->isConstraintConvex());

    // Tighten bounds of all complicating variables
    std::vector<VariablePtr> variables;
    for (auto var : constraints->getComplicatingVariables())
    {
        if (assertNear(var->getUpperBound(), var->getLowerBound()))
            continue;

        variables.push_back(var);
    }

    // Check if there are any variables to tighten
    if (variables.size() < 1)
        return true;

    // Tighten bounds
    return tightenBoundsSequential(convexConstraints, variables);
//    bool success = true;

//    if (doParallelComputing)
//    {
//        tightenBoundsParallel(convexConstraints, variables);
//    }
//    else
//    {
//        success = tightenBoundsSequential(convexConstraints, variables);
//    }

//    return success;
}
Пример #24
0
bool ParQGHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr, bool &,
                           double &)
{
  int error=0;
  double act, cUb;
  ConstraintPtr c;
  const double *x = sol->getPrimal();

  for (CCIter it=nlCons_.begin(); it!=nlCons_.end(); ++it) {
    c = *it;
    act = c->getActivity(x, &error);
    if (error == 0) {
      cUb = c->getUb();
      if ((act > cUb + solAbsTol_) &&
          (cUb == 0 || act > cUb + fabs(cUb)*solRelTol_)) {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << "constraint " <<
          c->getName() << " violated with violation = " << act - cUb <<
          std::endl;
#endif
        return false;
      }
    }	else {
      logger_->msgStream(LogError) << me_ << c->getName() <<
        "constraint not defined at this point."<< std::endl;
#if SPEW
      logger_->msgStream(LogDebug) << me_ << "constraint " << c->getName() <<
        " not defined at this point." << std::endl;
#endif
      return false;
    }
  }

  if (oNl_) {
    error = 0;
    relobj_ = x[objVar_->getIndex()];
    act = minlp_->getObjValue(x, &error);
    if (error == 0) {
      if ((act > relobj_ + solAbsTol_) &&
          (relobj_ == 0 || (act > relobj_ + fabs(relobj_)*solRelTol_))) {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << "objective violated with "
          << "violation = " << act - relobj_ << std::endl;
#endif
        return false;
      }
    }	else {
      logger_->msgStream(LogError) << me_
        <<"objective not defined at this point."<< std::endl;
      return false;
    }
  }
  return true;
}
Пример #25
0
bool isIntegerProblem(ConstraintPtr constraints)
{

    auto vars = constraints->getVariables();

    for (unsigned int i = 0; i < vars.size(); i++)
    {
        if (vars.at(i)->getType() == VariableType::BINARY
            || vars.at(i)->getType() == VariableType::INTEGER)
        {
            if (vars.at(i)->getLowerBound() != vars.at(i)->getUpperBound())
                return true;
        }
    }

    return false;
}
Пример #26
0
void ParQGHandler::oaCutToCons_(const double *nlpx, const double *lpx,
                             CutManager *cutman, SeparationStatus *status)
{
  int error=0;
  ConstraintPtr con;
  double nlpact, cUb;

  for (CCIter it = nlCons_.begin(); it != nlCons_.end(); ++it) {
    con = *it;
    nlpact =  con->getActivity(lpx, &error);
    if (error == 0) {
      cUb = con->getUb();
      if ((nlpact > cUb + solAbsTol_) &&
          (cUb == 0 || nlpact > cUb+fabs(cUb)*solRelTol_)) {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << " constraint " <<
          con->getName() << " violated at LP solution with violation = " <<
          nlpact - cUb << std::endl;
#endif
        addCut_(nlpx, lpx, con, cutman, status);
      } else {
#if SPEW
        logger_->msgStream(LogDebug) << me_ << " constraint " << con->getName() <<
          " feasible at LP solution. No OA cut to be added." << std::endl;
#endif
      }
    }	else {
      logger_->msgStream(LogError) << me_ << "Constraint not defined at"
        << " this point. "<<  std::endl;
#if SPEW
          logger_->msgStream(LogDebug) << me_ << "constraint " <<
            con->getName() << " not defined at this point." << std::endl;
#endif
    }
  }
  return;
}
Пример #27
0
void
MultilinearFormulation::makeTermByTerm()
{

  // First we do some processing of the instance to determine how many 
  //  multilinear or quadratic constraints, and we store the indicies
  // in the instance for later    
  vector<int> lcid;
  vector<int> mlcid;
  for(ConstConstraintIterator it = originalInstance_->consBegin(); 
      it != originalInstance_->consEnd(); ++it) {
    FunctionType ft = (*it)->getFunctionType();
    if (ft == Multilinear) {
      mlcid.push_back((*it)->getId());
    }    
    else if (ft == Bilinear) {
      mlcid.push_back((*it)->getId());
    }
    else if (ft == Linear) {
      lcid.push_back((*it)->getId());
    }
  }

  // add x variables
  vector<double> lb;
  vector<double> ub;

  vector<VariablePtr> xvars;
  int nv = 0;
  for (ConstVariableIterator it = originalInstance_->varsBegin(); 
       it != originalInstance_->varsEnd(); ++it) {
    VariablePtr v = *it;
    VariablePtr vnew = VariablePtr(new Variable(nv, v->getLb(), v->getUb(), v->getType()));
    lb.push_back(v->getLb());
    ub.push_back(v->getUb());

    variableMapping_.insert(make_pair(vnew,v));    
    variables_.push_back(vnew);
    xvars.push_back(vnew);
    nv++;
  }

  // Add the linear constraints
  for(int i = 0; i < lcid.size(); i++) {
    const ConstraintPtr mlc = originalInstance_->getConstraint(lcid[i]);
    const LinearFunctionPtr olf = mlc->getLinearFunction();
    LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());
    for(ConstVariableGroupIterator it = olf->varsBegin(); it != olf->varsEnd(); ++it) {
      lf->addTerm(xvars[it->first->getId()], it->second);
    }
    FunctionPtr f = (FunctionPtr) new Function(lf);
    ConstraintPtr c = (ConstraintPtr) new Constraint(f, mlc->getLb(), mlc->getUb());
    constraints_.push_back(c);    

#if defined(DEBUG_TERM_BY_TERM)
      c->display();
#endif

  }


  // The w variables
  vector<VariablePtr> wvars;
  // This holds a map between the 'w' variable added and indices of x vars in multilinear product
  map <VariablePtr, vector<int> > mlterms;

  // Go through multilinear rows.  Add constraints, and create maps
  for(int i = 0; i < mlcid.size(); i++) {

    const ConstraintPtr omlc = originalInstance_->getConstraint(mlcid[i]);
    const LinearFunctionPtr olf = omlc->getLinearFunction();
    const QuadraticFunctionPtr oqf = omlc->getQuadraticFunction();
    const NonlinearFunctionPtr onlf = omlc->getNonlinearFunction();
    //!!! Don't make this shared by boost, it will get confused in counting
    MultilinearFunction *omlf = dynamic_cast<MultilinearFunction *>(onlf.get());
    
    LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());

    // Linear part of constraint remains the same
    for(ConstVariableGroupIterator it = olf->varsBegin(); it != olf->varsEnd(); ++it) {
      lf->addTerm(xvars[it->first->getId()], it->second);
    }

    // Quadratic part gets a new variable for every term
    for(ConstVariablePairGroupIterator it = oqf->begin(); it != oqf->end(); ++it) {

      vector<int> mlix;
      mlix.push_back(it->first.first->getId());
      mlix.push_back(it->first.second->getId());

      VariablePtr w = VariablePtr(new Variable(nv, -INFINITY,INFINITY, Continuous));
      nv++;
      variables_.push_back(w);
      wvars.push_back(w);
      //XXX Need to store term for evaluation
      mlterms.insert(make_pair(w,mlix));
      lf->addTerm(w,it->second);
    }

    // Multilinear part gets a new var for every term
    for(constMultilinearTermContainerIterator it = omlf->termsBegin(); 
        it != omlf->termsEnd(); ++it) {

      vector<int> mlix;
      for(set<ConstVariablePtr>::const_iterator it2 = it->second.begin();
          it2 != it->second.end(); ++it2) {
        mlix.push_back((*it2)->getId());
      }
      
      VariablePtr w = VariablePtr(new Variable(nv, -INFINITY, INFINITY, Continuous));
      nv++;
      variables_.push_back(w);
      wvars.push_back(w);
      mlterms.insert(make_pair(w,mlix));
    
      lf->addTerm(w,it->first);
    }
    FunctionPtr f = (FunctionPtr) new Function(lf);
    ConstraintPtr c = (ConstraintPtr) new Constraint(f, omlc->getLb(), omlc->getUb());
    constraints_.push_back(c); 

#if defined(DEBUG_TERM_BY_TERM)
    c->display();
#endif

  }
  
  // Now add all the constraints for each new bilinear/multilinear term
  for(map<VariablePtr, vector<int> >::iterator it = mlterms.begin();
      it != mlterms.end(); ++it) {

    ConstVariablePtr w = it->first;
    vector<int> &mlix = it->second;

#if defined(DEBUG_TERM_BY_TERM)
    cout << "mlix: ";
    copy(mlix.begin(), mlix.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
#endif

    // Enumerate extreme points
    vector<vector<double> > V;
    vector<VariablePtr> lambdavars;
    allExtreme(mlix, lb, ub, V);

    // Add lambda vars
    for(UInt j = 0; j < V.size(); j++) {
      VariablePtr vnew = VariablePtr(new Variable(nv,0.0,1.0,Continuous));
      variables_.push_back(vnew);
      nv++;
      lambdavars.push_back(vnew);
    }

    // Write x as convex combination of lambda (for each component)
    for(UInt k = 0; k < mlix.size(); k++) {
      LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());
      lf->addTerm(xvars[mlix[k]], -1.0);

      for(UInt j = 0; j < V.size(); j++) {
        lf->addTerm(lambdavars[j], V[j][k]);
      }                
      
      FunctionPtr f = (FunctionPtr) new Function(lf);
      ConstraintPtr c = (ConstraintPtr) new Constraint(f, 0.0, 0.0);
      constraints_.push_back(c);  

#if defined(DEBUG_TERM_BY_TERM)
      c->display();
#endif
    }

    // Write w (term) as convex combination of function values at extreme points
    LinearFunctionPtr wlf = LinearFunctionPtr(new LinearFunction());
    wlf->addTerm(w, -1.0);
    
    for(int j = 0; j < V.size(); j++) {
      // Evaluation at extreme point is just the product
      double product = 1.0;
      for(int k = 0; k < V[j].size(); k++) {
        product *= V[j][k];
      }
      if (product > 1.0e-9 || product < -1.0e-9) {
        wlf->addTerm(lambdavars[j], product);
      }
    }
    FunctionPtr wf = (FunctionPtr) new Function(wlf);
    ConstraintPtr wc = (ConstraintPtr) new Constraint(wf, 0.0, 0.0);
    constraints_.push_back(wc);  

#if defined(DEBUG_TERM_BY_TERM)
    wc->display();
#endif
  
    // Also add sum (lambda) = 1
    LinearFunctionPtr convex_lf =  LinearFunctionPtr(new LinearFunction());
    for(int j = 0; j < V.size(); j++) {
      convex_lf->addTerm(lambdavars[j], 1.0);
    }
    FunctionPtr convex_f = (FunctionPtr) new Function(convex_lf);
    ConstraintPtr convex_c = (ConstraintPtr) new Constraint(convex_f, 1.0, 1.0);
    constraints_.push_back(convex_c);      

#if defined(DEBUG_TERM_BY_TERM)
    convex_c->display();
#endif

  }


  LinearFunctionPtr olf = LinearFunctionPtr(new LinearFunction());
  const LinearFunctionPtr originalInstance_olf = originalInstance_->getObjective()->getLinearFunction();
  for (ConstVariableGroupIterator it = originalInstance_olf->varsBegin(); 
       it != originalInstance_olf->varsEnd(); ++it) {
    olf->addTerm(xvars[it->first->getId()], it->second);    
  }
  FunctionPtr of = (FunctionPtr) new Function(olf);
  objective_ = ObjectivePtr(new Objective(of, 0));    


}
Пример #28
0
bool OBBT::tightenVariableBound(ConstraintPtr cs, VariablePtr variable)
{
    assert(cs->hasVariable(variable));

    auto vars = cs->getVariables();

    // Store and set objective costs to zero
    std::vector<double> costs;

    for (auto var : vars)
    {
        costs.push_back(var->getCost());
    }

    // Set costs for lower bound problem
    for (auto var : vars)
    {
        if (var == variable)
            var->setCost(1); // Min. variable
        else
            var->setCost(0);
    }

    //SolverIpopt solver_min(cs);
    SolverGurobi solver_min(cs);
    SolverResult result_min = solver_min.optimize();

    // Set costs for upper bound problem
    for (auto var : vars)
    {
        if (var == variable)
            var->setCost(-1); // Max. variable
        else
            var->setCost(0);
    }

    //SolverIpopt solver_max(cs);
    SolverGurobi solver_max(cs);
    SolverResult result_max = solver_max.optimize();

    // Reset costs
    int counter = 0;
    for (auto var : vars)
    {
        var->setCost(costs.at(counter));
        counter++;
    }

    // Check for infeasibility
    if (result_min.status == SolverStatus::INFEASIBLE
        || result_max.status == SolverStatus::INFEASIBLE)
        return false;

    // Update lower bound
    if (result_min.status == SolverStatus::OPTIMAL)
    {
        if (!variable->updateLowerBound(result_min.objectiveValue))
        {
            // This should never happen!
            cout << "Min bound" << endl;
            cout << *variable << endl;
            cout << result_min << endl;
            return false;
        }
    }

    // Update upper bound
    if (result_max.status == SolverStatus::OPTIMAL)
    {
        if (!variable->updateUpperBound(-result_max.objectiveValue))
        {
            cout << std::setprecision(10) << -result_max.objectiveValue << endl;
            cout << std::setprecision(10) << variable->getLowerBound() << endl;
            cout << std::setprecision(10) << variable->getLowerBound() + result_max.objectiveValue << endl;
            // This should never happen!
            cout << "Max bound" << endl;
            cout << *variable << endl;
            cout << result_max << endl;
            return false;
        }
    }

    // No update
    return true;
}
Пример #29
0
void
MultilinearFormulation::makeConvexHull()
{
  
  // First we do some processing of the instance to determine how many 
  //  multilinear or quadratic constraints, and we store the indicies
  // in the instance for later    
  vector<int> lcid;
  vector<int> mlcid;
  for(ConstConstraintIterator it = originalInstance_->consBegin(); 
      it != originalInstance_->consEnd(); ++it) {
    FunctionType ft = (*it)->getFunctionType();
    if (ft == Multilinear) {
      mlcid.push_back((*it)->getId());
    }    
    else if (ft == Bilinear) {
      mlcid.push_back((*it)->getId());
    }
    else if (ft == Linear) {
      lcid.push_back((*it)->getId());
    }
  }
    

  // add x variables
  vector<double> lb;
  vector<double> ub;

  vector<VariablePtr> xvars;
  int nv = 0;
  for (ConstVariableIterator it = originalInstance_->varsBegin(); 
       it != originalInstance_->varsEnd(); ++it) {
    VariablePtr v = *it;
    VariablePtr vnew = VariablePtr(new Variable(nv, v->getLb(), v->getUb(), v->getType()));
    lb.push_back(v->getLb());
    ub.push_back(v->getUb());

    variableMapping_.insert(make_pair(vnew,v));    
    variables_.push_back(vnew);
    xvars.push_back(vnew);
    nv++;
  }

  // Add z vars
  vector<VariablePtr> zvars;
  for(UInt i = 0; i < mlcid.size(); i++) {
    const ConstraintPtr mlc = originalInstance_->getConstraint(mlcid[i]);

    VariablePtr vnew = VariablePtr(new Variable(nv,mlc->getLb(),mlc->getUb(),Continuous));
    variables_.push_back(vnew);
    zvars.push_back(vnew);
    nv++;    
  }

  // Enumerate all extreme points
  int origNumVars = originalInstance_->getNumVars();
  vector<int> S(origNumVars);
  for(int i = 0; i < origNumVars; i++) {
    S[i] = i;
  }
  vector<vector<double> > V;
  allExtreme(S, lb, ub, V);

  // Add lambda variables
  vector<VariablePtr> lambdavars;
  for(UInt i = 0; i < V.size(); i++) {
    VariablePtr vnew = VariablePtr(new Variable(nv,0.0,1.0,Continuous));
    variables_.push_back(vnew);
    lambdavars.push_back(vnew);
    nv++;    
  }    

  // Add the original linear constraints (on x)
  for(int i = 0; i < lcid.size(); i++) {
    const ConstraintPtr mlc = originalInstance_->getConstraint(lcid[i]);
    const LinearFunctionPtr olf = mlc->getLinearFunction();
    LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());
    for(ConstVariableGroupIterator it = olf->varsBegin(); it != olf->varsEnd(); ++it) {
      lf->addTerm(xvars[it->first->getId()], it->second);
    }
    FunctionPtr f = (FunctionPtr) new Function(lf);
    ConstraintPtr c = (ConstraintPtr) new Constraint(f, mlc->getLb(), mlc->getUb());
    constraints_.push_back(c);    
#if defined(DEBUG_CONVEX_HULL)
      c->display();
#endif

  }

  // Write x in terms of extreme points
  for(int i = 0; i < origNumVars; i++) {
    LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());
    lf->addTerm(xvars[i], -1.0);
    for(int j = 0; j < V.size(); j++) {
      lf->addTerm(lambdavars[j], V[j][i]);
    }
    //lf->display();
    FunctionPtr f = (FunctionPtr) new Function(lf);
    ConstraintPtr c = (ConstraintPtr) new Constraint(f, 0.0, 0.0);
    constraints_.push_back(c);    
    //XXX Should I set the ID?
#if defined(DEBUG_CONVEX_HULL)
      c->display();
#endif

  }

  // Write z in terms of extreme points
  for(int i = 0; i < mlcid.size(); i++) {
     LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction());
     lf->addTerm(zvars[i], -1.0);
     const ConstraintPtr mlc = originalInstance_->getConstraint(mlcid[i]);
     const FunctionPtr mlf = mlc->getFunction();

     for(int j = 0; j < V.size(); j++) {
       double zval = mlf->eval(V[j]);
       //cout << "zval = " << zval << endl;
       lf->addTerm(lambdavars[j], zval);
     }
     //lf->display();  cout << endl << endl;     
     FunctionPtr f = (FunctionPtr) new Function(lf);
     ConstraintPtr c = (ConstraintPtr) new Constraint(f, 0.0, 0.0);
     constraints_.push_back(c);    
#if defined(DEBUG_CONVEX_HULL)
      c->display();
#endif

  }

  // Add convexity constraint
  LinearFunctionPtr lf =  LinearFunctionPtr(new LinearFunction());
  for(int j = 0; j < V.size(); j++) {
    lf->addTerm(lambdavars[j], 1.0);
  }
  FunctionPtr f = (FunctionPtr) new Function(lf);
  ConstraintPtr c = (ConstraintPtr) new Constraint(f, 1.0, 1.0);
  constraints_.push_back(c);      

#if defined(DEBUG_CONVEX_HULL)
      c->display();
#endif


  LinearFunctionPtr olf = LinearFunctionPtr(new LinearFunction());

  // Add objective (on x vars only)
  const LinearFunctionPtr originalInstance_olf = originalInstance_->getObjective()->getLinearFunction();
  for (ConstVariableGroupIterator it = originalInstance_olf->varsBegin(); 
       it != originalInstance_olf->varsEnd(); ++it) {
    olf->addTerm(xvars[it->first->getId()], it->second);    
  }
  FunctionPtr of = (FunctionPtr) new Function(olf);
  objective_ = ObjectivePtr(new Objective(of, 0));    

}
Пример #30
0
void UnqualifierSet::explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) {
  auto uq = this->uqs.find(cst->name());
  if (uq != this->uqs.end()) {
    uq->second->explain(tenv, cst, e, ds, msgs);
  }
}