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; }
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; }
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; }
// 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()); }
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; } }
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); } }
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; }
// ----------------------------------------------------------------------------------- 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); } } }
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; }
// ------------------------------------------------------------- // 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); }
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); } } }
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); }
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; }
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; }
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); } }
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); } }
// ----------------------------------------------------------------------------------- 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); }
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; }
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; }
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'); } } }
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; }
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; } } }
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; }
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; }
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; }
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; }
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)); }
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; }
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)); }
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); } }