void ParQGHandler::linearizeObj_() { ObjectivePtr o = minlp_->getObjective(); FunctionType fType = o->getFunctionType(); if (!o) { assert(!"need objective in QG!"); } else if (fType != Linear && fType != Constant) { oNl_ = true; FunctionPtr f; VariablePtr vPtr; ObjectiveType objType = o->getObjectiveType(); LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(); for (VariableConstIterator viter=rel_->varsBegin(); viter!=rel_->varsEnd(); ++viter) { vPtr = *viter; if (vPtr->getName() == "eta") { assert(o->getObjectiveType()==Minimize); rel_->removeObjective(); lf->addTerm(vPtr, 1.0); f = (FunctionPtr) new Function(lf); rel_->newObjective(f, 0.0, objType); objVar_ = vPtr; break; } } } return; }
AllocaInsn::AllocaInsn(const VariablePtr& variable, const ValuePtr& size, const ValueList& dimensions) : Insn(IC_Stack, IT_Alloca), size(size), variable(variable), dimensions(dimensions) { assert(variable && "variable must not be null"); assert(variable->getValueType() == Value::VT_Memory && "variable must not be a temporary"); assert(size && "size must not be null"); assert(size->getType()->isInt() && "size must be of type int"); if (analysis::types::isArray(variable->getType())) { auto type = cast<ArrayType>(variable->getType()); assert(type->getNumOfDimensions() == dimensions.size() && "dimension information mismatch with type"); } }
Branches MultilinearTermsHandler::getBranches(BrCandPtr cand, DoubleVector & x, RelaxationPtr, SolutionPoolPtr) { BrVarCandPtr vcand = boost::dynamic_pointer_cast <BrVarCand> (cand); VariablePtr v = vcand->getVar(); double value = x[v->getIndex()]; // can't branch on something that is at its bounds. if (!(value > v->getLb()+1e-8 && value < v->getUb()-1e-8)) { cerr << "Warning! Branching on variable with bounds/value: [" << v->getLb() << " , " << value << " " << v->getUb() << " ]" << endl; //assert(value > v->getLb()+1e-8 && value < v->getUb()-1e-8); } Branches branches = (Branches) new BranchPtrVector(); BranchPtr branch; branch = doBranch_(DownBranch, v, value); branches->push_back(branch); branch = doBranch_(UpBranch, v, value); branches->push_back(branch); logger_->msgStream(LogDebug2) << "branching on " << v->getName(); logger_->msgStream(LogDebug2) << " <= " << value << " or " << " >= " << value << endl; #if defined(DEBUG_MULTILINEARTERMS_HANDLER) cout << "branching on " << v->getName(); cout << " <= " << value << " or " << " >= " << value << endl; #endif return branches; }
SecantMod::SecantMod(ConstraintPtr con, LinearFunctionPtr new_lf, double new_rhs, VariablePtr x, BoundType lu, double new_b, VariablePtr y) { double y_lb, y_ub, b2; if (lu==Lower) { b2 = x->getUb(); BoundsOnSquare(new_b, b2, y_lb, y_ub); } else { b2 = x->getLb(); BoundsOnSquare(b2, new_b, y_lb, y_ub); } ymod_ = (VarBoundMod2Ptr) new VarBoundMod2(y, y_lb, y_ub); xmod_ = (VarBoundModPtr) new VarBoundMod(x, lu, new_b); lmod_ = (LinConModPtr) new LinConMod(con, new_lf, -INFINITY, new_rhs); }
bool SOS1Handler::isGUB(SOS *sos) { VariablePtr var; int nz = sos->getNz(); ConstConstraintPtr c; FunctionPtr f; LinearFunctionPtr lf; bool isgub = false; for (VariableConstIterator viter = sos->varsBegin(); viter!=sos->varsEnd(); ++viter) { var = *viter; if (Binary!=var->getType() || ImplBin!=var->getType()) { return false; } } // If we are here, then it means all variables are binary. Check if their sum // is <= 1. var = *(sos->varsBegin()); for (ConstrSet::iterator it=var->consBegin(); it!=var->consEnd() && false==isgub; ++it) { c = *it; f = c->getFunction(); isgub = true; if (Linear!=f->getType()) { isgub = false; } else if ((UInt) nz==f->getNumVars()) { isgub = false; } else if (fabs(c->getUb()-1.0)>zTol_) { isgub = false; } else { lf = f->getLinearFunction(); for (VariableConstIterator viter = sos->varsBegin(); viter!=sos->varsEnd(); ++viter) { if ((lf->getWeight(*viter)-1.0)>zTol_) { isgub = false; break; } } } } return isgub; }
void Sgd<T>::update_impl(const string &key, VariablePtr param) { Size_t size = param->size(); const T *grad = param->get_grad_pointer<T>(this->ctx_); T *data = param->cast_data_and_get_pointer<T>(this->ctx_); std::transform(grad, grad + size, data, data, [this](T g, T x) { return x - lr_ * g; }); }
void ParQGHandler::fixInts_(const double *x) { double xval; VariablePtr v; VarBoundMod2 *m = 0; for (VariableConstIterator vit=minlp_->varsBegin(); vit!=minlp_->varsEnd(); ++vit) { v = *vit; if (v->getType()==Binary || v->getType()==Integer) { xval = x[v->getIndex()]; xval = floor(xval + 0.5); m = new VarBoundMod2(v, xval, xval); m->applyToProblem(minlp_); nlpMods_.push(m); } } return; }
void LinFeasPump::constructObj_(ProblemPtr, ConstSolutionPtr) { double value, lb, ub; VariablePtr variable; UInt i; //double obj_relaxation; double obj_weight; double constant; FunctionPtr f; LinearFunctionPtr olf_mod; //obj_relaxation = sol->getPrimal()[r_->getNumVars()-1]; obj_weight = 0; //std::min(1/(fabs(obj_relaxation)+1e-7), 0.1); obj_weight = 0.0; i = 0; constant = 0; olf_mod = olfClone_->clone(); (*olf_mod) *= obj_weight; for (VariableConstIterator v_iter=r_->varsBegin(); v_iter!=r_->varsEnd(); ++v_iter, ++i) { variable = *v_iter; if (variable->getType() == Binary) { value = roundedSol_[i]; lb = variable->getLb(); ub = variable->getUb(); if (fabs(value - lb) > intTol_) { olf_mod->addTerm(variable,-1.0); constant += ub; } else if (fabs(value - ub) > intTol_) { olf_mod->addTerm(variable,1.0); constant -= lb; } else { // add a new variable with coeff 1 // add two constraints for absolute value } } } f = (FunctionPtr) new Function(olf_mod); r_->changeObj(f, constant); }
void ParQGHandler::setObjVar() { ObjectivePtr o = minlp_->getObjective(); FunctionType fType = o->getFunctionType(); if (!o) { assert(!"need objective in QG!"); } else if (fType != Linear && fType != Constant) { oNl_ = true; VariablePtr vPtr; for (VariableConstIterator viter=rel_->varsBegin(); viter!=rel_->varsEnd(); ++viter) { vPtr = *viter; if (vPtr->getName() == "eta") { assert(o->getObjectiveType()==Minimize); objVar_ = vPtr; break; } } } return; }
int VariableLuaMetaData::Index(lua_State * L, const VariablePtr var, const std::string & index) { ///*if (index == "Const") //{ // lua_pushboolean(L, var->GetType()->IsConst() ? 1 : 0); // return 1; //} //else if (index == "ConstPointer") //{ // lua_pushboolean(L, var->GetType()->IsConstPointer() ? 1 : 0); // return 1; //} //else if (index == "Pointer") //{ // lua_pushboolean(L, var->GetType()->IsPointer() ? 1 : 0); // return 1; //} //else if (index == "Reference") //{ // lua_pushboolean(L, var->GetType()->IsReference() ? 1 : 0); // return 1; //} //else if (index == "TypeNode") //{ // Model::NodeLuaMetaData::PutInstanceOnStack(L, var->GetType()->GetNode()); // return 1; //}*/ if (index == "Initializer") { lua_pushstring(L, var->GetInitializer().c_str()); return 1; } else if (index == "Type") { Model::TypeLuaMetaData::PutInstanceOnStack(L, var->GetType()); return 1; } return 0; }
// ----------------------------------------------------------------------------------- void CBCSolver::setUpVariablesAndObj(std::vector<VariablePtr>& variables, ObjFuncPtr& obj) { for (int i = 0; i < variables.size(); i++) { VariablePtr v = variables.at(i); switch(v->type()) { case Variable::INT: builder_.setColumnBounds(i,intBound(v->lbound()),intBound(v->ubound())); builder_.setInteger(i); break; case Variable::LINEAR: builder_.setColumnBounds(i,doubleBound(v->lbound()),doubleBound(v->ubound())); break; } builder_.setObjective(i,obj->getModifier(v)); } }
// Implement Handler::getBranches(). Branches CxUnivarHandler::getBranches(BrCandPtr cand, DoubleVector &x, RelaxationPtr , SolutionPoolPtr ) { double minFromBds = 0.1; BrVarCandPtr vcand = boost::dynamic_pointer_cast <BrVarCand> (cand); VariablePtr v = vcand->getVar(); double xval = x[v->getIndex()]; double value = xval; // Make sure branch value is not too close to an end point double len = v->getUb() - v->getLb(); if (value < v->getLb() + minFromBds*len) { value = v->getLb() + minFromBds*len; } else if (value > v->getUb() - minFromBds*len) { value = v->getUb() - minFromBds*len; } // can't branch on something that is at its bounds. if (!(value > v->getLb()+1e-8 && value < v->getUb()-1e-8)) { std::cerr << "Warning! Branching on variable with bounds/value: [" << v->getLb() << " , " << value << " " << v->getUb() << " ]" << std::endl; //assert(value > v->getLb()+1e-8 && value < v->getUb()-1e-8); } Branches branches = (Branches) new BranchPtrVector(); BranchPtr branch = (BranchPtr) new Branch(); VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Upper, value); assert(!"add Mod correctly here."); branch->addPMod(mod); branch->setActivity((v->getUb()-value)/len); branches->push_back(branch); branch = (BranchPtr) new Branch(); mod = (VarBoundModPtr) new VarBoundMod(v, Lower, value); assert(!"add Mod correctly here."); branch->addPMod(mod); branch->setActivity((value - v->getLb())/len); branches->push_back(branch); logger_->msgStream(LogDebug2) << "branching on " << v->getName(); logger_->msgStream(LogDebug2) << " <= " << value << " or " << " >= " << value << std::endl; #if defined(DEBUG_CXUNIVARHANDLER) std::cout << "branching on " << v->getName(); std::cout << " <= " << value << " or " << " >= " << value << std::endl; #endif return branches; }
// Implement Handler::getBrMod(). ModificationPtr CxUnivarHandler::getBrMod(BrCandPtr cand, DoubleVector &x, RelaxationPtr , BranchDirection brdir) { // This method is used in Reliability branching. //XXX If you want it to be more accurate, you should add the new secant and linearizations // into lmods. LinModsPtr lmods; lmods = (LinModsPtr) new LinMods(); double minFromBds = 0.1; BrVarCandPtr vcand = boost::dynamic_pointer_cast <BrVarCand> (cand); VariablePtr v = vcand->getVar(); #if defined(DEBUG_CXUNIVARHANDLER) std::cout << "Branching mod candidate (working problem) ID: " << v->getId() << " address: " << ( v.get() ) << std::endl; #endif // x is a *relaxation* solution, while we have put the *original* (or // working) problem variables into the BrCandPtr, so we need to // update our value appropriately... double xval = x[v->getIndex()]; double value = xval; // Make sure branch value is not too close to an end point double len = v->getUb() - v->getLb(); if (value < v->getLb() + minFromBds*len) { value = v->getLb() + minFromBds*len; } else if (value > v->getUb() - minFromBds*len) { value = v->getUb() - minFromBds*len; } // can't branch on something that is at its bounds. if (!(value > v->getLb()+1e-8 && value < v->getUb()-1e-8)) { std::cerr << "Warning! Branching on variable with bounds/value: [" << v->getLb() << " , " << value << " " << v->getUb() << " ]" << std::endl; //assert(value > v->getLb()+1e-8 && value < v->getUb()-1e-8); } if (brdir == DownBranch) { // down branch VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Upper, value); lmods->insert(mod); } else if (brdir == UpBranch) { // up branch VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Lower, value); lmods->insert(mod); } return lmods; }
bool IpoptEngine::presolve_() { bool should_stop = false; VariablePtr v; double diff; bool all_fixed = true; int e=0; status_ = EngineUnknownStatus; // visit each variable and check bounds. Stop if bad bounds are found or if // all variables are fixed. for (VariableConstIterator it=problem_->varsBegin(); it!=problem_->varsEnd(); ++it) { v = *it; diff = v->getUb() - v->getLb(); if (diff < -etol_) { status_ = ProvenLocalInfeasible; return true; } if (fabs(diff)>etol_) { all_fixed = false; } } if (all_fixed == true) { double obj_value; double *x; double vio = -INFINITY; double act; x = new double[problem_->getNumVars()]; should_stop = true; for (VariableConstIterator it=problem_->varsBegin(); it!=problem_->varsEnd(); ++it) { v = *it; x[v->getIndex()] = v->getUb(); } obj_value = problem_->getObjValue(x, &e); // check if constraints are violated. for (ConstraintConstIterator it=problem_->consBegin(); it!=problem_->consEnd(); ++it) { act = (*it)->getActivity(x, &e); vio = std::max(act-(*it)->getUb(), (*it)->getLb()-act); vio = std::max(vio, 0.); if (vio>etol_ || e!=0) { break; } } // sol_ must be set even if the problem is infeasible because QG handler // may need this point for cut generation etc. sol_->setPrimal(x); if (vio>etol_) { status_ = ProvenLocalInfeasible; } else { sol_->setObjValue(obj_value); mynlp_->setSolution(sol_); status_ = ProvenLocalOptimal; } delete [] x; } return should_stop; }
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)); }
void MultilinearFormulation::makeRowByRow() { // First we do some processing of the instance to determine how many // multilinear or quadratic constraints, and we store the indicies // 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); } vector<VariablePtr> zvars; vector<vector< VariablePtr> > lambdavars(mlcid.size()); for(UInt i = 0; i < mlcid.size(); i++) { // One 'z' var per row VariablePtr zvar = VariablePtr(new Variable(nv, -INFINITY, INFINITY, Continuous)); variables_.push_back(zvar); zvars.push_back(zvar); nv++; // Determine what variables appear nonlinearly... const ConstraintPtr mlc = originalInstance_->getConstraint(mlcid[i]); vector<int> nlvars = nonlinearVarsInConstraint(mlc); #if defined(DEBUG_ROW_BY_ROW) cout << "Vars in ml constraint " << i << " have ix: "; for(vector<int>::iterator it = nlvars.begin(); it != nlvars.end(); ++it) { cout << (*it) << " "; } cout << endl; #endif // Add lambda vars for this row vector<vector<double> > V; allExtreme(nlvars, lb, ub, V); for(UInt j = 0; j < V.size(); j++) { VariablePtr vnew = VariablePtr(new Variable(nv,0.0,1.0,Continuous)); variables_.push_back(vnew); lambdavars[i].push_back(vnew); nv++; } for(UInt k = 0; k < nlvars.size(); k++) { // Create 'x' portion of this constraint LinearFunctionPtr lf = LinearFunctionPtr(new LinearFunction()); lf->addTerm(xvars[nlvars[k]], -1.0); for(UInt j = 0; j < V.size(); j++) { lf->addTerm(lambdavars[i][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_ROW_BY_ROW) c->display(); #endif } // Now add the 'z' var definition LinearFunctionPtr tlf = LinearFunctionPtr(new LinearFunction()); tlf->addTerm(zvar, -1.0); const FunctionPtr mlf = mlc->getFunction(); const LinearFunctionPtr mlf_lf = mlf->getLinearFunction(); for(int j = 0; j < V.size(); j++) { //XXX Kludgy, but just create a vector for the (full) point int onv = originalInstance_->getNumVars(); vector<double> xe(onv,0.0); for(UInt k = 0; k < nlvars.size(); k++) { xe[nlvars[k]] = V[j][k]; } double zval = mlf->eval(xe); // Need to subtract off linear part, since yuo keep those variables in zval -= mlf_lf->eval(xe); tlf->addTerm(lambdavars[i][j], zval); } FunctionPtr tf = (FunctionPtr) new Function(tlf); ConstraintPtr tc = (ConstraintPtr) new Constraint(tf, 0.0, 0.0); constraints_.push_back(tc); #if defined(DEBUG_ROW_BY_ROW) tc->display(); #endif // Now add the linear constraint involving linear x and t LinearFunctionPtr xtlf = LinearFunctionPtr(new LinearFunction()); for(ConstVariableGroupIterator it = mlf_lf->varsBegin(); it != mlf_lf->varsEnd(); ++it) { xtlf->addTerm(xvars[it->first->getId()], it->second); } xtlf->addTerm(zvar,1.0); FunctionPtr xtf = (FunctionPtr) new Function(xtlf); ConstraintPtr xtc = (ConstraintPtr) new Constraint(xtf, mlc->getLb(), mlc->getUb()); constraints_.push_back(xtc); #if defined(DEBUG_ROW_BY_ROW) xtc->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[i][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_ROW_BY_ROW) 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)); }
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; }
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; }
ExpressionPtr KernelReplacer::createKernelCallLambda(const ExpressionAddress localKernel, const ExpressionPtr work_dim, const ExpressionPtr local_work_size, const ExpressionPtr global_work_size) { NodeManager& mgr = prog->getNodeManager(); IRBuilder builder(mgr); ExpressionPtr k = utils::getRootVariable(localKernel).as<ExpressionPtr>(); /* std::cout << "searching " << *k << " from " << *localKernel << std::endl; if(kernelFunctions.empty()) std::cout << "\tnothing\n"; for_each(kernelFunctions, [](std::pair<core::ExpressionPtr, core::LambdaExprPtr> kernel) { std::cout << "in " << *kernel.first << std::endl; }); */ // try to find coresponding kernel function assert(kernelFunctions.find(k) != kernelFunctions.end() && "Cannot find OpenCL Kernel"); const ExpressionPtr local = anythingToVec3(work_dim, local_work_size); const ExpressionPtr global = anythingToVec3(work_dim, global_work_size); LambdaExprPtr lambda = kernelFunctions[k].as<LambdaExprPtr>(); //dumpPretty(lambda); //for_each(kernelTypes[k], [&](TypePtr ty) { // std::cout << "->\t" << *ty << std::endl; //}); /* assert(kernelArgs.find(k) != kernelArgs.end() && "No arguments for call to kernel function found"); const VariablePtr& args = kernelArgs[k]; const TupleTypePtr& argTypes = dynamic_pointer_cast<const TupleType>(args->getType());*/ const VariableList& interface = lambda->getParameterList()->getElements(); vector<ExpressionPtr> innerArgs; const core::lang::BasicGenerator& gen = builder.getLangBasic(); // construct call to kernel function // if(localMemDecls.find(k) == localMemDecls.end() || localMemDecls[k].size() == 0) { //std::cout << "lmd " << localMemDecls[k] << std::endl; TypeList kernelType = kernelTypes[k]; /* body of a newly created function which replaces clNDRangeKernel. It contains * the kernel call * return 0; */ StatementList body; // Kernel variable to be used inside the newly created function VariablePtr innerKernel = builder.variable(builder.tupleType(kernelType)); for(size_t i = 0; i < interface.size() -2 /*argTypes->getElementTypes().size()*/; ++i) { //?? TypePtr argTy = utils::vectorArrayTypeToScalarArrayType(interface.at(i)->getType(), builder); TypePtr argTy = interface.at(i)->getType(); TypePtr memberTy = kernelType.at(i); ExpressionPtr tupleMemberAccess = builder.callExpr(memberTy, gen.getTupleMemberAccess(), utils::removeDoubleRef(innerKernel), builder.literal(gen.getUInt8(), toString(i)), builder.getTypeLiteral(memberTy)); ExpressionPtr argument = handleArgument(argTy, memberTy, tupleMemberAccess, body); innerArgs.push_back(argument); } const TypePtr vecTy = builder.vectorType(gen.getUInt8(), builder.concreteIntTypeParam(static_cast<size_t>(3))); // local and global size to be used inside the newly created function VariablePtr innerGlobal = builder.variable(vecTy); VariablePtr innerLocal = builder.variable(vecTy); // add global and local size to arguments innerArgs.push_back(innerGlobal); innerArgs.push_back(innerLocal); ExpressionPtr kernelCall = builder.callExpr(gen.getInt4(), lambda, innerArgs); body.push_back(kernelCall); // calling the kernel function body.push_back(builder.returnStmt(builder.intLit(0))); // return CL_SUCCESS // create function type for inner function: kernel tuple, global size, local size TypeList innerFctInterface; innerFctInterface.push_back(innerKernel->getType()); innerFctInterface.push_back(vecTy); innerFctInterface.push_back(vecTy); FunctionTypePtr innerFctTy = builder.functionType(innerFctInterface, gen.getInt4()); // collect inner function parameters VariableList innerFctParams; innerFctParams.push_back(innerKernel); innerFctParams.push_back(innerGlobal); innerFctParams.push_back(innerLocal); // create lambda for inner function LambdaExprPtr innerLambda = builder.lambdaExpr(innerFctTy, builder.parameters(innerFctParams), builder.compoundStmt(body)); return builder.callExpr(gen.getInt4(), innerLambda, builder.deref(localKernel), global, local); }
void ArrayType::setSize(const VariablePtr& size) { if(size) assert_pred1(size->getNodeManager().getLangBasic().isUIntInf, size->getType()); this->size = size; }
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)); }
Bool logobj(LinearFunctionPtr lf, CGraphPtr nlf) { UInt numvars = lf->getNumTerms(); // VariableSet vars; // lf->getVars(&vars); VariableGroup::const_iterator it; VariableGroup::const_iterator begin = lf->termsBegin(); VariableGroup::const_iterator end = lf->termsEnd(); // Variable nodes. std::map<UInt,CNode*> varnodes; std::map<CNode*, CNode*> lognodes; std::map<UInt, CNode*> logidnodes; std::map<CNode*, CNode*> numnodes; std::map<UInt, CNode*> numidnodes; std::map<CNode*, CNode*> mulnodes; std::map<UInt, CNode*> mulidnodes; std::set<CNode*> multnodes; std::map<UInt, CNode*> multidnodes; CNode** multnodesvec = new CNode*[numvars]; // Iterate through variables. CNode* tempnode; CNode* lognode; CNode* numnode; CNode* mulnode; CNode* onenode; CNode* sumnode; // Create numnode for one. UInt index = 0; for(it=begin; it!=end; ++it) { VariablePtr var = it->first; Double varlb = var->getLb(); if (varlb >= 0) { UInt varid = var->getId(); Double coeff = it->second; // Create variable node and add it to a set. tempnode = nlf->newNode(var); varnodes.insert(std::pair<UInt,CNode*>(varid,tempnode)); onenode = nlf->newNode(1.0); // Create sumnode. sumnode = nlf->newNode(OpPlus, onenode, tempnode); // Create log nodes. lognode = nlf->newNode(OpLog, &sumnode, 1); lognodes.insert(std::pair<CNode* , CNode*>(tempnode, lognode)); logidnodes.insert(std::pair<UInt, CNode*>(varid, lognode)); // Create num nodes. numnode = nlf->newNode(coeff); numnodes.insert(std::pair<CNode*, CNode*>(tempnode, numnode)); numidnodes.insert(std::pair<UInt, CNode*>(varid, numnode)); // Create mul nodes. mulnode = nlf->newNode(OpMult, numnode, lognode); multnodes.insert(mulnode); multidnodes.insert(std::pair<UInt, CNode*>(varid,mulnode)); multnodesvec[index] = mulnode; index++; } } // This is the root node. CNode* sumlistnode = nlf->newNode(OpSumList, multnodesvec, index); nlf->setOut(sumlistnode); nlf->finalize(); return true; }
ModificationPtr MultilinearTermsHandler::getBrMod(BrCandPtr cand, DoubleVector &xval, RelaxationPtr , BranchDirection dir) { LinModsPtr linmods; //XXX Put (bool init) back in handle{x,z}def... BrVarCandPtr vcand = boost::dynamic_pointer_cast <BrVarCand> (cand); VariablePtr v = vcand->getVar(); double branching_value = xval[v->getIndex()]; BoundType lu; VariableType vtype = v->getType(); // Change bounds on the x var (called v here) if (dir == DownBranch) { lu = Upper; if (vtype != Continuous) branching_value = floor(branching_value); } else { lu = Lower; if (vtype != Continuous) branching_value = ceil(branching_value); } linmods = (LinModsPtr) new LinMods(); VarBoundModPtr vmod = (VarBoundModPtr) new VarBoundMod(v, lu, branching_value); linmods->insert(vmod); // This chunk of code changes the // x_{V_g} = \sum_{k=1}^{2 |V_g|} \lambda_k^g \chi^{k,g} \forall g \in G for (UInt gix = 0; gix < groups_.size(); ++gix) { for(SetOfVars::const_iterator it = groups_[gix].begin(); it != groups_[gix].end(); ++it) { ConstVariablePtr xvar = *it; if (v != xvar) continue; LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(); lf->addTerm(xvar, -1.0); UInt pix = 0; for (std::set<SetOfVars>::iterator it2 = points_[gix].begin(); it2 != points_[gix].end(); ++it2) { VariablePtr lam = lambdavars_[gix][pix]; double val = -INFINITY; bool atLower = varIsAtLowerBoundAtPoint_(v, *it2); bool atUpper = !atLower; if (lu == Upper && atUpper) val = branching_value; else if (lu == Lower && atLower) val = branching_value; else val = (atLower ? v->getLb() : v->getUb()); lf->addTerm(lam, val); ++pix; } FunctionPtr f = (FunctionPtr) new Function(lf); IntVarPtrPairConstraintMap::iterator pos; pos = xConMap_.find(IntVarPtrPair(gix, xvar)); if (pos == xConMap_.end()) { assert(0); } ConstraintPtr c = pos->second; LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "getBrMod(). Will change 'x =' constraint to have linear function "; lf->write(std::cout); std::cout << std::endl; #endif linmods->insert(lcmod); } } // This will change the z_t = sum \sum_{k=1}^{2|V_g} \lambda_k^g \chi^{k,g}. // Probably not very efficient way to do this... for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) { SetOfVars const &jt = it->second; for (UInt gix = 0; gix < groups_.size(); ++gix) { SetOfVars &vg = groups_[gix]; std::set<ConstVariablePtr>::iterator pos1; pos1 = jt.find(v); if (pos1 == jt.end()) continue; // J_t does not contain v, go to next group // J_t is not in V_g, go to next group if (! std::includes(vg.begin(), vg.end(), jt.begin(), jt.end())) continue; ConstVariablePtr zvar = it->first; LinearFunctionPtr lf = (LinearFunctionPtr) new LinearFunction(); lf->addTerm(zvar, -1.0); // Get ConstraintToChange IntVarPtrPairConstraintMap::iterator pos2; pos2 = zConMap_.find(IntVarPtrPair(gix, zvar)); if (pos2 == zConMap_.end()) { assert(0); } ConstraintPtr c = pos2->second; UInt 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]; // Compute new extreme point value for this lambda for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) { ConstVariablePtr xvar = *jt_it; double val = 0.0; bool atLower = varIsAtLowerBoundAtPoint_(xvar, *it2); bool atUpper = !atLower; if (xvar == v) { if (lu == Upper && atUpper) val = branching_value; else if (lu == Lower && atLower) val = branching_value; else val = (atLower ? xvar->getLb() : xvar->getUb()); } else { val = atLower ? xvar->getLb() : xvar->getUb(); } prodval *= val; } lf->addTerm(lam, prodval); ++pix; } // Add new mod LinConModPtr lcmod = (LinConModPtr) new LinConMod(c, lf, 0.0, 0.0); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "getBrMod(): Will change 'zt = ' constraint to have linear function: "; lf->write(std::cout); std::cout << std::endl; #endif linmods->insert(lcmod); } } return linmods; return ModificationPtr(); }
void POP03::runProblem() { // Problem 3 (Nataraj) // cout << "\n\nSolving problem P03..." << endl; int dim = 4; // x1,x2,l1,l2 std::vector<double> costs = {1, 0, 0, 0}; std::vector<double> lb = {-10,-10,0,-1000}; std::vector<double> ub = {10,10,100,1000}; std::vector<double> z0(dim,0); std::vector<VariablePtr> vars; for (int i = 0; i < dim; i++) { auto var = std::make_shared<Variable>(costs.at(i), lb.at(i), ub.at(i)); vars.push_back(var); } ConstraintSetPtr cs = std::make_shared<ConstraintSet>(); { // x1^2 = l1 VariablePtr var = vars.at(0); std::vector<double> thislb = {var->getLowerBound()}; std::vector<double> thisub = {var->getUpperBound()}; std::vector<unsigned int> deg = {2}; DenseVector c(3); c.setZero(); c(0) = 0; c(1) = 0; c(2) = 1; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs.transpose(), knots, deg); std::vector<VariablePtr> cvars = {var, vars.at(2)}; ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // x1^3 = l1 VariablePtr var = vars.at(0); std::vector<double> thislb = {var->getLowerBound()}; std::vector<double> thisub = {var->getUpperBound()}; std::vector<unsigned int> deg = {3}; DenseVector c(4); c.setZero(); c(0) = 0; c(1) = 0; c(2) = 0; c(3) = 1; DenseMatrix T = getTransformationMatrix(deg, thislb, thisub); DenseMatrix coeffs = T*c; std::vector< std::vector<double> > knots = getRegularKnotVectors(deg, thislb, thisub); BSpline bs(coeffs.transpose(), knots, deg); std::vector<VariablePtr> cvars = {var, vars.at(3)}; ConstraintPtr cbs = std::make_shared<ConstraintBSpline>(cvars, bs, true); cs->add(cbs); } { // x2 - l1 <= 0, x2 - l2 <= 0 DenseMatrix A(2,3); A.setZero(); A(0,0) = -1; A(0,1) = 1; A(1,0) = 1; A(1,1) = 2; A(1,2) = -1; DenseVector b; b.setZero(2); b(1) = -1e-5; std::vector<VariablePtr> cvars = { vars.at(1), vars.at(2), vars.at(3) }; ConstraintPtr lincon = std::make_shared<ConstraintLinear>(cvars, A, b, false); cs->add(lincon); } BB::BranchAndBound bnb(cs); Timer timer; timer.start(); SolverResult res = bnb.optimize(); timer.stop(); cout << "Time: " << timer.getMilliSeconds() << " (ms)" << endl; if (res.status == SolverStatus::OPTIMAL) fopt_found = res.objectiveValue; }
AllocaInsnPtr NodeManager::buildAlloca(const VariablePtr& variable, const ValuePtr& size, const ValueList& dimensions) { auto alloca = std::make_shared<AllocaInsn>(variable, size, dimensions); variable->setParent(alloca); return alloca; }
void MultilinearTermsHandler::weightedDegreeHeuristic_() { // Cover all terms at least once bool positiveWeight = false; do { VariablePtr heavyVar = H_->maxWeightedDegreeVertex(positiveWeight); if (positiveWeight) { assert(heavyVar != 0); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Heaviest vertex is: "; heavyVar->write(std::cout); #endif Hypergraph::ListOfSetOfVars edges = H_->incidentEdges(heavyVar); for(Hypergraph::ListOfSetOfVars::const_iterator e_it = edges.begin(); e_it != edges.end(); ++e_it) { const SetOfVars &e = *e_it; double we = H_->getWeight(e); if (we <= 0.0) continue; // If weight is not positive, we skip the edge addEdgeToGroups_(e, true); // Remove edge from H by setting weight to 0 H_->setWeight(e, 0.0); } } } while(positiveWeight); initialTermCoverSize_ = groups_.size(); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Initial term cover has size: " << groups_.size() << std::endl; #endif // Do the second phase H_->resetWeights(); UInt final_cover_size = (UInt) (augmentCoverFactor_ * initialTermCoverSize_); while(groups_.size() <= final_cover_size) { VariablePtr heavyVar = H_->maxWeightedDegreeVertex(positiveWeight); if (positiveWeight) { assert(heavyVar != 0); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Heaviest vertex is: "; heavyVar->write(std::cout); #endif Hypergraph::ListOfSetOfVars edges = H_->incidentEdges(heavyVar); for(Hypergraph::ListOfSetOfVars::const_iterator e_it = edges.begin(); e_it != edges.end(); ++e_it) { const SetOfVars &e = *e_it; double we = H_->getWeight(e); if (we <= 0.0) continue; // If weight is not positive, we skip the edge addEdgeToGroups_(e, false); H_->setWeight(e, we/2.0); } } #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Size of groups is now: " << groups_.size() << std::endl; #endif } }
void MultilinearFormulation::makeMcCormick() { // 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); } // The w variables vector<VariablePtr> wvars; // The z vars: These are what you put in the objective vector<ConstVariablePtr> zvars; // The bilinear terms map <VariablePtr, ConstVariablePair> blterms; // Go through multilinear rows. Add constraints, and create maps // for mccormick vars 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) { ConstVariablePtr x1 = it->first.first; ConstVariablePtr x2 = it->first.second; //Bounds on product depend on whether variable bounds are < 0, > 0 double lb = 0.0; double ub = 0.0; boundsOnProduct(x1,x2,lb,ub); VariablePtr w = VariablePtr(new Variable(nv, lb, ub, Continuous)); nv++; variables_.push_back(w); wvars.push_back(w); blterms.insert(make_pair(w,ConstVariablePair(x1,x2))); lf->addTerm(w,it->second); } // Multilinear part gets d-1 new vars. // We do mccormick (for now) in the FIFO way for(constMultilinearTermContainerIterator it = omlf->termsBegin(); it != omlf->termsEnd(); ++it) { set<ConstVariablePtr>::const_iterator it2 = it->second.begin(); ConstVariablePtr x1 = *it2; ++it2; for( ; it2 != it->second.end(); ++it2) { ConstVariablePtr x2 = *it2; double lb = 0.0; double ub = 0.0; boundsOnProduct(x1,x2,lb,ub); VariablePtr w = VariablePtr(new Variable(nv, lb, ub, Continuous)); nv++; variables_.push_back(w); wvars.push_back(w); blterms.insert(make_pair(w,ConstVariablePair(x1,x2))); x1 = w; } // Now x1 is the var you should add to the linear constraint lf->addTerm(x1,it->first); zvars.push_back(x1); } FunctionPtr f = (FunctionPtr) new Function(lf); ConstraintPtr c = (ConstraintPtr) new Constraint(f, omlc->getLb(), omlc->getUb()); constraints_.push_back(c); } // Now add all the constraints for each new bilinear term for(map<VariablePtr, ConstVariablePair>::iterator it = blterms.begin(); it != blterms.end(); ++it) { ConstVariablePtr w = it->first; ConstVariablePtr x1 = it->second.first; ConstVariablePtr x2 = it->second.second; LinearFunctionPtr lf1 = LinearFunctionPtr(new LinearFunction()); LinearFunctionPtr lf2 = LinearFunctionPtr(new LinearFunction()); LinearFunctionPtr lfw = LinearFunctionPtr(new LinearFunction()); // Create new lambda variables VariablePtr lamll = VariablePtr(new Variable(nv, 0.0, 1.0, Continuous)); nv++; variables_.push_back(lamll); VariablePtr lamul = VariablePtr(new Variable(nv, 0.0, 1.0, Continuous)); nv++; variables_.push_back(lamul); VariablePtr lamuu = VariablePtr(new Variable(nv, 0.0, 1.0, Continuous)); nv++; variables_.push_back(lamuu); VariablePtr lamlu = VariablePtr(new Variable(nv, 0.0, 1.0, Continuous)); nv++; variables_.push_back(lamlu); // Just enumerate extreme points yourself lf1->addTerm(x1,-1.0); lf1->addTerm(lamll, x1->getLb()); lf1->addTerm(lamul, x1->getUb()); lf1->addTerm(lamuu, x1->getUb()); lf1->addTerm(lamlu, x1->getLb()); // Just enumerate extreme points yourself lf2->addTerm(x2,-1.0); lf2->addTerm(lamll, x2->getLb()); lf2->addTerm(lamul, x2->getLb()); lf2->addTerm(lamuu, x2->getUb()); lf2->addTerm(lamlu, x2->getUb()); lfw->addTerm(w, -1.0); lfw->addTerm(lamll, x1->getLb()*x2->getLb()); lfw->addTerm(lamul, x1->getUb()*x2->getLb()); lfw->addTerm(lamuu, x1->getUb()*x2->getUb()); lfw->addTerm(lamlu, x1->getLb()*x2->getUb()); // Add the x1,x2,and w rows FunctionPtr f1 = (FunctionPtr) new Function(lf1); ConstraintPtr c1 = (ConstraintPtr) new Constraint(f1, 0.0, 0.0); constraints_.push_back(c1); FunctionPtr f2 = (FunctionPtr) new Function(lf2); ConstraintPtr c2 = (ConstraintPtr) new Constraint(f2, 0.0, 0.0); constraints_.push_back(c2); FunctionPtr fw = (FunctionPtr) new Function(lfw); ConstraintPtr cw = (ConstraintPtr) new Constraint(fw, 0.0, 0.0); constraints_.push_back(cw); // Add the convexity constraint LinearFunctionPtr convex_lf = LinearFunctionPtr(new LinearFunction()); convex_lf->addTerm(lamll, 1.0); convex_lf->addTerm(lamul, 1.0); convex_lf->addTerm(lamuu, 1.0); convex_lf->addTerm(lamlu, 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); } 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)); }