source: trunk/ClpModel.cpp @ 114

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

Re-order variables

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