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"
12class CoinBaseModel {
13
14public:
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
86protected:
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
152class CoinModel : public CoinBaseModel {
153
154public:
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 //@}
846private:
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);
868public:
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
907private:
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
1032double getFunctionValueFromString(const char * string, const char * x, double xValue);
1033/// faster version
1034double getDoubleFromString(CoinYacc & info, const char * string, const char * x, double xValue);
1035#endif
1036