20 #define COUENNE_AGGR_PROBING_FINITE_BOUND 1.0e+10
21 #define COUENNE_AGGR_PROBING_MIN_INTERVAL 1.0e-2
22 #define COUENNE_AGGR_PROBING_BND_RELAX COUENNE_EPS
24 using namespace Couenne;
96 double initUpper = lp->getColUpper()[index];
97 double initLower = lp->getColLower()[index];
99 double* initLowerLp =
new double[
numCols_];
100 double* initUpperLp =
new double[
numCols_];
102 memcpy(initLowerLp, lp->getColLower(),
numCols_*
sizeof(double));
103 memcpy(initUpperLp, lp->getColUpper(),
numCols_*
sizeof(double));
107 return ((probeLower) ? initLower : initUpper);
114 double initCutoff = problem->
getCutOff ();
116 double* initCutoffSol = NULL;
119 initCutoffSol =
new double[
numCols_];
139 double currentBound = (probeLower) ? initLower : initUpper;
140 double startTime = CoinCpuTime();
142 double intervalSize = 0.0;
143 double tryBound = 0.0;
148 std::cout <<
"Probing lower on var " << index << std::endl;
150 std::cout <<
"Probing upper on var " << index << std::endl;
161 lp->setColLower(index, currentBound);
162 problem->
Lb()[index] = currentBound;
163 lp->setColUpper(index, tryBound);
164 problem->
Ub()[index] = tryBound;
165 if (index < problem->nOrigVars()){
166 nlp->setColLower(index, currentBound);
167 nlp->setColUpper(index, tryBound);
172 lp->setColLower(index, tryBound);
173 problem->
Lb()[index] = tryBound;
174 lp->setColUpper(index, currentBound);
175 problem->
Ub()[index] = currentBound;
176 if (index < problem->nOrigVars()){
177 nlp->setColLower(index, tryBound);
178 nlp->setColUpper(index, currentBound);
184 CoinMin(
maxTime_-(CoinCpuTime()-startTime),
190 problem->
Ub(indobj) = initCutoff;
194 std::cout <<
"Iteration " << iter <<
", current bound " << currentBound
195 <<
", try bound " << tryBound << std::endl;
204 if (bb.
model().isProvenInfeasible()){
206 currentBound = tryBound;
207 std::cout <<
"Probing succeeded; brought to finite" << std::endl;
211 std::cout <<
"Probing failed; still infinity, exit" << std::endl;
227 ((CoinCpuTime() - startTime) <
maxTime_) &&
234 tryBound = currentBound + intervalSize;
235 if (tryBound > initUpper){
238 tryBound = initUpper;
240 if (lp->isInteger(index)){
241 tryBound = floor(tryBound);
246 lp->setColUpper(index, tryBound + COUENNE_AGGR_PROBING_BND_RELAX);
248 if (index < problem->nOrigVars()){
249 nlp->setColLower(index, currentBound - COUENNE_AGGR_PROBING_BND_RELAX);
250 nlp->setColUpper(index, tryBound + COUENNE_AGGR_PROBING_BND_RELAX);
254 tryBound = currentBound - intervalSize;
255 if (tryBound < initLower){
258 tryBound = initLower;
260 if (lp->isInteger(index)){
261 tryBound = ceil(tryBound);
266 lp->setColUpper(index, currentBound + COUENNE_AGGR_PROBING_BND_RELAX);
268 if (index < problem->nOrigVars()){
269 nlp->setColLower(index, tryBound - COUENNE_AGGR_PROBING_BND_RELAX);
270 nlp->setColUpper(index, currentBound + COUENNE_AGGR_PROBING_BND_RELAX);
276 lp->getColLower(), lp->getColUpper());
280 CoinMin(
maxTime_-(CoinCpuTime()-startTime),
285 problem->
Ub(indobj) = initCutoff;
290 std::cout <<
"Iteration " << iter <<
", current bound " << currentBound
291 <<
", try bound " << tryBound << std::endl;
304 bool intervalSearched = (bb.
model().isProvenOptimal() ||
305 bb.
model().isProvenInfeasible());
307 if ((!intervalSearched) ||
312 if (lp->isInteger(index) && fabs(tryBound-currentBound) < 0.5){
320 std::cout <<
"Probing failed; shrinking interval" << std::endl;
327 if (lp->isInteger(index) && fabs(tryBound-currentBound) < 0.5){
335 currentBound = tryBound;
336 if (lp->isInteger(index)){
345 std::cout <<
"Probing succeeded; enlarging interval" << std::endl;
350 if ((probeLower && fabs(currentBound-initUpper) <
COUENNE_EPS) ||
351 (!probeLower && fabs(currentBound-initLower) <
COUENNE_EPS)){
358 problem->
Ub(indobj) = initCutoff;
370 lp->setColLower(initLowerLp);
371 lp->setColUpper(initUpperLp);
372 nlp->setColLower(initLowerLp);
373 nlp->setColUpper(initUpperLp);
374 memcpy(problem->
Lb(), initLowerLp,
numCols_*
sizeof(double));
375 memcpy(problem->
Ub(), initUpperLp,
numCols_*
sizeof(double));
389 problem->
setCutOff(initCutoff, initCutoffSol);
391 delete[] initCutoffSol;
395 delete[] initLowerLp;
396 delete[] initUpperLp;
412 double initUpper = lp->getColUpper()[index];
413 double initLower = lp->getColLower()[index];
417 return ((probeLower) ? initLower : initUpper);
439 double* initLpObj =
new double[
numCols_];
440 memcpy(initLpObj, lp->getObjCoefficients(),
numCols_*
sizeof(double));
443 double* newLpObj =
new double[
numCols_];
444 memset(newLpObj, 0,
numCols_*
sizeof(
double));
449 lp->writeLp(
"before");
452 std::cout <<
"Probing LOWER" << std::endl;
454 newLpObj[index] = 1.0;
455 lp->setObjective(newLpObj);
457 lp->writeLp(
"lower");
473 lp->setObjective(newLpObj);
474 lp->addCol(0, NULL, NULL, -initUpper, -initLower, 1.0);
477 int rowIndices[2] = {index, extraCol};
478 double rowElements[2] = {1.0, 1.0};
479 lp->addRow(2, rowIndices, rowElements, 0.0, 0.0);
483 extraVar = problem->
addVariable(lp->isInteger(index), NULL);
486 problem->
Obj(0)->
Body(extraVar);
492 lp->writeLp(
"upper");
506 double bestBound = bb.
model().getBestPossibleObjValue();
508 std::cout <<
"Obtained bound: " << bb.
model().getBestPossibleObjValue() << std::endl;
519 int extra = lp->getNumCols()-1;
520 lp->deleteCols(1, &extra);
521 extra = lp->getNumRows()-1;
522 lp->deleteRows(1, &extra);
528 lp->setObjective(initLpObj);
529 problem->
Obj(0)->
Body(initProbObj);
534 return ((probeLower) ? bestBound : -bestBound);
int getIntParameter(const IntParameter &p) const
Return value of integer parameter.
CouNumber & Ub(int i) const
upper bound on
int nVars() const
Total number of variables.
CouenneCutGenerator * couennePtr() const
return pointer to cut generator (used to get pointer to problem)
void setCutOff(CouNumber cutoff, const CouNumber *sol=NULL) const
Set cutoff.
expression * Body() const
get body
Cut Generator for aggressive BT; i.e., an aggressive probing.
CouNumber & Lb(int i) const
lower bound on
CouenneSetup * couenne_
Pointer to the CouenneProblem representation.
bool getRestoreCutoff() const
void setMaxNodes(int value)
Set/get maximum number of nodes to probe one variable.
CouenneProblem * Problem() const
return pointer to symbolic problem
Domain * domain() const
return current point & bounds
CouNumber getCutOff() const
Get cutoff.
void setMaxTime(double value)
Set/get maximum time to probe one variable.
bool restoreCutoff_
Restore initial cutoff (value and solution)?
CouNumber * getCutOffSol() const
Get cutoff solution.
void setDoubleParameter(const DoubleParameter &p, const double val)
modify parameter (used for MaxTime)
limit on number of integer feasible solution.
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
void fint fint fint real fint real real real real real real real real real fint real fint * lp
void pop()
restore previous point
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Add list of options to be read from file.
expression * addVariable(bool isint=false, Domain *d=NULL)
Add original variable.
int numCols_
Number of columns (want to have this handy)
Class for MINLP problems with symbolic information.
double initCutoff_
Initial cutoff.
#define COUENNE_AGGR_PROBING_BND_RELAX
double getMaxTime() const
std::vector< exprVar * > & Variables()
Return vector of variables (symbolic representation)
double probeVariable(int index, bool probeLower)
Probe one variable (try to tigthen the lower or the upper bound, depending on the value of the second...
int maxFailedSteps_
Maximum number of failed iterations.
#define COUENNE_AGGR_PROBING_MIN_INTERVAL
double probeVariable2(int index, bool lower)
Alternative probing algorithm.
void installCutOff() const
Make cutoff known to the problem.
NodeComparison & nodeComparisonMethod()
Method used to compare nodes.
~CouenneAggrProbing()
Destructor.
void setNodeComparisonMethod(Bonmin::BabSetupBase::NodeComparison c)
NodeComparison
Strategies for comparing the nodes on the heap.
void resetCutOff(CouNumber value=COUENNE_INFINITY) const
Reset cutoff.
int getMaxFailedSteps() const
void push(int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy=true)
save current point and start using another
OsiTMINLPInterface * nonlinearSolver()
Pointer to the non-linear solver used.
OsiSolverInterface * continuousSolver()
Pointer to the continuous solver to use for relaxations.
#define COUENNE_AGGR_PROBING_FINITE_BOUND
void setIntParameter(const IntParameter &p, const int v)
Return value of integer parameter.
bool checkNLP(const double *solution, double &obj, bool recompute=false) const
Check if solution is MINLP feasible.
HeuristicMethods & heuristics()
list of Heuristic methods to use.
void setMaxFailedSteps(int value)
Set/get maximum number of failed steps.
CouenneObjective * Obj(int i) const
i-th objective
void setCheckAuxBounds(bool value)
set the value for checkAuxBounds.
std::list< HeuristicMethod > HeuristicMethods
int maxNodes_
Maximum number of nodes in probing.
const CbcModel & model() const
Get cbc model used to solve.
void setRestoreCutoff(bool value)
Set/get restoreCutoff parameter (should we restore the initial cutoff value after each probing run...
double maxTime_
Maximum time to probe one variable.
double getDoubleParameter(const DoubleParameter &p) const
modify parameter (used for MaxTime)
CouenneAggrProbing(CouenneSetup *couenne, const Ipopt::SmartPtr< Ipopt::OptionsList > options)
Constructor.