source: trunk/ClpModel.cpp @ 169

Last change on this file since 169 was 169, checked in by forrest, 16 years ago

Fixes for Mikhail

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