bool MultilinearTermsHandler::isFeasible(ConstSolutionPtr sol, RelaxationPtr , bool &, double &) { const double *x = sol->getPrimal(); bool is_feas = true; #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Checking feasibility: " << std::endl; #endif for (ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) { ConstVariablePtr zt = it->first; SetOfVars const &jt = it->second; if (allVarsBinary_(jt)) continue; double zval = x[zt->getIndex()]; double xval = 1.0; for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) { xval *= x[(*jt_it)->getIndex()]; } #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Term for variable: " << std::endl; zt->write(std::cout); std::cout << " has error: " << fabs(zval - xval) << std::endl; #endif if (fabs(zval - xval) > eTol_) { is_feas = false; break; } } return(is_feas); }
void Hypergraph::create(std::map<ConstVariablePtr, SetOfVars > const &terms) { // Add the vertices std::map<ConstVariablePtr, SetOfVars >::const_iterator terms_it; for(terms_it = terms.begin(); terms_it != terms.end(); ++terms_it) { SetOfVars const &jt = terms_it->second; for(SetOfVars::iterator it = jt.begin(); it != jt.end(); ++it) { V_.insert(*it); } } // Add empty lists for the hyperedges for(SetOfVars::iterator v_it = V_.begin(); v_it != V_.end(); ++v_it) { std::list<SetOfVars> e_list; adjList_.insert(make_pair(*v_it, e_list)); } // Now add the edges for(terms_it = terms.begin(); terms_it != terms.end(); ++terms_it) { SetOfVars const &jt = terms_it->second; E_.insert(jt); // Put it in the adjacency lists for (SetOfVars::const_iterator it = jt.begin(); it != jt.end(); ++it) { AdjListType::iterator pos = adjList_.find(*it); assert(pos != adjList_.end()); std::list<SetOfVars> &e_list = pos->second; e_list.push_back(jt); } // Determine weight ConstVariablePtr zvar = terms_it->first; double zweight = 0.0; for (ConstrSet::iterator it2 = zvar->consBegin(); it2 != zvar->consEnd(); ++it2) { const LinearFunctionPtr lf = (*it2)->getLinearFunction(); double w = lf->getWeight(zvar); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) zvar->write(std::cout); std::cout << " has weight: " << w << " in constraint: "; (*it2)->write(std::cout); #endif zweight += fabs(w); } // Add objective weight const LinearFunctionPtr obj = problem_->getObjective()->getLinearFunction(); if (obj != 0) { double w = obj->getWeight(zvar); zweight += fabs(w); } weights_.insert(make_pair(jt, zweight)); originalWeights_.insert(make_pair(jt, zweight)); } }
void Hypergraph::write(std::ostream &out) const { for(AdjListType::const_iterator it = adjList_.begin(); it != adjList_.end(); ++it) { ConstVariablePtr v = it->first; std::cout << "Vertex: "; v->write(out); std::list<SetOfVars> e_list = it->second; for(std::list<SetOfVars>::const_iterator e_it = e_list.begin(); e_it != e_list.end(); ++e_it) { std::cout << " has edge: " << std::endl; for(SetOfVars::const_iterator v_it = e_it->begin(); v_it != e_it->end(); ++v_it) { (*v_it)->write(out); } } } }
void MultilinearTermsHandler::setupWeights_() { for(ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) { ConstVariablePtr zvar = it->first; double zweight = 0.0; for (ConstrSet::iterator it2 = zvar->consBegin(); it2 != zvar->consEnd(); ++it2) { const LinearFunctionPtr lf = (*it2)->getLinearFunction(); double w = lf->getWeight(zvar); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) zvar->write(std::cout); std::cout << " has weight: " << w << " in constraint: "; (*it2)->write(std::cout); #endif zweight += fabs(w); } weights_.insert(std::make_pair(zvar, zweight)); } }
BranchPtr MultilinearTermsHandler::doBranch_(BranchDirection UpOrDown, ConstVariablePtr v, double bvalue) { BranchPtr branch; BoundType lu; VariableType vtype = v->getType(); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Branching: " << (UpOrDown == DownBranch ? "Down" : "Up") << " at value: " << bvalue << " on: " << std::endl; v->write(std::cout); #endif branch = (BranchPtr) new Branch(); double branching_value = bvalue; // Change bounds on the x var (called v here) if (UpOrDown == DownBranch) { lu = Upper; if (vtype != Continuous) branching_value = floor(bvalue); } else { lu = Lower; if (vtype != Continuous) branching_value = ceil(bvalue); } VarBoundModPtr vmod = (VarBoundModPtr) new VarBoundMod(v, lu, branching_value); assert(!"check whether this needs to be addRMod instead"); branch->addPMod(vmod); branch->setActivity(0.5);// TODO: set this correctly return branch; }
BranchPtr CxUnivarHandler::doBranch_(BranchDirection UpOrDown, ConstVariablePtr v, double bvalue) { BranchPtr branch; LinModsPtr linmods; #if defined(DEBUG_CXUNIVARHANDLER) std::cout << "CxUnivarHandler, Branching: " << (UpOrDown == DownBranch ? "Down" : "Up") << " at value: " << bvalue << " on: " << std::endl; v->write(std::cout); #endif // Zero out tmpX and grad each time, or else bad things happen for (UInt j = 0; j < tmpX_.size(); ++j) { tmpX_[j] = 0.0; grad_[j] = 0.0; } branch = (BranchPtr) new Branch(); linmods = (LinModsPtr) new LinMods(); // Change bounds on the x var (called v here) if (UpOrDown == DownBranch) { VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Upper, bvalue); linmods->insert(mod); // Find *all* cons_data that has v as an input variable. CxUnivarConstraintIterator dit; for (dit = cons_data_.begin(); dit != cons_data_.end(); ++dit) { if ((*dit)->getRInputVar() == v) { ConstVariablePtr rov = (*dit)->getROutVar(); FunctionPtr fn = (*dit)->getOriginalCon()->getFunction(); int error; // Change the secant constraint ConstraintPtr secCon = (*dit)->getSecantCon(); LinearFunctionPtr lf; FunctionPtr f; double xlb = v->getLb(); double xub = bvalue; // TODO: Check the error value! tmpX_[v->getIndex()] = xlb; double fxlb = fn->eval(tmpX_, &error); tmpX_[v->getIndex()] = xub; double fxub = fn->eval(tmpX_, &error); tmpX_[v->getIndex()] = 0.0; // TODO: check/remedy numerical issues in this division double m = 0.0; if (xub - xlb > 10e-7) { m = (fxub - fxlb)/(xub - xlb); } double intercept = fxlb - m*xlb; lf = (LinearFunctionPtr) new LinearFunction(); lf->addTerm(rov, 1.0); lf->addTerm(v, -m); LinConModPtr lcmod = (LinConModPtr) new LinConMod(secCon, lf, -INFINITY, intercept); linmods->insert(lcmod); // Change all linearization constraints ConstraintVector::iterator lin_it; for(lin_it = (*dit)->linConsBegin(); lin_it != (*dit)->linConsEnd(); ++lin_it) { ConstraintPtr c = *lin_it; } } } } else { VarBoundModPtr mod = (VarBoundModPtr) new VarBoundMod(v, Lower, bvalue); linmods->insert(mod); } assert(!"add Mod correctly here."); branch->addPMod(linmods); return branch; }
void MultilinearTermsHandler::getBranchingCandidates(RelaxationPtr, const DoubleVector &x, ModVector &, BrVarCandSet &cands, BrCandVector &, bool &is_inf) { // Implementation notes: // (1) You must insert into the set cands // (2) Super naive implmentation: Just pick the variable from infeasible // terms whose total 'bound product' is largest std::set<ConstVariablePtr> candidates; for (ConstTermIterator it = termsR_.begin(); it != termsR_.end(); ++it) { ConstVariablePtr zt = it->first; SetOfVars const &jt = it->second; if (allVarsBinary_(jt)) continue; double zval = x[zt->getIndex()]; #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Relaxation term variable: "; zt->write(std::cout); std::cout << " Has LP value: " << zval << std::endl; #endif double termval = 1.0; double largest_score = eTol_; ConstVariablePtr largest_score_var; for(SetOfVars::const_iterator jt_it = jt.begin(); jt_it != jt.end(); ++jt_it) { ConstVariablePtr termvar = *jt_it; termval *= x[termvar->getIndex()]; #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Term variable: "; termvar->write(std::cout); std::cout << " has value: " << x[termvar->getIndex()] << std::endl; #endif double score = (termvar->getUb() - x[termvar->getIndex()])* (x[termvar->getIndex()] - termvar->getLb()); if (score > largest_score) { largest_score = score; largest_score_var = termvar; } } if (fabs(zval - termval) > eTol_) { candidates.insert(largest_score_var); #if defined(DEBUG_MULTILINEARTERMS_HANDLER) largest_score_var->write(std::cout); std::cout << " will be a candidate" << std::endl; #endif } } #if defined(DEBUG_MULTILINEARTERMS_HANDLER) std::cout << "Branching candidates are: " << std::endl; for(SetOfVars::const_iterator it = candidates.begin(); it != candidates.end(); ++it) { (*it)->write(std::cout); } #endif for(SetOfVars::const_iterator it = candidates.begin(); it != candidates.end(); ++it) { ConstVariablePtr v = *it; BrVarCandPtr br_can = (BrVarCandPtr) new BrVarCand(v, v->getIndex(), 0.5, 0.5); cands.insert(br_can); } is_inf = false; }