source: branches/devel-1/ClpModel.cpp @ 28

Last change on this file since 28 was 28, checked in by forrest, 17 years ago

For presolve

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.8 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include <cmath>
9#include <cassert>
10#include <cfloat>
11#include <string>
12#include <cstdio>
13#include <iostream>
14
15#include <time.h>
16#include <sys/times.h>
17#include <sys/resource.h>
18#include <unistd.h>
19
20#include "CoinHelperFunctions.hpp"
21#include "ClpModel.hpp"
22#include "ClpPackedMatrix.hpp"
23#include "CoinIndexedVector.hpp"
24#include "CoinMpsIO.hpp"
25#include "ClpMessage.hpp"
26
27// This returns a non const array filled with input from scalar
28// or actual array
29template <class T> inline T*
30copyOfArray( const T * array, const int size, T value)
31{
32  T * arrayNew = new T[size];
33  if (array) 
34    CoinDisjointCopyN(array,size,arrayNew);
35  else
36    CoinFillN ( arrayNew, size,value);
37  return arrayNew;
38}
39
40// This returns a non const array filled with actual array (or NULL)
41template <class T> inline T*
42copyOfArray( const T * array, const int size)
43{
44  if (array) {
45    T * arrayNew = new T[size];
46    CoinDisjointCopyN(array,size,arrayNew);
47    return arrayNew;
48  } else {
49    return NULL;
50  }
51}
52static double cpuTime()
53{
54  double cpu_temp;
55#if defined(_MSC_VER)
56  unsigned int ticksnow;        /* clock_t is same as int */
57 
58  ticksnow = (unsigned int)clock();
59 
60  cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC);
61#else
62  struct rusage usage;
63  getrusage(RUSAGE_SELF,&usage);
64  cpu_temp = usage.ru_utime.tv_sec;
65  cpu_temp += 1.0e-6*((double) usage.ru_utime.tv_usec);
66#endif
67  return cpu_temp;
68}
69//#############################################################################
70
71ClpModel::ClpModel () :
72
73  optimizationDirection_(1),
74  numberRows_(0),
75  numberColumns_(0),
76  rowActivity_(NULL),
77  columnActivity_(NULL),
78  dual_(NULL),
79  reducedCost_(NULL),
80  rowLower_(NULL),
81  rowUpper_(NULL),
82  objective_(NULL),
83  rowObjective_(NULL),
84  columnLower_(NULL),
85  columnUpper_(NULL),
86  matrix_(NULL),
87  rowCopy_(NULL),
88  ray_(NULL),
89  objectiveValue_(0.0),
90  numberIterations_(0),
91  problemStatus_(-1),
92  maximumIterations_(1000000000),
93  defaultHandler_(true),
94  lengthNames_(0),
95  rowNames_(),
96  columnNames_(),
97  integerType_(NULL)
98{
99  intParam_[ClpMaxNumIteration] = 9999999;
100  intParam_[ClpMaxNumIterationHotStart] = 9999999;
101
102  dblParam_[ClpDualObjectiveLimit] = DBL_MAX;
103  dblParam_[ClpPrimalObjectiveLimit] = DBL_MAX;
104  dblParam_[ClpDualTolerance] = 1e-7;
105  dblParam_[ClpPrimalTolerance] = 1e-7;
106  dblParam_[ClpObjOffset] = 0.0;
107
108  strParam_[ClpProbName] = "ClpDefaultName";
109  handler_ = new CoinMessageHandler();
110  handler_->setLogLevel(2);
111  messages_ = ClpMessage();
112}
113
114//-----------------------------------------------------------------------------
115
116ClpModel::~ClpModel ()
117{
118  if (defaultHandler_) {
119    delete handler_;
120    handler_ = NULL;
121  }
122  gutsOfDelete();
123}
124void ClpModel::gutsOfDelete()
125{
126  delete [] rowActivity_;
127  rowActivity_=NULL;
128  delete [] columnActivity_;
129  columnActivity_=NULL;
130  delete [] dual_;
131  dual_=NULL;
132  delete [] reducedCost_;
133  reducedCost_=NULL;
134  delete [] rowLower_;
135  delete [] rowUpper_;
136  delete [] rowObjective_;
137  rowLower_=NULL;
138  rowUpper_=NULL;
139  rowObjective_=NULL;
140  delete [] columnLower_;
141  delete [] columnUpper_;
142  delete [] objective_;
143  columnLower_=NULL;
144  columnUpper_=NULL;
145  objective_=NULL;
146  delete matrix_;
147  matrix_=NULL;
148  delete rowCopy_;
149  rowCopy_=NULL;
150  delete [] ray_;
151  ray_ = NULL;
152  delete [] integerType_;
153  integerType_ = NULL;
154}
155//#############################################################################
156void ClpModel::setPrimalTolerance( double value) 
157{
158  if (value>0.0&&value<1.0e10)
159    dblParam_[ClpPrimalTolerance]=value;
160}
161void ClpModel::setDualTolerance( double value) 
162{
163  if (value>0.0&&value<1.0e10)
164    dblParam_[ClpDualTolerance]=value;
165}
166void ClpModel::setOptimizationDirection( int value) 
167{
168  if (value>=-1&&value<=1)
169    optimizationDirection_=value;
170}
171void
172ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, 
173                     const double* collb, const double* colub,   
174                     const double* obj,
175                     const double* rowlb, const double* rowub,
176                                const double * rowObjective)
177{
178  gutsOfDelete();
179  numberRows_=numberRows;
180  numberColumns_=numberColumns;
181  rowActivity_=new double[numberRows_];
182  columnActivity_=new double[numberColumns_];
183  dual_=new double[numberRows_];
184  reducedCost_=new double[numberColumns_];
185
186  CoinFillN(dual_,numberRows_,0.0);
187  CoinFillN(reducedCost_,numberColumns_,0.0);
188  int iRow,iColumn;
189
190  rowLower_=copyOfArray(rowlb,numberRows_,-DBL_MAX);
191  rowUpper_=copyOfArray(rowub,numberRows_,DBL_MAX);
192  objective_=copyOfArray(obj,numberColumns_,0.0);
193  rowObjective_=copyOfArray(rowObjective,numberRows_);
194  columnLower_=copyOfArray(collb,numberColumns_,0.0);
195  columnUpper_=copyOfArray(colub,numberColumns_,DBL_MAX);
196  // set default solution
197  for (iRow=0;iRow<numberRows_;iRow++) {
198    if (rowLower_[iRow]>0.0) {
199      rowActivity_[iRow]=rowLower_[iRow];
200    } else if (rowUpper_[iRow]<0.0) {
201      rowActivity_[iRow]=rowUpper_[iRow];
202    } else {
203      rowActivity_[iRow]=0.0;
204    }
205  }
206  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
207    if (columnLower_[iColumn]>0.0) {
208      columnActivity_[iColumn]=columnLower_[iColumn];
209    } else if (columnUpper_[iColumn]<0.0) {
210      columnActivity_[iColumn]=columnUpper_[iColumn];
211    } else {
212      columnActivity_[iColumn]=0.0;
213    }
214  }
215}
216void
217ClpModel::loadProblem (  const ClpMatrixBase& matrix,
218                     const double* collb, const double* colub,   
219                     const double* obj,
220                     const double* rowlb, const double* rowub,
221                                const double * rowObjective)
222{
223  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
224                  collb, colub, obj, rowlb, rowub, rowObjective);
225  if (matrix.isColOrdered()) {
226    matrix_=matrix.clone();
227  } else {
228    // later may want to keep as unknown class
229    CoinPackedMatrix matrix2;
230    matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
231    matrix.releasePackedMatrix();
232    matrix_=new ClpPackedMatrix(matrix2);
233  }   
234}
235void
236ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
237                     const double* collb, const double* colub,   
238                     const double* obj,
239                     const double* rowlb, const double* rowub,
240                                const double * rowObjective)
241{
242  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
243                  collb, colub, obj, rowlb, rowub, rowObjective);
244  if (matrix.isColOrdered()) {
245    matrix_=new ClpPackedMatrix(matrix);
246  } else {
247    CoinPackedMatrix matrix2;
248    matrix2.reverseOrderedCopyOf(matrix);
249    matrix_=new ClpPackedMatrix(matrix2);
250  }   
251}
252void
253ClpModel::loadProblem ( 
254                              const int numcols, const int numrows,
255                              const int* start, const int* index,
256                              const double* value,
257                              const double* collb, const double* colub,   
258                              const double* obj,
259                              const double* rowlb, const double* rowub,
260                              const double * rowObjective)
261{
262  gutsOfLoadModel(numrows, numcols,
263                  collb, colub, obj, rowlb, rowub, rowObjective);
264  CoinPackedMatrix matrix(true,numrows,numcols,start[numcols],
265                              value,index,start,NULL);
266  matrix_ = new ClpPackedMatrix(matrix);
267}
268void
269ClpModel::loadProblem ( 
270                              const int numcols, const int numrows,
271                              const int* start, const int* index,
272                              const double* value,const int* length,
273                              const double* collb, const double* colub,   
274                              const double* obj,
275                              const double* rowlb, const double* rowub,
276                              const double * rowObjective)
277{
278  gutsOfLoadModel(numrows, numcols,
279                  collb, colub, obj, rowlb, rowub, rowObjective);
280  // Compute number of elements
281  int numberElements = 0;
282  int i;
283  for (i=0;i<numcols;i++) 
284    numberElements += length[i];
285  CoinPackedMatrix matrix(true,numrows,numcols,numberElements,
286                              value,index,start,length);
287  matrix_ = new ClpPackedMatrix(matrix);
288}
289void
290ClpModel::getRowBound(int iRow, double& lower, double& upper) const
291{
292  lower=-DBL_MAX;
293  upper=DBL_MAX;
294  if (rowUpper_)
295    upper=rowUpper_[iRow];
296  if (rowLower_)
297    lower=rowLower_[iRow];
298}
299//#############################################################################
300// Copy constructor.
301ClpModel::ClpModel(const ClpModel &rhs) :
302  optimizationDirection_(rhs.optimizationDirection_),
303  numberRows_(rhs.numberRows_),
304  numberColumns_(rhs.numberColumns_)
305{
306  gutsOfCopy(rhs);
307}
308// Assignment operator. This copies the data
309ClpModel & 
310ClpModel::operator=(const ClpModel & rhs)
311{
312  if (this != &rhs) {
313    if (defaultHandler_) {
314      delete handler_;
315      handler_ = NULL;
316    }
317    gutsOfDelete();
318    optimizationDirection_ = rhs.optimizationDirection_;
319    numberRows_ = rhs.numberRows_;
320    numberColumns_ = rhs.numberColumns_;
321    gutsOfCopy(rhs);
322  }
323  return *this;
324}
325// Does most of copying
326void 
327ClpModel::gutsOfCopy(const ClpModel & rhs, bool trueCopy)
328{
329  defaultHandler_ = rhs.defaultHandler_;
330  if (defaultHandler_) 
331    handler_ = new CoinMessageHandler(*rhs.handler_);
332   else 
333    handler_ = rhs.handler_;
334  messages_ = rhs.messages_;
335  intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
336  intParam_[ClpMaxNumIterationHotStart] = 
337    rhs.intParam_[ClpMaxNumIterationHotStart];
338
339  dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit];
340  dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit];
341  dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance];
342  dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance];
343  dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset];
344
345  strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
346
347  objectiveValue_=rhs.objectiveValue_;
348  numberIterations_ = rhs.numberIterations_;
349  problemStatus_ = rhs.problemStatus_;
350  maximumIterations_ = rhs.maximumIterations_;
351  if (trueCopy) {
352    lengthNames_ = rhs.lengthNames_;
353    rowNames_ = rhs.rowNames_;
354    columnNames_ = rhs.columnNames_;
355    if (rhs.integerType_) {
356      integerType_ = new char[numberColumns_];
357      memcpy(integerType_,rhs.integerType_,numberColumns_*sizeof(char));
358    } else {
359      integerType_ = NULL;
360    }
361    if (rhs.rowActivity_) {
362      rowActivity_=new double[numberRows_];
363      columnActivity_=new double[numberColumns_];
364      dual_=new double[numberRows_];
365      reducedCost_=new double[numberColumns_];
366      CoinDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
367                          rowActivity_);
368      CoinDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
369                          columnActivity_);
370      CoinDisjointCopyN ( rhs.dual_, numberRows_ , 
371                          dual_);
372      CoinDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
373                          reducedCost_);
374    } else {
375      rowActivity_=NULL;
376      columnActivity_=NULL;
377      dual_=NULL;
378      reducedCost_=NULL;
379    }
380    rowLower_ = copyOfArray ( rhs.rowLower_, numberRows_ );
381    rowUpper_ = copyOfArray ( rhs.rowUpper_, numberRows_ );
382    columnLower_ = copyOfArray ( rhs.columnLower_, numberColumns_ );
383    columnUpper_ = copyOfArray ( rhs.columnUpper_, numberColumns_ );
384    objective_ = copyOfArray ( rhs.objective_, numberColumns_ );
385    rowObjective_ = copyOfArray ( rhs.rowObjective_, numberRows_ );
386    ray_ = NULL;
387    if (problemStatus_==1)
388      ray_ = copyOfArray (rhs.ray_,numberRows_);
389    else if (problemStatus_==2)
390      ray_ = copyOfArray (rhs.ray_,numberColumns_);
391    if (rhs.rowCopy_) {
392      rowCopy_ = rhs.rowCopy_->clone();
393    } else {
394      rowCopy_=NULL;
395    }
396    matrix_=NULL;
397    if (rhs.matrix_) {
398      matrix_ = rhs.matrix_->clone();
399    }
400  } else {
401    rowActivity_ = rhs.rowActivity_;
402    columnActivity_ = rhs.columnActivity_;
403    dual_ = rhs.dual_;
404    reducedCost_ = rhs.reducedCost_;
405    rowLower_ = rhs.rowLower_;
406    rowUpper_ = rhs.rowUpper_;
407    objective_ = rhs.objective_;
408    rowObjective_ = rhs.rowObjective_;
409    columnLower_ = rhs.columnLower_;
410    columnUpper_ = rhs.columnUpper_;
411    matrix_ = rhs.matrix_;
412    rowCopy_ = rhs.rowCopy_;
413    ray_ = rhs.ray_;
414    lengthNames_ = 0;
415    rowNames_ = std::vector<std::string> ();
416    columnNames_ = std::vector<std::string> ();
417    integerType_ = NULL;
418  }
419}
420/* Borrow model.  This is so we dont have to copy large amounts
421   of data around.  It assumes a derived class wants to overwrite
422   an empty model with a real one - while it does an algorithm */
423void 
424ClpModel::borrowModel(ClpModel & rhs)
425{
426  if (defaultHandler_) {
427    delete handler_;
428    handler_ = NULL;
429  }
430  gutsOfDelete();
431  optimizationDirection_ = rhs.optimizationDirection_;
432  numberRows_ = rhs.numberRows_;
433  numberColumns_ = rhs.numberColumns_;
434  delete [] rhs.ray_;
435  rhs.ray_=NULL;
436  gutsOfCopy(rhs,false);
437}
438// Return model - nulls all arrays so can be deleted safely
439void 
440ClpModel::returnModel(ClpModel & otherModel)
441{
442  otherModel.objectiveValue_=objectiveValue_;
443  otherModel.numberIterations_ = numberIterations_;
444  otherModel.problemStatus_ = problemStatus_;
445  rowActivity_ = NULL;
446  columnActivity_ = NULL;
447  dual_ = NULL;
448  reducedCost_ = NULL;
449  rowLower_ = NULL;
450  rowUpper_ = NULL;
451  objective_ = NULL;
452  rowObjective_ = NULL;
453  columnLower_ = NULL;
454  columnUpper_ = NULL;
455  matrix_ = NULL;
456  rowCopy_ = NULL;
457  delete [] otherModel.ray_;
458  otherModel.ray_ = ray_;
459  ray_ = NULL;
460}
461//#############################################################################
462// Parameter related methods
463//#############################################################################
464
465bool
466ClpModel::setIntParam(ClpIntParam key, int value)
467{
468  switch (key) {
469  case ClpMaxNumIteration:
470    if (value < 0)
471      return false;
472    break;
473  case ClpMaxNumIterationHotStart:
474    if (value < 0)
475      return false;
476    break;
477  case ClpLastIntParam:
478    return false;
479  }
480  intParam_[key] = value;
481  return true;
482}
483
484//-----------------------------------------------------------------------------
485
486bool
487ClpModel::setDblParam(ClpDblParam key, double value)
488{
489
490  switch (key) {
491  case ClpDualObjectiveLimit:
492    break;
493
494  case ClpPrimalObjectiveLimit:
495    break;
496
497  case ClpDualTolerance: 
498    if (value<=0.0||value>1.0e10)
499      return false;
500    break;
501   
502  case ClpPrimalTolerance: 
503    if (value<=0.0||value>1.0e10)
504      return false;
505    break;
506   
507  case ClpObjOffset: 
508    break;
509
510  case ClpLastDblParam:
511    return false;
512  }
513  dblParam_[key] = value;
514  return true;
515}
516
517//-----------------------------------------------------------------------------
518
519bool
520ClpModel::setStrParam(ClpStrParam key, const std::string & value)
521{
522
523  switch (key) {
524  case ClpProbName:
525    break;
526
527  case ClpLastStrParam:
528    return false;
529  }
530  strParam_[key] = value;
531  return true;
532}
533// Useful routines
534// Returns resized array and deletes incoming
535double * resizeDouble(double * array , int size, int newSize, double fill)
536{
537  if (array&&size!=newSize) {
538    int i;
539    double * newArray = new double[newSize];
540    memcpy(newArray,array,min(newSize,size)*sizeof(double));
541    delete [] array;
542    array = newArray;
543    for (i=size;i<newSize;i++) 
544      array[i]=fill;
545  } 
546  return array;
547}
548// Returns resized array and updates size
549double * deleteDouble(double * array , int size, 
550                      int number, const int * which,int & newSize)
551{
552  if (array) {
553    int i ;
554    char * deleted = new char[size];
555    int numberDeleted=0;
556    memset(deleted,0,size*sizeof(char));
557    for (i=0;i<number;i++) {
558      int j = which[i];
559      if (j>=0&&j<size&&!deleted[j]) {
560        numberDeleted++;
561        deleted[j]=1;
562      }
563    }
564    newSize = size-numberDeleted;
565    double * newArray = new double[newSize];
566    int put=0;
567    for (i=0;i<size;i++) {
568      if (!deleted[i]) {
569        newArray[put++]=array[i];
570      }
571    }
572    delete [] array;
573    array = newArray;
574    delete [] deleted;
575  }
576  return array;
577}
578char * deleteChar(char * array , int size, 
579                      int number, const int * which,int & newSize)
580{
581  if (array) {
582    int i ;
583    char * deleted = new char[size];
584    int numberDeleted=0;
585    memset(deleted,0,size*sizeof(char));
586    for (i=0;i<number;i++) {
587      int j = which[i];
588      if (j>=0&&j<size&&!deleted[j]) {
589        numberDeleted++;
590        deleted[j]=1;
591      }
592    }
593    newSize = size-numberDeleted;
594    char * newArray = new char[newSize];
595    int put=0;
596    for (i=0;i<size;i++) {
597      if (!deleted[i]) {
598        newArray[put++]=array[i];
599      }
600    }
601    delete [] array;
602    array = newArray;
603    delete [] deleted;
604  }
605  return array;
606}
607// Resizes
608void 
609ClpModel::resize (int newNumberRows, int newNumberColumns)
610{
611  rowActivity_ = resizeDouble(rowActivity_,numberRows_,
612                              newNumberRows,0.0);
613  dual_ = resizeDouble(dual_,numberRows_,
614                       newNumberRows,0.0);
615  rowObjective_ = resizeDouble(rowObjective_,numberRows_,
616                               newNumberRows,0.0);
617  rowLower_ = resizeDouble(rowLower_,numberRows_,
618                           newNumberRows,-DBL_MAX);
619  rowUpper_ = resizeDouble(rowUpper_,numberRows_,
620                           newNumberRows,DBL_MAX);
621  columnActivity_ = resizeDouble(columnActivity_,numberColumns_,
622                                 newNumberColumns,0.0);
623  reducedCost_ = resizeDouble(reducedCost_,numberColumns_,
624                              newNumberColumns,0.0);
625  objective_ = resizeDouble(objective_,numberColumns_,
626                            newNumberColumns,0.0);
627  columnLower_ = resizeDouble(columnLower_,numberColumns_,
628                              newNumberColumns,0.0);
629  columnUpper_ = resizeDouble(columnUpper_,numberColumns_,
630                              newNumberColumns,DBL_MAX);
631  if (newNumberRows<numberRows_) {
632    int * which = new int[numberRows_-newNumberRows];
633    int i;
634    for (i=newNumberRows;i<numberRows_;i++) 
635      which[i-newNumberRows]=i;
636    matrix_->deleteRows(numberRows_-newNumberRows,which);
637    delete [] which;
638  }
639  if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) {
640    // set state back to unknown
641    problemStatus_ = -1;
642    delete [] ray_;
643    ray_ = NULL;
644  }
645  numberRows_ = newNumberRows;
646  if (newNumberColumns<numberColumns_) {
647    int * which = new int[numberColumns_-newNumberColumns];
648    int i;
649    for (i=newNumberColumns;i<numberColumns_;i++) 
650      which[i-newNumberColumns]=i;
651    matrix_->deleteCols(numberColumns_-newNumberColumns,which);
652    delete [] which;
653  }
654  if (integerType_) {
655    char * temp = new char [newNumberColumns];
656    memset(temp,0,newNumberColumns*sizeof(char));
657    memcpy(temp,integerType_,
658           min(newNumberColumns,numberColumns_)*sizeof(char));
659    delete [] integerType_;
660    integerType_ = temp;
661  }
662  numberColumns_ = newNumberColumns;
663  // for now gets rid of names
664  lengthNames_ = 0;
665  rowNames_ = std::vector<std::string> ();
666  columnNames_ = std::vector<std::string> ();
667}
668// Deletes rows
669void 
670ClpModel::deleteRows(int number, const int * which)
671{
672  int newSize=0;
673  rowActivity_ = deleteDouble(rowActivity_,numberRows_,
674                              number, which, newSize);
675  dual_ = deleteDouble(dual_,numberRows_,
676                              number, which, newSize);
677  rowObjective_ = deleteDouble(rowObjective_,numberRows_,
678                              number, which, newSize);
679  rowLower_ = deleteDouble(rowLower_,numberRows_,
680                              number, which, newSize);
681  rowUpper_ = deleteDouble(rowUpper_,numberRows_,
682                              number, which, newSize);
683  matrix_->deleteRows(number,which);
684  numberRows_=newSize;
685  // set state back to unknown
686  problemStatus_ = -1;
687  delete [] ray_;
688  ray_ = NULL;
689  // for now gets rid of names
690  lengthNames_ = 0;
691  rowNames_ = std::vector<std::string> ();
692  columnNames_ = std::vector<std::string> ();
693}
694// Deletes columns
695void 
696ClpModel::deleteColumns(int number, const int * which)
697{
698  int newSize=0;
699  columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
700                              number, which, newSize);
701  reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
702                              number, which, newSize);
703  objective_ = deleteDouble(objective_,numberColumns_,
704                              number, which, newSize);
705  columnLower_ = deleteDouble(columnLower_,numberColumns_,
706                              number, which, newSize);
707  columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
708                              number, which, newSize);
709  matrix_->deleteCols(number,which);
710  numberColumns_=newSize;
711  // set state back to unknown
712  problemStatus_ = -1;
713  delete [] ray_;
714  ray_ = NULL;
715  // for now gets rid of names
716  lengthNames_ = 0;
717  rowNames_ = std::vector<std::string> ();
718  columnNames_ = std::vector<std::string> ();
719  integerType_ = deleteChar(integerType_,numberColumns_,
720                            number, which, newSize);
721}
722// Infeasibility/unbounded ray (NULL returned if none/wrong)
723double * 
724ClpModel::infeasibilityRay() const
725{
726  double * array = NULL;
727  if (problemStatus_==1) 
728    array = copyOfArray(ray_,numberRows_);
729  return array;
730}
731double * 
732ClpModel::unboundedRay() const
733{
734  double * array = NULL;
735  if (problemStatus_==2) 
736    array = copyOfArray(ray_,numberColumns_);
737  return array;
738}
739void 
740ClpModel::setMaximumIterations(int value)
741{
742  if(value>=0)
743    maximumIterations_=value;
744}
745// Pass in Message handler (not deleted at end)
746void 
747ClpModel::passInMessageHandler(CoinMessageHandler * handler)
748{
749  defaultHandler_=false;
750  handler_=handler;
751}
752// Set language
753void 
754ClpModel::newLanguage(CoinMessages::Language language)
755{
756  messages_ = ClpMessage(language);
757}
758// Read an mps file from the given filename
759int 
760ClpModel::readMps(const char *fileName,
761                  bool keepNames,
762                  bool ignoreErrors)
763{
764  bool canOpen=false;
765  if (fileName=="-") {
766    // stdin
767    canOpen=true;
768    fileName = "-";
769  } else {
770    FILE *fp=fopen(fileName,"r");
771    if (fp) {
772      // can open - lets go for it
773      fclose(fp);
774      canOpen=true;
775    } else {
776      handler_->message(CLP_UNABLE_OPEN,messages_)
777        <<fileName<<CoinMessageEol;
778      return -1;
779    }
780  }
781  CoinMpsIO m;
782  double time1 = cpuTime(),time2;
783  int status=m.readMps(fileName,"");
784  if (!status||ignoreErrors) {
785    loadProblem(*m.getMatrixByCol(),
786                m.getColLower(),m.getColUpper(),
787                m.getObjCoefficients(),
788                m.getRowLower(),m.getRowUpper());
789    if (m.integerColumns()) {
790      integerType_ = new char[numberColumns_];
791      memcpy(integerType_,m.integerColumns(),numberColumns_*sizeof(char));
792    } else {
793      integerType_ = NULL;
794    }
795    // set problem name
796    setStrParam(ClpProbName,m.getProblemName());
797    // do names
798    if (keepNames) {
799      unsigned int maxLength=0;
800      int iRow;
801      rowNames_.reserve(numberRows_);
802      for (iRow=0;iRow<numberRows_;iRow++) {
803        const char * name = m.rowName(iRow);
804        maxLength = max(maxLength,(unsigned int) strlen(name));
805          rowNames_.push_back(name);
806      }
807     
808      int iColumn;
809      columnNames_.reserve(numberColumns_);
810      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
811        const char * name = m.columnName(iColumn);
812        maxLength = max(maxLength,(unsigned int) strlen(name));
813        columnNames_.push_back(name);
814      }
815      lengthNames_=(int) maxLength;
816    } else {
817      lengthNames_=0;
818    }
819    setDblParam(ClpObjOffset,m.objectiveOffset());
820    time2 = cpuTime();
821    handler_->message(CLP_IMPORT_RESULT,messages_)
822      <<fileName
823      <<time2-time1<<CoinMessageEol;
824  } else {
825    // errors
826    handler_->message(CLP_IMPORT_ERRORS,messages_)
827      <<status<<fileName<<CoinMessageEol;
828  }
829
830  return status;
831}
832bool ClpModel::isPrimalObjectiveLimitReached() const
833{
834  double limit = 0.0;
835  getDblParam(ClpPrimalObjectiveLimit, limit);
836  if (limit > 1e30) {
837    // was not ever set
838    return false;
839  }
840   
841  const double obj = objectiveValue();
842  const int maxmin = optimizationDirection();
843
844  if (problemStatus_ == 0) // optimal
845    return maxmin > 0 ? (obj < limit) /*minim*/ : (obj > limit) /*maxim*/;
846  else if (problemStatus_==2)
847    return true;
848  else
849    return false;
850}
851
852bool ClpModel::isDualObjectiveLimitReached() const
853{
854
855  double limit = 0.0;
856  getDblParam(ClpDualObjectiveLimit, limit);
857  if (limit > 1e30) {
858    // was not ever set
859    return false;
860  }
861   
862  const double obj = objectiveValue();
863  const int maxmin = optimizationDirection();
864
865  if (problemStatus_ == 0) // optimal
866    return maxmin > 0 ? (obj > limit) /*minim*/ : (obj < limit) /*maxim*/;
867  else if (problemStatus_==1)
868    return true;
869  else
870    return false;
871
872}
873void 
874ClpModel::copyInIntegerInformation(const char * information)
875{
876  delete [] integerType_;
877  if (information) {
878    integerType_ = new char[numberColumns_];
879    memcpy(integerType_,information,numberColumns_*sizeof(char));
880  } else {
881    integerType_ = NULL;
882  }
883}
884// Drops names - makes lengthnames 0 and names empty
885void 
886ClpModel::dropNames()
887{
888  lengthNames_=0;
889  rowNames_ = std::vector<std::string> ();
890  columnNames_ = std::vector<std::string> ();
891}
892// Drop integer informations
893void 
894ClpModel::deleteIntegerInformation()
895{
896  delete [] integerType_;
897  integerType_ = NULL;
898}
Note: See TracBrowser for help on using the repository browser.