source: trunk/ClpModel.cpp @ 284

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

Objective limit

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.6 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
12#include "CoinPragma.hpp"
13
14#include "CoinHelperFunctions.hpp"
15#include "CoinTime.hpp"
16#include "ClpModel.hpp"
17#include "ClpPackedMatrix.hpp"
18#include "CoinPackedVector.hpp"
19#include "CoinIndexedVector.hpp"
20#include "CoinMpsIO.hpp"
21#include "ClpMessage.hpp"
22#include "ClpLinearObjective.hpp"
23#include "ClpQuadraticObjective.hpp"
24
25//#############################################################################
26
27ClpModel::ClpModel () :
28
29  optimizationDirection_(1),
30  objectiveValue_(0.0),
31  smallElement_(1.0e-20),
32  numberRows_(0),
33  numberColumns_(0),
34  rowActivity_(NULL),
35  columnActivity_(NULL),
36  dual_(NULL),
37  reducedCost_(NULL),
38  rowLower_(NULL),
39  rowUpper_(NULL),
40  objective_(NULL),
41  rowObjective_(NULL),
42  columnLower_(NULL),
43  columnUpper_(NULL),
44  matrix_(NULL),
45  rowCopy_(NULL),
46  ray_(NULL),
47  status_(NULL),
48  integerType_(NULL),
49  userPointer_(NULL),
50  numberIterations_(0),
51  solveType_(0),
52  problemStatus_(-1),
53  secondaryStatus_(0),
54  lengthNames_(0),
55  defaultHandler_(true),
56  rowNames_(),
57  columnNames_()
58{
59  intParam_[ClpMaxNumIteration] = 99999999;
60  intParam_[ClpMaxNumIterationHotStart] = 9999999;
61
62  dblParam_[ClpDualObjectiveLimit] = COIN_DBL_MAX;
63  dblParam_[ClpPrimalObjectiveLimit] = COIN_DBL_MAX;
64  dblParam_[ClpDualTolerance] = 1e-7;
65  dblParam_[ClpPrimalTolerance] = 1e-7;
66  dblParam_[ClpObjOffset] = 0.0;
67  dblParam_[ClpMaxSeconds] = -1.0;
68
69  strParam_[ClpProbName] = "ClpDefaultName";
70  handler_ = new CoinMessageHandler();
71  handler_->setLogLevel(1);
72  messages_ = ClpMessage();
73}
74
75//-----------------------------------------------------------------------------
76
77ClpModel::~ClpModel ()
78{
79  if (defaultHandler_) {
80    delete handler_;
81    handler_ = NULL;
82  }
83  gutsOfDelete();
84}
85void ClpModel::gutsOfDelete()
86{
87  delete [] rowActivity_;
88  rowActivity_=NULL;
89  delete [] columnActivity_;
90  columnActivity_=NULL;
91  delete [] dual_;
92  dual_=NULL;
93  delete [] reducedCost_;
94  reducedCost_=NULL;
95  delete [] rowLower_;
96  delete [] rowUpper_;
97  delete [] rowObjective_;
98  rowLower_=NULL;
99  rowUpper_=NULL;
100  rowObjective_=NULL;
101  delete [] columnLower_;
102  delete [] columnUpper_;
103  delete objective_;
104  columnLower_=NULL;
105  columnUpper_=NULL;
106  objective_=NULL;
107  delete matrix_;
108  matrix_=NULL;
109  delete rowCopy_;
110  rowCopy_=NULL;
111  delete [] ray_;
112  ray_ = NULL;
113  delete [] integerType_;
114  integerType_ = NULL;
115  delete [] status_;
116  status_=NULL;
117}
118//#############################################################################
119void ClpModel::setPrimalTolerance( double value) 
120{
121  if (value>0.0&&value<1.0e10)
122    dblParam_[ClpPrimalTolerance]=value;
123}
124void ClpModel::setDualTolerance( double value) 
125{
126  if (value>0.0&&value<1.0e10)
127    dblParam_[ClpDualTolerance]=value;
128}
129void ClpModel::setOptimizationDirection( double value) 
130{
131  optimizationDirection_=value;
132}
133void
134ClpModel::gutsOfLoadModel (int numberRows, int numberColumns, 
135                     const double* collb, const double* colub,   
136                     const double* obj,
137                     const double* rowlb, const double* rowub,
138                                const double * rowObjective)
139{
140  gutsOfDelete();
141  numberRows_=numberRows;
142  numberColumns_=numberColumns;
143  rowActivity_=new double[numberRows_];
144  columnActivity_=new double[numberColumns_];
145  dual_=new double[numberRows_];
146  reducedCost_=new double[numberColumns_];
147
148  ClpFillN(dual_,numberRows_,0.0);
149  ClpFillN(reducedCost_,numberColumns_,0.0);
150  int iRow,iColumn;
151
152  rowLower_=ClpCopyOfArray(rowlb,numberRows_,-COIN_DBL_MAX);
153  rowUpper_=ClpCopyOfArray(rowub,numberRows_,COIN_DBL_MAX);
154  double * objective=ClpCopyOfArray(obj,numberColumns_,0.0);
155  objective_ = new ClpLinearObjective(objective,numberColumns_);
156  delete [] objective;
157  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
158  columnLower_=ClpCopyOfArray(collb,numberColumns_,0.0);
159  columnUpper_=ClpCopyOfArray(colub,numberColumns_,COIN_DBL_MAX);
160  // set default solution
161  for (iRow=0;iRow<numberRows_;iRow++) {
162    if (rowLower_[iRow]>0.0) {
163      rowActivity_[iRow]=rowLower_[iRow];
164    } else if (rowUpper_[iRow]<0.0) {
165      rowActivity_[iRow]=rowUpper_[iRow];
166    } else {
167      rowActivity_[iRow]=0.0;
168    }
169  }
170  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
171    if (columnLower_[iColumn]>0.0) {
172      columnActivity_[iColumn]=columnLower_[iColumn];
173    } else if (columnUpper_[iColumn]<0.0) {
174      columnActivity_[iColumn]=columnUpper_[iColumn];
175    } else {
176      columnActivity_[iColumn]=0.0;
177    }
178  }
179}
180// This just loads up a row objective
181void ClpModel::setRowObjective(const double * rowObjective)
182{
183  delete [] rowObjective_;
184  rowObjective_=ClpCopyOfArray(rowObjective,numberRows_);
185}
186void
187ClpModel::loadProblem (  const ClpMatrixBase& matrix,
188                     const double* collb, const double* colub,   
189                     const double* obj,
190                     const double* rowlb, const double* rowub,
191                                const double * rowObjective)
192{
193  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
194                  collb, colub, obj, rowlb, rowub, rowObjective);
195  if (matrix.isColOrdered()) {
196    matrix_=matrix.clone();
197  } else {
198    // later may want to keep as unknown class
199    CoinPackedMatrix matrix2;
200    matrix2.reverseOrderedCopyOf(*matrix.getPackedMatrix());
201    matrix.releasePackedMatrix();
202    matrix_=new ClpPackedMatrix(matrix2);
203  }   
204}
205void
206ClpModel::loadProblem (  const CoinPackedMatrix& matrix,
207                     const double* collb, const double* colub,   
208                     const double* obj,
209                     const double* rowlb, const double* rowub,
210                                const double * rowObjective)
211{
212  gutsOfLoadModel(matrix.getNumRows(),matrix.getNumCols(),
213                  collb, colub, obj, rowlb, rowub, rowObjective);
214  if (matrix.isColOrdered()) {
215    matrix_=new ClpPackedMatrix(matrix);
216  } else {
217    CoinPackedMatrix matrix2;
218    matrix2.reverseOrderedCopyOf(matrix);
219    matrix_=new ClpPackedMatrix(matrix2);
220  }   
221}
222void
223ClpModel::loadProblem ( 
224                              const int numcols, const int numrows,
225                              const CoinBigIndex* start, const int* index,
226                              const double* value,
227                              const double* collb, const double* colub,   
228                              const double* obj,
229                              const double* rowlb, const double* rowub,
230                              const double * rowObjective)
231{
232  gutsOfLoadModel(numrows, numcols,
233                  collb, colub, obj, rowlb, rowub, rowObjective);
234  CoinPackedMatrix matrix(true,numrows,numcols,start[numcols],
235                              value,index,start,NULL);
236  matrix_ = new ClpPackedMatrix(matrix);
237}
238void
239ClpModel::loadProblem ( 
240                              const int numcols, const int numrows,
241                              const CoinBigIndex* start, const int* index,
242                              const double* value,const int* length,
243                              const double* collb, const double* colub,   
244                              const double* obj,
245                              const double* rowlb, const double* rowub,
246                              const double * rowObjective)
247{
248  gutsOfLoadModel(numrows, numcols,
249                  collb, colub, obj, rowlb, rowub, rowObjective);
250  // Compute number of elements
251  int numberElements = 0;
252  int i;
253  for (i=0;i<numcols;i++) 
254    numberElements += length[i];
255  CoinPackedMatrix matrix(true,numrows,numcols,numberElements,
256                              value,index,start,length);
257  matrix_ = new ClpPackedMatrix(matrix);
258}
259void
260ClpModel::getRowBound(int iRow, double& lower, double& upper) const
261{
262  lower=-COIN_DBL_MAX;
263  upper=COIN_DBL_MAX;
264  if (rowUpper_)
265    upper=rowUpper_[iRow];
266  if (rowLower_)
267    lower=rowLower_[iRow];
268}
269//#############################################################################
270// Copy constructor.
271ClpModel::ClpModel(const ClpModel &rhs) :
272  optimizationDirection_(rhs.optimizationDirection_),
273  numberRows_(rhs.numberRows_),
274  numberColumns_(rhs.numberColumns_)
275{
276  gutsOfCopy(rhs);
277}
278// Assignment operator. This copies the data
279ClpModel & 
280ClpModel::operator=(const ClpModel & rhs)
281{
282  if (this != &rhs) {
283    if (defaultHandler_) {
284      delete handler_;
285      handler_ = NULL;
286    }
287    gutsOfDelete();
288    optimizationDirection_ = rhs.optimizationDirection_;
289    numberRows_ = rhs.numberRows_;
290    numberColumns_ = rhs.numberColumns_;
291    gutsOfCopy(rhs);
292  }
293  return *this;
294}
295// Does most of copying
296void 
297ClpModel::gutsOfCopy(const ClpModel & rhs, bool trueCopy)
298{
299  defaultHandler_ = rhs.defaultHandler_;
300  if (defaultHandler_) 
301    handler_ = new CoinMessageHandler(*rhs.handler_);
302   else 
303    handler_ = rhs.handler_;
304  messages_ = rhs.messages_;
305  intParam_[ClpMaxNumIteration] = rhs.intParam_[ClpMaxNumIteration];
306  intParam_[ClpMaxNumIterationHotStart] = 
307    rhs.intParam_[ClpMaxNumIterationHotStart];
308
309  dblParam_[ClpDualObjectiveLimit] = rhs.dblParam_[ClpDualObjectiveLimit];
310  dblParam_[ClpPrimalObjectiveLimit] = rhs.dblParam_[ClpPrimalObjectiveLimit];
311  dblParam_[ClpDualTolerance] = rhs.dblParam_[ClpDualTolerance];
312  dblParam_[ClpPrimalTolerance] = rhs.dblParam_[ClpPrimalTolerance];
313  dblParam_[ClpObjOffset] = rhs.dblParam_[ClpObjOffset];
314  dblParam_[ClpMaxSeconds] = rhs.dblParam_[ClpMaxSeconds];
315
316  strParam_[ClpProbName] = rhs.strParam_[ClpProbName];
317
318  optimizationDirection_ = rhs.optimizationDirection_;
319  objectiveValue_=rhs.objectiveValue_;
320  smallElement_ = rhs.smallElement_;
321  numberIterations_ = rhs.numberIterations_;
322  solveType_ = rhs.solveType_;
323  problemStatus_ = rhs.problemStatus_;
324  secondaryStatus_ = rhs.secondaryStatus_;
325  numberRows_ = rhs.numberRows_;
326  numberColumns_ = rhs.numberColumns_;
327  userPointer_ = rhs.userPointer_;
328  if (trueCopy) {
329    lengthNames_ = rhs.lengthNames_;
330    rowNames_ = rhs.rowNames_;
331    columnNames_ = rhs.columnNames_;
332    if (rhs.integerType_) {
333      integerType_ = new char[numberColumns_];
334      memcpy(integerType_,rhs.integerType_,numberColumns_*sizeof(char));
335    } else {
336      integerType_ = NULL;
337    }
338    if (rhs.rowActivity_) {
339      rowActivity_=new double[numberRows_];
340      columnActivity_=new double[numberColumns_];
341      dual_=new double[numberRows_];
342      reducedCost_=new double[numberColumns_];
343      ClpDisjointCopyN ( rhs.rowActivity_, numberRows_ ,
344                          rowActivity_);
345      ClpDisjointCopyN ( rhs.columnActivity_, numberColumns_ ,
346                          columnActivity_);
347      ClpDisjointCopyN ( rhs.dual_, numberRows_ , 
348                          dual_);
349      ClpDisjointCopyN ( rhs.reducedCost_, numberColumns_ ,
350                          reducedCost_);
351    } else {
352      rowActivity_=NULL;
353      columnActivity_=NULL;
354      dual_=NULL;
355      reducedCost_=NULL;
356    }
357    rowLower_ = ClpCopyOfArray ( rhs.rowLower_, numberRows_ );
358    rowUpper_ = ClpCopyOfArray ( rhs.rowUpper_, numberRows_ );
359    columnLower_ = ClpCopyOfArray ( rhs.columnLower_, numberColumns_ );
360    columnUpper_ = ClpCopyOfArray ( rhs.columnUpper_, numberColumns_ );
361    if (rhs.objective_)
362      objective_  = rhs.objective_->clone();
363    else
364      objective_ = NULL;
365    rowObjective_ = ClpCopyOfArray ( rhs.rowObjective_, numberRows_ );
366    status_ = ClpCopyOfArray( rhs.status_,numberColumns_+numberRows_);
367    ray_ = NULL;
368    if (problemStatus_==1&&!secondaryStatus_)
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_ = NULL;
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  otherModel.secondaryStatus_ = secondaryStatus_;
428  rowActivity_ = NULL;
429  columnActivity_ = NULL;
430  dual_ = NULL;
431  reducedCost_ = NULL;
432  rowLower_ = NULL;
433  rowUpper_ = NULL;
434  objective_ = NULL;
435  rowObjective_ = NULL;
436  columnLower_ = NULL;
437  columnUpper_ = NULL;
438  matrix_ = NULL;
439  rowCopy_ = NULL;
440  delete [] otherModel.ray_;
441  otherModel.ray_ = ray_;
442  ray_ = NULL;
443  // do status
444  if (otherModel.status_!=status_) {
445    delete [] otherModel.status_;
446    otherModel.status_ = status_;
447  }
448  status_ = NULL;
449  if (defaultHandler_) {
450    delete handler_;
451    handler_ = NULL;
452  }
453}
454//#############################################################################
455// Parameter related methods
456//#############################################################################
457
458bool
459ClpModel::setIntParam(ClpIntParam key, int value)
460{
461  switch (key) {
462  case ClpMaxNumIteration:
463    if (value < 0)
464      return false;
465    break;
466  case ClpMaxNumIterationHotStart:
467    if (value < 0)
468      return false;
469    break;
470  case ClpLastIntParam:
471    return false;
472  }
473  intParam_[key] = value;
474  return true;
475}
476
477//-----------------------------------------------------------------------------
478
479bool
480ClpModel::setDblParam(ClpDblParam key, double value)
481{
482
483  switch (key) {
484  case ClpDualObjectiveLimit:
485    break;
486
487  case ClpPrimalObjectiveLimit:
488    break;
489
490  case ClpDualTolerance: 
491    if (value<=0.0||value>1.0e10)
492      return false;
493    break;
494   
495  case ClpPrimalTolerance: 
496    if (value<=0.0||value>1.0e10)
497      return false;
498    break;
499   
500  case ClpObjOffset: 
501    break;
502
503  case ClpMaxSeconds: 
504    if(value>=0)
505      value += CoinCpuTime();
506    else
507      value = -1.0;
508    break;
509
510  case ClpLastDblParam:
511    return false;
512  }
513  dblParam_[key] = value;
514  return true;
515}
516
517//-----------------------------------------------------------------------------
518
519bool
520ClpModel::setStrParam(ClpStrParam key, const std::string & value)
521{
522
523  switch (key) {
524  case ClpProbName:
525    break;
526
527  case ClpLastStrParam:
528    return false;
529  }
530  strParam_[key] = value;
531  return true;
532}
533// Useful routines
534// Returns resized array and deletes incoming
535double * resizeDouble(double * array , int size, int newSize, double fill,
536                      bool createArray)
537{
538  if ((array||createArray)&&size!=newSize) {
539    int i;
540    double * newArray = new double[newSize];
541    if (array)
542      memcpy(newArray,array,min(newSize,size)*sizeof(double));
543    delete [] array;
544    array = newArray;
545    for (i=size;i<newSize;i++) 
546      array[i]=fill;
547  } 
548  return array;
549}
550// Returns resized array and updates size
551double * deleteDouble(double * array , int size, 
552                      int number, const int * which,int & newSize)
553{
554  if (array) {
555    int i ;
556    char * deleted = new char[size];
557    int numberDeleted=0;
558    memset(deleted,0,size*sizeof(char));
559    for (i=0;i<number;i++) {
560      int j = which[i];
561      if (j>=0&&j<size&&!deleted[j]) {
562        numberDeleted++;
563        deleted[j]=1;
564      }
565    }
566    newSize = size-numberDeleted;
567    double * newArray = new double[newSize];
568    int put=0;
569    for (i=0;i<size;i++) {
570      if (!deleted[i]) {
571        newArray[put++]=array[i];
572      }
573    }
574    delete [] array;
575    array = newArray;
576    delete [] deleted;
577  }
578  return array;
579}
580char * deleteChar(char * array , int size, 
581                  int number, const int * which,int & newSize,
582                  bool ifDelete)
583{
584  if (array) {
585    int i ;
586    char * deleted = new char[size];
587    int numberDeleted=0;
588    memset(deleted,0,size*sizeof(char));
589    for (i=0;i<number;i++) {
590      int j = which[i];
591      if (j>=0&&j<size&&!deleted[j]) {
592        numberDeleted++;
593        deleted[j]=1;
594      }
595    }
596    newSize = size-numberDeleted;
597    char * newArray = new char[newSize];
598    int put=0;
599    for (i=0;i<size;i++) {
600      if (!deleted[i]) {
601        newArray[put++]=array[i];
602      }
603    }
604    if (ifDelete)
605      delete [] array;
606    array = newArray;
607    delete [] deleted;
608  }
609  return array;
610}
611// Create empty ClpPackedMatrix
612void 
613ClpModel::createEmptyMatrix()
614{
615  delete matrix_;
616  CoinPackedMatrix matrix2;
617  matrix_=new ClpPackedMatrix(matrix2);
618}
619// Resizes
620void 
621ClpModel::resize (int newNumberRows, int newNumberColumns)
622{
623  rowActivity_ = resizeDouble(rowActivity_,numberRows_,
624                              newNumberRows,0.0,true);
625  dual_ = resizeDouble(dual_,numberRows_,
626                       newNumberRows,0.0,true);
627  rowObjective_ = resizeDouble(rowObjective_,numberRows_,
628                               newNumberRows,0.0,false);
629  rowLower_ = resizeDouble(rowLower_,numberRows_,
630                           newNumberRows,-COIN_DBL_MAX,true);
631  rowUpper_ = resizeDouble(rowUpper_,numberRows_,
632                           newNumberRows,COIN_DBL_MAX,true);
633  columnActivity_ = resizeDouble(columnActivity_,numberColumns_,
634                                 newNumberColumns,0.0,true);
635  reducedCost_ = resizeDouble(reducedCost_,numberColumns_,
636                              newNumberColumns,0.0,true);
637  if (objective_)
638    objective_->resize(newNumberColumns);
639  else 
640    objective_ = new ClpLinearObjective(NULL,newNumberColumns);
641  columnLower_ = resizeDouble(columnLower_,numberColumns_,
642                              newNumberColumns,0.0,true);
643  columnUpper_ = resizeDouble(columnUpper_,numberColumns_,
644                              newNumberColumns,COIN_DBL_MAX,true);
645  if (newNumberRows<numberRows_) {
646    int * which = new int[numberRows_-newNumberRows];
647    int i;
648    for (i=newNumberRows;i<numberRows_;i++) 
649      which[i-newNumberRows]=i;
650    matrix_->deleteRows(numberRows_-newNumberRows,which);
651    delete [] which;
652  }
653  if (numberRows_!=newNumberRows||numberColumns_!=newNumberColumns) {
654    // set state back to unknown
655    problemStatus_ = -1;
656    secondaryStatus_ = 0;
657    delete [] ray_;
658    ray_ = NULL;
659  }
660  if (status_) {
661    unsigned char * tempC = new unsigned char [newNumberColumns+newNumberRows];
662    unsigned char * tempR = tempC + newNumberColumns;
663    memset(tempC,0,(newNumberColumns+newNumberRows)*sizeof(unsigned char));
664    memcpy(tempC,status_,min(newNumberColumns,numberColumns_)*sizeof(unsigned char));
665    memcpy(tempR,status_+numberColumns_,min(newNumberRows,numberRows_)*sizeof(unsigned char));
666    delete [] status_;
667    status_ = tempC;
668  }
669  numberRows_ = newNumberRows;
670  if (newNumberColumns<numberColumns_) {
671    int * which = new int[numberColumns_-newNumberColumns];
672    int i;
673    for (i=newNumberColumns;i<numberColumns_;i++) 
674      which[i-newNumberColumns]=i;
675    matrix_->deleteCols(numberColumns_-newNumberColumns,which);
676    delete [] which;
677  }
678  if (integerType_) {
679    char * temp = new char [newNumberColumns];
680    memset(temp,0,newNumberColumns*sizeof(char));
681    memcpy(temp,integerType_,
682           min(newNumberColumns,numberColumns_)*sizeof(char));
683    delete [] integerType_;
684    integerType_ = temp;
685  }
686  numberColumns_ = newNumberColumns;
687  // for now gets rid of names
688  lengthNames_ = 0;
689  rowNames_ = std::vector<std::string> ();
690  columnNames_ = std::vector<std::string> ();
691}
692// Deletes rows
693void 
694ClpModel::deleteRows(int number, const int * which)
695{
696  int newSize=0;
697  rowActivity_ = deleteDouble(rowActivity_,numberRows_,
698                              number, which, newSize);
699  dual_ = deleteDouble(dual_,numberRows_,
700                              number, which, newSize);
701  rowObjective_ = deleteDouble(rowObjective_,numberRows_,
702                              number, which, newSize);
703  rowLower_ = deleteDouble(rowLower_,numberRows_,
704                              number, which, newSize);
705  rowUpper_ = deleteDouble(rowUpper_,numberRows_,
706                              number, which, newSize);
707  matrix_->deleteRows(number,which);
708  //matrix_->removeGaps();
709  // status
710  if (status_) {
711    unsigned char * tempR  = (unsigned char *) deleteChar((char *)status_+numberColumns_,
712                                        numberRows_,
713                                        number, which, newSize,false);
714    unsigned char * tempC = new unsigned char [numberColumns_+newSize];
715    memcpy(tempC,status_,numberColumns_*sizeof(unsigned char));
716    memcpy(tempC+numberColumns_,tempR,newSize*sizeof(unsigned char));
717    delete [] tempR;
718    delete [] status_;
719    status_ = tempC;
720  }
721  numberRows_=newSize;
722  // set state back to unknown
723  problemStatus_ = -1;
724  secondaryStatus_ = 0;
725  delete [] ray_;
726  ray_ = NULL;
727  // for now gets rid of names
728  lengthNames_ = 0;
729  rowNames_ = std::vector<std::string> ();
730  columnNames_ = std::vector<std::string> ();
731}
732// Deletes columns
733void 
734ClpModel::deleteColumns(int number, const int * which)
735{
736  int newSize=0;
737  columnActivity_ = deleteDouble(columnActivity_,numberColumns_,
738                              number, which, newSize);
739  reducedCost_ = deleteDouble(reducedCost_,numberColumns_,
740                              number, which, newSize);
741  objective_->deleteSome(number, which);
742  columnLower_ = deleteDouble(columnLower_,numberColumns_,
743                              number, which, newSize);
744  columnUpper_ = deleteDouble(columnUpper_,numberColumns_,
745                              number, which, newSize);
746  matrix_->deleteCols(number,which);
747  //matrix_->removeGaps();
748  // status
749  if (status_) {
750    unsigned char * tempC  = (unsigned char *) deleteChar((char *)status_,
751                                        numberColumns_,
752                                        number, which, newSize,false);
753    unsigned char * temp = new unsigned char [numberRows_+newSize];
754    memcpy(temp,tempC,newSize*sizeof(unsigned char));
755    memcpy(temp+newSize,status_+numberColumns_,
756           numberRows_*sizeof(unsigned char));
757    delete [] tempC;
758    delete [] status_;
759    status_ = temp;
760  }
761  integerType_ = deleteChar(integerType_,numberColumns_,
762                            number, which, newSize,true);
763  numberColumns_=newSize;
764  // set state back to unknown
765  problemStatus_ = -1;
766  secondaryStatus_ = 0;
767  delete [] ray_;
768  ray_ = NULL;
769  // for now gets rid of names
770  lengthNames_ = 0;
771  rowNames_ = std::vector<std::string> ();
772  columnNames_ = std::vector<std::string> ();
773}
774// Add rows
775void 
776ClpModel::addRows(int number, const double * rowLower, 
777                  const double * rowUpper,
778                  const int * rowStarts, const int * columns,
779                  const double * elements)
780{
781  // Create a list of CoinPackedVectors
782  if (number) {
783    CoinPackedVectorBase ** rows=
784      new CoinPackedVectorBase * [number];
785    int iRow;
786    for (iRow=0;iRow<number;iRow++) {
787      int iStart = rowStarts[iRow];
788      rows[iRow] = 
789        new CoinPackedVector(rowStarts[iRow+1]-iStart,
790                             columns+iStart,elements+iStart);
791    }
792    addRows(number, rowLower, rowUpper,
793            rows);
794    for (iRow=0;iRow<number;iRow++) 
795      delete rows[iRow];
796    delete [] rows;
797  }
798}
799// Add rows
800void 
801ClpModel::addRows(int number, const double * rowLower, 
802                  const double * rowUpper,
803                  const int * rowStarts, 
804                  const int * rowLengths, const int * columns,
805                  const double * elements)
806{
807  // Create a list of CoinPackedVectors
808  if (number) {
809    CoinPackedVectorBase ** rows=
810      new CoinPackedVectorBase * [number];
811    int iRow;
812    for (iRow=0;iRow<number;iRow++) {
813      int iStart = rowStarts[iRow];
814      rows[iRow] = 
815        new CoinPackedVector(rowLengths[iRow],
816                             columns+iStart,elements+iStart);
817    }
818    addRows(number, rowLower, rowUpper,
819            rows);
820    for (iRow=0;iRow<number;iRow++) 
821      delete rows[iRow];
822    delete [] rows;
823  }
824}
825void 
826ClpModel::addRows(int number, const double * rowLower, 
827                  const double * rowUpper,
828                  const CoinPackedVectorBase * const * rows)
829{
830  if (!number)
831    return;
832  int numberRowsNow = numberRows_;
833  resize(numberRowsNow+number,numberColumns_);
834  double * lower = rowLower_+numberRowsNow;
835  double * upper = rowUpper_+numberRowsNow;
836  int iRow;
837  if (rowLower) {
838    for (iRow = 0; iRow < number; iRow++) {
839      double value = rowLower[iRow];
840      if (value<-1.0e20)
841        value = -COIN_DBL_MAX;
842      lower[iRow]= value;
843    }
844  } else {
845    for (iRow = 0; iRow < number; iRow++) {
846      lower[iRow]= -COIN_DBL_MAX;
847    }
848  }
849  if (rowUpper) {
850    for (iRow = 0; iRow < number; iRow++) {
851      double value = rowUpper[iRow];
852      if (value>1.0e20)
853        value = COIN_DBL_MAX;
854      upper[iRow]= value;
855    }
856  } else {
857    for (iRow = 0; iRow < number; iRow++) {
858      upper[iRow]= COIN_DBL_MAX;
859    }
860  }
861  // Deal with matrix
862
863  delete rowCopy_;
864  rowCopy_=NULL;
865  if (!matrix_)
866    createEmptyMatrix();
867  matrix_->appendRows(number,rows);
868}
869// Add columns
870void 
871ClpModel::addColumns(int number, const double * columnLower, 
872                     const double * columnUpper,
873                     const double * objIn,
874                     const int * columnStarts, const int * rows,
875                     const double * elements)
876{
877  // Create a list of CoinPackedVectors
878  if (number) {
879    CoinPackedVectorBase ** columns=
880      new CoinPackedVectorBase * [number];
881    int iColumn;
882    for (iColumn=0;iColumn<number;iColumn++) {
883      int iStart = columnStarts[iColumn];
884      columns[iColumn] = 
885        new CoinPackedVector(columnStarts[iColumn+1]-iStart,
886                             rows+iStart,elements+iStart);
887    }
888    addColumns(number, columnLower, columnUpper,
889               objIn, columns);
890    for (iColumn=0;iColumn<number;iColumn++) 
891      delete columns[iColumn];
892    delete [] columns;
893
894  }
895}
896// Add columns
897void 
898ClpModel::addColumns(int number, const double * columnLower, 
899                     const double * columnUpper,
900                     const double * objIn,
901                     const int * columnStarts, 
902                     const int * columnLengths, const int * rows,
903                     const double * elements)
904{
905  // Create a list of CoinPackedVectors
906  if (number) {
907    CoinPackedVectorBase ** columns=
908      new CoinPackedVectorBase * [number];
909    int iColumn;
910    for (iColumn=0;iColumn<number;iColumn++) {
911      int iStart = columnStarts[iColumn];
912      columns[iColumn] = 
913        new CoinPackedVector(columnLengths[iColumn],
914                             rows+iStart,elements+iStart);
915    }
916    addColumns(number, columnLower, columnUpper,
917               objIn, columns);
918    for (iColumn=0;iColumn<number;iColumn++) 
919      delete columns[iColumn];
920    delete [] columns;
921
922  }
923}
924void 
925ClpModel::addColumns(int number, const double * columnLower, 
926                     const double * columnUpper,
927                     const double * objIn,
928                     const CoinPackedVectorBase * const * columns)
929{
930  if (!number)
931    return;
932  int numberColumnsNow = numberColumns_;
933  resize(numberRows_,numberColumnsNow+number);
934  double * lower = columnLower_+numberColumnsNow;
935  double * upper = columnUpper_+numberColumnsNow;
936  double * obj = objective()+numberColumnsNow;
937  int iColumn;
938  if (columnLower) {
939    for (iColumn = 0; iColumn < number; iColumn++) {
940      double value = columnLower[iColumn];
941      if (value<-1.0e20)
942        value = -COIN_DBL_MAX;
943      lower[iColumn]= value;
944    }
945  } else {
946    for (iColumn = 0; iColumn < number; iColumn++) {
947      lower[iColumn]= 0.0;
948    }
949  }
950  if (columnUpper) {
951    for (iColumn = 0; iColumn < number; iColumn++) {
952      double value = columnUpper[iColumn];
953      if (value>1.0e20)
954        value = COIN_DBL_MAX;
955      upper[iColumn]= value;
956    }
957  } else {
958    for (iColumn = 0; iColumn < number; iColumn++) {
959      upper[iColumn]= COIN_DBL_MAX;
960    }
961  }
962  if (objIn) {
963    for (iColumn = 0; iColumn < number; iColumn++) {
964      obj[iColumn] = objIn[iColumn];
965    }
966  } else {
967    for (iColumn = 0; iColumn < number; iColumn++) {
968      obj[iColumn]= 0.0;
969    }
970  }
971  // Deal with matrix
972
973  delete rowCopy_;
974  rowCopy_=NULL;
975  if (!matrix_)
976    createEmptyMatrix();
977  matrix_->appendCols(number,columns);
978}
979// Infeasibility/unbounded ray (NULL returned if none/wrong)
980double * 
981ClpModel::infeasibilityRay() const
982{
983  double * array = NULL;
984  if (problemStatus_==1&&!secondaryStatus_) 
985    array = ClpCopyOfArray(ray_,numberRows_);
986  return array;
987}
988double * 
989ClpModel::unboundedRay() const
990{
991  double * array = NULL;
992  if (problemStatus_==2) 
993    array = ClpCopyOfArray(ray_,numberColumns_);
994  return array;
995}
996void 
997ClpModel::setMaximumIterations(int value)
998{
999  if(value>=0)
1000    intParam_[ClpMaxNumIteration]=value;
1001}
1002void 
1003ClpModel::setMaximumSeconds(double value)
1004{
1005  if(value>=0)
1006    dblParam_[ClpMaxSeconds]=value+CoinCpuTime();
1007  else
1008    dblParam_[ClpMaxSeconds]=-1.0;
1009}
1010// Returns true if hit maximum iterations (or time)
1011bool 
1012ClpModel::hitMaximumIterations() const
1013{
1014  bool hitMax= (numberIterations_>=maximumIterations());
1015  if (dblParam_[ClpMaxSeconds]>=0.0&&!hitMax)
1016    hitMax = (CoinCpuTime()>=dblParam_[ClpMaxSeconds]);
1017  return hitMax;
1018}
1019// Pass in Message handler (not deleted at end)
1020void 
1021ClpModel::passInMessageHandler(CoinMessageHandler * handler)
1022{
1023  if (defaultHandler_)
1024    delete handler_;
1025  defaultHandler_=false;
1026  handler_=handler;
1027}
1028// Set language
1029void 
1030ClpModel::newLanguage(CoinMessages::Language language)
1031{
1032  messages_ = ClpMessage(language);
1033}
1034// Read an mps file from the given filename
1035int 
1036ClpModel::readMps(const char *fileName,
1037                  bool keepNames,
1038                  bool ignoreErrors)
1039{
1040  bool canOpen=false;
1041  if (!strcmp(fileName,"-")||!strcmp(fileName,"stdin")) {
1042    // stdin
1043    canOpen=true;
1044  } else {
1045    FILE *fp=fopen(fileName,"r");
1046    if (fp) {
1047      // can open - lets go for it
1048      fclose(fp);
1049      canOpen=true;
1050    } else {
1051      handler_->message(CLP_UNABLE_OPEN,messages_)
1052        <<fileName<<CoinMessageEol;
1053      return -1;
1054    }
1055  }
1056  CoinMpsIO m;
1057  m.passInMessageHandler(handler_);
1058  bool savePrefix =m.messageHandler()->prefix();
1059  m.messageHandler()->setPrefix(handler_->prefix());
1060  double time1 = CoinCpuTime(),time2;
1061  int status=m.readMps(fileName,"");
1062  m.messageHandler()->setPrefix(savePrefix);
1063  if (!status||ignoreErrors) {
1064    loadProblem(*m.getMatrixByCol(),
1065                m.getColLower(),m.getColUpper(),
1066                m.getObjCoefficients(),
1067                m.getRowLower(),m.getRowUpper());
1068    if (m.integerColumns()) {
1069      integerType_ = new char[numberColumns_];
1070      memcpy(integerType_,m.integerColumns(),numberColumns_*sizeof(char));
1071    } else {
1072      integerType_ = NULL;
1073    }
1074    // set problem name
1075    setStrParam(ClpProbName,m.getProblemName());
1076    // do names
1077    if (keepNames) {
1078      unsigned int maxLength=0;
1079      int iRow;
1080      rowNames_ = std::vector<std::string> ();
1081      columnNames_ = std::vector<std::string> ();
1082      rowNames_.reserve(numberRows_);
1083      for (iRow=0;iRow<numberRows_;iRow++) {
1084        const char * name = m.rowName(iRow);
1085        maxLength = max(maxLength,(unsigned int) strlen(name));
1086          rowNames_.push_back(name);
1087      }
1088     
1089      int iColumn;
1090      columnNames_.reserve(numberColumns_);
1091      for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1092        const char * name = m.columnName(iColumn);
1093        maxLength = max(maxLength,(unsigned int) strlen(name));
1094        columnNames_.push_back(name);
1095      }
1096      lengthNames_=(int) maxLength;
1097    } else {
1098      lengthNames_=0;
1099    }
1100    setDblParam(ClpObjOffset,m.objectiveOffset());
1101    time2 = CoinCpuTime();
1102    handler_->message(CLP_IMPORT_RESULT,messages_)
1103      <<fileName
1104      <<time2-time1<<CoinMessageEol;
1105  } else {
1106    // errors
1107    handler_->message(CLP_IMPORT_ERRORS,messages_)
1108      <<status<<fileName<<CoinMessageEol;
1109  }
1110
1111  return status;
1112}
1113bool ClpModel::isPrimalObjectiveLimitReached() const
1114{
1115  double limit = 0.0;
1116  getDblParam(ClpPrimalObjectiveLimit, limit);
1117  if (limit > 1e30) {
1118    // was not ever set
1119    return false;
1120  }
1121   
1122  const double obj = objectiveValue();
1123  const double maxmin = optimizationDirection();
1124
1125  if (problemStatus_ == 0) // optimal
1126    return maxmin > 0 ? (obj < limit) /*minim*/ : (-obj < limit) /*maxim*/;
1127  else if (problemStatus_==2)
1128    return true;
1129  else
1130    return false;
1131}
1132
1133bool ClpModel::isDualObjectiveLimitReached() const
1134{
1135
1136  double limit = 0.0;
1137  getDblParam(ClpDualObjectiveLimit, limit);
1138  if (limit > 1e30) {
1139    // was not ever set
1140    return false;
1141  }
1142   
1143  const double obj = objectiveValue();
1144  const double maxmin = optimizationDirection();
1145
1146  if (problemStatus_ == 0) // optimal
1147    return maxmin > 0 ? (obj > limit) /*minim*/ : (-obj > limit) /*maxim*/;
1148  else if (problemStatus_==1)
1149    return true;
1150  else
1151    return false;
1152
1153}
1154void 
1155ClpModel::copyInIntegerInformation(const char * information)
1156{
1157  delete [] integerType_;
1158  if (information) {
1159    integerType_ = new char[numberColumns_];
1160    memcpy(integerType_,information,numberColumns_*sizeof(char));
1161  } else {
1162    integerType_ = NULL;
1163  }
1164}
1165// Drops names - makes lengthnames 0 and names empty
1166void 
1167ClpModel::dropNames()
1168{
1169  lengthNames_=0;
1170  rowNames_ = std::vector<std::string> ();
1171  columnNames_ = std::vector<std::string> ();
1172}
1173// Drop integer informations
1174void 
1175ClpModel::deleteIntegerInformation()
1176{
1177  delete [] integerType_;
1178  integerType_ = NULL;
1179}
1180/* Return copy of status array (char[numberRows+numberColumns]),
1181   use delete [] */
1182unsigned char * 
1183ClpModel::statusCopy() const
1184{
1185  return ClpCopyOfArray(status_,numberRows_+numberColumns_);
1186}
1187// Copy in status vector
1188void 
1189ClpModel::copyinStatus(const unsigned char * statusArray)
1190{
1191  delete [] status_;
1192  if (statusArray) {
1193    status_ = new unsigned char [numberRows_+numberColumns_];
1194    memcpy(status_,statusArray,(numberRows_+numberColumns_)*sizeof(unsigned char));
1195  } else {
1196    status_=NULL;
1197  }
1198}
1199
1200// Load up quadratic objective
1201void 
1202ClpModel::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
1203                              const int * column, const double * element)
1204{
1205  assert (numberColumns==numberColumns_);
1206  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
1207  double offset;
1208  ClpObjective * obj = new ClpQuadraticObjective(objective_->gradient(NULL,offset,false),numberColumns,
1209                                             start,column,element);
1210  delete objective_;
1211  objective_ = obj;
1212
1213}
1214void 
1215ClpModel::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
1216{
1217  assert (matrix.getNumCols()==numberColumns_);
1218  assert ((dynamic_cast< ClpLinearObjective*>(objective_)));
1219  double offset;
1220  ClpQuadraticObjective * obj = 
1221    new ClpQuadraticObjective(objective_->gradient(NULL,offset,false),numberColumns_,
1222                                                 NULL,NULL,NULL);
1223  delete objective_;
1224  objective_ = obj;
1225  obj->loadQuadraticObjective(matrix);
1226}
1227// Get rid of quadratic objective
1228void 
1229ClpModel::deleteQuadraticObjective()
1230{
1231  ClpQuadraticObjective * obj = (dynamic_cast< ClpQuadraticObjective*>(objective_));
1232  if (obj)
1233    obj->deleteQuadraticObjective();
1234}
1235void 
1236ClpModel::setObjective(ClpObjective * objective)
1237{
1238  delete objective_;
1239  objective_=objective->clone();
1240}
1241// Returns resized array and updates size
1242double * whichDouble(double * array , int number, const int * which)
1243{
1244  double * newArray=NULL;
1245  if (array&&number) {
1246    int i ;
1247    newArray = new double[number];
1248    for (i=0;i<number;i++) 
1249      newArray[i]=array[which[i]];
1250  }
1251  return newArray;
1252}
1253char * whichChar(char * array , int number, const int * which)
1254{
1255  char * newArray=NULL;
1256  if (array&&number) {
1257    int i ;
1258    newArray = new char[number];
1259    for (i=0;i<number;i++) 
1260      newArray[i]=array[which[i]];
1261  }
1262  return newArray;
1263}
1264unsigned char * whichUnsignedChar(unsigned char * array , 
1265                                  int number, const int * which)
1266{
1267  unsigned char * newArray=NULL;
1268  if (array&&number) {
1269    int i ;
1270    newArray = new unsigned char[number];
1271    for (i=0;i<number;i++) 
1272      newArray[i]=array[which[i]];
1273  }
1274  return newArray;
1275}
1276// Replace Clp Matrix (current is not deleted)
1277void 
1278ClpModel::replaceMatrix( ClpMatrixBase * matrix)
1279{
1280  matrix_=matrix;
1281}
1282// Subproblem constructor
1283ClpModel::ClpModel ( const ClpModel * rhs,
1284                     int numberRows, const int * whichRow,
1285                     int numberColumns, const int * whichColumn,
1286                     bool dropNames, bool dropIntegers)
1287{
1288#if 0
1289  // Could be recoded to be faster and take less memory
1290  // and to allow re-ordering and duplicates etc
1291  gutsOfCopy(*rhs,true);
1292  int numberRowsWhole = rhs->numberRows();
1293  int * delRow = new int[numberRowsWhole];
1294  memset(delRow,0,numberRowsWhole*sizeof(int));
1295  int i;
1296  for (i=0;i<numberRows;i++) {
1297    int iRow=whichRow[i];
1298    assert (iRow>=0&&iRow<numberRowsWhole);
1299    delRow[iRow]=1;
1300  }
1301  numberRows=0;
1302  for (i=0;i<numberRowsWhole;i++) {
1303    if (delRow[i]==0)
1304      delRow[numberRows++]=i;
1305  }
1306  deleteRows(numberRows,delRow);
1307  delete [] delRow;
1308  int numberColumnsWhole = rhs->numberColumns();
1309  int * delColumn = new int[numberColumnsWhole];
1310  memset(delColumn,0,numberColumnsWhole*sizeof(int));
1311  for (i=0;i<numberColumns;i++) {
1312    int iColumn=whichColumn[i];
1313    assert (iColumn>=0&&iColumn<numberColumnsWhole);
1314    delColumn[iColumn]=1;
1315  }
1316  numberColumns=0;
1317  for (i=0;i<numberColumnsWhole;i++) {
1318    if (delColumn[i]==0)
1319      delColumn[numberColumns++]=i;
1320  }
1321  deleteColumns(numberColumns,delColumn);
1322  delete [] delColumn;
1323#else
1324  defaultHandler_ = rhs->defaultHandler_;
1325  if (defaultHandler_)
1326    handler_ = new CoinMessageHandler(*rhs->handler_);
1327   else
1328    handler_ = rhs->handler_;
1329  messages_ = rhs->messages_;
1330  intParam_[ClpMaxNumIteration] = rhs->intParam_[ClpMaxNumIteration];
1331  intParam_[ClpMaxNumIterationHotStart] =
1332    rhs->intParam_[ClpMaxNumIterationHotStart];
1333
1334  dblParam_[ClpDualObjectiveLimit] = rhs->dblParam_[ClpDualObjectiveLimit];
1335  dblParam_[ClpPrimalObjectiveLimit] = rhs->dblParam_[ClpPrimalObjectiveLimit];
1336  dblParam_[ClpDualTolerance] = rhs->dblParam_[ClpDualTolerance];
1337  dblParam_[ClpPrimalTolerance] = rhs->dblParam_[ClpPrimalTolerance];
1338  dblParam_[ClpObjOffset] = rhs->dblParam_[ClpObjOffset];
1339  dblParam_[ClpMaxSeconds] = rhs->dblParam_[ClpMaxSeconds];
1340
1341  strParam_[ClpProbName] = rhs->strParam_[ClpProbName];
1342
1343  optimizationDirection_ = rhs->optimizationDirection_;
1344  objectiveValue_=rhs->objectiveValue_;
1345  smallElement_ = rhs->smallElement_;
1346  numberIterations_ = rhs->numberIterations_;
1347  solveType_ = rhs->solveType_;
1348  problemStatus_ = rhs->problemStatus_;
1349  secondaryStatus_ = rhs->secondaryStatus_;
1350  // check valid lists
1351  int numberBad=0;
1352  int i;
1353  for (i=0;i<numberRows;i++)
1354    if (whichRow[i]<0||whichRow[i]>=rhs->numberRows_)
1355      numberBad++;
1356  if (numberBad)
1357    throw CoinError("bad row list", "subproblem constructor", "ClpModel");
1358  numberBad=0;
1359  for (i=0;i<numberColumns;i++)
1360    if (whichColumn[i]<0||whichColumn[i]>=rhs->numberColumns_)
1361      numberBad++;
1362  if (numberBad)
1363    throw CoinError("bad column list", "subproblem constructor", "ClpModel");
1364  numberRows_ = numberRows;
1365  numberColumns_ = numberColumns;
1366  userPointer_ = rhs->userPointer_;
1367  if (!dropNames) {
1368    unsigned int maxLength=0;
1369    int iRow;
1370    rowNames_ = std::vector<std::string> ();
1371    columnNames_ = std::vector<std::string> ();
1372    rowNames_.reserve(numberRows_);
1373    for (iRow=0;iRow<numberRows_;iRow++) {
1374      rowNames_[iRow] = rhs->rowNames_[whichRow[iRow]];
1375      maxLength = max(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
1376    }
1377    int iColumn;
1378    columnNames_.reserve(numberColumns_);
1379    for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1380      columnNames_[iColumn] = rhs->columnNames_[whichColumn[iColumn]];
1381      maxLength = max(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
1382    }
1383    lengthNames_=(int) maxLength;
1384  } else {
1385    lengthNames_ = 0;
1386    rowNames_ = std::vector<std::string> ();
1387    columnNames_ = std::vector<std::string> ();
1388  }
1389  if (rhs->integerType_&&!dropIntegers) {
1390    integerType_ = whichChar(rhs->integerType_,numberColumns,whichColumn);
1391  } else {
1392    integerType_ = NULL;
1393  }
1394  if (rhs->rowActivity_) {
1395    rowActivity_=whichDouble(rhs->rowActivity_,numberRows,whichRow);
1396    dual_=whichDouble(rhs->dual_,numberRows,whichRow);
1397    columnActivity_=whichDouble(rhs->columnActivity_,numberColumns,
1398                                whichColumn);
1399    reducedCost_=whichDouble(rhs->reducedCost_,numberColumns,
1400                                whichColumn);
1401  } else {
1402    rowActivity_=NULL;
1403    columnActivity_=NULL;
1404    dual_=NULL;
1405    reducedCost_=NULL;
1406  }
1407  rowLower_=whichDouble(rhs->rowLower_,numberRows,whichRow);
1408  rowUpper_=whichDouble(rhs->rowUpper_,numberRows,whichRow);
1409  columnLower_=whichDouble(rhs->columnLower_,numberColumns,whichColumn);
1410  columnUpper_=whichDouble(rhs->columnUpper_,numberColumns,whichColumn);
1411  if (rhs->objective_)
1412    objective_  = rhs->objective_->subsetClone(numberColumns,whichColumn);
1413  else
1414    objective_ = NULL;
1415  rowObjective_=whichDouble(rhs->rowObjective_,numberRows,whichRow);
1416  // status has to be done in two stages
1417  status_ = new unsigned char[numberColumns_+numberRows_];
1418  unsigned char * rowStatus = whichUnsignedChar(rhs->status_+rhs->numberColumns_,
1419                                                numberRows_,whichRow);
1420  unsigned char * columnStatus = whichUnsignedChar(rhs->status_,
1421                                                numberColumns_,whichColumn);
1422  memcpy(status_+numberColumns_,rowStatus,numberRows_);
1423  delete [] rowStatus;
1424  memcpy(status_,columnStatus,numberColumns_);
1425  delete [] columnStatus;
1426  ray_ = NULL;
1427  if (problemStatus_==1&&!secondaryStatus_)
1428    ray_ = whichDouble (rhs->ray_,numberRows,whichRow);
1429  else if (problemStatus_==2)
1430    ray_ = whichDouble (rhs->ray_,numberColumns,whichColumn);
1431  if (rhs->rowCopy_) {
1432    rowCopy_ = rhs->rowCopy_->subsetClone(numberRows,whichRow,
1433                                          numberColumns,whichColumn);
1434  } else {
1435    rowCopy_=NULL;
1436  }
1437  matrix_=NULL;
1438  if (rhs->matrix_) {
1439    matrix_ = rhs->matrix_->subsetClone(numberRows,whichRow,
1440                                        numberColumns,whichColumn);
1441  }
1442#endif
1443}
1444// Copies in names
1445void 
1446ClpModel::copyNames(std::vector<std::string> & rowNames,
1447                 std::vector<std::string> & columnNames)
1448{
1449  unsigned int maxLength=0;
1450  int iRow;
1451  rowNames_ = std::vector<std::string> ();
1452  columnNames_ = std::vector<std::string> ();
1453  rowNames_.reserve(numberRows_);
1454  for (iRow=0;iRow<numberRows_;iRow++) {
1455    rowNames_.push_back(rowNames[iRow]);
1456    maxLength = max(maxLength,(unsigned int) strlen(rowNames_[iRow].c_str()));
1457  }
1458  int iColumn;
1459  columnNames_.reserve(numberColumns_);
1460  for (iColumn=0;iColumn<numberColumns_;iColumn++) {
1461    columnNames_.push_back(columnNames[iColumn]);
1462    maxLength = max(maxLength,(unsigned int) strlen(columnNames_[iColumn].c_str()));
1463  }
1464  lengthNames_=(int) maxLength;
1465}
1466// Dual objective limit
1467void 
1468ClpModel::setDualObjectiveLimit(double value)
1469{
1470  dblParam_[ClpDualObjectiveLimit]=value;
1471}
1472// Objective offset
1473void 
1474ClpModel::setObjectiveOffset(double value)
1475{
1476  dblParam_[ClpObjOffset]=value;
1477}
1478//#############################################################################
1479// Constructors / Destructor / Assignment
1480//#############################################################################
1481
1482//-------------------------------------------------------------------
1483// Default Constructor
1484//-------------------------------------------------------------------
1485ClpDataSave::ClpDataSave () 
1486{
1487  dualBound_ = 0.0;
1488  infeasibilityCost_ = 0.0;
1489  sparseThreshold_ = 0;
1490  perturbation_ = 0;
1491}
1492
1493//-------------------------------------------------------------------
1494// Copy constructor
1495//-------------------------------------------------------------------
1496ClpDataSave::ClpDataSave (const ClpDataSave & rhs) 
1497{ 
1498  dualBound_ = rhs.dualBound_;
1499  infeasibilityCost_ = rhs.infeasibilityCost_;
1500  sparseThreshold_ = rhs.sparseThreshold_;
1501  perturbation_ = rhs.perturbation_;
1502}
1503
1504//-------------------------------------------------------------------
1505// Destructor
1506//-------------------------------------------------------------------
1507ClpDataSave::~ClpDataSave ()
1508{
1509
1510}
1511
1512//----------------------------------------------------------------
1513// Assignment operator
1514//-------------------------------------------------------------------
1515ClpDataSave &
1516ClpDataSave::operator=(const ClpDataSave& rhs)
1517{
1518  if (this != &rhs) {
1519    dualBound_ = rhs.dualBound_;
1520    infeasibilityCost_ = rhs.infeasibilityCost_;
1521    sparseThreshold_ = rhs.sparseThreshold_;
1522    perturbation_ = rhs.perturbation_;
1523  }
1524  return *this;
1525}
Note: See TracBrowser for help on using the repository browser.