1 | // Copyright (C) 2000, International Business Machines |
---|
2 | // Corporation and others. All Rights Reserved. |
---|
3 | |
---|
4 | #ifndef OsiClpSolverInterface_H |
---|
5 | #define OsiClpSolverInterface_H |
---|
6 | |
---|
7 | #include <string> |
---|
8 | #include <cfloat> |
---|
9 | #include <map> |
---|
10 | |
---|
11 | #include "ClpSimplex.hpp" |
---|
12 | #include "ClpLinearObjective.hpp" |
---|
13 | #include "CoinPackedMatrix.hpp" |
---|
14 | #include "OsiSolverInterface.hpp" |
---|
15 | #include "CoinWarmStartBasis.hpp" |
---|
16 | #include "ClpEventHandler.hpp" |
---|
17 | #include "ClpNode.hpp" |
---|
18 | #include "CoinIndexedVector.hpp" |
---|
19 | |
---|
20 | class OsiRowCut; |
---|
21 | class OsiClpUserSolver; |
---|
22 | class OsiClpDisasterHandler; |
---|
23 | class CoinSet; |
---|
24 | #ifndef COIN_DBL_MAX |
---|
25 | static const double OsiClpInfinity = DBL_MAX; |
---|
26 | #else |
---|
27 | static const double OsiClpInfinity = COIN_DBL_MAX; |
---|
28 | #endif |
---|
29 | |
---|
30 | //############################################################################# |
---|
31 | |
---|
32 | /** Clp Solver Interface |
---|
33 | |
---|
34 | Instantiation of OsiClpSolverInterface for the Model Algorithm. |
---|
35 | |
---|
36 | */ |
---|
37 | |
---|
38 | class OsiClpSolverInterface : |
---|
39 | virtual public OsiSolverInterface { |
---|
40 | friend int OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); |
---|
41 | |
---|
42 | public: |
---|
43 | //--------------------------------------------------------------------------- |
---|
44 | /**@name Solve methods */ |
---|
45 | //@{ |
---|
46 | /// Solve initial LP relaxation |
---|
47 | virtual void initialSolve(); |
---|
48 | |
---|
49 | /// Resolve an LP relaxation after problem modification |
---|
50 | virtual void resolve(); |
---|
51 | |
---|
52 | /// Invoke solver's built-in enumeration algorithm |
---|
53 | virtual void branchAndBound(); |
---|
54 | |
---|
55 | /** Solve when primal column and dual row solutions are near-optimal |
---|
56 | options - 0 no presolve (use primal and dual) |
---|
57 | 1 presolve (just use primal) |
---|
58 | 2 no presolve (just use primal) |
---|
59 | basis - 0 use all slack basis |
---|
60 | 1 try and put some in basis |
---|
61 | */ |
---|
62 | void crossover(int options,int basis); |
---|
63 | //@} |
---|
64 | |
---|
65 | ///@name OsiSimplexInterface methods |
---|
66 | //@{ |
---|
67 | |
---|
68 | /**Enables normal operation of subsequent functions. |
---|
69 | This method is supposed to ensure that all typical things (like |
---|
70 | reduced costs, etc.) are updated when individual pivots are executed |
---|
71 | and can be queried by other methods |
---|
72 | */ |
---|
73 | virtual void enableSimplexInterface(bool doingPrimal); |
---|
74 | |
---|
75 | ///Undo whatever setting changes the above method had to make |
---|
76 | virtual void disableSimplexInterface(); |
---|
77 | /** Returns 1 if can just do getBInv etc |
---|
78 | 2 if has all OsiSimplex methods |
---|
79 | and 0 if it has none */ |
---|
80 | virtual int canDoSimplexInterface() const; |
---|
81 | /** Tells solver that calls to getBInv etc are about to take place. |
---|
82 | Underlying code may need mutable as this may be called from |
---|
83 | CglCut:;generateCuts which is const. If that is too horrific then |
---|
84 | each solver e.g. BCP or CBC will have to do something outside |
---|
85 | main loop. |
---|
86 | */ |
---|
87 | virtual void enableFactorization() const; |
---|
88 | /// and stop |
---|
89 | virtual void disableFactorization() const; |
---|
90 | |
---|
91 | /** Sets up solver for repeated use by Osi interface. |
---|
92 | The normal usage does things like keeping factorization around so can be used. |
---|
93 | Will also do things like keep scaling and row copy of matrix if |
---|
94 | matrix does not change. |
---|
95 | adventure: |
---|
96 | 0 - safe stuff as above |
---|
97 | 1 - will take more risks - if it does not work then bug which will be fixed |
---|
98 | 2 - don't bother doing most extreme termination checks e.g. don't bother |
---|
99 | re-factorizing if less than 20 iterations. |
---|
100 | 3 - Actually safer than 1 (mainly just keeps factorization) |
---|
101 | |
---|
102 | printOut - -1 always skip round common messages instead of doing some work |
---|
103 | 0 skip if normal defaults |
---|
104 | 1 leaves |
---|
105 | */ |
---|
106 | void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0); |
---|
107 | /// Synchronize model (really if no cuts in tree) |
---|
108 | virtual void synchronizeModel(); |
---|
109 | // Sleazy methods to fool const requirements (no less safe as modelPtr_ mutable) |
---|
110 | void setSpecialOptionsMutable(unsigned int value) const; |
---|
111 | |
---|
112 | /** Returns true if a basis is available |
---|
113 | AND problem is optimal. This should be used to see if |
---|
114 | the BInvARow type operations are possible and meaningful. |
---|
115 | */ |
---|
116 | virtual bool basisIsAvailable() const; |
---|
117 | |
---|
118 | /** The following two methods may be replaced by the |
---|
119 | methods of OsiSolverInterface using OsiWarmStartBasis if: |
---|
120 | 1. OsiWarmStartBasis resize operation is implemented |
---|
121 | more efficiently and |
---|
122 | 2. It is ensured that effects on the solver are the same |
---|
123 | |
---|
124 | Returns a basis status of the structural/artificial variables |
---|
125 | At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower |
---|
126 | |
---|
127 | NOTE artificials are treated as +1 elements so for <= rhs |
---|
128 | artificial will be at lower bound if constraint is tight |
---|
129 | |
---|
130 | This means that Clpsimplex flips artificials as it works |
---|
131 | in terms of row activities |
---|
132 | */ |
---|
133 | virtual void getBasisStatus(int* cstat, int* rstat) const; |
---|
134 | |
---|
135 | /** Set the status of structural/artificial variables and |
---|
136 | factorize, update solution etc |
---|
137 | |
---|
138 | NOTE artificials are treated as +1 elements so for <= rhs |
---|
139 | artificial will be at lower bound if constraint is tight |
---|
140 | |
---|
141 | This means that Clpsimplex flips artificials as it works |
---|
142 | in terms of row activities |
---|
143 | Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ... |
---|
144 | */ |
---|
145 | virtual int setBasisStatus(const int* cstat, const int* rstat); |
---|
146 | |
---|
147 | /** Perform a pivot by substituting a colIn for colOut in the basis. |
---|
148 | The status of the leaving variable is given in statOut. Where |
---|
149 | 1 is to upper bound, -1 to lower bound |
---|
150 | Return code is 0 for okay, |
---|
151 | 1 if inaccuracy forced re-factorization (should be okay) and |
---|
152 | -1 for singular factorization |
---|
153 | */ |
---|
154 | virtual int pivot(int colIn, int colOut, int outStatus); |
---|
155 | |
---|
156 | /** Obtain a result of the primal pivot |
---|
157 | Outputs: colOut -- leaving column, outStatus -- its status, |
---|
158 | t -- step size, and, if dx!=NULL, *dx -- primal ray direction. |
---|
159 | Inputs: colIn -- entering column, sign -- direction of its change (+/-1). |
---|
160 | Both for colIn and colOut, artificial variables are index by |
---|
161 | the negative of the row index minus 1. |
---|
162 | Return code (for now): 0 -- leaving variable found, |
---|
163 | -1 -- everything else? |
---|
164 | Clearly, more informative set of return values is required |
---|
165 | Primal and dual solutions are updated |
---|
166 | */ |
---|
167 | virtual int primalPivotResult(int colIn, int sign, |
---|
168 | int& colOut, int& outStatus, |
---|
169 | double& t, CoinPackedVector* dx); |
---|
170 | |
---|
171 | /** Obtain a result of the dual pivot (similar to the previous method) |
---|
172 | Differences: entering variable and a sign of its change are now |
---|
173 | the outputs, the leaving variable and its statuts -- the inputs |
---|
174 | If dx!=NULL, then *dx contains dual ray |
---|
175 | Return code: same |
---|
176 | */ |
---|
177 | virtual int dualPivotResult(int& colIn, int& sign, |
---|
178 | int colOut, int outStatus, |
---|
179 | double& t, CoinPackedVector* dx); |
---|
180 | |
---|
181 | ///Get the reduced gradient for the cost vector c |
---|
182 | virtual void getReducedGradient(double* columnReducedCosts, |
---|
183 | double * duals, |
---|
184 | const double * c) const ; |
---|
185 | |
---|
186 | ///Get a row of the tableau (slack part in slack if not NULL) |
---|
187 | virtual void getBInvARow(int row, double* z, double * slack=NULL) const; |
---|
188 | |
---|
189 | /** Get a row of the tableau (slack part in slack if not NULL) |
---|
190 | If keepScaled is true then scale factors not applied after so |
---|
191 | user has to use coding similar to what is in this method |
---|
192 | */ |
---|
193 | virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=NULL, |
---|
194 | bool keepScaled=false) const; |
---|
195 | |
---|
196 | ///Get a row of the basis inverse |
---|
197 | virtual void getBInvRow(int row, double* z) const; |
---|
198 | |
---|
199 | ///Get a column of the tableau |
---|
200 | virtual void getBInvACol(int col, double* vec) const ; |
---|
201 | |
---|
202 | ///Get a column of the tableau |
---|
203 | virtual void getBInvACol(int col, CoinIndexedVector * vec) const ; |
---|
204 | |
---|
205 | /** Update (i.e. ftran) the vector passed in. |
---|
206 | Unscaling is applied after - can't be applied before |
---|
207 | */ |
---|
208 | |
---|
209 | virtual void getBInvACol(CoinIndexedVector * vec) const ; |
---|
210 | |
---|
211 | ///Get a column of the basis inverse |
---|
212 | virtual void getBInvCol(int col, double* vec) const ; |
---|
213 | |
---|
214 | /** Get basic indices (order of indices corresponds to the |
---|
215 | order of elements in a vector retured by getBInvACol() and |
---|
216 | getBInvCol()). |
---|
217 | */ |
---|
218 | virtual void getBasics(int* index) const; |
---|
219 | |
---|
220 | //@} |
---|
221 | //--------------------------------------------------------------------------- |
---|
222 | /**@name Parameter set/get methods |
---|
223 | |
---|
224 | The set methods return true if the parameter was set to the given value, |
---|
225 | false otherwise. There can be various reasons for failure: the given |
---|
226 | parameter is not applicable for the solver (e.g., refactorization |
---|
227 | frequency for the clp algorithm), the parameter is not yet implemented |
---|
228 | for the solver or simply the value of the parameter is out of the range |
---|
229 | the solver accepts. If a parameter setting call returns false check the |
---|
230 | details of your solver. |
---|
231 | |
---|
232 | The get methods return true if the given parameter is applicable for the |
---|
233 | solver and is implemented. In this case the value of the parameter is |
---|
234 | returned in the second argument. Otherwise they return false. |
---|
235 | */ |
---|
236 | //@{ |
---|
237 | // Set an integer parameter |
---|
238 | bool setIntParam(OsiIntParam key, int value); |
---|
239 | // Set an double parameter |
---|
240 | bool setDblParam(OsiDblParam key, double value); |
---|
241 | // Set a string parameter |
---|
242 | bool setStrParam(OsiStrParam key, const std::string & value); |
---|
243 | // Get an integer parameter |
---|
244 | bool getIntParam(OsiIntParam key, int& value) const; |
---|
245 | // Get an double parameter |
---|
246 | bool getDblParam(OsiDblParam key, double& value) const; |
---|
247 | // Get a string parameter |
---|
248 | bool getStrParam(OsiStrParam key, std::string& value) const; |
---|
249 | // Set a hint parameter - overrides OsiSolverInterface |
---|
250 | virtual bool setHintParam(OsiHintParam key, bool yesNo=true, |
---|
251 | OsiHintStrength strength=OsiHintTry, |
---|
252 | void * otherInformation=NULL); |
---|
253 | //@} |
---|
254 | |
---|
255 | //--------------------------------------------------------------------------- |
---|
256 | ///@name Methods returning info on how the solution process terminated |
---|
257 | //@{ |
---|
258 | /// Are there a numerical difficulties? |
---|
259 | virtual bool isAbandoned() const; |
---|
260 | /// Is optimality proven? |
---|
261 | virtual bool isProvenOptimal() const; |
---|
262 | /// Is primal infeasiblity proven? |
---|
263 | virtual bool isProvenPrimalInfeasible() const; |
---|
264 | /// Is dual infeasiblity proven? |
---|
265 | virtual bool isProvenDualInfeasible() const; |
---|
266 | /// Is the given primal objective limit reached? |
---|
267 | virtual bool isPrimalObjectiveLimitReached() const; |
---|
268 | /// Is the given dual objective limit reached? |
---|
269 | virtual bool isDualObjectiveLimitReached() const; |
---|
270 | /// Iteration limit reached? |
---|
271 | virtual bool isIterationLimitReached() const; |
---|
272 | //@} |
---|
273 | |
---|
274 | //--------------------------------------------------------------------------- |
---|
275 | /**@name WarmStart related methods */ |
---|
276 | //@{ |
---|
277 | |
---|
278 | /*! \brief Get an empty warm start object |
---|
279 | |
---|
280 | This routine returns an empty CoinWarmStartBasis object. Its purpose is |
---|
281 | to provide a way to give a client a warm start basis object of the |
---|
282 | appropriate type, which can resized and modified as desired. |
---|
283 | */ |
---|
284 | |
---|
285 | virtual CoinWarmStart *getEmptyWarmStart () const; |
---|
286 | |
---|
287 | /// Get warmstarting information |
---|
288 | virtual CoinWarmStart* getWarmStart() const; |
---|
289 | /// Get warmstarting information |
---|
290 | inline CoinWarmStartBasis* getPointerToWarmStart() |
---|
291 | { return &basis_;} |
---|
292 | /// Get warmstarting information |
---|
293 | inline const CoinWarmStartBasis* getConstPointerToWarmStart() const |
---|
294 | { return &basis_;} |
---|
295 | /** Set warmstarting information. Return true/false depending on whether |
---|
296 | the warmstart information was accepted or not. */ |
---|
297 | virtual bool setWarmStart(const CoinWarmStart* warmstart); |
---|
298 | /** \brief Get warm start information. |
---|
299 | |
---|
300 | Return warm start information for the current state of the solver |
---|
301 | interface. If there is no valid warm start information, an empty warm |
---|
302 | start object wil be returned. This does not necessarily create an |
---|
303 | object - may just point to one. must Delete set true if user |
---|
304 | should delete returned object. |
---|
305 | OsiClp version always returns pointer and false. |
---|
306 | */ |
---|
307 | virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; |
---|
308 | |
---|
309 | //@} |
---|
310 | |
---|
311 | //--------------------------------------------------------------------------- |
---|
312 | /**@name Hotstart related methods (primarily used in strong branching). <br> |
---|
313 | The user can create a hotstart (a snapshot) of the optimization process |
---|
314 | then reoptimize over and over again always starting from there.<br> |
---|
315 | <strong>NOTE</strong>: between hotstarted optimizations only |
---|
316 | bound changes are allowed. */ |
---|
317 | //@{ |
---|
318 | /// Create a hotstart point of the optimization process |
---|
319 | virtual void markHotStart(); |
---|
320 | /// Optimize starting from the hotstart |
---|
321 | virtual void solveFromHotStart(); |
---|
322 | /// Delete the snapshot |
---|
323 | virtual void unmarkHotStart(); |
---|
324 | /** Start faster dual - returns negative if problems 1 if infeasible, |
---|
325 | Options to pass to solver |
---|
326 | 1 - create external reduced costs for columns |
---|
327 | 2 - create external reduced costs for rows |
---|
328 | 4 - create external row activity (columns always done) |
---|
329 | Above only done if feasible |
---|
330 | When set resolve does less work |
---|
331 | */ |
---|
332 | int startFastDual(int options); |
---|
333 | /// Stop fast dual |
---|
334 | void stopFastDual(); |
---|
335 | /// Sets integer tolerance and increment |
---|
336 | void setStuff(double tolerance,double increment); |
---|
337 | //@} |
---|
338 | |
---|
339 | //--------------------------------------------------------------------------- |
---|
340 | /**@name Problem information methods |
---|
341 | |
---|
342 | These methods call the solver's query routines to return |
---|
343 | information about the problem referred to by the current object. |
---|
344 | Querying a problem that has no data associated with it result in |
---|
345 | zeros for the number of rows and columns, and NULL pointers from |
---|
346 | the methods that return vectors. |
---|
347 | |
---|
348 | Const pointers returned from any data-query method are valid as |
---|
349 | long as the data is unchanged and the solver is not called. |
---|
350 | */ |
---|
351 | //@{ |
---|
352 | /**@name Methods related to querying the input data */ |
---|
353 | //@{ |
---|
354 | /// Get number of columns |
---|
355 | virtual int getNumCols() const { |
---|
356 | return modelPtr_->numberColumns(); } |
---|
357 | |
---|
358 | /// Get number of rows |
---|
359 | virtual int getNumRows() const { |
---|
360 | return modelPtr_->numberRows(); } |
---|
361 | |
---|
362 | /// Get number of nonzero elements |
---|
363 | virtual int getNumElements() const { |
---|
364 | int retVal = 0; |
---|
365 | const CoinPackedMatrix * matrix =modelPtr_->matrix(); |
---|
366 | if ( matrix != NULL ) retVal=matrix->getNumElements(); |
---|
367 | return retVal; } |
---|
368 | |
---|
369 | /// Return name of row if one exists or Rnnnnnnn |
---|
370 | /// maxLen is currently ignored and only there to match the signature from the base class! |
---|
371 | virtual std::string getRowName(int rowIndex, |
---|
372 | unsigned maxLen = std::string::npos) const; |
---|
373 | |
---|
374 | /// Return name of column if one exists or Cnnnnnnn |
---|
375 | /// maxLen is currently ignored and only there to match the signature from the base class! |
---|
376 | virtual std::string getColName(int colIndex, |
---|
377 | unsigned maxLen = std::string::npos) const; |
---|
378 | |
---|
379 | |
---|
380 | /// Get pointer to array[getNumCols()] of column lower bounds |
---|
381 | virtual const double * getColLower() const { return modelPtr_->columnLower(); } |
---|
382 | |
---|
383 | /// Get pointer to array[getNumCols()] of column upper bounds |
---|
384 | virtual const double * getColUpper() const { return modelPtr_->columnUpper(); } |
---|
385 | |
---|
386 | /** Get pointer to array[getNumRows()] of row constraint senses. |
---|
387 | <ul> |
---|
388 | <li>'L' <= constraint |
---|
389 | <li>'E' = constraint |
---|
390 | <li>'G' >= constraint |
---|
391 | <li>'R' ranged constraint |
---|
392 | <li>'N' free constraint |
---|
393 | </ul> |
---|
394 | */ |
---|
395 | virtual const char * getRowSense() const; |
---|
396 | |
---|
397 | /** Get pointer to array[getNumRows()] of rows right-hand sides |
---|
398 | <ul> |
---|
399 | <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] |
---|
400 | <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] |
---|
401 | <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] |
---|
402 | <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 |
---|
403 | </ul> |
---|
404 | */ |
---|
405 | virtual const double * getRightHandSide() const ; |
---|
406 | |
---|
407 | /** Get pointer to array[getNumRows()] of row ranges. |
---|
408 | <ul> |
---|
409 | <li> if rowsense()[i] == 'R' then |
---|
410 | rowrange()[i] == rowupper()[i] - rowlower()[i] |
---|
411 | <li> if rowsense()[i] != 'R' then |
---|
412 | rowrange()[i] is undefined |
---|
413 | </ul> |
---|
414 | */ |
---|
415 | virtual const double * getRowRange() const ; |
---|
416 | |
---|
417 | /// Get pointer to array[getNumRows()] of row lower bounds |
---|
418 | virtual const double * getRowLower() const { return modelPtr_->rowLower(); } |
---|
419 | |
---|
420 | /// Get pointer to array[getNumRows()] of row upper bounds |
---|
421 | virtual const double * getRowUpper() const { return modelPtr_->rowUpper(); } |
---|
422 | |
---|
423 | /// Get pointer to array[getNumCols()] of objective function coefficients |
---|
424 | virtual const double * getObjCoefficients() const |
---|
425 | { return modelPtr_->objective(); } |
---|
426 | |
---|
427 | /// Get objective function sense (1 for min (default), -1 for max) |
---|
428 | virtual double getObjSense() const |
---|
429 | { return modelPtr_->optimizationDirection(); } |
---|
430 | |
---|
431 | /// Return true if column is continuous |
---|
432 | virtual bool isContinuous(int colNumber) const; |
---|
433 | /// Return true if variable is binary |
---|
434 | virtual bool isBinary(int colIndex) const; |
---|
435 | |
---|
436 | /** Return true if column is integer. |
---|
437 | Note: This function returns true if the the column |
---|
438 | is binary or a general integer. |
---|
439 | */ |
---|
440 | virtual bool isInteger(int colIndex) const; |
---|
441 | |
---|
442 | /// Return true if variable is general integer |
---|
443 | virtual bool isIntegerNonBinary(int colIndex) const; |
---|
444 | |
---|
445 | /// Return true if variable is binary and not fixed at either bound |
---|
446 | virtual bool isFreeBinary(int colIndex) const; |
---|
447 | /** Return array of column length |
---|
448 | 0 - continuous |
---|
449 | 1 - binary (may get fixed later) |
---|
450 | 2 - general integer (may get fixed later) |
---|
451 | */ |
---|
452 | virtual const char * getColType(bool refresh=false) const; |
---|
453 | |
---|
454 | /** Return true if column is integer but does not have to |
---|
455 | be declared as such. |
---|
456 | Note: This function returns true if the the column |
---|
457 | is binary or a general integer. |
---|
458 | */ |
---|
459 | bool isOptionalInteger(int colIndex) const; |
---|
460 | /** Set the index-th variable to be an optional integer variable */ |
---|
461 | void setOptionalInteger(int index); |
---|
462 | |
---|
463 | /// Get pointer to row-wise copy of matrix |
---|
464 | virtual const CoinPackedMatrix * getMatrixByRow() const; |
---|
465 | |
---|
466 | /// Get pointer to column-wise copy of matrix |
---|
467 | virtual const CoinPackedMatrix * getMatrixByCol() const; |
---|
468 | |
---|
469 | /// Get pointer to mutable column-wise copy of matrix |
---|
470 | virtual CoinPackedMatrix * getMutableMatrixByCol() const; |
---|
471 | |
---|
472 | /// Get solver's value for infinity |
---|
473 | virtual double getInfinity() const { return OsiClpInfinity; } |
---|
474 | //@} |
---|
475 | |
---|
476 | /**@name Methods related to querying the solution */ |
---|
477 | //@{ |
---|
478 | /// Get pointer to array[getNumCols()] of primal solution vector |
---|
479 | virtual const double * getColSolution() const; |
---|
480 | |
---|
481 | /// Get pointer to array[getNumRows()] of dual prices |
---|
482 | virtual const double * getRowPrice() const; |
---|
483 | |
---|
484 | /// Get a pointer to array[getNumCols()] of reduced costs |
---|
485 | virtual const double * getReducedCost() const; |
---|
486 | |
---|
487 | /** Get pointer to array[getNumRows()] of row activity levels (constraint |
---|
488 | matrix times the solution vector */ |
---|
489 | virtual const double * getRowActivity() const; |
---|
490 | |
---|
491 | /// Get objective function value |
---|
492 | virtual double getObjValue() const; |
---|
493 | |
---|
494 | /** Get how many iterations it took to solve the problem (whatever |
---|
495 | "iteration" mean to the solver. */ |
---|
496 | virtual int getIterationCount() const |
---|
497 | { return modelPtr_->numberIterations(); } |
---|
498 | |
---|
499 | /** Get as many dual rays as the solver can provide. (In case of proven |
---|
500 | primal infeasibility there should be at least one.) |
---|
501 | |
---|
502 | The first getNumRows() ray components will always be associated with |
---|
503 | the row duals (as returned by getRowPrice()). If \c fullRay is true, |
---|
504 | the final getNumCols() entries will correspond to the ray components |
---|
505 | associated with the nonbasic variables. If the full ray is requested |
---|
506 | and the method cannot provide it, it will throw an exception. |
---|
507 | |
---|
508 | <strong>NOTE for implementers of solver interfaces:</strong> <br> |
---|
509 | The double pointers in the vector should point to arrays of length |
---|
510 | getNumRows() and they should be allocated via new[]. <br> |
---|
511 | |
---|
512 | <strong>NOTE for users of solver interfaces:</strong> <br> |
---|
513 | It is the user's responsibility to free the double pointers in the |
---|
514 | vector using delete[]. |
---|
515 | */ |
---|
516 | virtual std::vector<double*> getDualRays(int maxNumRays, |
---|
517 | bool fullRay = false) const; |
---|
518 | /** Get as many primal rays as the solver can provide. (In case of proven |
---|
519 | dual infeasibility there should be at least one.) |
---|
520 | |
---|
521 | <strong>NOTE for implementers of solver interfaces:</strong> <br> |
---|
522 | The double pointers in the vector should point to arrays of length |
---|
523 | getNumCols() and they should be allocated via new[]. <br> |
---|
524 | |
---|
525 | <strong>NOTE for users of solver interfaces:</strong> <br> |
---|
526 | It is the user's responsibility to free the double pointers in the |
---|
527 | vector using delete[]. |
---|
528 | */ |
---|
529 | virtual std::vector<double*> getPrimalRays(int maxNumRays) const; |
---|
530 | |
---|
531 | //@} |
---|
532 | //@} |
---|
533 | |
---|
534 | //--------------------------------------------------------------------------- |
---|
535 | |
---|
536 | /**@name Problem modifying methods */ |
---|
537 | //@{ |
---|
538 | //------------------------------------------------------------------------- |
---|
539 | /**@name Changing bounds on variables and constraints */ |
---|
540 | //@{ |
---|
541 | /** Set an objective function coefficient */ |
---|
542 | virtual void setObjCoeff( int elementIndex, double elementValue ); |
---|
543 | |
---|
544 | /** Set a single column lower bound<br> |
---|
545 | Use -DBL_MAX for -infinity. */ |
---|
546 | virtual void setColLower( int elementIndex, double elementValue ); |
---|
547 | |
---|
548 | /** Set a single column upper bound<br> |
---|
549 | Use DBL_MAX for infinity. */ |
---|
550 | virtual void setColUpper( int elementIndex, double elementValue ); |
---|
551 | |
---|
552 | /** Set a single column lower and upper bound */ |
---|
553 | virtual void setColBounds( int elementIndex, |
---|
554 | double lower, double upper ); |
---|
555 | |
---|
556 | /** Set the bounds on a number of columns simultaneously<br> |
---|
557 | The default implementation just invokes setColLower() and |
---|
558 | setColUpper() over and over again. |
---|
559 | @param indexFirst,indexLast pointers to the beginning and after the |
---|
560 | end of the array of the indices of the variables whose |
---|
561 | <em>either</em> bound changes |
---|
562 | @param boundList the new lower/upper bound pairs for the variables |
---|
563 | */ |
---|
564 | virtual void setColSetBounds(const int* indexFirst, |
---|
565 | const int* indexLast, |
---|
566 | const double* boundList); |
---|
567 | |
---|
568 | /** Set a single row lower bound<br> |
---|
569 | Use -DBL_MAX for -infinity. */ |
---|
570 | virtual void setRowLower( int elementIndex, double elementValue ); |
---|
571 | |
---|
572 | /** Set a single row upper bound<br> |
---|
573 | Use DBL_MAX for infinity. */ |
---|
574 | virtual void setRowUpper( int elementIndex, double elementValue ) ; |
---|
575 | |
---|
576 | /** Set a single row lower and upper bound */ |
---|
577 | virtual void setRowBounds( int elementIndex, |
---|
578 | double lower, double upper ) ; |
---|
579 | |
---|
580 | /** Set the type of a single row<br> */ |
---|
581 | virtual void setRowType(int index, char sense, double rightHandSide, |
---|
582 | double range); |
---|
583 | |
---|
584 | /** Set the bounds on a number of rows simultaneously<br> |
---|
585 | The default implementation just invokes setRowLower() and |
---|
586 | setRowUpper() over and over again. |
---|
587 | @param indexFirst,indexLast pointers to the beginning and after the |
---|
588 | end of the array of the indices of the constraints whose |
---|
589 | <em>either</em> bound changes |
---|
590 | @param boundList the new lower/upper bound pairs for the constraints |
---|
591 | */ |
---|
592 | virtual void setRowSetBounds(const int* indexFirst, |
---|
593 | const int* indexLast, |
---|
594 | const double* boundList); |
---|
595 | |
---|
596 | /** Set the type of a number of rows simultaneously<br> |
---|
597 | The default implementation just invokes setRowType() |
---|
598 | over and over again. |
---|
599 | @param indexFirst,indexLast pointers to the beginning and after the |
---|
600 | end of the array of the indices of the constraints whose |
---|
601 | <em>any</em> characteristics changes |
---|
602 | @param senseList the new senses |
---|
603 | @param rhsList the new right hand sides |
---|
604 | @param rangeList the new ranges |
---|
605 | */ |
---|
606 | virtual void setRowSetTypes(const int* indexFirst, |
---|
607 | const int* indexLast, |
---|
608 | const char* senseList, |
---|
609 | const double* rhsList, |
---|
610 | const double* rangeList); |
---|
611 | /** Set the objective coefficients for all columns |
---|
612 | array [getNumCols()] is an array of values for the objective. |
---|
613 | This defaults to a series of set operations and is here for speed. |
---|
614 | */ |
---|
615 | virtual void setObjective(const double * array); |
---|
616 | |
---|
617 | /** Set the lower bounds for all columns |
---|
618 | array [getNumCols()] is an array of values for the objective. |
---|
619 | This defaults to a series of set operations and is here for speed. |
---|
620 | */ |
---|
621 | virtual void setColLower(const double * array); |
---|
622 | |
---|
623 | /** Set the upper bounds for all columns |
---|
624 | array [getNumCols()] is an array of values for the objective. |
---|
625 | This defaults to a series of set operations and is here for speed. |
---|
626 | */ |
---|
627 | virtual void setColUpper(const double * array); |
---|
628 | |
---|
629 | // using OsiSolverInterface::setRowName ; |
---|
630 | /// Set name of row |
---|
631 | // virtual void setRowName(int rowIndex, std::string & name) ; |
---|
632 | virtual void setRowName(int rowIndex, std::string name) ; |
---|
633 | |
---|
634 | // using OsiSolverInterface::setColName ; |
---|
635 | /// Set name of column |
---|
636 | // virtual void setColName(int colIndex, std::string & name) ; |
---|
637 | virtual void setColName(int colIndex, std::string name) ; |
---|
638 | |
---|
639 | //@} |
---|
640 | |
---|
641 | //------------------------------------------------------------------------- |
---|
642 | /**@name Integrality related changing methods */ |
---|
643 | //@{ |
---|
644 | /** Set the index-th variable to be a continuous variable */ |
---|
645 | virtual void setContinuous(int index); |
---|
646 | /** Set the index-th variable to be an integer variable */ |
---|
647 | virtual void setInteger(int index); |
---|
648 | /** Set the variables listed in indices (which is of length len) to be |
---|
649 | continuous variables */ |
---|
650 | virtual void setContinuous(const int* indices, int len); |
---|
651 | /** Set the variables listed in indices (which is of length len) to be |
---|
652 | integer variables */ |
---|
653 | virtual void setInteger(const int* indices, int len); |
---|
654 | /// Number of SOS sets |
---|
655 | inline int numberSOS() const |
---|
656 | { return numberSOS_;} |
---|
657 | /// SOS set info |
---|
658 | inline const CoinSet * setInfo() const |
---|
659 | { return setInfo_;} |
---|
660 | /** \brief Identify integer variables and SOS and create corresponding objects. |
---|
661 | |
---|
662 | Record integer variables and create an OsiSimpleInteger object for each |
---|
663 | one. All existing OsiSimpleInteger objects will be destroyed. |
---|
664 | If the solver supports SOS then do the same for SOS. |
---|
665 | If justCount then no objects created and we just store numberIntegers_ |
---|
666 | Returns number of SOS |
---|
667 | */ |
---|
668 | |
---|
669 | virtual int findIntegersAndSOS(bool justCount); |
---|
670 | //@} |
---|
671 | |
---|
672 | //------------------------------------------------------------------------- |
---|
673 | /// Set objective function sense (1 for min (default), -1 for max,) |
---|
674 | virtual void setObjSense(double s ) |
---|
675 | { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); } |
---|
676 | |
---|
677 | /** Set the primal solution column values |
---|
678 | |
---|
679 | colsol[numcols()] is an array of values of the problem column |
---|
680 | variables. These values are copied to memory owned by the |
---|
681 | solver object or the solver. They will be returned as the |
---|
682 | result of colsol() until changed by another call to |
---|
683 | setColsol() or by a call to any solver routine. Whether the |
---|
684 | solver makes use of the solution in any way is |
---|
685 | solver-dependent. |
---|
686 | */ |
---|
687 | virtual void setColSolution(const double * colsol); |
---|
688 | |
---|
689 | /** Set dual solution vector |
---|
690 | |
---|
691 | rowprice[numrows()] is an array of values of the problem row |
---|
692 | dual variables. These values are copied to memory owned by the |
---|
693 | solver object or the solver. They will be returned as the |
---|
694 | result of rowprice() until changed by another call to |
---|
695 | setRowprice() or by a call to any solver routine. Whether the |
---|
696 | solver makes use of the solution in any way is |
---|
697 | solver-dependent. |
---|
698 | */ |
---|
699 | virtual void setRowPrice(const double * rowprice); |
---|
700 | |
---|
701 | //------------------------------------------------------------------------- |
---|
702 | /**@name Methods to expand a problem.<br> |
---|
703 | Note that if a column is added then by default it will correspond to a |
---|
704 | continuous variable. */ |
---|
705 | //@{ |
---|
706 | |
---|
707 | //using OsiSolverInterface::addCol ; |
---|
708 | /** */ |
---|
709 | virtual void addCol(const CoinPackedVectorBase& vec, |
---|
710 | const double collb, const double colub, |
---|
711 | const double obj); |
---|
712 | /*! \brief Add a named column (primal variable) to the problem. |
---|
713 | */ |
---|
714 | virtual void addCol(const CoinPackedVectorBase& vec, |
---|
715 | const double collb, const double colub, |
---|
716 | const double obj, std::string name) ; |
---|
717 | /** Add a column (primal variable) to the problem. */ |
---|
718 | virtual void addCol(int numberElements, const int * rows, const double * elements, |
---|
719 | const double collb, const double colub, |
---|
720 | const double obj) ; |
---|
721 | /*! \brief Add a named column (primal variable) to the problem. |
---|
722 | */ |
---|
723 | virtual void addCol(int numberElements, |
---|
724 | const int* rows, const double* elements, |
---|
725 | const double collb, const double colub, |
---|
726 | const double obj, std::string name) ; |
---|
727 | /** */ |
---|
728 | virtual void addCols(const int numcols, |
---|
729 | const CoinPackedVectorBase * const * cols, |
---|
730 | const double* collb, const double* colub, |
---|
731 | const double* obj); |
---|
732 | /** */ |
---|
733 | virtual void addCols(const int numcols, |
---|
734 | const int * columnStarts, const int * rows, const double * elements, |
---|
735 | const double* collb, const double* colub, |
---|
736 | const double* obj); |
---|
737 | /** */ |
---|
738 | virtual void deleteCols(const int num, const int * colIndices); |
---|
739 | |
---|
740 | /** */ |
---|
741 | virtual void addRow(const CoinPackedVectorBase& vec, |
---|
742 | const double rowlb, const double rowub); |
---|
743 | /** */ |
---|
744 | /*! \brief Add a named row (constraint) to the problem. |
---|
745 | |
---|
746 | The default implementation adds the row, then changes the name. This |
---|
747 | can surely be made more efficient within an OsiXXX class. |
---|
748 | */ |
---|
749 | virtual void addRow(const CoinPackedVectorBase& vec, |
---|
750 | const double rowlb, const double rowub, |
---|
751 | std::string name) ; |
---|
752 | virtual void addRow(const CoinPackedVectorBase& vec, |
---|
753 | const char rowsen, const double rowrhs, |
---|
754 | const double rowrng); |
---|
755 | /** Add a row (constraint) to the problem. */ |
---|
756 | virtual void addRow(int numberElements, const int * columns, const double * element, |
---|
757 | const double rowlb, const double rowub) ; |
---|
758 | /*! \brief Add a named row (constraint) to the problem. |
---|
759 | */ |
---|
760 | virtual void addRow(const CoinPackedVectorBase& vec, |
---|
761 | const char rowsen, const double rowrhs, |
---|
762 | const double rowrng, std::string name) ; |
---|
763 | /** */ |
---|
764 | virtual void addRows(const int numrows, |
---|
765 | const CoinPackedVectorBase * const * rows, |
---|
766 | const double* rowlb, const double* rowub); |
---|
767 | /** */ |
---|
768 | virtual void addRows(const int numrows, |
---|
769 | const CoinPackedVectorBase * const * rows, |
---|
770 | const char* rowsen, const double* rowrhs, |
---|
771 | const double* rowrng); |
---|
772 | |
---|
773 | /** */ |
---|
774 | virtual void addRows(const int numrows, |
---|
775 | const int * rowStarts, const int * columns, const double * element, |
---|
776 | const double* rowlb, const double* rowub); |
---|
777 | /// |
---|
778 | void modifyCoefficient(int row, int column, double newElement, |
---|
779 | bool keepZero=false) |
---|
780 | {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);} |
---|
781 | |
---|
782 | /** */ |
---|
783 | virtual void deleteRows(const int num, const int * rowIndices); |
---|
784 | /** If solver wants it can save a copy of "base" (continuous) model here |
---|
785 | */ |
---|
786 | virtual void saveBaseModel() ; |
---|
787 | /** Strip off rows to get to this number of rows. |
---|
788 | If solver wants it can restore a copy of "base" (continuous) model here |
---|
789 | */ |
---|
790 | virtual void restoreBaseModel(int numberRows); |
---|
791 | |
---|
792 | //----------------------------------------------------------------------- |
---|
793 | /** Apply a collection of row cuts which are all effective. |
---|
794 | applyCuts seems to do one at a time which seems inefficient. |
---|
795 | */ |
---|
796 | virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); |
---|
797 | /** Apply a collection of row cuts which are all effective. |
---|
798 | applyCuts seems to do one at a time which seems inefficient. |
---|
799 | This uses array of pointers |
---|
800 | */ |
---|
801 | virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); |
---|
802 | /** Apply a collection of cuts. |
---|
803 | |
---|
804 | Only cuts which have an <code>effectiveness >= effectivenessLb</code> |
---|
805 | are applied. |
---|
806 | <ul> |
---|
807 | <li> ReturnCode.getNumineffective() -- number of cuts which were |
---|
808 | not applied because they had an |
---|
809 | <code>effectiveness < effectivenessLb</code> |
---|
810 | <li> ReturnCode.getNuminconsistent() -- number of invalid cuts |
---|
811 | <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of |
---|
812 | cuts that are invalid with respect to this integer model |
---|
813 | <li> ReturnCode.getNuminfeasible() -- number of cuts that would |
---|
814 | make this integer model infeasible |
---|
815 | <li> ReturnCode.getNumApplied() -- number of integer cuts which |
---|
816 | were applied to the integer model |
---|
817 | <li> cs.size() == getNumineffective() + |
---|
818 | getNuminconsistent() + |
---|
819 | getNuminconsistentWrtIntegerModel() + |
---|
820 | getNuminfeasible() + |
---|
821 | getNumApplied() |
---|
822 | </ul> |
---|
823 | */ |
---|
824 | virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, |
---|
825 | double effectivenessLb = 0.0); |
---|
826 | |
---|
827 | //@} |
---|
828 | //@} |
---|
829 | |
---|
830 | //--------------------------------------------------------------------------- |
---|
831 | |
---|
832 | public: |
---|
833 | |
---|
834 | /**@name Methods to input a problem */ |
---|
835 | //@{ |
---|
836 | /** Load in an problem by copying the arguments (the constraints on the |
---|
837 | rows are given by lower and upper bounds). If a pointer is NULL then the |
---|
838 | following values are the default: |
---|
839 | <ul> |
---|
840 | <li> <code>colub</code>: all columns have upper bound infinity |
---|
841 | <li> <code>collb</code>: all columns have lower bound 0 |
---|
842 | <li> <code>rowub</code>: all rows have upper bound infinity |
---|
843 | <li> <code>rowlb</code>: all rows have lower bound -infinity |
---|
844 | <li> <code>obj</code>: all variables have 0 objective coefficient |
---|
845 | </ul> |
---|
846 | */ |
---|
847 | virtual void loadProblem(const CoinPackedMatrix& matrix, |
---|
848 | const double* collb, const double* colub, |
---|
849 | const double* obj, |
---|
850 | const double* rowlb, const double* rowub); |
---|
851 | |
---|
852 | /** Load in an problem by assuming ownership of the arguments (the |
---|
853 | constraints on the rows are given by lower and upper bounds). For |
---|
854 | default values see the previous method. <br> |
---|
855 | <strong>WARNING</strong>: The arguments passed to this method will be |
---|
856 | freed using the C++ <code>delete</code> and <code>delete[]</code> |
---|
857 | functions. |
---|
858 | */ |
---|
859 | virtual void assignProblem(CoinPackedMatrix*& matrix, |
---|
860 | double*& collb, double*& colub, double*& obj, |
---|
861 | double*& rowlb, double*& rowub); |
---|
862 | |
---|
863 | /** Load in an problem by copying the arguments (the constraints on the |
---|
864 | rows are given by sense/rhs/range triplets). If a pointer is NULL then the |
---|
865 | following values are the default: |
---|
866 | <ul> |
---|
867 | <li> <code>colub</code>: all columns have upper bound infinity |
---|
868 | <li> <code>collb</code>: all columns have lower bound 0 |
---|
869 | <li> <code>obj</code>: all variables have 0 objective coefficient |
---|
870 | <li> <code>rowsen</code>: all rows are >= |
---|
871 | <li> <code>rowrhs</code>: all right hand sides are 0 |
---|
872 | <li> <code>rowrng</code>: 0 for the ranged rows |
---|
873 | </ul> |
---|
874 | */ |
---|
875 | virtual void loadProblem(const CoinPackedMatrix& matrix, |
---|
876 | const double* collb, const double* colub, |
---|
877 | const double* obj, |
---|
878 | const char* rowsen, const double* rowrhs, |
---|
879 | const double* rowrng); |
---|
880 | |
---|
881 | /** Load in an problem by assuming ownership of the arguments (the |
---|
882 | constraints on the rows are given by sense/rhs/range triplets). For |
---|
883 | default values see the previous method. <br> |
---|
884 | <strong>WARNING</strong>: The arguments passed to this method will be |
---|
885 | freed using the C++ <code>delete</code> and <code>delete[]</code> |
---|
886 | functions. |
---|
887 | */ |
---|
888 | virtual void assignProblem(CoinPackedMatrix*& matrix, |
---|
889 | double*& collb, double*& colub, double*& obj, |
---|
890 | char*& rowsen, double*& rowrhs, |
---|
891 | double*& rowrng); |
---|
892 | |
---|
893 | /** Just like the other loadProblem() methods except that the matrix is |
---|
894 | given in a standard column major ordered format (without gaps). */ |
---|
895 | virtual void loadProblem(const int numcols, const int numrows, |
---|
896 | const CoinBigIndex * start, const int* index, |
---|
897 | const double* value, |
---|
898 | const double* collb, const double* colub, |
---|
899 | const double* obj, |
---|
900 | const double* rowlb, const double* rowub); |
---|
901 | |
---|
902 | /** Just like the other loadProblem() methods except that the matrix is |
---|
903 | given in a standard column major ordered format (without gaps). */ |
---|
904 | virtual void loadProblem(const int numcols, const int numrows, |
---|
905 | const CoinBigIndex * start, const int* index, |
---|
906 | const double* value, |
---|
907 | const double* collb, const double* colub, |
---|
908 | const double* obj, |
---|
909 | const char* rowsen, const double* rowrhs, |
---|
910 | const double* rowrng); |
---|
911 | /// This loads a model from a coinModel object - returns number of errors |
---|
912 | virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false); |
---|
913 | |
---|
914 | using OsiSolverInterface::readMps ; |
---|
915 | /** Read an mps file from the given filename (defaults to Osi reader) - returns |
---|
916 | number of errors (see OsiMpsReader class) */ |
---|
917 | virtual int readMps(const char *filename, |
---|
918 | const char *extension = "mps") ; |
---|
919 | /** Read an mps file from the given filename returns |
---|
920 | number of errors (see OsiMpsReader class) */ |
---|
921 | int readMps(const char *filename,bool keepNames,bool allowErrors); |
---|
922 | /// Read an mps file |
---|
923 | virtual int readMps (const char *filename, const char*extension, |
---|
924 | int & numberSets, CoinSet ** & sets); |
---|
925 | |
---|
926 | /** Write the problem into an mps file of the given filename. |
---|
927 | If objSense is non zero then -1.0 forces the code to write a |
---|
928 | maximization objective and +1.0 to write a minimization one. |
---|
929 | If 0.0 then solver can do what it wants */ |
---|
930 | virtual void writeMps(const char *filename, |
---|
931 | const char *extension = "mps", |
---|
932 | double objSense=0.0) const; |
---|
933 | /** Write the problem into an mps file of the given filename, |
---|
934 | names may be null. formatType is |
---|
935 | 0 - normal |
---|
936 | 1 - extra accuracy |
---|
937 | 2 - IEEE hex (later) |
---|
938 | |
---|
939 | Returns non-zero on I/O error |
---|
940 | */ |
---|
941 | virtual int writeMpsNative(const char *filename, |
---|
942 | const char ** rowNames, const char ** columnNames, |
---|
943 | int formatType=0,int numberAcross=2, |
---|
944 | double objSense=0.0) const ; |
---|
945 | /// Read file in LP format (with names) |
---|
946 | virtual int readLp(const char *filename, const double epsilon = 1e-5); |
---|
947 | /** Write the problem into an Lp file of the given filename. |
---|
948 | If objSense is non zero then -1.0 forces the code to write a |
---|
949 | maximization objective and +1.0 to write a minimization one. |
---|
950 | If 0.0 then solver can do what it wants. |
---|
951 | This version calls writeLpNative with names */ |
---|
952 | virtual void writeLp(const char *filename, |
---|
953 | const char *extension = "lp", |
---|
954 | double epsilon = 1e-5, |
---|
955 | int numberAcross = 10, |
---|
956 | int decimals = 5, |
---|
957 | double objSense = 0.0, |
---|
958 | bool useRowNames = true) const; |
---|
959 | /** Write the problem into the file pointed to by the parameter fp. |
---|
960 | Other parameters are similar to |
---|
961 | those of writeLp() with first parameter filename. |
---|
962 | */ |
---|
963 | virtual void writeLp(FILE *fp, |
---|
964 | double epsilon = 1e-5, |
---|
965 | int numberAcross = 10, |
---|
966 | int decimals = 5, |
---|
967 | double objSense = 0.0, |
---|
968 | bool useRowNames = true) const; |
---|
969 | /** |
---|
970 | I (JJF) am getting annoyed because I can't just replace a matrix. |
---|
971 | The default behavior of this is do nothing so only use where that would not matter |
---|
972 | e.g. strengthening a matrix for MIP |
---|
973 | */ |
---|
974 | virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix); |
---|
975 | /// And if it does matter (not used at present) |
---|
976 | virtual void replaceMatrix(const CoinPackedMatrix & matrix) ; |
---|
977 | //@} |
---|
978 | |
---|
979 | /**@name Message handling (extra for Clp messages). |
---|
980 | Normally I presume you would want the same language. |
---|
981 | If not then you could use underlying model pointer */ |
---|
982 | //@{ |
---|
983 | /** Pass in a message handler |
---|
984 | |
---|
985 | It is the client's responsibility to destroy a message handler installed |
---|
986 | by this routine; it will not be destroyed when the solver interface is |
---|
987 | destroyed. |
---|
988 | */ |
---|
989 | virtual void passInMessageHandler(CoinMessageHandler * handler); |
---|
990 | /// Set language |
---|
991 | void newLanguage(CoinMessages::Language language); |
---|
992 | void setLanguage(CoinMessages::Language language) |
---|
993 | {newLanguage(language);} |
---|
994 | /// Set log level (will also set underlying solver's log level) |
---|
995 | void setLogLevel(int value); |
---|
996 | /// Create C++ lines to get to current state |
---|
997 | void generateCpp( FILE * fp); |
---|
998 | //@} |
---|
999 | //--------------------------------------------------------------------------- |
---|
1000 | |
---|
1001 | /**@name Clp specific public interfaces */ |
---|
1002 | //@{ |
---|
1003 | /// Get pointer to Clp model |
---|
1004 | ClpSimplex * getModelPtr() const ; |
---|
1005 | /// Set pointer to Clp model and return old |
---|
1006 | inline ClpSimplex * swapModelPtr(ClpSimplex * newModel) |
---|
1007 | { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;} |
---|
1008 | /// Get special options |
---|
1009 | inline unsigned int specialOptions() const |
---|
1010 | { return specialOptions_;} |
---|
1011 | void setSpecialOptions(unsigned int value); |
---|
1012 | /// Last algorithm used , 1 = primal, 2 = dual |
---|
1013 | inline int lastAlgorithm() const |
---|
1014 | { return lastAlgorithm_;} |
---|
1015 | /// Get scaling action option |
---|
1016 | inline int cleanupScaling() const |
---|
1017 | { return cleanupScaling_;} |
---|
1018 | /** Set Scaling option |
---|
1019 | When scaling is on it is possible that the scaled problem |
---|
1020 | is feasible but the unscaled is not. Clp returns a secondary |
---|
1021 | status code to that effect. This option allows for a cleanup. |
---|
1022 | If you use it I would suggest 1. |
---|
1023 | This only affects actions when scaled optimal |
---|
1024 | 0 - no action |
---|
1025 | 1 - clean up using dual if primal infeasibility |
---|
1026 | 2 - clean up using dual if dual infeasibility |
---|
1027 | 3 - clean up using dual if primal or dual infeasibility |
---|
1028 | 11,12,13 - as 1,2,3 but use primal |
---|
1029 | */ |
---|
1030 | inline void setCleanupScaling(int value) |
---|
1031 | { cleanupScaling_=value;} |
---|
1032 | /** Get smallest allowed element in cut. |
---|
1033 | If smaller than this then ignored */ |
---|
1034 | inline double smallestElementInCut() const |
---|
1035 | { return smallestElementInCut_;} |
---|
1036 | /** Set smallest allowed element in cut. |
---|
1037 | If smaller than this then ignored */ |
---|
1038 | inline void setSmallestElementInCut(double value) |
---|
1039 | { smallestElementInCut_=value;} |
---|
1040 | /** Get smallest change in cut. |
---|
1041 | If (upper-lower)*element < this then element is |
---|
1042 | taken out and cut relaxed. |
---|
1043 | (upper-lower) is taken to be at least 1.0 and |
---|
1044 | this is assumed >= smallestElementInCut_ |
---|
1045 | */ |
---|
1046 | inline double smallestChangeInCut() const |
---|
1047 | { return smallestChangeInCut_;} |
---|
1048 | /** Set smallest change in cut. |
---|
1049 | If (upper-lower)*element < this then element is |
---|
1050 | taken out and cut relaxed. |
---|
1051 | (upper-lower) is taken to be at least 1.0 and |
---|
1052 | this is assumed >= smallestElementInCut_ |
---|
1053 | */ |
---|
1054 | inline void setSmallestChangeInCut(double value) |
---|
1055 | { smallestChangeInCut_=value;} |
---|
1056 | /// Pass in initial solve options |
---|
1057 | inline void setSolveOptions(const ClpSolve & options) |
---|
1058 | { solveOptions_ = options;} |
---|
1059 | /** Tighten bounds - lightweight or very lightweight |
---|
1060 | 0 - normal, 1 lightweight but just integers, 2 lightweight and all |
---|
1061 | */ |
---|
1062 | virtual int tightenBounds(int lightweight=0); |
---|
1063 | /// Return number of entries in L part of current factorization |
---|
1064 | virtual CoinBigIndex getSizeL() const; |
---|
1065 | /// Return number of entries in U part of current factorization |
---|
1066 | virtual CoinBigIndex getSizeU() const; |
---|
1067 | /// Get disaster handler |
---|
1068 | const OsiClpDisasterHandler * disasterHandler() const |
---|
1069 | { return disasterHandler_;} |
---|
1070 | /// Pass in disaster handler |
---|
1071 | void passInDisasterHandler(OsiClpDisasterHandler * handler); |
---|
1072 | /// Get fake objective |
---|
1073 | ClpLinearObjective * fakeObjective() const |
---|
1074 | { return fakeObjective_;} |
---|
1075 | /// Set fake objective (and take ownership) |
---|
1076 | void setFakeObjective(ClpLinearObjective * fakeObjective); |
---|
1077 | /// Set fake objective |
---|
1078 | void setFakeObjective(double * fakeObjective); |
---|
1079 | //@} |
---|
1080 | |
---|
1081 | //--------------------------------------------------------------------------- |
---|
1082 | |
---|
1083 | /**@name Constructors and destructors */ |
---|
1084 | //@{ |
---|
1085 | /// Default Constructor |
---|
1086 | OsiClpSolverInterface (); |
---|
1087 | |
---|
1088 | /// Clone |
---|
1089 | virtual OsiSolverInterface * clone(bool copyData = true) const; |
---|
1090 | |
---|
1091 | /// Copy constructor |
---|
1092 | OsiClpSolverInterface (const OsiClpSolverInterface &); |
---|
1093 | |
---|
1094 | /// Borrow constructor - only delete one copy |
---|
1095 | OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false); |
---|
1096 | |
---|
1097 | /// Releases so won't error |
---|
1098 | void releaseClp(); |
---|
1099 | |
---|
1100 | /// Assignment operator |
---|
1101 | OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs); |
---|
1102 | |
---|
1103 | /// Destructor |
---|
1104 | virtual ~OsiClpSolverInterface (); |
---|
1105 | |
---|
1106 | /// Resets as if default constructor |
---|
1107 | virtual void reset(); |
---|
1108 | //@} |
---|
1109 | |
---|
1110 | //--------------------------------------------------------------------------- |
---|
1111 | |
---|
1112 | protected: |
---|
1113 | ///@name Protected methods |
---|
1114 | //@{ |
---|
1115 | /** Apply a row cut (append to constraint matrix). */ |
---|
1116 | virtual void applyRowCut(const OsiRowCut& rc); |
---|
1117 | |
---|
1118 | /** Apply a column cut (adjust one or more bounds). */ |
---|
1119 | virtual void applyColCut(const OsiColCut& cc); |
---|
1120 | //@} |
---|
1121 | |
---|
1122 | //--------------------------------------------------------------------------- |
---|
1123 | |
---|
1124 | protected: |
---|
1125 | /**@name Protected methods */ |
---|
1126 | //@{ |
---|
1127 | /// The real work of a copy constructor (used by copy and assignment) |
---|
1128 | void gutsOfDestructor(); |
---|
1129 | |
---|
1130 | /// Deletes all mutable stuff |
---|
1131 | void freeCachedResults() const; |
---|
1132 | |
---|
1133 | /// Deletes all mutable stuff for row ranges etc |
---|
1134 | void freeCachedResults0() const; |
---|
1135 | |
---|
1136 | /// Deletes all mutable stuff for matrix etc |
---|
1137 | void freeCachedResults1() const; |
---|
1138 | |
---|
1139 | /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays |
---|
1140 | void extractSenseRhsRange() const; |
---|
1141 | |
---|
1142 | /// |
---|
1143 | void fillParamMaps(); |
---|
1144 | /** Warm start |
---|
1145 | |
---|
1146 | NOTE artificials are treated as +1 elements so for <= rhs |
---|
1147 | artificial will be at lower bound if constraint is tight |
---|
1148 | |
---|
1149 | This means that Clpsimplex flips artificials as it works |
---|
1150 | in terms of row activities |
---|
1151 | */ |
---|
1152 | CoinWarmStartBasis getBasis(ClpSimplex * model) const; |
---|
1153 | /** Sets up working basis as a copy of input |
---|
1154 | |
---|
1155 | NOTE artificials are treated as +1 elements so for <= rhs |
---|
1156 | artificial will be at lower bound if constraint is tight |
---|
1157 | |
---|
1158 | This means that Clpsimplex flips artificials as it works |
---|
1159 | in terms of row activities |
---|
1160 | */ |
---|
1161 | void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model); |
---|
1162 | /// Crunch down problem a bit |
---|
1163 | void crunch(); |
---|
1164 | /// Extend scale factors |
---|
1165 | void redoScaleFactors(int numberRows,const CoinBigIndex * starts, |
---|
1166 | const int * indices, const double * elements); |
---|
1167 | public: |
---|
1168 | /** Sets up working basis as a copy of input and puts in as basis |
---|
1169 | */ |
---|
1170 | void setBasis( const CoinWarmStartBasis & basis); |
---|
1171 | /// Just puts current basis_ into ClpSimplex model |
---|
1172 | inline void setBasis( ) |
---|
1173 | { setBasis(basis_,modelPtr_);} |
---|
1174 | /// Warm start difference from basis_ to statusArray |
---|
1175 | CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ; |
---|
1176 | /// Warm start from statusArray |
---|
1177 | CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ; |
---|
1178 | /// Delete all scale factor stuff and reset option |
---|
1179 | void deleteScaleFactors(); |
---|
1180 | /// If doing fast hot start then ranges are computed |
---|
1181 | inline const double * upRange() const |
---|
1182 | { return rowActivity_;} |
---|
1183 | inline const double * downRange() const |
---|
1184 | { return columnActivity_;} |
---|
1185 | /// Pass in range array |
---|
1186 | inline void passInRanges(int * array) |
---|
1187 | { whichRange_=array;} |
---|
1188 | /// Pass in sos stuff from AMPl |
---|
1189 | void setSOSData(int numberSOS,const char * type, |
---|
1190 | const int * start,const int * indices, const double * weights=NULL); |
---|
1191 | /// Compute largest amount any at continuous away from bound |
---|
1192 | void computeLargestAway(); |
---|
1193 | /// Get largest amount continuous away from bound |
---|
1194 | inline double largestAway() const |
---|
1195 | { return largestAway_;} |
---|
1196 | /// Set largest amount continuous away from bound |
---|
1197 | inline void setLargestAway(double value) |
---|
1198 | { largestAway_ = value;} |
---|
1199 | /// Sort of lexicographic resolve |
---|
1200 | void lexSolve(); |
---|
1201 | protected: |
---|
1202 | //@} |
---|
1203 | |
---|
1204 | /**@name Protected member data */ |
---|
1205 | //@{ |
---|
1206 | /// Clp model represented by this class instance |
---|
1207 | mutable ClpSimplex * modelPtr_; |
---|
1208 | /// Linear objective - just points to ClpModel |
---|
1209 | double * linearObjective_; |
---|
1210 | /**@name Cached information derived from the OSL model */ |
---|
1211 | //@{ |
---|
1212 | /// Pointer to dense vector of row sense indicators |
---|
1213 | mutable char *rowsense_; |
---|
1214 | |
---|
1215 | /// Pointer to dense vector of row right-hand side values |
---|
1216 | mutable double *rhs_; |
---|
1217 | |
---|
1218 | /** Pointer to dense vector of slack upper bounds for range |
---|
1219 | constraints (undefined for non-range rows) |
---|
1220 | */ |
---|
1221 | mutable double *rowrange_; |
---|
1222 | |
---|
1223 | /** A pointer to the warmstart information to be used in the hotstarts. |
---|
1224 | This is NOT efficient and more thought should be given to it... */ |
---|
1225 | mutable CoinWarmStartBasis* ws_; |
---|
1226 | /** also save row and column information for hot starts |
---|
1227 | only used in hotstarts so can be casual */ |
---|
1228 | mutable double * rowActivity_; |
---|
1229 | mutable double * columnActivity_; |
---|
1230 | /// Stuff for fast dual |
---|
1231 | ClpNodeStuff stuff_; |
---|
1232 | /// Number of SOS sets |
---|
1233 | int numberSOS_; |
---|
1234 | /// SOS set info |
---|
1235 | CoinSet * setInfo_; |
---|
1236 | /// Alternate model (hot starts) - but also could be permanent and used for crunch |
---|
1237 | ClpSimplex * smallModel_; |
---|
1238 | /// factorization for hot starts |
---|
1239 | ClpFactorization * factorization_; |
---|
1240 | /** Smallest allowed element in cut. |
---|
1241 | If smaller than this then ignored */ |
---|
1242 | double smallestElementInCut_; |
---|
1243 | /** Smallest change in cut. |
---|
1244 | If (upper-lower)*element < this then element is |
---|
1245 | taken out and cut relaxed. */ |
---|
1246 | double smallestChangeInCut_; |
---|
1247 | /// Largest amount continuous away from bound |
---|
1248 | double largestAway_; |
---|
1249 | /// Arrays for hot starts |
---|
1250 | char * spareArrays_; |
---|
1251 | /** Warmstart information to be used in resolves. */ |
---|
1252 | CoinWarmStartBasis basis_; |
---|
1253 | /** The original iteration limit before hotstarts started. */ |
---|
1254 | int itlimOrig_; |
---|
1255 | |
---|
1256 | /// Last algorithm used , 1 = primal, 2 = dual |
---|
1257 | mutable int lastAlgorithm_; |
---|
1258 | |
---|
1259 | /// To say if destructor should delete underlying model |
---|
1260 | bool notOwned_; |
---|
1261 | |
---|
1262 | /// Pointer to row-wise copy of problem matrix coefficients. |
---|
1263 | mutable CoinPackedMatrix *matrixByRow_; |
---|
1264 | |
---|
1265 | /// Pointer to row-wise copy of continuous problem matrix coefficients. |
---|
1266 | CoinPackedMatrix *matrixByRowAtContinuous_; |
---|
1267 | |
---|
1268 | /// Pointer to integer information |
---|
1269 | char * integerInformation_; |
---|
1270 | |
---|
1271 | /** Pointer to variables for which we want range information |
---|
1272 | The number is in [0] |
---|
1273 | memory is not owned by OsiClp |
---|
1274 | */ |
---|
1275 | int * whichRange_; |
---|
1276 | |
---|
1277 | //std::map<OsiIntParam, ClpIntParam> intParamMap_; |
---|
1278 | //std::map<OsiDblParam, ClpDblParam> dblParamMap_; |
---|
1279 | //std::map<OsiStrParam, ClpStrParam> strParamMap_; |
---|
1280 | |
---|
1281 | /// To save data in OsiSimplex stuff |
---|
1282 | mutable ClpDataSave saveData_; |
---|
1283 | /// Options for initialSolve |
---|
1284 | ClpSolve solveOptions_; |
---|
1285 | /** Scaling option |
---|
1286 | When scaling is on it is possible that the scaled problem |
---|
1287 | is feasible but the unscaled is not. Clp returns a secondary |
---|
1288 | status code to that effect. This option allows for a cleanup. |
---|
1289 | If you use it I would suggest 1. |
---|
1290 | This only affects actions when scaled optimal |
---|
1291 | 0 - no action |
---|
1292 | 1 - clean up using dual if primal infeasibility |
---|
1293 | 2 - clean up using dual if dual infeasibility |
---|
1294 | 3 - clean up using dual if primal or dual infeasibility |
---|
1295 | 11,12,13 - as 1,2,3 but use primal |
---|
1296 | */ |
---|
1297 | int cleanupScaling_; |
---|
1298 | /** Special options |
---|
1299 | 0x80000000 off |
---|
1300 | 0 simple stuff for branch and bound |
---|
1301 | 1 try and keep work regions as much as possible |
---|
1302 | 2 do not use any perturbation |
---|
1303 | 4 allow exit before re-factorization |
---|
1304 | 8 try and re-use factorization if no cuts |
---|
1305 | 16 use standard strong branching rather than clp's |
---|
1306 | 32 Just go to first factorization in fast dual |
---|
1307 | 64 try and tighten bounds in crunch |
---|
1308 | 128 Model will only change in column bounds |
---|
1309 | 256 Clean up model before hot start |
---|
1310 | 512 Give user direct access to Clp regions in getBInvARow etc |
---|
1311 | 1024 Don't "borrow" model in initialSolve |
---|
1312 | 2048 Don't crunch |
---|
1313 | 4096 quick check for optimality |
---|
1314 | Bits above 8192 give where called from in Cbc |
---|
1315 | At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check |
---|
1316 | 65536 Keep simple i.e. no crunch etc |
---|
1317 | 131072 Try and keep scaling factors around |
---|
1318 | 262144 Don't try and tighten bounds (funny global cuts) |
---|
1319 | 524288 Fake objective and 0-1 |
---|
1320 | 1048576 Don't recompute ray after crunch |
---|
1321 | */ |
---|
1322 | mutable unsigned int specialOptions_; |
---|
1323 | /// Copy of model when option 131072 set |
---|
1324 | ClpSimplex * baseModel_; |
---|
1325 | /// Number of rows when last "scaled" |
---|
1326 | int lastNumberRows_; |
---|
1327 | /// Continuous model |
---|
1328 | ClpSimplex * continuousModel_; |
---|
1329 | /// Possible disaster handler |
---|
1330 | OsiClpDisasterHandler * disasterHandler_ ; |
---|
1331 | /// Fake objective |
---|
1332 | ClpLinearObjective * fakeObjective_; |
---|
1333 | /// Row scale factors (has inverse at end) |
---|
1334 | CoinDoubleArrayWithLength rowScale_; |
---|
1335 | /// Column scale factors (has inverse at end) |
---|
1336 | CoinDoubleArrayWithLength columnScale_; |
---|
1337 | //@} |
---|
1338 | }; |
---|
1339 | |
---|
1340 | class OsiClpDisasterHandler : public ClpDisasterHandler { |
---|
1341 | public: |
---|
1342 | /**@name Virtual methods that the derived classe should provide. |
---|
1343 | */ |
---|
1344 | //@{ |
---|
1345 | /// Into simplex |
---|
1346 | virtual void intoSimplex(); |
---|
1347 | /// Checks if disaster |
---|
1348 | virtual bool check() const ; |
---|
1349 | /// saves information for next attempt |
---|
1350 | virtual void saveInfo(); |
---|
1351 | /// Type of disaster 0 can fix, 1 abort |
---|
1352 | virtual int typeOfDisaster(); |
---|
1353 | //@} |
---|
1354 | |
---|
1355 | |
---|
1356 | /**@name Constructors, destructor */ |
---|
1357 | |
---|
1358 | //@{ |
---|
1359 | /** Default constructor. */ |
---|
1360 | OsiClpDisasterHandler(OsiClpSolverInterface * model = NULL); |
---|
1361 | /** Destructor */ |
---|
1362 | virtual ~OsiClpDisasterHandler(); |
---|
1363 | // Copy |
---|
1364 | OsiClpDisasterHandler(const OsiClpDisasterHandler&); |
---|
1365 | // Assignment |
---|
1366 | OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&); |
---|
1367 | /// Clone |
---|
1368 | virtual ClpDisasterHandler * clone() const; |
---|
1369 | |
---|
1370 | //@} |
---|
1371 | |
---|
1372 | /**@name Sets/gets */ |
---|
1373 | |
---|
1374 | //@{ |
---|
1375 | /** set model. */ |
---|
1376 | void setOsiModel(OsiClpSolverInterface * model); |
---|
1377 | /// Get model |
---|
1378 | inline OsiClpSolverInterface * osiModel() const |
---|
1379 | { return osiModel_;} |
---|
1380 | /// Set where from |
---|
1381 | inline void setWhereFrom(int value) |
---|
1382 | { whereFrom_=value;} |
---|
1383 | /// Get where from |
---|
1384 | inline int whereFrom() const |
---|
1385 | { return whereFrom_;} |
---|
1386 | /// Set phase |
---|
1387 | inline void setPhase(int value) |
---|
1388 | { phase_=value;} |
---|
1389 | /// Get phase |
---|
1390 | inline int phase() const |
---|
1391 | { return phase_;} |
---|
1392 | /// are we in trouble |
---|
1393 | inline bool inTrouble() const |
---|
1394 | { return inTrouble_;} |
---|
1395 | |
---|
1396 | //@} |
---|
1397 | |
---|
1398 | |
---|
1399 | protected: |
---|
1400 | /**@name Data members |
---|
1401 | The data members are protected to allow access for derived classes. */ |
---|
1402 | //@{ |
---|
1403 | /// Pointer to model |
---|
1404 | OsiClpSolverInterface * osiModel_; |
---|
1405 | /** Where from |
---|
1406 | 0 dual (resolve) |
---|
1407 | 1 crunch |
---|
1408 | 2 primal (resolve) |
---|
1409 | 4 dual (initialSolve) |
---|
1410 | 6 primal (initialSolve) |
---|
1411 | */ |
---|
1412 | int whereFrom_; |
---|
1413 | /** phase |
---|
1414 | 0 initial |
---|
1415 | 1 trying continuing with back in and maybe different perturb |
---|
1416 | 2 trying continuing with back in and different scaling |
---|
1417 | 3 trying dual from all slack |
---|
1418 | 4 trying primal from previous stored basis |
---|
1419 | */ |
---|
1420 | int phase_; |
---|
1421 | /// Are we in trouble |
---|
1422 | bool inTrouble_; |
---|
1423 | |
---|
1424 | //@} |
---|
1425 | }; |
---|
1426 | // So unit test can find out if NDEBUG set |
---|
1427 | bool OsiClpHasNDEBUG(); |
---|
1428 | //############################################################################# |
---|
1429 | /** A function that tests the methods in the OsiClpSolverInterface class. The |
---|
1430 | only reason for it not to be a member method is that this way it doesn't |
---|
1431 | have to be compiled into the library. And that's a gain, because the |
---|
1432 | library should be compiled with optimization on, but this method should be |
---|
1433 | compiled with debugging. Also, if this method is compiled with |
---|
1434 | optimization, the compilation takes 10-15 minutes and the machine pages |
---|
1435 | (has 256M core memory!)... */ |
---|
1436 | int |
---|
1437 | OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); |
---|
1438 | #endif |
---|