CouenneProblem.cpp
Go to the documentation of this file.
1 /* $Id: CouenneProblem.cpp 1147 2015-05-04 14:01:51Z stefan $
2  *
3  * Name: CouenneProblem.cpp
4  * Author: Pietro Belotti
5  * Purpose: methods of the class CouenneProblem
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <vector>
12 
13 #include "CoinHelperFunctions.hpp"
14 #include "CoinTime.hpp"
15 
16 #include "CbcBranchActual.hpp"
17 
18 #include "CouenneTypes.hpp"
19 
20 #include "CouenneExpression.hpp"
21 #include "CouenneExprConst.hpp"
22 #include "CouenneExprQuad.hpp"
23 #include "CouenneExprClone.hpp"
24 #include "CouenneExprIVar.hpp"
25 #include "CouenneExprAux.hpp"
26 #include "CouenneExprOpp.hpp"
27 
28 #include "CouenneProblem.hpp"
29 #include "CouenneGlobalCutOff.hpp"
30 #include "CouenneProblemElem.hpp"
31 #include "CouenneDepGraph.hpp"
32 #include "CouenneLQelems.hpp"
33 
34 #include "CouenneJournalist.hpp"
35 #include "CouenneObject.hpp"
36 
37 using namespace Couenne;
38 
40 
41 void CouenneProblem::addObjective (expression *newobj, const std::string &sense) {
42  objectives_ . push_back
43  (new CouenneObjective ((sense == "min") ?
44  newobj : new exprOpp (new exprClone (newobj))));
45 }
46 
47 
49 
52 
53  if (!rhs) rhs = new exprConst (0.);
54  constraints_ . push_back (new CouenneConstraint (body, rhs, new exprClone (rhs)));
55 }
56 
59  if (!rhs) rhs = new exprConst (0.);
60  constraints_ . push_back (new CouenneConstraint
61  (body, rhs, new exprConst (COUENNE_INFINITY)));
62 }
63 
66  if (!rhs) rhs = new exprConst (0.);
67  constraints_ . push_back (new CouenneConstraint
68  (body, new exprConst (-COUENNE_INFINITY), rhs));
69 }
70 
72 void CouenneProblem::setObjective (int indObj, expression * newObj, const std::string &sense) {
73  objectives_ [indObj] = (new CouenneObjective ((sense == "min") ?
74  newObj : new exprOpp (new exprClone (newObj))));
75 }
76 
77 
80  if (!lb) lb = new exprConst (0.);
81  if (!ub) ub = new exprConst (0.);
82  constraints_ . push_back (new CouenneConstraint (body, lb, ub));
83 }
84 
85 
86 
88 
90 
91  exprVar *var = (isDiscrete) ?
92  (new exprIVar (variables_ . size (), d)) :
93  (new exprVar (variables_ . size (), d));
94 
95  variables_ . push_back (var);
96 
97  if (isDiscrete)
98  nIntVars_++;
99 
100  nOrigVars_++;
101 
102  return var;
103 }
104 
105 
109 
110  // check if image is already in the expression database auxSet_
111  std::set <exprAux *, compExpr>::iterator i;
112 
113  int var_ind = variables_ . size ();
114  domain_. current () -> resize (var_ind + 1);
115 
116  symbolic -> getBounds (domain_. lb (var_ind),
117  domain_. ub (var_ind));
118 
119  // create new aux associated with that expression
120  exprAux *w = new exprAux (symbolic,
121  var_ind,
122  1 + symbolic -> rank (),
124  &domain_);
125  //symbolic -> isInteger () ? exprAux::Integer : exprAux::Continuous);
126 
127  // w -> linkDomain (&domain_);
128 
129  // seek expression in the set
130  if ((i = auxSet_ -> find (w)) == auxSet_ -> end ()) {
131 
132  // no such expression found in the set, create entry therein
133  variables_ . push_back (w);
134  auxSet_ -> insert (w); // insert into repetition checking structure
135  graph_ -> insert (w); // insert into acyclic structure
136 
137  } else { // otherwise, just return the entry's pointer
138 
139  w -> Image (NULL); // otherwise "delete w" will also delete user given expression "symbolic"
140  delete w;
141  w = *i;
142  (*i) -> increaseMult ();
143  }
144 
145  return w;
146 }
147 
148 
150 void CouenneProblem::indcoe2vector (int *indexL,
151  CouNumber *coeff,
152  std::vector <std::pair <exprVar *, CouNumber> > &lcoeff) {
153  // TODO: sort
154 
155  for (int i=0; indexL [i] >= 0; i++)
156  lcoeff.push_back (std::pair <exprVar *, CouNumber> (Var (indexL [i]), coeff [i]));
157 }
158 
159 
162  int *indexJ,
163  CouNumber *coeff,
164  std::vector <quadElem> &qcoeff) {
165  // TODO: sort
166 
167  for (int i=0; indexI [i] >= 0; i++)
168  qcoeff.push_back (quadElem (Var (indexI [i]), Var (indexJ [i]), coeff [i]));
169 }
170 
171 
174 
175  if (integerRank_)
176  return;
177 
178  int nvars = nVars ();
179 
180  integerRank_ = new int [nvars];
181 
182  CoinZeroN (integerRank_, nvars);
183 
184  // 0: fractional
185  // 1: integer
186  // k: integer, depending on at least one integer with associated value k-1, or
187  // k: fractional, depending on at least one integer with associated value k
188 
189  for (int ii = 0; ii < nvars; ii++) {
190 
191  int index = numbering_ [ii];
192 
193  if (Var (index) -> Multiplicity () <= 0) {
194  integerRank_ [index] = 0;
195  continue;
196  }
197 
198  bool isInt = Var (index) -> isDefinedInteger ();
199 
200  // sets all originals to either 0 (fractional) or 1 (integer)
201  integerRank_ [index] = (isInt) ? 1 : 0;
202 
203  if (Var (index) -> Type () == AUX) {
204 
205  std::set <int> deplist;
206 
207  if (Var (index) -> Image () -> DepList (deplist, STOP_AT_AUX) != 0) // depends on something
208  for (std::set <int>::iterator i = deplist.begin (); i != deplist.end (); ++i) {
209 
210  int token = integerRank_ [*i];
211  if (isInt) token++;
212 
213  if (token > integerRank_ [index]) // there's a free integer below us
214  integerRank_ [index] = token;
215  }
216  }
217  }
218 
219  jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "Free (original) integers\n");
220  for (int i=0; i<nOrigVars_; i++)
221  jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, integerRank_ [i]);
222 
223  // fill in numberInRank_
224  for (int i=0; i<nOrigVars_ - ndefined_; i++)
225  if ((variables_ [i] -> isDefinedInteger ()) &&
226  (variables_ [i] -> Multiplicity () > 0)) {
227 
228  int rank = integerRank_ [i];
229 
230  if (numberInRank_.size () <= (unsigned int) rank)
231  for (int j=numberInRank_.size (); j <= rank; j++)
232  numberInRank_ .push_back (0);
233 
234  numberInRank_ [rank] ++;
235  }
236 
237  jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "numInteger [neglect non-originals]\n");
238  for (unsigned int i=0; i<numberInRank_.size(); i++)
239  jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, numberInRank_ [i]);
240 }
241 
242 // /// rescans problem after adding new auxiliaries
243 // void CouenneProblem::resizeAuxs (int nOld, int nNew) {
244 
245 // #define resizeOld(typeD,oldV,oldN,newN) { \
246 // if (oldV) { \
247 // typeD *newV = new typeD [newN]; \
248 // CoinCopyN (oldV, oldN, newV); \
249 // delete [] oldV; \
250 // oldV = newV; \
251 // } \
252 // }
253 
254 // resizeOld (int, numbering_, nOld, nNew);
255 // resizeOld (bool, commuted_, nOld, nNew);
256 // resizeOld (int, integerRank_, nOld, nNew);
257 // //resizeOld (double, optimum_, nOld, nNew);
258 
259 // optimum_ = (double *) realloc (optimum_, nNew * sizeof (double));
260 
261 // if (numbering_) for (int i=nOld; i<nNew; ++i) numbering_ [i] = i;
262 // if (commuted_) for (int i=nOld; i<nNew; ++i) commuted_ [i] = false;
263 // if (integerRank_) for (int i=nOld; i<nNew; ++i) integerRank_ [i] = nNew;
264 // if (optimum_) for (int i=nOld; i<nNew; ++i) optimum_ [i] = 0.;
265 
266 // domain_ . current () -> resize (nNew);
267 
268 // // post-rescan: update
269 // //
270 // // numbering_
271 // // domain_
272 // // commuted_
273 // // optimum_
274 // // integerRank_
275 // //
276 // // since there are new variables
277 // }
278 
281 {return pcutoff_ -> getCutOff ();}
282 
285 {return pcutoff_ -> getCutOffSol ();}
286 
289 {return ConstPtr (jnlst_);}
290 
291 // set lastPrioSort_
292 void CouenneProblem::setLastPrioSort(int givenLastPS) {
293  lastPrioSort_ = givenLastPS;
294 }
void setObjective(int indObj=0, expression *=NULL, const std::string &="min")
Add (non linear) objective function.
GlobalCutOff * pcutoff_
Pointer to a global cutoff object.
void setLastPrioSort(int givenLastPS)
void addLEConstraint(expression *, expression *=NULL)
Add constraint, .
int nVars() const
Total number of variables.
void addObjective(expression *, const std::string &="min")
Add (non linear) objective function.
std::vector< CouenneObjective * > objectives_
Objectives.
class opposite,
int nIntVars_
Number of discrete variables.
void fillIntegerRank() const
fill freeIntegers_ array
DepGraph * graph_
Dependence (acyclic) graph: shows dependence of all auxiliary variables on one another and on origina...
int * integerRank_
each element is true if variable is integer and, if auxiliary, depends on no integer ...
std::set< exprAux *, compExpr > * auxSet_
Expression map for comparison in standardization and to count occurrences of an auxiliary.
constant-type operator
static char * j
Definition: OSdtoa.cpp:3622
exprAux * addAuxiliary(expression *)
Add auxiliary variable and associate it with expression given as argument (used in standardization) ...
CouNumber getCutOff() const
Get cutoff.
CouNumber * getCutOffSol() const
Get cutoff solution.
Class to represent nonlinear constraints.
int ndefined_
Number of &quot;defined variables&quot; (aka &quot;common expressions&quot;)
void addEQConstraint(expression *, expression *=NULL)
Add equality constraint .
ConstJnlstPtr Jnlst() const
Provide Journalist.
std::vector< int > numberInRank_
numberInRank_ [i] is the number of integer variables in rank i
std::vector< CouenneConstraint * > constraints_
Constraints.
fint end
expression * addVariable(bool isint=false, Domain *d=NULL)
Add original variable.
OSSmartPtr< const U > ConstPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:458
expression clone (points to another expression)
exprVar * Var(int i) const
Return pointer to i-th variable.
std::vector< exprVar * > variables_
Variables (original, auxiliary, and defined)
static int
Definition: OSdtoa.cpp:2173
Domain domain_
current point and bounds;
int * numbering_
numbering of variables.
void addGEConstraint(expression *, expression *=NULL)
Add constraint, .
double CouNumber
main number type in Couenne
int nOrigVars_
Number of original variables.
variable-type operator.
void addRNGConstraint(expression *, expression *=NULL, expression *=NULL)
Add range constraint, .
#define COUENNE_INFINITY
Auxiliary variable.
variable-type operator
JnlstPtr jnlst_
SmartPointer to the Journalist.
void indcoe2vector(int *indexL, CouNumber *coeff, std::vector< std::pair< exprVar *, CouNumber > > &lcoeff)
translates pair (indices, coefficients) into vector with pointers to variables
Expression base class.
void fint fint fint real fint real real real real real real real real * w
const Ipopt::EJournalCategory J_PROBLEM(Ipopt::J_USER4)
Define a dynamic point+bounds, with a way to save and restore previous points+bounds through a LIFO s...