00001 // Copyright (C) 2002, International Business Machines 00002 // Corporation and others. All Rights Reserved. 00003 00004 #include "CoinPragma.hpp" 00005 #include "ClpSimplex.hpp" 00006 #include "ClpDualRowDantzig.hpp" 00007 #include "CoinIndexedVector.hpp" 00008 00009 //############################################################################# 00010 // Constructors / Destructor / Assignment 00011 //############################################################################# 00012 00013 //------------------------------------------------------------------- 00014 // Default Constructor 00015 //------------------------------------------------------------------- 00016 ClpDualRowDantzig::ClpDualRowDantzig () 00017 : ClpDualRowPivot() 00018 { 00019 type_=1; 00020 } 00021 00022 //------------------------------------------------------------------- 00023 // Copy constructor 00024 //------------------------------------------------------------------- 00025 ClpDualRowDantzig::ClpDualRowDantzig (const ClpDualRowDantzig & source) 00026 : ClpDualRowPivot(source) 00027 { 00028 00029 } 00030 00031 //------------------------------------------------------------------- 00032 // Destructor 00033 //------------------------------------------------------------------- 00034 ClpDualRowDantzig::~ClpDualRowDantzig () 00035 { 00036 00037 } 00038 00039 //---------------------------------------------------------------- 00040 // Assignment operator 00041 //------------------------------------------------------------------- 00042 ClpDualRowDantzig & 00043 ClpDualRowDantzig::operator=(const ClpDualRowDantzig& rhs) 00044 { 00045 if (this != &rhs) { 00046 ClpDualRowPivot::operator=(rhs); 00047 } 00048 return *this; 00049 } 00050 00051 // Returns pivot row, -1 if none 00052 int 00053 ClpDualRowDantzig::pivotRow() 00054 { 00055 assert(model_); 00056 int iRow; 00057 const int * pivotVariable = model_->pivotVariable(); 00058 double largest=model_->currentPrimalTolerance(); 00059 // we can't really trust infeasibilities if there is primal error 00060 if (model_->largestPrimalError()>1.0e-8) 00061 largest *= model_->largestPrimalError()/1.0e-8; 00062 int chosenRow=-1; 00063 for (iRow=0;iRow<model_->numberRows();iRow++) { 00064 int iPivot=pivotVariable[iRow]; 00065 double value = model_->solution(iPivot); 00066 double lower = model_->lower(iPivot); 00067 double upper = model_->upper(iPivot); 00068 if (max(value-upper,lower-value)>largest) { 00069 int iSequence = pivotVariable[iRow]; 00070 if (!model_->flagged(iSequence)) { 00071 chosenRow=iRow; 00072 largest=max(value-upper,lower-value); 00073 } 00074 } 00075 } 00076 return chosenRow; 00077 } 00078 // Returns pivot alpha 00079 double 00080 ClpDualRowDantzig::updateWeights(CoinIndexedVector * input, 00081 CoinIndexedVector * spare, 00082 CoinIndexedVector * updatedColumn) 00083 { 00084 // pivot element 00085 double alpha=0.0; 00086 // look at updated column 00087 double * work = updatedColumn->denseVector(); 00088 int number = updatedColumn->getNumElements(); 00089 int * which = updatedColumn->getIndices(); 00090 int i; 00091 int pivotRow = model_->pivotRow(); 00092 00093 if (updatedColumn->packedMode()) { 00094 for (i =0; i < number; i++) { 00095 int iRow = which[i]; 00096 if (iRow==pivotRow) { 00097 alpha = work[i]; 00098 break; 00099 } 00100 } 00101 } else { 00102 alpha = work[pivotRow]; 00103 } 00104 return alpha; 00105 } 00106 00107 /* Updates primal solution (and maybe list of candidates) 00108 Uses input vector which it deletes 00109 Computes change in objective function 00110 */ 00111 void 00112 ClpDualRowDantzig::updatePrimalSolution(CoinIndexedVector * primalUpdate, 00113 double primalRatio, 00114 double & objectiveChange) 00115 { 00116 double * work = primalUpdate->denseVector(); 00117 int number = primalUpdate->getNumElements(); 00118 int * which = primalUpdate->getIndices(); 00119 int i; 00120 double changeObj=0.0; 00121 const int * pivotVariable = model_->pivotVariable(); 00122 if (primalUpdate->packedMode()) { 00123 for (i=0;i<number;i++) { 00124 int iRow=which[i]; 00125 int iPivot=pivotVariable[iRow]; 00126 double & value = model_->solutionAddress(iPivot); 00127 double cost = model_->cost(iPivot); 00128 double change = primalRatio*work[i]; 00129 value -= change; 00130 changeObj -= change*cost; 00131 work[i]=0.0; 00132 } 00133 } else { 00134 for (i=0;i<number;i++) { 00135 int iRow=which[i]; 00136 int iPivot=pivotVariable[iRow]; 00137 double & value = model_->solutionAddress(iPivot); 00138 double cost = model_->cost(iPivot); 00139 double change = primalRatio*work[iRow]; 00140 value -= change; 00141 changeObj -= change*cost; 00142 work[iRow]=0.0; 00143 } 00144 } 00145 primalUpdate->setNumElements(0); 00146 objectiveChange += changeObj; 00147 } 00148 //------------------------------------------------------------------- 00149 // Clone 00150 //------------------------------------------------------------------- 00151 ClpDualRowPivot * ClpDualRowDantzig::clone(bool CopyData) const 00152 { 00153 if (CopyData) { 00154 return new ClpDualRowDantzig(*this); 00155 } else { 00156 return new ClpDualRowDantzig(); 00157 } 00158 } 00159