1 | /* $Id: CoinModel.hpp 1448 2011-06-19 15:34:41Z stefan $ */ |
2 | // Copyright (C) 2005, International Business Machines |
3 | // Corporation and others. All Rights Reserved. |
4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
5 | |
6 | #ifndef CoinModel_H |
7 | #define CoinModel_H |
8 | |
9 | #include "CoinModelUseful.hpp" |
10 | #include "CoinPackedMatrix.hpp" |
11 | #include "CoinFinite.hpp" |
12 | class CoinBaseModel { |
13 | |
14 | public: |
15 | |
16 | |
17 | /**@name Constructors, destructor */ |
18 | //@{ |
19 | /// Default Constructor |
20 | CoinBaseModel (); |
21 | |
22 | /// Copy constructor |
23 | CoinBaseModel ( const CoinBaseModel &rhs); |
24 | |
25 | /// Assignment operator |
26 | CoinBaseModel & operator=( const CoinBaseModel& rhs); |
27 | |
28 | /// Clone |
29 | virtual CoinBaseModel * clone() const=0; |
30 | |
31 | /// Destructor |
32 | virtual ~CoinBaseModel () ; |
33 | //@} |
34 | |
35 | /**@name For getting information */ |
36 | //@{ |
37 | /// Return number of rows |
38 | inline int numberRows() const |
39 | { return numberRows_;} |
40 | /// Return number of columns |
41 | inline int numberColumns() const |
42 | { return numberColumns_;} |
43 | /// Return number of elements |
44 | virtual CoinBigIndex numberElements() const = 0; |
45 | /** Returns the (constant) objective offset |
46 | This is the RHS entry for the objective row |
47 | */ |
48 | inline double objectiveOffset() const |
49 | { return objectiveOffset_;} |
50 | /// Set objective offset |
51 | inline void setObjectiveOffset(double value) |
52 | { objectiveOffset_=value;} |
53 | /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
54 | inline double optimizationDirection() const { |
55 | return optimizationDirection_; |
56 | } |
57 | /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
58 | inline void setOptimizationDirection(double value) |
59 | { optimizationDirection_=value;} |
60 | /// Get print level 0 - off, 1 - errors, 2 - more |
61 | inline int logLevel() const |
62 | { return logLevel_;} |
63 | /// Set print level 0 - off, 1 - errors, 2 - more |
64 | void setLogLevel(int value); |
65 | /// Return the problem name |
66 | inline const char * getProblemName() const |
67 | { return problemName_.c_str();} |
68 | /// Set problem name |
69 | void setProblemName(const char *name) ; |
70 | /// Set problem name |
71 | void setProblemName(const std::string &name) ; |
72 | /// Return the row block name |
73 | inline const std::string & getRowBlock() const |
74 | { return rowBlockName_;} |
75 | /// Set row block name |
76 | inline void setRowBlock(const std::string &name) |
77 | { rowBlockName_ = name;} |
78 | /// Return the column block name |
79 | inline const std::string & getColumnBlock() const |
80 | { return columnBlockName_;} |
81 | /// Set column block name |
82 | inline void setColumnBlock(const std::string &name) |
83 | { columnBlockName_ = name;} |
84 | //@} |
85 | |
86 | protected: |
87 | /**@name Data members */ |
88 | //@{ |
89 | /// Current number of rows |
90 | int numberRows_; |
91 | /// Current number of columns |
92 | int numberColumns_; |
93 | /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
94 | double optimizationDirection_; |
95 | /// Objective offset to be passed on |
96 | double objectiveOffset_; |
97 | /// Problem name |
98 | std::string problemName_; |
99 | /// Rowblock name |
100 | std::string rowBlockName_; |
101 | /// Columnblock name |
102 | std::string columnBlockName_; |
103 | /** Print level. |
104 | I could have gone for full message handling but this should normally |
105 | be silent and lightweight. I can always change. |
106 | 0 - no output |
107 | 1 - on errors |
108 | 2 - more detailed |
109 | */ |
110 | int logLevel_; |
111 | //@} |
112 | /// data |
113 | |
114 | }; |
115 | |
116 | /** |
117 | This is a simple minded model which is stored in a format which makes |
118 | it easier to construct and modify but not efficient for algorithms. It has |
119 | to be passed across to ClpModel or OsiSolverInterface by addRows, addCol(umn)s |
120 | or loadProblem. |
121 | |
122 | It may have up to four parts - |
123 | 1) A matrix of doubles (or strings - see note A) |
124 | 2) Column information including integer information and names |
125 | 3) Row information including names |
126 | 4) Quadratic objective (not implemented - but see A) |
127 | |
128 | This class is meant to make it more efficient to build a model. It is at |
129 | its most efficient when all additions are done as addRow or as addCol but |
130 | not mixed. If only 1 and 2 exist then solver.addColumns may be used to pass to solver, |
131 | if only 1 and 3 exist then solver.addRows may be used. Otherwise solver.loadProblem |
132 | must be used. |
133 | |
134 | If addRows and addColumns are mixed or if individual elements are set then the |
135 | speed will drop to some extent and more memory will be used. |
136 | |
137 | It is also possible to iterate over existing elements and to access columns and rows |
138 | by name. Again each of these use memory and cpu time. However memory is unlikely |
139 | to be critical as most algorithms will use much more. |
140 | |
141 | Notes: |
142 | A) Although this could be used to pass nonlinear information around the |
143 | only use at present is to have named values e.g. value1 which can then be |
144 | set to a value after model is created. I have no idea whether that could |
145 | be useful but I thought it might be fun. |
146 | Quadratic terms are allowed in strings! A solver could try and use this |
147 | if so - the convention is that 0.5* quadratic is stored |
148 | |
149 | B) This class could be useful for modeling. |
150 | */ |
151 | |
152 | class CoinModel : public CoinBaseModel { |
153 | |
154 | public: |
155 | /**@name Useful methods for building model */ |
156 | //@{ |
157 | /** add a row - numberInRow may be zero */ |
158 | void addRow(int numberInRow, const int * columns, |
159 | const double * elements, double rowLower=-COIN_DBL_MAX, |
160 | double rowUpper=COIN_DBL_MAX, const char * name=nullptr); |
161 | /// add a column - numberInColumn may be zero */ |
162 | void addColumn(int numberInColumn, const int * rows, |
163 | const double * elements, |
164 | double columnLower=0.0, |
165 | double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, |
166 | const char * name=nullptr, bool isInteger=false); |
167 | /// add a column - numberInColumn may be zero */ |
168 | inline void addCol(int numberInColumn, const int * rows, |
169 | const double * elements, |
170 | double columnLower=0.0, |
171 | double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, |
172 | const char * name=nullptr, bool isInteger=false) |
173 | { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue, |
174 | name,isInteger);} |
175 | /// Sets value for row i and column j |
176 | inline void operator() (int i,int j,double value) |
177 | { setElement(i,j,value);} |
178 | /// Sets value for row i and column j |
179 | void setElement(int i,int j,double value) ; |
180 | /** Gets sorted row - user must provide enough space |
181 | (easiest is allocate number of columns). |
182 | If column or element NULL then just returns number |
183 | Returns number of elements |
184 | */ |
185 | int getRow(int whichRow, int * column, double * element); |
186 | /** Gets sorted column - user must provide enough space |
187 | (easiest is allocate number of rows). |
188 | If row or element NULL then just returns number |
189 | Returns number of elements |
190 | */ |
191 | int getColumn(int whichColumn, int * column, double * element); |
192 | /// Sets quadratic value for column i and j |
193 | void setQuadraticElement(int i,int j,double value) ; |
194 | /// Sets value for row i and column j as string |
195 | inline void operator() (int i,int j,const char * value) |
196 | { setElement(i,j,value);} |
197 | /// Sets value for row i and column j as string |
198 | void setElement(int i,int j,const char * value) ; |
199 | /// Associates a string with a value. Returns string id (or -1 if does not exist) |
200 | int associateElement(const char * stringValue, double value); |
201 | /** Sets rowLower (if row does not exist then |
202 | all rows up to this are defined with default values and no elements) |
203 | */ |
204 | void setRowLower(int whichRow,double rowLower); |
205 | /** Sets rowUpper (if row does not exist then |
206 | all rows up to this are defined with default values and no elements) |
207 | */ |
208 | void setRowUpper(int whichRow,double rowUpper); |
209 | /** Sets rowLower and rowUpper (if row does not exist then |
210 | all rows up to this are defined with default values and no elements) |
211 | */ |
212 | void setRowBounds(int whichRow,double rowLower,double rowUpper); |
213 | /** Sets name (if row does not exist then |
214 | all rows up to this are defined with default values and no elements) |
215 | */ |
216 | void setRowName(int whichRow,const char * rowName); |
217 | /** Sets columnLower (if column does not exist then |
218 | all columns up to this are defined with default values and no elements) |
219 | */ |
220 | void setColumnLower(int whichColumn,double columnLower); |
221 | /** Sets columnUpper (if column does not exist then |
222 | all columns up to this are defined with default values and no elements) |
223 | */ |
224 | void setColumnUpper(int whichColumn,double columnUpper); |
225 | /** Sets columnLower and columnUpper (if column does not exist then |
226 | all columns up to this are defined with default values and no elements) |
227 | */ |
228 | void setColumnBounds(int whichColumn,double columnLower,double columnUpper); |
229 | /** Sets columnObjective (if column does not exist then |
230 | all columns up to this are defined with default values and no elements) |
231 | */ |
232 | void setColumnObjective(int whichColumn,double columnObjective); |
233 | /** Sets name (if column does not exist then |
234 | all columns up to this are defined with default values and no elements) |
235 | */ |
236 | void setColumnName(int whichColumn,const char * columnName); |
237 | /** Sets integer state (if column does not exist then |
238 | all columns up to this are defined with default values and no elements) |
239 | */ |
240 | void setColumnIsInteger(int whichColumn,bool columnIsInteger); |
241 | /** Sets columnObjective (if column does not exist then |
242 | all columns up to this are defined with default values and no elements) |
243 | */ |
244 | inline void setObjective(int whichColumn,double columnObjective) |
245 | { setColumnObjective( whichColumn, columnObjective);} |
246 | /** Sets integer state (if column does not exist then |
247 | all columns up to this are defined with default values and no elements) |
248 | */ |
249 | inline void setIsInteger(int whichColumn,bool columnIsInteger) |
250 | { setColumnIsInteger( whichColumn, columnIsInteger);} |
251 | /** Sets integer (if column does not exist then |
252 | all columns up to this are defined with default values and no elements) |
253 | */ |
254 | inline void setInteger(int whichColumn) |
255 | { setColumnIsInteger( whichColumn, true);} |
256 | /** Sets continuous (if column does not exist then |
257 | all columns up to this are defined with default values and no elements) |
258 | */ |
259 | inline void setContinuous(int whichColumn) |
260 | { setColumnIsInteger( whichColumn, false);} |
261 | /** Sets columnLower (if column does not exist then |
262 | all columns up to this are defined with default values and no elements) |
263 | */ |
264 | inline void setColLower(int whichColumn,double columnLower) |
265 | { setColumnLower( whichColumn, columnLower);} |
266 | /** Sets columnUpper (if column does not exist then |
267 | all columns up to this are defined with default values and no elements) |
268 | */ |
269 | inline void setColUpper(int whichColumn,double columnUpper) |
270 | { setColumnUpper( whichColumn, columnUpper);} |
271 | /** Sets columnLower and columnUpper (if column does not exist then |
272 | all columns up to this are defined with default values and no elements) |
273 | */ |
274 | inline void setColBounds(int whichColumn,double columnLower,double columnUpper) |
275 | { setColumnBounds( whichColumn, columnLower, columnUpper);} |
276 | /** Sets columnObjective (if column does not exist then |
277 | all columns up to this are defined with default values and no elements) |
278 | */ |
279 | inline void setColObjective(int whichColumn,double columnObjective) |
280 | { setColumnObjective( whichColumn, columnObjective);} |
281 | /** Sets name (if column does not exist then |
282 | all columns up to this are defined with default values and no elements) |
283 | */ |
284 | inline void setColName(int whichColumn,const char * columnName) |
285 | { setColumnName( whichColumn, columnName);} |
286 | /** Sets integer (if column does not exist then |
287 | all columns up to this are defined with default values and no elements) |
288 | */ |
289 | inline void setColIsInteger(int whichColumn,bool columnIsInteger) |
290 | { setColumnIsInteger( whichColumn, columnIsInteger);} |
291 | /** Sets rowLower (if row does not exist then |
292 | all rows up to this are defined with default values and no elements) |
293 | */ |
294 | void setRowLower(int whichRow,const char * rowLower); |
295 | /** Sets rowUpper (if row does not exist then |
296 | all rows up to this are defined with default values and no elements) |
297 | */ |
298 | void setRowUpper(int whichRow,const char * rowUpper); |
299 | /** Sets columnLower (if column does not exist then |
300 | all columns up to this are defined with default values and no elements) |
301 | */ |
302 | void setColumnLower(int whichColumn,const char * columnLower); |
303 | /** Sets columnUpper (if column does not exist then |
304 | all columns up to this are defined with default values and no elements) |
305 | */ |
306 | void setColumnUpper(int whichColumn,const char * columnUpper); |
307 | /** Sets columnObjective (if column does not exist then |
308 | all columns up to this are defined with default values and no elements) |
309 | */ |
310 | void setColumnObjective(int whichColumn,const char * columnObjective); |
311 | /** Sets integer (if column does not exist then |
312 | all columns up to this are defined with default values and no elements) |
313 | */ |
314 | void setColumnIsInteger(int whichColumn,const char * columnIsInteger); |
315 | /** Sets columnObjective (if column does not exist then |
316 | all columns up to this are defined with default values and no elements) |
317 | */ |
318 | inline void setObjective(int whichColumn,const char * columnObjective) |
319 | { setColumnObjective( whichColumn, columnObjective);} |
320 | /** Sets integer (if column does not exist then |
321 | all columns up to this are defined with default values and no elements) |
322 | */ |
323 | inline void setIsInteger(int whichColumn,const char * columnIsInteger) |
324 | { setColumnIsInteger( whichColumn, columnIsInteger);} |
325 | /** Deletes all entries in row and bounds. Will be ignored by |
326 | writeMps etc and will be packed down if asked for. */ |
327 | void deleteRow(int whichRow); |
328 | /** Deletes all entries in column and bounds and objective. Will be ignored by |
329 | writeMps etc and will be packed down if asked for. */ |
330 | void deleteColumn(int whichColumn); |
331 | /** Deletes all entries in column and bounds. If last column the number of columns |
332 | will be decremented and true returned. */ |
333 | inline void deleteCol(int whichColumn) |
334 | { deleteColumn(whichColumn);} |
335 | /// Takes element out of matrix - returning position (<0 if not there); |
336 | int deleteElement(int row, int column); |
337 | /// Takes element out of matrix when position known |
338 | void deleteThisElement(int row, int column,int position); |
339 | /** Packs down all rows i.e. removes empty rows permanently. Empty rows |
340 | have no elements and feasible bounds. returns number of rows deleted. */ |
341 | int packRows(); |
342 | /** Packs down all columns i.e. removes empty columns permanently. Empty columns |
343 | have no elements and no objective. returns number of columns deleted. */ |
344 | int packColumns(); |
345 | /** Packs down all columns i.e. removes empty columns permanently. Empty columns |
346 | have no elements and no objective. returns number of columns deleted. */ |
347 | inline int packCols() |
348 | { return packColumns();} |
349 | /** Packs down all rows and columns. i.e. removes empty rows and columns permanently. |
350 | Empty rows have no elements and feasible bounds. |
351 | Empty columns have no elements and no objective. |
352 | returns number of rows+columns deleted. */ |
353 | int pack(); |
354 | |
355 | /** Sets columnObjective array |
356 | */ |
357 | void setObjective(int numberColumns,const double * objective) ; |
358 | /** Sets columnLower array |
359 | */ |
360 | void setColumnLower(int numberColumns,const double * columnLower); |
361 | /** Sets columnLower array |
362 | */ |
363 | inline void setColLower(int numberColumns,const double * columnLower) |
364 | { setColumnLower( numberColumns, columnLower);} |
365 | /** Sets columnUpper array |
366 | */ |
367 | void setColumnUpper(int numberColumns,const double * columnUpper); |
368 | /** Sets columnUpper array |
369 | */ |
370 | inline void setColUpper(int numberColumns,const double * columnUpper) |
371 | { setColumnUpper( numberColumns, columnUpper);} |
372 | /** Sets rowLower array |
373 | */ |
374 | void setRowLower(int numberRows,const double * rowLower); |
375 | /** Sets rowUpper array |
376 | */ |
377 | void setRowUpper(int numberRows,const double * rowUpper); |
378 | |
379 | /** Write the problem in MPS format to a file with the given filename. |
380 | |
381 | \param compression can be set to three values to indicate what kind |
382 | of file should be written |
383 | <ul> |
384 | <li> 0: plain text (default) |
385 | <li> 1: gzip compressed (.gz is appended to \c filename) |
386 | <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) |
387 | </ul> |
388 | If the library was not compiled with the requested compression then |
389 | writeMps falls back to writing a plain text file. |
390 | |
391 | \param formatType specifies the precision to used for values in the |
392 | MPS file |
393 | <ul> |
394 | <li> 0: normal precision (default) |
395 | <li> 1: extra accuracy |
396 | <li> 2: IEEE hex |
397 | </ul> |
398 | |
399 | \param numberAcross specifies whether 1 or 2 (default) values should be |
400 | specified on every data line in the MPS file. |
401 | |
402 | not const as may change model e.g. fill in default bounds |
403 | */ |
404 | int writeMps(const char *filename, int compression = 0, |
405 | int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; |
406 | |
407 | /** Check two models against each other. Return nonzero if different. |
408 | Ignore names if that set. |
409 | May modify both models by cleaning up |
410 | */ |
411 | int differentModel(CoinModel & other, bool ignoreNames); |
412 | //@} |
413 | |
414 | |
415 | /**@name For structured models */ |
416 | //@{ |
417 | /// Pass in CoinPackedMatrix (and switch off element updates) |
418 | void passInMatrix(const CoinPackedMatrix & matrix); |
419 | /** Convert elements to CoinPackedMatrix (and switch off element updates). |
420 | Returns number of errors */ |
421 | int convertMatrix(); |
422 | /// Return a pointer to CoinPackedMatrix (or NULL) |
423 | inline const CoinPackedMatrix * packedMatrix() const |
424 | { return packedMatrix_;} |
425 | /// Return pointers to original rows (for decomposition) |
426 | inline const int * originalRows() const |
427 | { return rowType_;} |
428 | /// Return pointers to original columns (for decomposition) |
429 | inline const int * originalColumns() const |
430 | { return columnType_;} |
431 | //@} |
432 | |
433 | |
434 | /**@name For getting information */ |
435 | //@{ |
436 | /// Return number of elements |
437 | inline CoinBigIndex numberElements() const override |
438 | { return numberElements_;} |
439 | /// Return elements as triples |
440 | inline const CoinModelTriple * elements() const |
441 | { return elements_;} |
442 | /// Returns value for row i and column j |
443 | inline double operator() (int i,int j) const |
444 | { return getElement(i,j);} |
445 | /// Returns value for row i and column j |
446 | double getElement(int i,int j) const; |
447 | /// Returns value for row rowName and column columnName |
448 | inline double operator() (const char * rowName,const char * columnName) const |
449 | { return getElement(rowName,columnName);} |
450 | /// Returns value for row rowName and column columnName |
451 | double getElement(const char * rowName,const char * columnName) const; |
452 | /// Returns quadratic value for columns i and j |
453 | double getQuadraticElement(int i,int j) const; |
454 | /** Returns value for row i and column j as string. |
455 | Returns NULL if does not exist. |
456 | Returns "Numeric" if not a string |
457 | */ |
458 | const char * getElementAsString(int i,int j) const; |
459 | /** Returns pointer to element for row i column j. |
460 | Only valid until next modification. |
461 | NULL if element does not exist */ |
462 | double * pointer (int i,int j) const; |
463 | /** Returns position in elements for row i column j. |
464 | Only valid until next modification. |
465 | -1 if element does not exist */ |
466 | int position (int i,int j) const; |
467 | |
468 | |
469 | /** Returns first element in given row - index is -1 if none. |
470 | Index is given by .index and value by .value |
471 | */ |
472 | CoinModelLink firstInRow(int whichRow) const ; |
473 | /** Returns last element in given row - index is -1 if none. |
474 | Index is given by .index and value by .value |
475 | */ |
476 | CoinModelLink lastInRow(int whichRow) const ; |
477 | /** Returns first element in given column - index is -1 if none. |
478 | Index is given by .index and value by .value |
479 | */ |
480 | CoinModelLink firstInColumn(int whichColumn) const ; |
481 | /** Returns last element in given column - index is -1 if none. |
482 | Index is given by .index and value by .value |
483 | */ |
484 | CoinModelLink lastInColumn(int whichColumn) const ; |
485 | /** Returns next element in current row or column - index is -1 if none. |
486 | Index is given by .index and value by .value. |
487 | User could also tell because input.next would be NULL |
488 | */ |
489 | CoinModelLink next(CoinModelLink & current) const ; |
490 | /** Returns previous element in current row or column - index is -1 if none. |
491 | Index is given by .index and value by .value. |
492 | User could also tell because input.previous would be NULL |
493 | May not be correct if matrix updated. |
494 | */ |
495 | CoinModelLink previous(CoinModelLink & current) const ; |
496 | /** Returns first element in given quadratic column - index is -1 if none. |
497 | Index is given by .index and value by .value |
498 | May not be correct if matrix updated. |
499 | */ |
500 | CoinModelLink firstInQuadraticColumn(int whichColumn) const ; |
501 | /** Returns last element in given quadratic column - index is -1 if none. |
502 | Index is given by .index and value by .value |
503 | */ |
504 | CoinModelLink lastInQuadraticColumn(int whichColumn) const ; |
505 | /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) |
506 | */ |
507 | double getRowLower(int whichRow) const ; |
508 | /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) |
509 | */ |
510 | double getRowUpper(int whichRow) const ; |
511 | /** Gets name (if row does not exist then NULL) |
512 | */ |
513 | const char * getRowName(int whichRow) const ; |
514 | inline double rowLower(int whichRow) const |
515 | { return getRowLower(whichRow);} |
516 | /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) |
517 | */ |
518 | inline double rowUpper(int whichRow) const |
519 | { return getRowUpper(whichRow) ;} |
520 | /** Gets name (if row does not exist then NULL) |
521 | */ |
522 | inline const char * rowName(int whichRow) const |
523 | { return getRowName(whichRow);} |
524 | /** Gets columnLower (if column does not exist then 0.0) |
525 | */ |
526 | double getColumnLower(int whichColumn) const ; |
527 | /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) |
528 | */ |
529 | double getColumnUpper(int whichColumn) const ; |
530 | /** Gets columnObjective (if column does not exist then 0.0) |
531 | */ |
532 | double getColumnObjective(int whichColumn) const ; |
533 | /** Gets name (if column does not exist then NULL) |
534 | */ |
535 | const char * getColumnName(int whichColumn) const ; |
536 | /** Gets if integer (if column does not exist then false) |
537 | */ |
538 | bool getColumnIsInteger(int whichColumn) const ; |
539 | /** Gets columnLower (if column does not exist then 0.0) |
540 | */ |
541 | inline double columnLower(int whichColumn) const |
542 | { return getColumnLower(whichColumn);} |
543 | /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) |
544 | */ |
545 | inline double columnUpper(int whichColumn) const |
546 | { return getColumnUpper(whichColumn) ;} |
547 | /** Gets columnObjective (if column does not exist then 0.0) |
548 | */ |
549 | inline double columnObjective(int whichColumn) const |
550 | { return getColumnObjective(whichColumn);} |
551 | /** Gets columnObjective (if column does not exist then 0.0) |
552 | */ |
553 | inline double objective(int whichColumn) const |
554 | { return getColumnObjective(whichColumn);} |
555 | /** Gets name (if column does not exist then NULL) |
556 | */ |
557 | inline const char * columnName(int whichColumn) const |
558 | { return getColumnName(whichColumn);} |
559 | /** Gets if integer (if column does not exist then false) |
560 | */ |
561 | inline bool columnIsInteger(int whichColumn) const |
562 | { return getColumnIsInteger(whichColumn);} |
563 | /** Gets if integer (if column does not exist then false) |
564 | */ |
565 | inline bool isInteger(int whichColumn) const |
566 | { return getColumnIsInteger(whichColumn);} |
567 | /** Gets columnLower (if column does not exist then 0.0) |
568 | */ |
569 | inline double getColLower(int whichColumn) const |
570 | { return getColumnLower(whichColumn);} |
571 | /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) |
572 | */ |
573 | inline double getColUpper(int whichColumn) const |
574 | { return getColumnUpper(whichColumn) ;} |
575 | /** Gets columnObjective (if column does not exist then 0.0) |
576 | */ |
577 | inline double getColObjective(int whichColumn) const |
578 | { return getColumnObjective(whichColumn);} |
579 | /** Gets name (if column does not exist then NULL) |
580 | */ |
581 | inline const char * getColName(int whichColumn) const |
582 | { return getColumnName(whichColumn);} |
583 | /** Gets if integer (if column does not exist then false) |
584 | */ |
585 | inline bool getColIsInteger(int whichColumn) const |
586 | { return getColumnIsInteger(whichColumn);} |
587 | /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) |
588 | */ |
589 | const char * getRowLowerAsString(int whichRow) const ; |
590 | /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) |
591 | */ |
592 | const char * getRowUpperAsString(int whichRow) const ; |
593 | inline const char * rowLowerAsString(int whichRow) const |
594 | { return getRowLowerAsString(whichRow);} |
595 | /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) |
596 | */ |
597 | inline const char * rowUpperAsString(int whichRow) const |
598 | { return getRowUpperAsString(whichRow) ;} |
599 | /** Gets columnLower (if column does not exist then 0.0) |
600 | */ |
601 | const char * getColumnLowerAsString(int whichColumn) const ; |
602 | /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) |
603 | */ |
604 | const char * getColumnUpperAsString(int whichColumn) const ; |
605 | /** Gets columnObjective (if column does not exist then 0.0) |
606 | */ |
607 | const char * getColumnObjectiveAsString(int whichColumn) const ; |
608 | /** Gets if integer (if column does not exist then false) |
609 | */ |
610 | const char * getColumnIsIntegerAsString(int whichColumn) const ; |
611 | /** Gets columnLower (if column does not exist then 0.0) |
612 | */ |
613 | inline const char * columnLowerAsString(int whichColumn) const |
614 | { return getColumnLowerAsString(whichColumn);} |
615 | /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) |
616 | */ |
617 | inline const char * columnUpperAsString(int whichColumn) const |
618 | { return getColumnUpperAsString(whichColumn) ;} |
619 | /** Gets columnObjective (if column does not exist then 0.0) |
620 | */ |
621 | inline const char * columnObjectiveAsString(int whichColumn) const |
622 | { return getColumnObjectiveAsString(whichColumn);} |
623 | /** Gets columnObjective (if column does not exist then 0.0) |
624 | */ |
625 | inline const char * objectiveAsString(int whichColumn) const |
626 | { return getColumnObjectiveAsString(whichColumn);} |
627 | /** Gets if integer (if column does not exist then false) |
628 | */ |
629 | inline const char * columnIsIntegerAsString(int whichColumn) const |
630 | { return getColumnIsIntegerAsString(whichColumn);} |
631 | /** Gets if integer (if column does not exist then false) |
632 | */ |
633 | inline const char * isIntegerAsString(int whichColumn) const |
634 | { return getColumnIsIntegerAsString(whichColumn);} |
635 | /// Row index from row name (-1 if no names or no match) |
636 | int row(const char * rowName) const; |
637 | /// Column index from column name (-1 if no names or no match) |
638 | int column(const char * columnName) const; |
639 | /// Returns type |
640 | inline int type() const |
641 | { return type_;} |
642 | /// returns unset value |
643 | inline double unsetValue() const |
644 | { return -1.23456787654321e-97;} |
645 | /// Creates a packed matrix - return number of errors |
646 | int createPackedMatrix(CoinPackedMatrix & matrix, |
647 | const double * associated); |
648 | /** Fills in startPositive and startNegative with counts for +-1 matrix. |
649 | If not +-1 then startPositive[0]==-1 otherwise counts and |
650 | startPositive[numberColumns]== size |
651 | - return number of errors |
652 | */ |
653 | int countPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, |
654 | const double * associated); |
655 | /** Creates +-1 matrix given startPositive and startNegative counts for +-1 matrix. |
656 | */ |
657 | void createPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, |
658 | int * indices, |
659 | const double * associated); |
660 | /// Creates copies of various arrays - return number of errors |
661 | int createArrays(double * & rowLower, double * & rowUpper, |
662 | double * & columnLower, double * & columnUpper, |
663 | double * & objective, int * & integerType, |
664 | double * & associated); |
665 | /// Says if strings exist |
666 | inline bool stringsExist() const |
667 | { return string_.numberItems()!=0;} |
668 | /// Return string array |
669 | inline const CoinModelHash * stringArray() const |
670 | { return &string_;} |
671 | /// Returns associated array |
672 | inline double * associatedArray() const |
673 | { return associated_;} |
674 | /// Return rowLower array |
675 | inline double * rowLowerArray() const |
676 | { return rowLower_;} |
677 | /// Return rowUpper array |
678 | inline double * rowUpperArray() const |
679 | { return rowUpper_;} |
680 | /// Return columnLower array |
681 | inline double * columnLowerArray() const |
682 | { return columnLower_;} |
683 | /// Return columnUpper array |
684 | inline double * columnUpperArray() const |
685 | { return columnUpper_;} |
686 | /// Return objective array |
687 | inline double * objectiveArray() const |
688 | { return objective_;} |
689 | /// Return integerType array |
690 | inline int * integerTypeArray() const |
691 | { return integerType_;} |
692 | /// Return row names array |
693 | inline const CoinModelHash * rowNames() const |
694 | { return &rowName_;} |
695 | /// Return column names array |
696 | inline const CoinModelHash * columnNames() const |
697 | { return &columnName_;} |
698 | /// Returns array of 0 or nonzero if can be a cut (or returns NULL) |
699 | inline const int * cutMarker() const |
700 | { return cut_;} |
701 | /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
702 | inline double optimizationDirection() const { |
703 | return optimizationDirection_; |
704 | } |
705 | /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
706 | inline void setOptimizationDirection(double value) |
707 | { optimizationDirection_=value;} |
708 | /// Return pointer to more information |
709 | inline void * moreInfo() const |
710 | { return moreInfo_;} |
711 | /// Set pointer to more information |
712 | inline void setMoreInfo(void * info) |
713 | { moreInfo_ = info;} |
714 | /** Returns which parts of model are set |
715 | 1 - matrix |
716 | 2 - rhs |
717 | 4 - row names |
718 | 8 - column bounds and/or objective |
719 | 16 - column names |
720 | 32 - integer types |
721 | */ |
722 | int whatIsSet() const; |
723 | //@} |
724 | |
725 | /**@name for block models - matrix will be CoinPackedMatrix */ |
726 | //@{ |
727 | /*! \brief Load in a problem by copying the arguments. The constraints on |
728 | the rows are given by lower and upper bounds. |
729 | |
730 | If a pointer is 0 then the following values are the default: |
731 | <ul> |
732 | <li> <code>colub</code>: all columns have upper bound infinity |
733 | <li> <code>collb</code>: all columns have lower bound 0 |
734 | <li> <code>rowub</code>: all rows have upper bound infinity |
735 | <li> <code>rowlb</code>: all rows have lower bound -infinity |
736 | <li> <code>obj</code>: all variables have 0 objective coefficient |
737 | </ul> |
738 | |
739 | Note that the default values for rowub and rowlb produce the |
740 | constraint -infty <= ax <= infty. This is probably not what you want. |
741 | */ |
742 | void loadBlock (const CoinPackedMatrix& matrix, |
743 | const double* collb, const double* colub, |
744 | const double* obj, |
745 | const double* rowlb, const double* rowub) ; |
746 | /*! \brief Load in a problem by copying the arguments. |
747 | The constraints on the rows are given by sense/rhs/range triplets. |
748 | |
749 | If a pointer is 0 then the following values are the default: |
750 | <ul> |
751 | <li> <code>colub</code>: all columns have upper bound infinity |
752 | <li> <code>collb</code>: all columns have lower bound 0 |
753 | <li> <code>obj</code>: all variables have 0 objective coefficient |
754 | <li> <code>rowsen</code>: all rows are >= |
755 | <li> <code>rowrhs</code>: all right hand sides are 0 |
756 | <li> <code>rowrng</code>: 0 for the ranged rows |
757 | </ul> |
758 | |
759 | Note that the default values for rowsen, rowrhs, and rowrng produce the |
760 | constraint ax >= 0. |
761 | */ |
762 | void loadBlock (const CoinPackedMatrix& matrix, |
763 | const double* collb, const double* colub, |
764 | const double* obj, |
765 | const char* rowsen, const double* rowrhs, |
766 | const double* rowrng) ; |
767 | |
768 | /*! \brief Load in a problem by copying the arguments. The constraint |
769 | matrix is is specified with standard column-major |
770 | column starts / row indices / coefficients vectors. |
771 | The constraints on the rows are given by lower and upper bounds. |
772 | |
773 | The matrix vectors must be gap-free. Note that <code>start</code> must |
774 | have <code>numcols+1</code> entries so that the length of the last column |
775 | can be calculated as <code>start[numcols]-start[numcols-1]</code>. |
776 | |
777 | See the previous loadBlock method using rowlb and rowub for default |
778 | argument values. |
779 | */ |
780 | void loadBlock (const int numcols, const int numrows, |
781 | const CoinBigIndex * start, const int* index, |
782 | const double* value, |
783 | const double* collb, const double* colub, |
784 | const double* obj, |
785 | const double* rowlb, const double* rowub) ; |
786 | |
787 | /*! \brief Load in a problem by copying the arguments. The constraint |
788 | matrix is is specified with standard column-major |
789 | column starts / row indices / coefficients vectors. |
790 | The constraints on the rows are given by sense/rhs/range triplets. |
791 | |
792 | The matrix vectors must be gap-free. Note that <code>start</code> must |
793 | have <code>numcols+1</code> entries so that the length of the last column |
794 | can be calculated as <code>start[numcols]-start[numcols-1]</code>. |
795 | |
796 | See the previous loadBlock method using sense/rhs/range for default |
797 | argument values. |
798 | */ |
799 | void loadBlock (const int numcols, const int numrows, |
800 | const CoinBigIndex * start, const int* index, |
801 | const double* value, |
802 | const double* collb, const double* colub, |
803 | const double* obj, |
804 | const char* rowsen, const double* rowrhs, |
805 | const double* rowrng) ; |
806 | |
807 | //@} |
808 | |
809 | /**@name Constructors, destructor */ |
810 | //@{ |
811 | /** Default constructor. */ |
812 | CoinModel(); |
813 | /** Read a problem in MPS or GAMS format from the given filename. |
814 | */ |
815 | CoinModel(const char *fileName, int allowStrings=0); |
816 | /** Read a problem from AMPL nl file |
817 | NOTE - as I can't work out configure etc the source code is in Cbc_ampl.cpp! |
818 | */ |
819 | CoinModel( int nonLinear, const char * fileName,const void * info); |
820 | /// From arrays |
821 | CoinModel(int numberRows, int numberColumns, |
822 | const CoinPackedMatrix * matrix, |
823 | const double * rowLower, const double * rowUpper, |
824 | const double * columnLower, const double * columnUpper, |
825 | const double * objective); |
826 | /// Clone |
827 | virtual CoinBaseModel * clone() const override; |
828 | |
829 | /** Destructor */ |
830 | virtual ~CoinModel(); |
831 | //@} |
832 | |
833 | /**@name Copy method */ |
834 | //@{ |
835 | /** The copy constructor. */ |
836 | CoinModel(const CoinModel&); |
837 | /// = |
838 | CoinModel& operator=(const CoinModel&); |
839 | //@} |
840 | |
841 | /**@name For debug */ |
842 | //@{ |
843 | /// Checks that links are consistent |
844 | void validateLinks() const; |
845 | //@} |
846 | private: |
847 | /// Resize |
848 | void resize(int maximumRows, int maximumColumns, int maximumElements); |
849 | /// Fill in default row information |
850 | void fillRows(int which,bool forceCreation,bool fromAddRow=false); |
851 | /// Fill in default column information |
852 | void fillColumns(int which,bool forceCreation,bool fromAddColumn=false); |
853 | /** Fill in default linked list information (1= row, 2 = column) |
854 | Marked as const as list is mutable */ |
855 | void fillList(int which, CoinModelLinkedList & list,int type) const ; |
856 | /** Create a linked list and synchronize free |
857 | type 1 for row 2 for column |
858 | Marked as const as list is mutable */ |
859 | void createList(int type) const; |
860 | /// Adds one string, returns index |
861 | int addString(const char * string); |
862 | /** Gets a double from a string possibly containing named strings, |
863 | returns unset if not found |
864 | */ |
865 | double getDoubleFromString(CoinYacc & info, const char * string); |
866 | /// Frees value memory |
867 | void freeStringMemory(CoinYacc & info); |
868 | public: |
869 | /// Fills in all associated - returning number of errors |
870 | int computeAssociated(double * associated); |
871 | /** Gets correct form for a quadratic row - user to delete |
872 | If row is not quadratic then returns which other variables are involved |
873 | with tiny (1.0e-100) elements and count of total number of variables which could not |
874 | be put in quadratic form |
875 | */ |
876 | CoinPackedMatrix * quadraticRow(int rowNumber,double * linear, |
877 | int & numberBad) const; |
878 | /// Replaces a quadratic row |
879 | void replaceQuadraticRow(int rowNumber,const double * linear, const CoinPackedMatrix * quadraticPart); |
880 | /** If possible return a model where if all variables marked nonzero are fixed |
881 | the problem will be linear. At present may only work if quadratic. |
882 | Returns NULL if not possible |
883 | */ |
884 | CoinModel * reorder(const char * mark) const; |
885 | /** Expands out all possible combinations for a knapsack |
886 | If buildObj NULL then just computes space needed - returns number elements |
887 | On entry numberOutput is maximum allowed, on exit it is number needed or |
888 | -1 (as will be number elements) if maximum exceeded. numberOutput will have at |
889 | least space to return values which reconstruct input. |
890 | Rows returned will be original rows but no entries will be returned for |
891 | any rows all of whose entries are in knapsack. So up to user to allow for this. |
892 | If reConstruct >=0 then returns number of entrie which make up item "reConstruct" |
893 | in expanded knapsack. Values in buildRow and buildElement; |
894 | */ |
895 | int expandKnapsack(int knapsackRow, int & numberOutput,double * buildObj, CoinBigIndex * buildStart, |
896 | int * buildRow, double * buildElement,int reConstruct=-1) const; |
897 | /// Sets cut marker array |
898 | void setCutMarker(int size,const int * marker); |
899 | /// Sets priority array |
900 | void setPriorities(int size,const int * priorities); |
901 | /// priorities (given for all columns (-1 if not integer) |
902 | inline const int * priorities() const |
903 | { return priority_;} |
904 | /// For decomposition set original row and column indices |
905 | void setOriginalIndices(const int * row, const int * column); |
906 | |
907 | private: |
908 | /** Read a problem from AMPL nl file |
909 | so not constructor so gdb will work |
910 | */ |
911 | void gdb( int nonLinear, const char * fileName, const void * info); |
912 | /// returns jColumn (-2 if linear term, -1 if unknown) and coefficient |
913 | int decodeBit(char * phrase, char * & nextPhrase, double & coefficient, bool ifFirst) const; |
914 | /// Aborts with message about packedMatrix |
915 | void badType() const; |
916 | /**@name Data members */ |
917 | //@{ |
918 | /// Maximum number of rows |
919 | int maximumRows_; |
920 | /// Maximum number of columns |
921 | int maximumColumns_; |
922 | /// Current number of elements |
923 | int numberElements_; |
924 | /// Maximum number of elements |
925 | int maximumElements_; |
926 | /// Current number of quadratic elements |
927 | int numberQuadraticElements_; |
928 | /// Maximum number of quadratic elements |
929 | int maximumQuadraticElements_; |
930 | /// Row lower |
931 | double * rowLower_; |
932 | /// Row upper |
933 | double * rowUpper_; |
934 | /// Row names |
935 | CoinModelHash rowName_; |
936 | /** Row types. |
937 | Has information - at present |
938 | bit 0 - rowLower is a string |
939 | bit 1 - rowUpper is a string |
940 | NOTE - if converted to CoinPackedMatrix - may be indices of |
941 | original rows (i.e. when decomposed) |
942 | */ |
943 | int * rowType_; |
944 | /// Objective |
945 | double * objective_; |
946 | /// Column Lower |
947 | double * columnLower_; |
948 | /// Column Upper |
949 | double * columnUpper_; |
950 | /// Column names |
951 | CoinModelHash columnName_; |
952 | /// Integer information |
953 | int * integerType_; |
954 | /// Strings |
955 | CoinModelHash string_; |
956 | /** Column types. |
957 | Has information - at present |
958 | bit 0 - columnLower is a string |
959 | bit 1 - columnUpper is a string |
960 | bit 2 - objective is a string |
961 | bit 3 - integer setting is a string |
962 | NOTE - if converted to CoinPackedMatrix - may be indices of |
963 | original columns (i.e. when decomposed) |
964 | */ |
965 | int * columnType_; |
966 | /// If simple then start of each row/column |
967 | int * start_; |
968 | /// Actual elements |
969 | CoinModelTriple * elements_; |
970 | /// Actual elements as CoinPackedMatrix |
971 | CoinPackedMatrix * packedMatrix_; |
972 | /// Hash for elements |
973 | mutable CoinModelHash2 hashElements_; |
974 | /// Linked list for rows |
975 | mutable CoinModelLinkedList rowList_; |
976 | /// Linked list for columns |
977 | mutable CoinModelLinkedList columnList_; |
978 | /// Actual quadratic elements (always linked lists) |
979 | CoinModelTriple * quadraticElements_; |
980 | /// Hash for quadratic elements |
981 | mutable CoinModelHash2 hashQuadraticElements_; |
982 | /// Array for sorting indices |
983 | int * sortIndices_; |
984 | /// Array for sorting elements |
985 | double * sortElements_; |
986 | /// Size of sort arrays |
987 | int sortSize_; |
988 | /// Linked list for quadratic rows |
989 | mutable CoinModelLinkedList quadraticRowList_; |
990 | /// Linked list for quadratic columns |
991 | mutable CoinModelLinkedList quadraticColumnList_; |
992 | /// Size of associated values |
993 | int sizeAssociated_; |
994 | /// Associated values |
995 | double * associated_; |
996 | /// Number of SOS - all these are done in one go e.g. from ampl |
997 | int numberSOS_; |
998 | /// SOS starts |
999 | int * startSOS_; |
1000 | /// SOS members |
1001 | int * memberSOS_; |
1002 | /// SOS type |
1003 | int * typeSOS_; |
1004 | /// SOS priority |
1005 | int * prioritySOS_; |
1006 | /// SOS reference |
1007 | double * referenceSOS_; |
1008 | /// priorities (given for all columns (-1 if not integer) |
1009 | int * priority_; |
1010 | /// Nonzero if row is cut - done in one go e.g. from ampl |
1011 | int * cut_; |
1012 | /// Pointer to more information |
1013 | void * moreInfo_; |
1014 | /** Type of build - |
1015 | -1 unset, |
1016 | 0 for row, |
1017 | 1 for column, |
1018 | 2 linked. |
1019 | 3 matrix is CoinPackedMatrix (and at present can't be modified); |
1020 | */ |
1021 | mutable int type_; |
1022 | /** Links present (could be tested by sizes of objects) |
1023 | 0 - none, |
1024 | 1 - row links, |
1025 | 2 - column links, |
1026 | 3 - both |
1027 | */ |
1028 | mutable int links_; |
1029 | //@} |
1030 | }; |
1031 | /// Just function of single variable x |
1032 | double getFunctionValueFromString(const char * string, const char * x, double xValue); |
1033 | /// faster version |
1034 | double getDoubleFromString(CoinYacc & info, const char * string, const char * x, double xValue); |
1035 | #endif |
1036 | |