1 | // Copyright (C) 2002, International Business Machines |
---|
2 | // Corporation and others. All Rights Reserved. |
---|
3 | |
---|
4 | #include <cmath> |
---|
5 | #include <cassert> |
---|
6 | #include <cfloat> |
---|
7 | #include <string> |
---|
8 | #include <cstdio> |
---|
9 | #include <iostream> |
---|
10 | |
---|
11 | #include <time.h> |
---|
12 | |
---|
13 | #include "CoinPragma.hpp" |
---|
14 | #ifndef _MSC_VER |
---|
15 | #include <sys/times.h> |
---|
16 | #include <sys/resource.h> |
---|
17 | #include <unistd.h> |
---|
18 | #endif |
---|
19 | |
---|
20 | #include "CoinHelperFunctions.hpp" |
---|
21 | #include "ClpModel.hpp" |
---|
22 | #include "ClpPackedMatrix.hpp" |
---|
23 | #include "CoinPackedVector.hpp" |
---|
24 | #include "CoinIndexedVector.hpp" |
---|
25 | #include "CoinMpsIO.hpp" |
---|
26 | #include "ClpMessage.hpp" |
---|
27 | #include "ClpLinearObjective.hpp" |
---|
28 | |
---|
29 | static double cpuTime() |
---|
30 | { |
---|
31 | double cpu_temp; |
---|
32 | #if defined(_MSC_VER) |
---|
33 | unsigned int ticksnow; /* clock_t is same as int */ |
---|
34 | |
---|
35 | ticksnow = (unsigned int)clock(); |
---|
36 | |
---|
37 | cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC); |
---|
38 | #else |
---|
39 | struct rusage usage; |
---|
40 | getrusage(RUSAGE_SELF,&usage); |
---|
41 | cpu_temp = usage.ru_utime.tv_sec; |
---|
42 | cpu_temp += 1.0e-6*((double) usage.ru_utime.tv_usec); |
---|
43 | #endif |
---|
44 | return cpu_temp; |
---|
45 | } |
---|
46 | //############################################################################# |
---|
47 | |
---|
48 | ClpModel::ClpModel () : |
---|
49 | |
---|
50 | optimizationDirection_(1), |
---|
51 | objectiveValue_(0.0), |
---|
52 | smallElement_(1.0e-20), |
---|
53 | numberRows_(0), |
---|
54 | numberColumns_(0), |
---|
55 | rowActivity_(NULL), |
---|
56 | columnActivity_(NULL), |
---|
57 | dual_(NULL), |
---|
58 | reducedCost_(NULL), |
---|
59 | rowLower_(NULL), |
---|
60 | rowUpper_(NULL), |
---|
61 | objective_(NULL), |
---|
62 | rowObjective_(NULL), |
---|
63 | columnLower_(NULL), |
---|
64 | columnUpper_(NULL), |
---|
65 | matrix_(NULL), |
---|
66 | rowCopy_(NULL), |
---|
67 | quadraticObjective_(NULL), |
---|
68 | ray_(NULL), |
---|
69 | status_(NULL), |
---|
70 | integerType_(NULL), |
---|
71 | numberIterations_(0), |
---|
72 | solveType_(0), |
---|
73 | problemStatus_(-1), |
---|
74 | lengthNames_(0), |
---|
75 | defaultHandler_(true), |
---|
76 | rowNames_(), |
---|
77 | columnNames_() |
---|
78 | { |
---|
79 | intParam_[ClpMaxNumIteration] = 99999999; |
---|
80 | intParam_[ClpMaxNumIterationHotStart] = 9999999; |
---|
81 | |
---|
82 | dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX; |
---|
83 | dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX; |
---|
84 | dblParam_[ClpDualTolerance] = 1e-7; |
---|
85 | dblParam_[ClpPrimalTolerance] = 1e-7; |
---|
86 | dblParam_[ClpObjOffset] = 0.0; |
---|
87 | dblParam_[ClpMaxSeconds] = -1.0; |
---|
88 | |
---|
89 | strParam_[ClpProbName] = "ClpDefaultName"; |
---|
90 | handler_ = new CoinMessageHandler(); |
---|
91 | handler_->setLogLevel(2); |
---|
92 | messages_ = ClpMessage(); |
---|
93 | } |
---|
94 | |
---|
95 | //----------------------------------------------------------------------------- |
---|
96 | |
---|
97 | ClpModel::~ClpModel () |
---|
98 | { |
---|
99 | if (defaultHandler_) { |
---|
100 | delete handler_; |
---|
101 | handler_ = NULL; |
---|
102 | } |
---|
103 | gutsOfDelete(); |
---|
104 | } |
---|
105 | void ClpModel::gutsOfDelete() |
---|
106 | { |
---|
107 | delete [] rowActivity_; |
---|
108 | rowActivity_=NULL; |
---|
109 | delete [] columnActivity_; |
---|
110 | columnActivity_=NULL; |
---|
111 | delete [] dual_; |
---|
112 | dual_=NULL; |
---|
113 | delete [] reducedCost_; |
---|
114 | reducedCost_=NULL; |
---|
115 | delete [] rowLower_; |
---|
116 | delete [] rowUpper_; |
---|
117 | delete [] rowObjective_; |
---|
118 | rowLower_=NULL; |
---|
119 | rowUpper_=NULL; |
---|
120 | rowObjective_=NULL; |
---|
121 | delete [] columnLower_; |
---|
122 | delete [] columnUpper_; |
---|
123 | delete objective_; |
---|
124 | columnLower_=NULL; |
---|
125 | columnUpper_=NULL; |
---|
126 | objective_=NULL; |
---|
127 | delete matrix_; |
---|
128 | matrix_=NULL; |
---|
129 | delete rowCopy_; |
---|
130 | rowCopy_=NULL; |
---|
131 | delete quadraticObjective_; |
---|
132 | quadraticObjective_ = NULL; |
---|
133 | delete [] ray_; |
---|
134 | ray_ = NULL; |
---|
135 | delete [] integerType_; |
---|
136 | integerType_ = NULL; |
---|
137 | delete [] status_; |
---|
138 | status_=NULL; |
---|
139 | } |
---|
140 | //############################################################################# |
---|
141 | void ClpModel::setPrimalTolerance( double value) |
---|
142 | { |
---|
143 | if (value>0.0&&value<1.0e10) |
---|
144 | dblParam_[ClpPrimalTolerance]=value; |
---|
145 | } |
---|
146 | void ClpModel::setDualTolerance( double value) |
---|
147 | { |
---|
148 | if (value>0.0&&value<1.0e10) |
---|
149 | dblParam_[ClpDualTolerance]=value; |
---|
150 | } |
---|
151 | void ClpModel::setOptimizationDirection( int value) |
---|
152 | { |
---|
153 | if (value>=-1&&value<=1) |
---|
154 | optimizationDirection_=value; |
---|
155 | } |
---|
156 | void |
---|
157 | ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, |
---|
158 | const double* collb, const double* colub, |
---|
159 | const double* obj, |
---|
160 | const double* rowlb, const double* rowub, |
---|
161 | const double * rowObjective) |
---|
162 | { |
---|
163 | gutsOfDelete(); |
---|
164 | numberRows_=numberRows; |
---|
165 | numberColumns_=numberColumns; |
---|
166 | rowActivity_=new double[numberRows_]; |
---|
167 | columnActivity_=new double[numberColumns_]; |
---|
168 | dual_=new double[numberRows_]; |
---|
169 | reducedCost_=new double[numberColumns_]; |
---|
170 | |
---|
171 | ClpFillN(dual_,numberRows_,0.0); |
---|
172 | ClpFillN(reducedCost_,numberColumns_,0.0); |
---|
173 | int iRow,iColumn; |
---|
174 | |
---|
175 | rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX); |
---|
176 | rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX); |
---|
177 | double * objective=ClpCopyOfArray(obj,numberColumns_,0.0); |
---|
178 | objective_ = new ClpLinearObjective(objective,numberColumns_); |
---|
179 | delete [] objective; |
---|
180 | rowObjective_=ClpCopyOfArray(rowObjective,numberRows_); |
---|
181 | columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0); |
---|
182 | columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX); |
---|
183 | // set default solution |
---|
184 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
185 | if (rowLower_[iRow]>0.0) { |
---|
186 | rowActivity_[iRow]=rowLower_[iRow]; |
---|
187 | } else if (rowUpper_[iRow]<0.0) { |
---|
188 | rowActivity_[iRow]=rowUpper_[iRow]; |
---|
189 | } else { |
---|
190 | rowActivity_[iRow]=0.0; |
---|
191 | } |
---|
192 | } |
---|
193 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
194 | if (columnLower_[iColumn]>0.0) { |
---|
195 | columnActivity_[iColumn]=columnLower_[iColumn]; |
---|
196 | } else if (columnUpper_[iColumn]<0.0) { |
---|
197 | columnActivity_[iColumn]=columnUpper_[iColumn]; |
---|
198 | } else { |
---|
199 | columnActivity_[iColumn]=0.0; |
---|
200 | } |
---|
201 | } |
---|
202 | } |
---|
203 | // This just loads up a row objective |
---|
204 | void ClpModel::setRowObjective(const double * rowObjective) |
---|
205 | { |
---|
206 | delete [] rowObjective_; |
---|
207 | rowObjective_=ClpCopyOfArray(rowObjective,numberRows_); |
---|
208 | } |
---|
209 | void |
---|
210 | ClpModel::loadProblem ( const ClpMatrixBase& matrix, |
---|
211 | const double* collb, const double* colub, |
---|
212 | const double* obj, |
---|
213 | const double* rowlb, const double* rowub, |
---|
214 | const double * rowObjective) |
---|
215 | { |
---|
216 | gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(), |
---|
217 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
218 | if (matrix.isColOrdered()) { |
---|
219 | matrix_=matrix.clone(); |
---|
220 | } else { |
---|
221 | // later may want to keep as unknown class |
---|
222 | CoinPackedMatrix matrix2; |
---|
223 | matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix()); |
---|
224 | matrix.releasePackedMatrix(); |
---|
225 | matrix_=new ClpPackedMatrix(matrix2); |
---|
226 | } |
---|
227 | } |
---|
228 | void |
---|
229 | ClpModel::loadProblem ( const CoinPackedMatrix& matrix, |
---|
230 | const double* collb, const double* colub, |
---|
231 | const double* obj, |
---|
232 | const double* rowlb, const double* rowub, |
---|
233 | const double * rowObjective) |
---|
234 | { |
---|
235 | gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(), |
---|
236 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
237 | if (matrix.isColOrdered()) { |
---|
238 | matrix_=new ClpPackedMatrix(matrix); |
---|
239 | } else { |
---|
240 | CoinPackedMatrix matrix2; |
---|
241 | matrix2.reverseOrderedCopyOf(matrix); |
---|
242 | matrix_=new ClpPackedMatrix(matrix2); |
---|
243 | } |
---|
244 | } |
---|
245 | void |
---|
246 | ClpModel::loadProblem ( |
---|
247 | const int numcols, const int numrows, |
---|
248 | const CoinBigIndex* start, const int* index, |
---|
249 | const double* value, |
---|
250 | const double* collb, const double* colub, |
---|
251 | const double* obj, |
---|
252 | const double* rowlb, const double* rowub, |
---|
253 | const double * rowObjective) |
---|
254 | { |
---|
255 | gutsOfLoadModel(numrows, numcols, |
---|
256 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
257 | CoinPackedMatrix matrix(true,numrows,numcols,start[numcols], |
---|
258 | value,index,start,NULL); |
---|
259 | matrix_ = new ClpPackedMatrix(matrix); |
---|
260 | } |
---|
261 | void |
---|
262 | ClpModel::loadProblem ( |
---|
263 | const int numcols, const int numrows, |
---|
264 | const CoinBigIndex* start, const int* index, |
---|
265 | const double* value,const int* length, |
---|
266 | const double* collb, const double* colub, |
---|
267 | const double* obj, |
---|
268 | const double* rowlb, const double* rowub, |
---|
269 | const double * rowObjective) |
---|
270 | { |
---|
271 | gutsOfLoadModel(numrows, numcols, |
---|
272 | collb, colub, obj, rowlb, rowub, rowObjective); |
---|
273 | // Compute number of elements |
---|
274 | int numberElements = 0; |
---|
275 | int i; |
---|
276 | for (i=0;i<numcols;i++) |
---|
277 | numberElements += length[i]; |
---|
278 | CoinPackedMatrix matrix(true,numrows,numcols,numberElements, |
---|
279 | value,index,start,length); |
---|
280 | matrix_ = new ClpPackedMatrix(matrix); |
---|
281 | } |
---|
282 | void |
---|
283 | ClpModel::getRowBound(int iRow, double& lower, double& upper) const |
---|
284 | { |
---|
285 | lower=-COIN_DBL_MAX; |
---|
286 | upper=COIN_DBL_MAX; |
---|
287 | if (rowUpper_) |
---|
288 | upper=rowUpper_[iRow]; |
---|
289 | if (rowLower_) |
---|
290 | lower=rowLower_[iRow]; |
---|
291 | } |
---|
292 | //############################################################################# |
---|
293 | // Copy constructor. |
---|
294 | ClpModel::ClpModel(const ClpModel &rhs) : |
---|
295 | optimizationDirection_(rhs.optimizationDirection_), |
---|
296 | numberRows_(rhs.numberRows_), |
---|
297 | numberColumns_(rhs.numberColumns_) |
---|
298 | { |
---|
299 | gutsOfCopy(rhs); |
---|
300 | } |
---|
301 | // Assignment operator. This copies the data |
---|
302 | ClpModel & |
---|
303 | ClpModel::operator=(const ClpModel & rhs) |
---|
304 | { |
---|
305 | if (this != &rhs) { |
---|
306 | if (defaultHandler_) { |
---|
307 | delete handler_; |
---|
308 | handler_ = NULL; |
---|
309 | } |
---|
310 | gutsOfDelete(); |
---|
311 | optimizationDirection_ = rhs.optimizationDirection_; |
---|
312 | numberRows_ = rhs.numberRows_; |
---|
313 | numberColumns_ = rhs.numberColumns_; |
---|
314 | gutsOfCopy(rhs); |
---|
315 | } |
---|
316 | return *this; |
---|
317 | } |
---|
318 | // Does most of copying |
---|
319 | void |
---|
320 | ClpModel::gutsOfCopy(const ClpModel & rhs, bool trueCopy) |
---|
321 | { |
---|
322 | defaultHandler_ = rhs.defaultHandler_; |
---|
323 | if (defaultHandler_) |
---|
324 | handler_ = new CoinMessageHandler(*rhs.handler_); |
---|
325 | else |
---|
326 | handler_ = rhs.handler_; |
---|
327 | messages_ = rhs.messages_; |
---|
328 | intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration]; |
---|
329 | intParam_[ClpMaxNumIterationHotStart] = |
---|
330 | rhs.intParam_[ClpMaxNumIterationHotStart]; |
---|
331 | |
---|
332 | dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit]; |
---|
333 | dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit]; |
---|
334 | dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance]; |
---|
335 | dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance]; |
---|
336 | dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset]; |
---|
337 | dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds]; |
---|
338 | |
---|
339 | strParam_[ClpProbName] = rhs.strParam_[ClpProbName]; |
---|
340 | |
---|
341 | objectiveValue_=rhs.objectiveValue_; |
---|
342 | smallElement_ = rhs.smallElement_; |
---|
343 | numberIterations_ = rhs.numberIterations_; |
---|
344 | solveType_ = rhs.solveType_; |
---|
345 | problemStatus_ = rhs.problemStatus_; |
---|
346 | if (trueCopy) { |
---|
347 | lengthNames_ = rhs.lengthNames_; |
---|
348 | rowNames_ = rhs.rowNames_; |
---|
349 | columnNames_ = rhs.columnNames_; |
---|
350 | if (rhs.integerType_) { |
---|
351 | integerType_ = new char[numberColumns_]; |
---|
352 | memcpy(integerType_,rhs.integerType_,numberColumns_*sizeof(char)); |
---|
353 | } else { |
---|
354 | integerType_ = NULL; |
---|
355 | } |
---|
356 | if (rhs.rowActivity_) { |
---|
357 | rowActivity_=new double[numberRows_]; |
---|
358 | columnActivity_=new double[numberColumns_]; |
---|
359 | dual_=new double[numberRows_]; |
---|
360 | reducedCost_=new double[numberColumns_]; |
---|
361 | ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ , |
---|
362 | rowActivity_); |
---|
363 | ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ , |
---|
364 | columnActivity_); |
---|
365 | ClpDisjointCopyN ( rhs.dual_, numberRows_ , |
---|
366 | dual_); |
---|
367 | ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ , |
---|
368 | reducedCost_); |
---|
369 | } else { |
---|
370 | rowActivity_=NULL; |
---|
371 | columnActivity_=NULL; |
---|
372 | dual_=NULL; |
---|
373 | reducedCost_=NULL; |
---|
374 | } |
---|
375 | rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ ); |
---|
376 | rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ ); |
---|
377 | columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ ); |
---|
378 | columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ ); |
---|
379 | if (rhs.objective_) |
---|
380 | objective_ = rhs.objective_->clone(); |
---|
381 | else |
---|
382 | objective_ = NULL; |
---|
383 | rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ ); |
---|
384 | status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_); |
---|
385 | ray_ = NULL; |
---|
386 | if (problemStatus_==1) |
---|
387 | ray_ = ClpCopyOfArray (rhs.ray_,numberRows_); |
---|
388 | else if (problemStatus_==2) |
---|
389 | ray_ = ClpCopyOfArray (rhs.ray_,numberColumns_); |
---|
390 | if (rhs.rowCopy_) { |
---|
391 | rowCopy_ = rhs.rowCopy_->clone(); |
---|
392 | } else { |
---|
393 | rowCopy_=NULL; |
---|
394 | } |
---|
395 | if (rhs.quadraticObjective_) { |
---|
396 | quadraticObjective_ = new CoinPackedMatrix(*rhs.quadraticObjective_); |
---|
397 | } else { |
---|
398 | quadraticObjective_=NULL; |
---|
399 | } |
---|
400 | matrix_=NULL; |
---|
401 | if (rhs.matrix_) { |
---|
402 | matrix_ = rhs.matrix_->clone(); |
---|
403 | } |
---|
404 | } else { |
---|
405 | rowActivity_ = rhs.rowActivity_; |
---|
406 | columnActivity_ = rhs.columnActivity_; |
---|
407 | dual_ = rhs.dual_; |
---|
408 | reducedCost_ = rhs.reducedCost_; |
---|
409 | rowLower_ = rhs.rowLower_; |
---|
410 | rowUpper_ = rhs.rowUpper_; |
---|
411 | objective_ = rhs.objective_; |
---|
412 | rowObjective_ = rhs.rowObjective_; |
---|
413 | columnLower_ = rhs.columnLower_; |
---|
414 | columnUpper_ = rhs.columnUpper_; |
---|
415 | matrix_ = rhs.matrix_; |
---|
416 | rowCopy_ = NULL; |
---|
417 | quadraticObjective_ = rhs.quadraticObjective_; |
---|
418 | ray_ = rhs.ray_; |
---|
419 | lengthNames_ = 0; |
---|
420 | rowNames_ = std::vector<std::string> (); |
---|
421 | columnNames_ = std::vector<std::string> (); |
---|
422 | integerType_ = NULL; |
---|
423 | status_ = rhs.status_; |
---|
424 | } |
---|
425 | } |
---|
426 | /* Borrow model. This is so we dont have to copy large amounts |
---|
427 | of data around. It assumes a derived class wants to overwrite |
---|
428 | an empty model with a real one - while it does an algorithm */ |
---|
429 | void |
---|
430 | ClpModel::borrowModel(ClpModel & rhs) |
---|
431 | { |
---|
432 | if (defaultHandler_) { |
---|
433 | delete handler_; |
---|
434 | handler_ = NULL; |
---|
435 | } |
---|
436 | gutsOfDelete(); |
---|
437 | optimizationDirection_ = rhs.optimizationDirection_; |
---|
438 | numberRows_ = rhs.numberRows_; |
---|
439 | numberColumns_ = rhs.numberColumns_; |
---|
440 | delete [] rhs.ray_; |
---|
441 | rhs.ray_=NULL; |
---|
442 | gutsOfCopy(rhs,false); |
---|
443 | } |
---|
444 | // Return model - nulls all arrays so can be deleted safely |
---|
445 | void |
---|
446 | ClpModel::returnModel(ClpModel & otherModel) |
---|
447 | { |
---|
448 | otherModel.objectiveValue_=objectiveValue_; |
---|
449 | otherModel.numberIterations_ = numberIterations_; |
---|
450 | otherModel.problemStatus_ = problemStatus_; |
---|
451 | rowActivity_ = NULL; |
---|
452 | columnActivity_ = NULL; |
---|
453 | dual_ = NULL; |
---|
454 | reducedCost_ = NULL; |
---|
455 | rowLower_ = NULL; |
---|
456 | rowUpper_ = NULL; |
---|
457 | objective_ = NULL; |
---|
458 | rowObjective_ = NULL; |
---|
459 | columnLower_ = NULL; |
---|
460 | columnUpper_ = NULL; |
---|
461 | matrix_ = NULL; |
---|
462 | rowCopy_ = NULL; |
---|
463 | quadraticObjective_=NULL, |
---|
464 | delete [] otherModel.ray_; |
---|
465 | otherModel.ray_ = ray_; |
---|
466 | ray_ = NULL; |
---|
467 | // do status |
---|
468 | if (otherModel.status_!=status_) { |
---|
469 | delete [] otherModel.status_; |
---|
470 | otherModel.status_ = status_; |
---|
471 | } |
---|
472 | status_ = NULL; |
---|
473 | if (defaultHandler_) { |
---|
474 | delete handler_; |
---|
475 | handler_ = NULL; |
---|
476 | } |
---|
477 | } |
---|
478 | //############################################################################# |
---|
479 | // Parameter related methods |
---|
480 | //############################################################################# |
---|
481 | |
---|
482 | bool |
---|
483 | ClpModel::setIntParam(ClpIntParam key, int value) |
---|
484 | { |
---|
485 | switch (key) { |
---|
486 | case ClpMaxNumIteration: |
---|
487 | if (value < 0) |
---|
488 | return false; |
---|
489 | break; |
---|
490 | case ClpMaxNumIterationHotStart: |
---|
491 | if (value < 0) |
---|
492 | return false; |
---|
493 | break; |
---|
494 | case ClpLastIntParam: |
---|
495 | return false; |
---|
496 | } |
---|
497 | intParam_[key] = value; |
---|
498 | return true; |
---|
499 | } |
---|
500 | |
---|
501 | //----------------------------------------------------------------------------- |
---|
502 | |
---|
503 | bool |
---|
504 | ClpModel::setDblParam(ClpDblParam key, double value) |
---|
505 | { |
---|
506 | |
---|
507 | switch (key) { |
---|
508 | case ClpDualObjectiveLimit: |
---|
509 | break; |
---|
510 | |
---|
511 | case ClpPrimalObjectiveLimit: |
---|
512 | break; |
---|
513 | |
---|
514 | case ClpDualTolerance: |
---|
515 | if (value<=0.0||value>1.0e10) |
---|
516 | return false; |
---|
517 | break; |
---|
518 | |
---|
519 | case ClpPrimalTolerance: |
---|
520 | if (value<=0.0||value>1.0e10) |
---|
521 | return false; |
---|
522 | break; |
---|
523 | |
---|
524 | case ClpObjOffset: |
---|
525 | break; |
---|
526 | |
---|
527 | case ClpMaxSeconds: |
---|
528 | if(value>=0) |
---|
529 | value += cpuTime(); |
---|
530 | else |
---|
531 | value = -1.0; |
---|
532 | break; |
---|
533 | |
---|
534 | case ClpLastDblParam: |
---|
535 | return false; |
---|
536 | } |
---|
537 | dblParam_[key] = value; |
---|
538 | return true; |
---|
539 | } |
---|
540 | |
---|
541 | //----------------------------------------------------------------------------- |
---|
542 | |
---|
543 | bool |
---|
544 | ClpModel::setStrParam(ClpStrParam key, const std::string & value) |
---|
545 | { |
---|
546 | |
---|
547 | switch (key) { |
---|
548 | case ClpProbName: |
---|
549 | break; |
---|
550 | |
---|
551 | case ClpLastStrParam: |
---|
552 | return false; |
---|
553 | } |
---|
554 | strParam_[key] = value; |
---|
555 | return true; |
---|
556 | } |
---|
557 | // Useful routines |
---|
558 | // Returns resized array and deletes incoming |
---|
559 | double * resizeDouble(double * array , int size, int newSize, double fill, |
---|
560 | bool createArray) |
---|
561 | { |
---|
562 | if ((array||createArray)&&size!=newSize) { |
---|
563 | int i; |
---|
564 | double * newArray = new double[newSize]; |
---|
565 | if (array) |
---|
566 | memcpy(newArray,array,min(newSize,size)*sizeof(double)); |
---|
567 | delete [] array; |
---|
568 | array = newArray; |
---|
569 | for (i=size;i<newSize;i++) |
---|
570 | array[i]=fill; |
---|
571 | } |
---|
572 | return array; |
---|
573 | } |
---|
574 | // Returns resized array and updates size |
---|
575 | double * deleteDouble(double * array , int size, |
---|
576 | int number, const int * which,int & newSize) |
---|
577 | { |
---|
578 | if (array) { |
---|
579 | int i ; |
---|
580 | char * deleted = new char[size]; |
---|
581 | int numberDeleted=0; |
---|
582 | memset(deleted,0,size*sizeof(char)); |
---|
583 | for (i=0;i<number;i++) { |
---|
584 | int j = which[i]; |
---|
585 | if (j>=0&&j<size&&!deleted[j]) { |
---|
586 | numberDeleted++; |
---|
587 | deleted[j]=1; |
---|
588 | } |
---|
589 | } |
---|
590 | newSize = size-numberDeleted; |
---|
591 | double * newArray = new double[newSize]; |
---|
592 | int put=0; |
---|
593 | for (i=0;i<size;i++) { |
---|
594 | if (!deleted[i]) { |
---|
595 | newArray[put++]=array[i]; |
---|
596 | } |
---|
597 | } |
---|
598 | delete [] array; |
---|
599 | array = newArray; |
---|
600 | delete [] deleted; |
---|
601 | } |
---|
602 | return array; |
---|
603 | } |
---|
604 | char * deleteChar(char * array , int size, |
---|
605 | int number, const int * which,int & newSize, |
---|
606 | bool ifDelete) |
---|
607 | { |
---|
608 | if (array) { |
---|
609 | int i ; |
---|
610 | char * deleted = new char[size]; |
---|
611 | int numberDeleted=0; |
---|
612 | memset(deleted,0,size*sizeof(char)); |
---|
613 | for (i=0;i<number;i++) { |
---|
614 | int j = which[i]; |
---|
615 | if (j>=0&&j<size&&!deleted[j]) { |
---|
616 | numberDeleted++; |
---|
617 | deleted[j]=1; |
---|
618 | } |
---|
619 | } |
---|
620 | newSize = size-numberDeleted; |
---|
621 | char * newArray = new char[newSize]; |
---|
622 | int put=0; |
---|
623 | for (i=0;i<size;i++) { |
---|
624 | if (!deleted[i]) { |
---|
625 | newArray[put++]=array[i]; |
---|
626 | } |
---|
627 | } |
---|
628 | if (ifDelete) |
---|
629 | delete [] array; |
---|
630 | array = newArray; |
---|
631 | delete [] deleted; |
---|
632 | } |
---|
633 | return array; |
---|
634 | } |
---|
635 | // Create empty ClpPackedMatrix |
---|
636 | void |
---|
637 | ClpModel::createEmptyMatrix() |
---|
638 | { |
---|
639 | delete matrix_; |
---|
640 | CoinPackedMatrix matrix2; |
---|
641 | matrix_=new ClpPackedMatrix(matrix2); |
---|
642 | } |
---|
643 | // Resizes |
---|
644 | void |
---|
645 | ClpModel::resize (int newNumberRows, int newNumberColumns) |
---|
646 | { |
---|
647 | rowActivity_ = resizeDouble(rowActivity_,numberRows_, |
---|
648 | newNumberRows,0.0,true); |
---|
649 | dual_ = resizeDouble(dual_,numberRows_, |
---|
650 | newNumberRows,0.0,true); |
---|
651 | rowObjective_ = resizeDouble(rowObjective_,numberRows_, |
---|
652 | newNumberRows,0.0,false); |
---|
653 | rowLower_ = resizeDouble(rowLower_,numberRows_, |
---|
654 | newNumberRows,-COIN_DBL_MAX,true); |
---|
655 | rowUpper_ = resizeDouble(rowUpper_,numberRows_, |
---|
656 | newNumberRows,COIN_DBL_MAX,true); |
---|
657 | columnActivity_ = resizeDouble(columnActivity_,numberColumns_, |
---|
658 | newNumberColumns,0.0,true); |
---|
659 | reducedCost_ = resizeDouble(reducedCost_,numberColumns_, |
---|
660 | newNumberColumns,0.0,true); |
---|
661 | if (objective_) |
---|
662 | objective_->resize(newNumberColumns); |
---|
663 | else |
---|
664 | objective_ = new ClpLinearObjective(NULL,newNumberColumns); |
---|
665 | columnLower_ = resizeDouble(columnLower_,numberColumns_, |
---|
666 | newNumberColumns,0.0,true); |
---|
667 | columnUpper_ = resizeDouble(columnUpper_,numberColumns_, |
---|
668 | newNumberColumns,COIN_DBL_MAX,true); |
---|
669 | if (newNumberRows<numberRows_) { |
---|
670 | int * which = new int[numberRows_-newNumberRows]; |
---|
671 | int i; |
---|
672 | for (i=newNumberRows;i<numberRows_;i++) |
---|
673 | which[i-newNumberRows]=i; |
---|
674 | matrix_->deleteRows(numberRows_-newNumberRows,which); |
---|
675 | delete [] which; |
---|
676 | } |
---|
677 | if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) { |
---|
678 | // set state back to unknown |
---|
679 | problemStatus_ = -1; |
---|
680 | delete [] ray_; |
---|
681 | ray_ = NULL; |
---|
682 | } |
---|
683 | if (status_) { |
---|
684 | unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows]; |
---|
685 | unsigned char * tempR = tempC + newNumberColumns; |
---|
686 | memset(tempC,0,(newNumberColumns+newNumberRows)*sizeof(unsigned char)); |
---|
687 | memcpy(tempC,status_,min(newNumberColumns,numberColumns_)*sizeof(unsigned char)); |
---|
688 | memcpy(tempR,status_+numberColumns_,min(newNumberRows,numberRows_)*sizeof(unsigned char)); |
---|
689 | delete [] status_; |
---|
690 | status_ = tempC; |
---|
691 | } |
---|
692 | numberRows_ = newNumberRows; |
---|
693 | if (newNumberColumns<numberColumns_) { |
---|
694 | int * which = new int[numberColumns_-newNumberColumns]; |
---|
695 | int i; |
---|
696 | for (i=newNumberColumns;i<numberColumns_;i++) |
---|
697 | which[i-newNumberColumns]=i; |
---|
698 | matrix_->deleteCols(numberColumns_-newNumberColumns,which); |
---|
699 | if (quadraticObjective_) { |
---|
700 | quadraticObjective_->deleteCols(numberColumns_-newNumberColumns,which); |
---|
701 | quadraticObjective_->deleteRows(numberColumns_-newNumberColumns,which); |
---|
702 | } |
---|
703 | delete [] which; |
---|
704 | } |
---|
705 | if (integerType_) { |
---|
706 | char * temp = new char [newNumberColumns]; |
---|
707 | memset(temp,0,newNumberColumns*sizeof(char)); |
---|
708 | memcpy(temp,integerType_, |
---|
709 | min(newNumberColumns,numberColumns_)*sizeof(char)); |
---|
710 | delete [] integerType_; |
---|
711 | integerType_ = temp; |
---|
712 | } |
---|
713 | numberColumns_ = newNumberColumns; |
---|
714 | // for now gets rid of names |
---|
715 | lengthNames_ = 0; |
---|
716 | rowNames_ = std::vector<std::string> (); |
---|
717 | columnNames_ = std::vector<std::string> (); |
---|
718 | } |
---|
719 | // Deletes rows |
---|
720 | void |
---|
721 | ClpModel::deleteRows(int number, const int * which) |
---|
722 | { |
---|
723 | int newSize=0; |
---|
724 | rowActivity_ = deleteDouble(rowActivity_,numberRows_, |
---|
725 | number, which, newSize); |
---|
726 | dual_ = deleteDouble(dual_,numberRows_, |
---|
727 | number, which, newSize); |
---|
728 | rowObjective_ = deleteDouble(rowObjective_,numberRows_, |
---|
729 | number, which, newSize); |
---|
730 | rowLower_ = deleteDouble(rowLower_,numberRows_, |
---|
731 | number, which, newSize); |
---|
732 | rowUpper_ = deleteDouble(rowUpper_,numberRows_, |
---|
733 | number, which, newSize); |
---|
734 | matrix_->deleteRows(number,which); |
---|
735 | // status |
---|
736 | if (status_) { |
---|
737 | unsigned char * tempR = (unsigned char *) deleteChar((char *)status_+numberColumns_, |
---|
738 | numberRows_, |
---|
739 | number, which, newSize,false); |
---|
740 | unsigned char * tempC = new unsigned char [numberColumns_+newSize]; |
---|
741 | memcpy(tempC,status_,numberColumns_*sizeof(unsigned char)); |
---|
742 | memcpy(tempC+numberColumns_,tempR,newSize*sizeof(unsigned char)); |
---|
743 | delete [] tempR; |
---|
744 | delete [] status_; |
---|
745 | status_ = tempC; |
---|
746 | } |
---|
747 | numberRows_=newSize; |
---|
748 | // set state back to unknown |
---|
749 | problemStatus_ = -1; |
---|
750 | delete [] ray_; |
---|
751 | ray_ = NULL; |
---|
752 | // for now gets rid of names |
---|
753 | lengthNames_ = 0; |
---|
754 | rowNames_ = std::vector<std::string> (); |
---|
755 | columnNames_ = std::vector<std::string> (); |
---|
756 | } |
---|
757 | // Deletes columns |
---|
758 | void |
---|
759 | ClpModel::deleteColumns(int number, const int * which) |
---|
760 | { |
---|
761 | int newSize=0; |
---|
762 | columnActivity_ = deleteDouble(columnActivity_,numberColumns_, |
---|
763 | number, which, newSize); |
---|
764 | reducedCost_ = deleteDouble(reducedCost_,numberColumns_, |
---|
765 | number, which, newSize); |
---|
766 | objective_->deleteSome(number, which); |
---|
767 | columnLower_ = deleteDouble(columnLower_,numberColumns_, |
---|
768 | number, which, newSize); |
---|
769 | columnUpper_ = deleteDouble(columnUpper_,numberColumns_, |
---|
770 | number, which, newSize); |
---|
771 | matrix_->deleteCols(number,which); |
---|
772 | if (quadraticObjective_) { |
---|
773 | quadraticObjective_->deleteCols(number,which); |
---|
774 | quadraticObjective_->deleteRows(number,which); |
---|
775 | } |
---|
776 | // status |
---|
777 | if (status_) { |
---|
778 | unsigned char * tempC = (unsigned char *) deleteChar((char *)status_, |
---|
779 | numberColumns_, |
---|
780 | number, which, newSize,false); |
---|
781 | unsigned char * temp = new unsigned char [numberRows_+newSize]; |
---|
782 | memcpy(temp,tempC,newSize*sizeof(unsigned char)); |
---|
783 | memcpy(temp+newSize,status_+numberColumns_, |
---|
784 | numberRows_*sizeof(unsigned char)); |
---|
785 | delete [] tempC; |
---|
786 | delete [] status_; |
---|
787 | status_ = temp; |
---|
788 | } |
---|
789 | numberColumns_=newSize; |
---|
790 | // set state back to unknown |
---|
791 | problemStatus_ = -1; |
---|
792 | delete [] ray_; |
---|
793 | ray_ = NULL; |
---|
794 | // for now gets rid of names |
---|
795 | lengthNames_ = 0; |
---|
796 | rowNames_ = std::vector<std::string> (); |
---|
797 | columnNames_ = std::vector<std::string> (); |
---|
798 | integerType_ = deleteChar(integerType_,numberColumns_, |
---|
799 | number, which, newSize,true); |
---|
800 | } |
---|
801 | // Add rows |
---|
802 | void |
---|
803 | ClpModel::addRows(int number, const double * rowLower, |
---|
804 | const double * rowUpper, |
---|
805 | const int * rowStarts, const int * columns, |
---|
806 | const double * elements) |
---|
807 | { |
---|
808 | // Create a list of CoinPackedVectors |
---|
809 | if (number) { |
---|
810 | CoinPackedVectorBase ** rows= |
---|
811 | new CoinPackedVectorBase * [number]; |
---|
812 | int iRow; |
---|
813 | for (iRow=0;iRow<number;iRow++) { |
---|
814 | int iStart = rowStarts[iRow]; |
---|
815 | rows[iRow] = |
---|
816 | new CoinPackedVector(rowStarts[iRow+1]-iStart, |
---|
817 | columns+iStart,elements+iStart); |
---|
818 | } |
---|
819 | addRows(number, rowLower, rowUpper, |
---|
820 | rows); |
---|
821 | for (iRow=0;iRow<number;iRow++) |
---|
822 | delete rows[iRow]; |
---|
823 | delete [] rows; |
---|
824 | } |
---|
825 | } |
---|
826 | void |
---|
827 | ClpModel::addRows(int number, const double * rowLower, |
---|
828 | const double * rowUpper, |
---|
829 | const CoinPackedVectorBase * const * rows) |
---|
830 | { |
---|
831 | if (!number) |
---|
832 | return; |
---|
833 | int numberRowsNow = numberRows_; |
---|
834 | resize(numberRowsNow+number,numberColumns_); |
---|
835 | double * lower = rowLower_+numberRowsNow; |
---|
836 | double * upper = rowUpper_+numberRowsNow; |
---|
837 | int iRow; |
---|
838 | if (rowLower) { |
---|
839 | for (iRow = 0; iRow < number; iRow++) { |
---|
840 | double value = rowLower[iRow]; |
---|
841 | if (value<-1.0e20) |
---|
842 | value = -COIN_DBL_MAX; |
---|
843 | lower[iRow]= value; |
---|
844 | } |
---|
845 | } else { |
---|
846 | for (iRow = 0; iRow < number; iRow++) { |
---|
847 | lower[iRow]= -COIN_DBL_MAX; |
---|
848 | } |
---|
849 | } |
---|
850 | if (rowUpper) { |
---|
851 | for (iRow = 0; iRow < number; iRow++) { |
---|
852 | double value = rowUpper[iRow]; |
---|
853 | if (value>1.0e20) |
---|
854 | value = COIN_DBL_MAX; |
---|
855 | upper[iRow]= value; |
---|
856 | } |
---|
857 | } else { |
---|
858 | for (iRow = 0; iRow < number; iRow++) { |
---|
859 | upper[iRow]= COIN_DBL_MAX; |
---|
860 | } |
---|
861 | } |
---|
862 | // Deal with matrix |
---|
863 | |
---|
864 | delete rowCopy_; |
---|
865 | rowCopy_=NULL; |
---|
866 | if (!matrix_) |
---|
867 | createEmptyMatrix(); |
---|
868 | // Use matrix() to get round virtual problem |
---|
869 | matrix()->appendRows(number,rows); |
---|
870 | } |
---|
871 | // Add columns |
---|
872 | void |
---|
873 | ClpModel::addColumns(int number, const double * columnLower, |
---|
874 | const double * columnUpper, |
---|
875 | const double * objIn, |
---|
876 | const int * columnStarts, const int * rows, |
---|
877 | const double * elements) |
---|
878 | { |
---|
879 | // Create a list of CoinPackedVectors |
---|
880 | if (number) { |
---|
881 | CoinPackedVectorBase ** columns= |
---|
882 | new CoinPackedVectorBase * [number]; |
---|
883 | int iColumn; |
---|
884 | for (iColumn=0;iColumn<number;iColumn++) { |
---|
885 | int iStart = columnStarts[iColumn]; |
---|
886 | columns[iColumn] = |
---|
887 | new CoinPackedVector(columnStarts[iColumn+1]-iStart, |
---|
888 | rows+iStart,elements+iStart); |
---|
889 | } |
---|
890 | addColumns(number, columnLower, columnUpper, |
---|
891 | objIn, columns); |
---|
892 | for (iColumn=0;iColumn<number;iColumn++) |
---|
893 | delete columns[iColumn]; |
---|
894 | delete [] columns; |
---|
895 | |
---|
896 | } |
---|
897 | } |
---|
898 | void |
---|
899 | ClpModel::addColumns(int number, const double * columnLower, |
---|
900 | const double * columnUpper, |
---|
901 | const double * objIn, |
---|
902 | const CoinPackedVectorBase * const * columns) |
---|
903 | { |
---|
904 | if (!number) |
---|
905 | return; |
---|
906 | int numberColumnsNow = numberColumns_; |
---|
907 | resize(numberRows_,numberColumnsNow+number); |
---|
908 | double * lower = columnLower_+numberColumnsNow; |
---|
909 | double * upper = columnUpper_+numberColumnsNow; |
---|
910 | double * obj = objective()+numberColumnsNow; |
---|
911 | int iColumn; |
---|
912 | if (columnLower) { |
---|
913 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
914 | double value = columnLower[iColumn]; |
---|
915 | if (value<-1.0e20) |
---|
916 | value = -COIN_DBL_MAX; |
---|
917 | lower[iColumn]= value; |
---|
918 | } |
---|
919 | } else { |
---|
920 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
921 | lower[iColumn]= 0.0; |
---|
922 | } |
---|
923 | } |
---|
924 | if (columnUpper) { |
---|
925 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
926 | double value = columnUpper[iColumn]; |
---|
927 | if (value>1.0e20) |
---|
928 | value = COIN_DBL_MAX; |
---|
929 | upper[iColumn]= value; |
---|
930 | } |
---|
931 | } else { |
---|
932 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
933 | upper[iColumn]= COIN_DBL_MAX; |
---|
934 | } |
---|
935 | } |
---|
936 | if (objIn) { |
---|
937 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
938 | obj[iColumn] = objIn[iColumn]; |
---|
939 | } |
---|
940 | } else { |
---|
941 | for (iColumn = 0; iColumn < number; iColumn++) { |
---|
942 | obj[iColumn]= 0.0; |
---|
943 | } |
---|
944 | } |
---|
945 | // Deal with matrix |
---|
946 | |
---|
947 | delete rowCopy_; |
---|
948 | rowCopy_=NULL; |
---|
949 | if (!matrix_) |
---|
950 | createEmptyMatrix(); |
---|
951 | // Use matrix() to get round virtual problem |
---|
952 | matrix()->appendCols(number,columns); |
---|
953 | } |
---|
954 | // Infeasibility/unbounded ray (NULL returned if none/wrong) |
---|
955 | double * |
---|
956 | ClpModel::infeasibilityRay() const |
---|
957 | { |
---|
958 | double * array = NULL; |
---|
959 | if (problemStatus_==1) |
---|
960 | array = ClpCopyOfArray(ray_,numberRows_); |
---|
961 | return array; |
---|
962 | } |
---|
963 | double * |
---|
964 | ClpModel::unboundedRay() const |
---|
965 | { |
---|
966 | double * array = NULL; |
---|
967 | if (problemStatus_==2) |
---|
968 | array = ClpCopyOfArray(ray_,numberColumns_); |
---|
969 | return array; |
---|
970 | } |
---|
971 | void |
---|
972 | ClpModel::setMaximumIterations(int value) |
---|
973 | { |
---|
974 | if(value>=0) |
---|
975 | intParam_[ClpMaxNumIteration]=value; |
---|
976 | } |
---|
977 | void |
---|
978 | ClpModel::setMaximumSeconds(double value) |
---|
979 | { |
---|
980 | if(value>=0) |
---|
981 | dblParam_[ClpMaxSeconds]=value+cpuTime(); |
---|
982 | else |
---|
983 | dblParam_[ClpMaxSeconds]=-1.0; |
---|
984 | } |
---|
985 | // Returns true if hit maximum iterations (or time) |
---|
986 | bool |
---|
987 | ClpModel::hitMaximumIterations() const |
---|
988 | { |
---|
989 | bool hitMax= (numberIterations_>=maximumIterations()); |
---|
990 | if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax) |
---|
991 | hitMax = (cpuTime()>=dblParam_[ClpMaxSeconds]); |
---|
992 | return hitMax; |
---|
993 | } |
---|
994 | // Pass in Message handler (not deleted at end) |
---|
995 | void |
---|
996 | ClpModel::passInMessageHandler(CoinMessageHandler * handler) |
---|
997 | { |
---|
998 | if (defaultHandler_) |
---|
999 | delete handler_; |
---|
1000 | defaultHandler_=false; |
---|
1001 | handler_=handler; |
---|
1002 | } |
---|
1003 | // Set language |
---|
1004 | void |
---|
1005 | ClpModel::newLanguage(CoinMessages::Language language) |
---|
1006 | { |
---|
1007 | messages_ = ClpMessage(language); |
---|
1008 | } |
---|
1009 | // Read an mps file from the given filename |
---|
1010 | int |
---|
1011 | ClpModel::readMps(const char *fileName, |
---|
1012 | bool keepNames, |
---|
1013 | bool ignoreErrors) |
---|
1014 | { |
---|
1015 | bool canOpen=false; |
---|
1016 | if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) { |
---|
1017 | // stdin |
---|
1018 | canOpen=true; |
---|
1019 | } else { |
---|
1020 | FILE *fp=fopen(fileName,"r"); |
---|
1021 | if (fp) { |
---|
1022 | // can open - lets go for it |
---|
1023 | fclose(fp); |
---|
1024 | canOpen=true; |
---|
1025 | } else { |
---|
1026 | handler_->message(CLP_UNABLE_OPEN,messages_) |
---|
1027 | <<fileName<<CoinMessageEol; |
---|
1028 | return -1; |
---|
1029 | } |
---|
1030 | } |
---|
1031 | CoinMpsIO m; |
---|
1032 | double time1 = cpuTime(),time2; |
---|
1033 | int status=m.readMps(fileName,""); |
---|
1034 | if (!status||ignoreErrors) { |
---|
1035 | loadProblem(*m.getMatrixByCol(), |
---|
1036 | m.getColLower(),m.getColUpper(), |
---|
1037 | m.getObjCoefficients(), |
---|
1038 | m.getRowLower(),m.getRowUpper()); |
---|
1039 | if (m.integerColumns()) { |
---|
1040 | integerType_ = new char[numberColumns_]; |
---|
1041 | memcpy(integerType_,m.integerColumns(),numberColumns_*sizeof(char)); |
---|
1042 | } else { |
---|
1043 | integerType_ = NULL; |
---|
1044 | } |
---|
1045 | // set problem name |
---|
1046 | setStrParam(ClpProbName,m.getProblemName()); |
---|
1047 | // do names |
---|
1048 | if (keepNames) { |
---|
1049 | unsigned int maxLength=0; |
---|
1050 | int iRow; |
---|
1051 | rowNames_.reserve(numberRows_); |
---|
1052 | for (iRow=0;iRow<numberRows_;iRow++) { |
---|
1053 | const char * name = m.rowName(iRow); |
---|
1054 | maxLength = max(maxLength,(unsigned int) strlen(name)); |
---|
1055 | rowNames_.push_back(name); |
---|
1056 | } |
---|
1057 | |
---|
1058 | int iColumn; |
---|
1059 | columnNames_.reserve(numberColumns_); |
---|
1060 | for (iColumn=0;iColumn<numberColumns_;iColumn++) { |
---|
1061 | const char * name = m.columnName(iColumn); |
---|
1062 | maxLength = max(maxLength,(unsigned int) strlen(name)); |
---|
1063 | columnNames_.push_back(name); |
---|
1064 | } |
---|
1065 | lengthNames_=(int) maxLength; |
---|
1066 | } else { |
---|
1067 | lengthNames_=0; |
---|
1068 | } |
---|
1069 | setDblParam(ClpObjOffset,m.objectiveOffset()); |
---|
1070 | time2 = cpuTime(); |
---|
1071 | handler_->message(CLP_IMPORT_RESULT,messages_) |
---|
1072 | <<fileName |
---|
1073 | <<time2-time1<<CoinMessageEol; |
---|
1074 | } else { |
---|
1075 | // errors |
---|
1076 | handler_->message(CLP_IMPORT_ERRORS,messages_) |
---|
1077 | <<status<<fileName<<CoinMessageEol; |
---|
1078 | } |
---|
1079 | |
---|
1080 | return status; |
---|
1081 | } |
---|
1082 | bool ClpModel::isPrimalObjectiveLimitReached() const |
---|
1083 | { |
---|
1084 | double limit = 0.0; |
---|
1085 | getDblParam(ClpPrimalObjectiveLimit, limit); |
---|
1086 | if (limit > 1e30) { |
---|
1087 | // was not ever set |
---|
1088 | return false; |
---|
1089 | } |
---|
1090 | |
---|
1091 | const double obj = objectiveValue(); |
---|
1092 | const int maxmin = optimizationDirection(); |
---|
1093 | |
---|
1094 | if (problemStatus_ == 0) // optimal |
---|
1095 | return maxmin > 0 ? (obj < limit) /*minim*/ : (obj > limit) /*maxim*/; |
---|
1096 | else if (problemStatus_==2) |
---|
1097 | return true; |
---|
1098 | else |
---|
1099 | return false; |
---|
1100 | } |
---|
1101 | |
---|
1102 | bool ClpModel::isDualObjectiveLimitReached() const |
---|
1103 | { |
---|
1104 | |
---|
1105 | double limit = 0.0; |
---|
1106 | getDblParam(ClpDualObjectiveLimit, limit); |
---|
1107 | if (limit > 1e30) { |
---|
1108 | // was not ever set |
---|
1109 | return false; |
---|
1110 | } |
---|
1111 | |
---|
1112 | const double obj = objectiveValue(); |
---|
1113 | const int maxmin = optimizationDirection(); |
---|
1114 | |
---|
1115 | if (problemStatus_ == 0) // optimal |
---|
1116 | return maxmin > 0 ? (obj > limit) /*minim*/ : (obj < limit) /*maxim*/; |
---|
1117 | else if (problemStatus_==1) |
---|
1118 | return true; |
---|
1119 | else |
---|
1120 | return false; |
---|
1121 | |
---|
1122 | } |
---|
1123 | void |
---|
1124 | ClpModel::copyInIntegerInformation(const char * information) |
---|
1125 | { |
---|
1126 | delete [] integerType_; |
---|
1127 | if (information) { |
---|
1128 | integerType_ = new char[numberColumns_]; |
---|
1129 | memcpy(integerType_,information,numberColumns_*sizeof(char)); |
---|
1130 | } else { |
---|
1131 | integerType_ = NULL; |
---|
1132 | } |
---|
1133 | } |
---|
1134 | // Drops names - makes lengthnames 0 and names empty |
---|
1135 | void |
---|
1136 | ClpModel::dropNames() |
---|
1137 | { |
---|
1138 | lengthNames_=0; |
---|
1139 | rowNames_ = std::vector<std::string> (); |
---|
1140 | columnNames_ = std::vector<std::string> (); |
---|
1141 | } |
---|
1142 | // Drop integer informations |
---|
1143 | void |
---|
1144 | ClpModel::deleteIntegerInformation() |
---|
1145 | { |
---|
1146 | delete [] integerType_; |
---|
1147 | integerType_ = NULL; |
---|
1148 | } |
---|
1149 | /* Return copy of status array (char[numberRows+numberColumns]), |
---|
1150 | use delete [] */ |
---|
1151 | unsigned char * |
---|
1152 | ClpModel::statusCopy() const |
---|
1153 | { |
---|
1154 | return ClpCopyOfArray(status_,numberRows_+numberColumns_); |
---|
1155 | } |
---|
1156 | // Copy in status vector |
---|
1157 | void |
---|
1158 | ClpModel::copyinStatus(const unsigned char * statusArray) |
---|
1159 | { |
---|
1160 | delete [] status_; |
---|
1161 | if (statusArray) { |
---|
1162 | status_ = new unsigned char [numberRows_+numberColumns_]; |
---|
1163 | memcpy(status_,statusArray,(numberRows_+numberColumns_)*sizeof(unsigned char)); |
---|
1164 | } else { |
---|
1165 | status_=NULL; |
---|
1166 | } |
---|
1167 | } |
---|
1168 | |
---|
1169 | // Load up quadratic objective |
---|
1170 | void |
---|
1171 | ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start, |
---|
1172 | const int * column, const double * element) |
---|
1173 | { |
---|
1174 | assert (numberColumns==numberColumns_); |
---|
1175 | quadraticObjective_ = new CoinPackedMatrix(true,numberColumns,numberColumns, |
---|
1176 | start[numberColumns],element,column,start,NULL); |
---|
1177 | } |
---|
1178 | void |
---|
1179 | ClpModel::loadQuadraticObjective ( const CoinPackedMatrix& matrix) |
---|
1180 | { |
---|
1181 | assert (matrix.getNumCols()==numberColumns_); |
---|
1182 | quadraticObjective_ = new CoinPackedMatrix(matrix); |
---|
1183 | } |
---|
1184 | // Get rid of quadratic objective |
---|
1185 | void |
---|
1186 | ClpModel::deleteQuadraticObjective() |
---|
1187 | { |
---|
1188 | delete quadraticObjective_; |
---|
1189 | quadraticObjective_ = NULL; |
---|
1190 | } |
---|
1191 | //############################################################################# |
---|
1192 | // Constructors / Destructor / Assignment |
---|
1193 | //############################################################################# |
---|
1194 | |
---|
1195 | //------------------------------------------------------------------- |
---|
1196 | // Default Constructor |
---|
1197 | //------------------------------------------------------------------- |
---|
1198 | ClpDataSave::ClpDataSave () |
---|
1199 | { |
---|
1200 | dualBound_ = 0.0; |
---|
1201 | infeasibilityCost_ = 0.0; |
---|
1202 | sparseThreshold_ = 0; |
---|
1203 | perturbation_ = 0; |
---|
1204 | } |
---|
1205 | |
---|
1206 | //------------------------------------------------------------------- |
---|
1207 | // Copy constructor |
---|
1208 | //------------------------------------------------------------------- |
---|
1209 | ClpDataSave::ClpDataSave (const ClpDataSave & rhs) |
---|
1210 | { |
---|
1211 | dualBound_ = rhs.dualBound_; |
---|
1212 | infeasibilityCost_ = rhs.infeasibilityCost_; |
---|
1213 | sparseThreshold_ = rhs.sparseThreshold_; |
---|
1214 | perturbation_ = rhs.perturbation_; |
---|
1215 | } |
---|
1216 | |
---|
1217 | //------------------------------------------------------------------- |
---|
1218 | // Destructor |
---|
1219 | //------------------------------------------------------------------- |
---|
1220 | ClpDataSave::~ClpDataSave () |
---|
1221 | { |
---|
1222 | |
---|
1223 | } |
---|
1224 | |
---|
1225 | //---------------------------------------------------------------- |
---|
1226 | // Assignment operator |
---|
1227 | //------------------------------------------------------------------- |
---|
1228 | ClpDataSave & |
---|
1229 | ClpDataSave::operator=(const ClpDataSave& rhs) |
---|
1230 | { |
---|
1231 | if (this != &rhs) { |
---|
1232 | dualBound_ = rhs.dualBound_; |
---|
1233 | infeasibilityCost_ = rhs.infeasibilityCost_; |
---|
1234 | sparseThreshold_ = rhs.sparseThreshold_; |
---|
1235 | perturbation_ = rhs.perturbation_; |
---|
1236 | } |
---|
1237 | return *this; |
---|
1238 | } |
---|