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

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

Presolve in as option

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