Changeset 1286 for branches/sandbox/Cbc/src/CbcBranchCut.cpp
 Timestamp:
 Nov 9, 2009 6:33:07 PM (10 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/sandbox/Cbc/src/CbcBranchCut.cpp
r1271 r1286 24 24 */ 25 25 CbcBranchCut::CbcBranchCut () 26 : CbcObject()26 : CbcObject() 27 27 { 28 28 } 29 29 30 30 /* Constructor so model can be passed up 31 */ 31 */ 32 32 CbcBranchCut::CbcBranchCut (CbcModel * model) 33 : CbcObject(model)34 { 35 } 36 // Copy constructor 33 : CbcObject(model) 34 { 35 } 36 // Copy constructor 37 37 CbcBranchCut::CbcBranchCut ( const CbcBranchCut & rhs) 38 :CbcObject(rhs)38 : CbcObject(rhs) 39 39 40 40 { … … 45 45 CbcBranchCut::clone() const 46 46 { 47 return new CbcBranchCut(*this);48 } 49 50 // Assignment operator 51 CbcBranchCut & 47 return new CbcBranchCut(*this); 48 } 49 50 // Assignment operator 51 CbcBranchCut & 52 52 CbcBranchCut::operator=( const CbcBranchCut& /*rhs*/) 53 53 { 54 return *this;55 } 56 57 // Destructor 54 return *this; 55 } 56 57 // Destructor 58 58 CbcBranchCut::~CbcBranchCut () 59 59 { 60 60 } 61 double 61 double 62 62 CbcBranchCut::infeasibility(const OsiBranchingInformation * /*info*/, 63 64 { 65 throw CoinError("Use of base class","infeasibility","CbcBranchCut");66 preferredWay=1;67 return 0.0;63 int &preferredWay) const 64 { 65 throw CoinError("Use of base class", "infeasibility", "CbcBranchCut"); 66 preferredWay = 1; 67 return 0.0; 68 68 } 69 69 … … 73 73 nearest integer value. 74 74 */ 75 void 75 void 76 76 CbcBranchCut::feasibleRegion() 77 77 { … … 79 79 /* Return true if branch created by object should fix variables 80 80 */ 81 bool 82 CbcBranchCut::boundBranch() const 83 {return false;} 84 CbcBranchingObject * 85 CbcBranchCut::createCbcBranch(OsiSolverInterface * /*solver*/,const OsiBranchingInformation * /*info*/, int /*way*/) 86 { 87 throw CoinError("Use of base class","createCbcBranch","CbcBranchCut"); 88 return new CbcCutBranchingObject(); 81 bool 82 CbcBranchCut::boundBranch() const 83 { 84 return false; 85 } 86 CbcBranchingObject * 87 CbcBranchCut::createCbcBranch(OsiSolverInterface * /*solver*/, const OsiBranchingInformation * /*info*/, int /*way*/) 88 { 89 throw CoinError("Use of base class", "createCbcBranch", "CbcBranchCut"); 90 return new CbcCutBranchingObject(); 89 91 } 90 92 … … 95 97 If no feasible point returns null 96 98 */ 97 CbcBranchingObject * 99 CbcBranchingObject * 98 100 CbcBranchCut::preferredNewFeasible() const 99 101 { 100 throw CoinError("Use of base class","preferredNewFeasible","CbcBranchCut");101 return new CbcCutBranchingObject();102 } 103 102 throw CoinError("Use of base class", "preferredNewFeasible", "CbcBranchCut"); 103 return new CbcCutBranchingObject(); 104 } 105 104 106 /* Given valid solution (i.e. satisfied) and reduced costs etc 105 107 returns a branching object which would give a new feasible … … 107 109 If no feasible point returns null 108 110 */ 109 CbcBranchingObject * 110 CbcBranchCut::notPreferredNewFeasible() const 111 { 112 throw CoinError("Use of base class","notPreferredNewFeasible","CbcBranchCut");113 return new CbcCutBranchingObject();114 } 115 111 CbcBranchingObject * 112 CbcBranchCut::notPreferredNewFeasible() const 113 { 114 throw CoinError("Use of base class", "notPreferredNewFeasible", "CbcBranchCut"); 115 return new CbcCutBranchingObject(); 116 } 117 116 118 /* 117 119 Bounds may be tightened, so it may be good to be able to refresh the local 118 120 copy of the original bounds. 119 121 */ 120 void 122 void 121 123 CbcBranchCut::resetBounds() 122 124 { … … 124 126 125 127 126 // Default Constructor 128 // Default Constructor 127 129 CbcCutBranchingObject::CbcCutBranchingObject() 128 :CbcBranchingObject()129 { 130 down_=OsiRowCut();131 up_=OsiRowCut();132 canFix_=false;130 : CbcBranchingObject() 131 { 132 down_ = OsiRowCut(); 133 up_ = OsiRowCut(); 134 canFix_ = false; 133 135 } 134 136 135 137 // Useful constructor 136 CbcCutBranchingObject::CbcCutBranchingObject (CbcModel * model, 137 OsiRowCut & down, 138 OsiRowCut &up, 139 bool canFix) 140 :CbcBranchingObject(model,0,1,0.0) 141 { 142 down_ = down; 143 up_ = up; 144 canFix_ = canFix; 145 } 146 147 // Copy constructor 148 CbcCutBranchingObject::CbcCutBranchingObject ( const CbcCutBranchingObject & rhs) :CbcBranchingObject(rhs) 149 { 150 down_ = rhs.down_; 151 up_ = rhs.up_; 152 canFix_ = rhs.canFix_; 153 } 154 155 // Assignment operator 156 CbcCutBranchingObject & 157 CbcCutBranchingObject::operator=( const CbcCutBranchingObject& rhs) 158 { 159 if (this != &rhs) { 160 CbcBranchingObject::operator=(rhs); 138 CbcCutBranchingObject::CbcCutBranchingObject (CbcModel * model, 139 OsiRowCut & down, 140 OsiRowCut &up, 141 bool canFix) 142 : CbcBranchingObject(model, 0, 1, 0.0) 143 { 144 down_ = down; 145 up_ = up; 146 canFix_ = canFix; 147 } 148 149 // Copy constructor 150 CbcCutBranchingObject::CbcCutBranchingObject ( const CbcCutBranchingObject & rhs) : CbcBranchingObject(rhs) 151 { 161 152 down_ = rhs.down_; 162 153 up_ = rhs.up_; 163 154 canFix_ = rhs.canFix_; 164 } 165 return *this; 166 } 167 CbcBranchingObject * 155 } 156 157 // Assignment operator 158 CbcCutBranchingObject & 159 CbcCutBranchingObject::operator=( const CbcCutBranchingObject & rhs) 160 { 161 if (this != &rhs) { 162 CbcBranchingObject::operator=(rhs); 163 down_ = rhs.down_; 164 up_ = rhs.up_; 165 canFix_ = rhs.canFix_; 166 } 167 return *this; 168 } 169 CbcBranchingObject * 168 170 CbcCutBranchingObject::clone() const 169 { 170 return (new CbcCutBranchingObject(*this));171 } 172 173 174 // Destructor 171 { 172 return (new CbcCutBranchingObject(*this)); 173 } 174 175 176 // Destructor 175 177 CbcCutBranchingObject::~CbcCutBranchingObject () 176 178 { … … 187 189 CbcCutBranchingObject::branch() 188 190 { 189 decrementNumberBranchesLeft(); 190 OsiRowCut * cut; 191 if (way_<0) { 192 cut = &down_; 193 way_=1; 194 } else { 195 cut = &up_; 196 way_=1; // Swap direction 197 } 198 printf("CUT %s ",(way_==1) ? "up" : "down"); 199 cut>print(); 200 // See if cut just fixes variables 201 double lb = cut>lb(); 202 double ub = cut>ub(); 203 int n=cut>row().getNumElements(); 204 const int * column = cut>row().getIndices(); 205 const double * element = cut>row().getElements(); 206 OsiSolverInterface * solver = model_>solver(); 207 const double * upper = solver>getColUpper(); 208 const double * lower = solver>getColLower(); 209 double low = 0.0; 210 double high=0.0; 211 for (int i=0;i<n;i++) { 212 int iColumn = column[i]; 213 double value = element[i]; 214 if (value>0.0) { 215 high += upper[iColumn]*value; 216 low += lower[iColumn]*value; 191 decrementNumberBranchesLeft(); 192 OsiRowCut * cut; 193 if (way_ < 0) { 194 cut = &down_; 195 way_ = 1; 217 196 } else { 218 high += lower[iColumn]*value; 219 low += upper[iColumn]*value; 220 } 221 } 222 // leave as cut 223 //model_>setNextRowCut(*cut); 224 //return 0.0; 225 // assume cut was cunningly constructed so we need not worry too much about tolerances 226 if (low+1.0e8>=ub&&canFix_) { 227 // fix 228 for (int i=0;i<n;i++) { 229 int iColumn = column[i]; 230 double value = element[i]; 231 if (value>0.0) { 232 solver>setColUpper(iColumn,lower[iColumn]); 233 } else { 234 solver>setColLower(iColumn,upper[iColumn]); 235 } 236 } 237 } else if (high1.0e8<=lb&&canFix_) { 238 // fix 239 for (int i=0;i<n;i++) { 240 int iColumn = column[i]; 241 double value = element[i]; 242 if (value>0.0) { 243 solver>setColLower(iColumn,upper[iColumn]); 244 } else { 245 solver>setColUpper(iColumn,lower[iColumn]); 246 } 247 } 248 } else { 197 cut = &up_; 198 way_ = 1; // Swap direction 199 } 200 printf("CUT %s ", (way_ == 1) ? "up" : "down"); 201 cut>print(); 202 // See if cut just fixes variables 203 double lb = cut>lb(); 204 double ub = cut>ub(); 205 int n = cut>row().getNumElements(); 206 const int * column = cut>row().getIndices(); 207 const double * element = cut>row().getElements(); 208 OsiSolverInterface * solver = model_>solver(); 209 const double * upper = solver>getColUpper(); 210 const double * lower = solver>getColLower(); 211 double low = 0.0; 212 double high = 0.0; 213 for (int i = 0; i < n; i++) { 214 int iColumn = column[i]; 215 double value = element[i]; 216 if (value > 0.0) { 217 high += upper[iColumn] * value; 218 low += lower[iColumn] * value; 219 } else { 220 high += lower[iColumn] * value; 221 low += upper[iColumn] * value; 222 } 223 } 249 224 // leave as cut 250 model_>setNextRowCut(*cut); 251 } 252 return 0.0; 253 } 254 // Print what would happen 225 //model_>setNextRowCut(*cut); 226 //return 0.0; 227 // assume cut was cunningly constructed so we need not worry too much about tolerances 228 if (low + 1.0e8 >= ub && canFix_) { 229 // fix 230 for (int i = 0; i < n; i++) { 231 int iColumn = column[i]; 232 double value = element[i]; 233 if (value > 0.0) { 234 solver>setColUpper(iColumn, lower[iColumn]); 235 } else { 236 solver>setColLower(iColumn, upper[iColumn]); 237 } 238 } 239 } else if (high  1.0e8 <= lb && canFix_) { 240 // fix 241 for (int i = 0; i < n; i++) { 242 int iColumn = column[i]; 243 double value = element[i]; 244 if (value > 0.0) { 245 solver>setColLower(iColumn, upper[iColumn]); 246 } else { 247 solver>setColUpper(iColumn, lower[iColumn]); 248 } 249 } 250 } else { 251 // leave as cut 252 model_>setNextRowCut(*cut); 253 } 254 return 0.0; 255 } 256 // Print what would happen 255 257 void 256 258 CbcCutBranchingObject::print() 257 259 { 258 OsiRowCut * cut;259 if (way_<0) {260 cut = &down_;261 printf("CbcCut would branch down");262 } else {263 cut = &up_;264 printf("CbcCut would branch up");265 }266 double lb = cut>lb();267 double ub = cut>ub();268 int n=cut>row().getNumElements();269 const int * column = cut>row().getIndices();270 const double * element = cut>row().getElements();271 if (n>5) {272 printf("  %d elements, lo=%g, up=%g\n",n,lb,ub);273 } else {274 printf("  %g <=",lb);275 for (int i=0;i<n;i++) {276 int iColumn = column[i];277 double value = element[i];278 printf(" (%d,%g)",iColumn,value);279 }280 printf(" <= %g\n",ub);281 }260 OsiRowCut * cut; 261 if (way_ < 0) { 262 cut = &down_; 263 printf("CbcCut would branch down"); 264 } else { 265 cut = &up_; 266 printf("CbcCut would branch up"); 267 } 268 double lb = cut>lb(); 269 double ub = cut>ub(); 270 int n = cut>row().getNumElements(); 271 const int * column = cut>row().getIndices(); 272 const double * element = cut>row().getElements(); 273 if (n > 5) { 274 printf("  %d elements, lo=%g, up=%g\n", n, lb, ub); 275 } else { 276 printf("  %g <=", lb); 277 for (int i = 0; i < n; i++) { 278 int iColumn = column[i]; 279 double value = element[i]; 280 printf(" (%d,%g)", iColumn, value); 281 } 282 printf(" <= %g\n", ub); 283 } 282 284 } 283 285 284 286 // Return true if branch should fix variables 285 bool 287 bool 286 288 CbcCutBranchingObject::boundBranch() const 287 289 { 288 return false;290 return false; 289 291 } 290 292 … … 292 294 brObj. Assumes that there is an ordering of the original objects. 293 295 This method should be invoked only if \c this and brObj are of the same 294 type. 296 type. 295 297 Return negative/0/positive depending on whether \c this is 296 298 smaller/same/larger than the argument. … … 300 302 (const CbcBranchingObject* brObj) const 301 303 { 302 const CbcCutBranchingObject* br =303 dynamic_cast<const CbcCutBranchingObject*>(brObj);304 assert(br);305 const OsiRowCut& r0 = way_ == 1 ? down_ : up_;306 const OsiRowCut& r1 = br>way_ == 1 ? br>down_ : br>up_;307 return r0.row().compare(r1.row());304 const CbcCutBranchingObject* br = 305 dynamic_cast<const CbcCutBranchingObject*>(brObj); 306 assert(br); 307 const OsiRowCut& r0 = way_ == 1 ? down_ : up_; 308 const OsiRowCut& r1 = br>way_ == 1 ? br>down_ : br>up_; 309 return r0.row().compare(r1.row()); 308 310 } 309 311 … … 321 323 (const CbcBranchingObject* brObj, const bool replaceIfOverlap) 322 324 { 323 const CbcCutBranchingObject* br = 324 dynamic_cast<const CbcCutBranchingObject*>(brObj); 325 assert(br); 326 OsiRowCut& r0 = way_ == 1 ? down_ : up_; 327 const OsiRowCut& r1 = br>way_ == 1 ? br>down_ : br>up_; 328 double thisBd[2]; 329 thisBd[0] = r0.lb(); 330 thisBd[1] = r0.ub(); 331 double otherBd[2]; 332 otherBd[0] = r1.lb(); 333 otherBd[1] = r1.ub(); 334 CbcRangeCompare comp = CbcCompareRanges(thisBd, otherBd, replaceIfOverlap); 335 if (comp != CbcRangeOverlap  (comp==CbcRangeOverlap && !replaceIfOverlap)) { 325 const CbcCutBranchingObject* br = 326 dynamic_cast<const CbcCutBranchingObject*>(brObj); 327 assert(br); 328 OsiRowCut& r0 = way_ == 1 ? down_ : up_; 329 const OsiRowCut& r1 = br>way_ == 1 ? br>down_ : br>up_; 330 double thisBd[2]; 331 thisBd[0] = r0.lb(); 332 thisBd[1] = r0.ub(); 333 double otherBd[2]; 334 otherBd[0] = r1.lb(); 335 otherBd[1] = r1.ub(); 336 CbcRangeCompare comp = CbcCompareRanges(thisBd, otherBd, replaceIfOverlap); 337 if (comp != CbcRangeOverlap  (comp == CbcRangeOverlap && !replaceIfOverlap)) { 338 return comp; 339 } 340 r0.setLb(thisBd[0]); 341 r0.setUb(thisBd[1]); 336 342 return comp; 337 }338 r0.setLb(thisBd[0]);339 r0.setUb(thisBd[1]);340 return comp;341 343 } 342 344 … … 348 350 */ 349 351 CbcBranchToFixLots::CbcBranchToFixLots () 350 : CbcBranchCut(),351 djTolerance_(COIN_DBL_MAX),352 fractionFixed_(1.0),353 mark_(NULL),354 depth_(1),355 numberClean_(0),356 alwaysCreate_(false)352 : CbcBranchCut(), 353 djTolerance_(COIN_DBL_MAX), 354 fractionFixed_(1.0), 355 mark_(NULL), 356 depth_(1), 357 numberClean_(0), 358 alwaysCreate_(false) 357 359 { 358 360 } … … 363 365 Always does if all 1 rows cleaned up and number>0 or if fraction columns reached 364 366 Also whether to create branch if can't reach fraction. 365 */ 367 */ 366 368 CbcBranchToFixLots::CbcBranchToFixLots (CbcModel * model, double djTolerance, 367 368 369 370 : CbcBranchCut(model)371 { 372 djTolerance_ = djTolerance;373 fractionFixed_ = fractionFixed;374 if (mark) {375 int numberColumns = model>getNumCols();376 mark_ = new char[numberColumns];377 memcpy(mark_,mark,numberColumns);378 } else {379 mark_ = NULL;380 }381 depth_ = depth;382 assert (model);383 OsiSolverInterface * solver = model_>solver();384 matrixByRow_ = *solver>getMatrixByRow();385 numberClean_ = numberClean;386 alwaysCreate_ = alwaysCreate;387 } 388 // Copy constructor 369 double fractionFixed, int depth, 370 int numberClean, 371 const char * mark, bool alwaysCreate) 372 : CbcBranchCut(model) 373 { 374 djTolerance_ = djTolerance; 375 fractionFixed_ = fractionFixed; 376 if (mark) { 377 int numberColumns = model>getNumCols(); 378 mark_ = new char[numberColumns]; 379 memcpy(mark_, mark, numberColumns); 380 } else { 381 mark_ = NULL; 382 } 383 depth_ = depth; 384 assert (model); 385 OsiSolverInterface * solver = model_>solver(); 386 matrixByRow_ = *solver>getMatrixByRow(); 387 numberClean_ = numberClean; 388 alwaysCreate_ = alwaysCreate; 389 } 390 // Copy constructor 389 391 CbcBranchToFixLots::CbcBranchToFixLots ( const CbcBranchToFixLots & rhs) 390 :CbcBranchCut(rhs)391 { 392 djTolerance_ = rhs.djTolerance_;393 fractionFixed_ = rhs.fractionFixed_;394 int numberColumns = model_>getNumCols();395 mark_ = CoinCopyOfArray(rhs.mark_,numberColumns);396 matrixByRow_=rhs.matrixByRow_;397 depth_ = rhs.depth_;398 numberClean_ = rhs.numberClean_;399 alwaysCreate_ = rhs.alwaysCreate_;392 : CbcBranchCut(rhs) 393 { 394 djTolerance_ = rhs.djTolerance_; 395 fractionFixed_ = rhs.fractionFixed_; 396 int numberColumns = model_>getNumCols(); 397 mark_ = CoinCopyOfArray(rhs.mark_, numberColumns); 398 matrixByRow_ = rhs.matrixByRow_; 399 depth_ = rhs.depth_; 400 numberClean_ = rhs.numberClean_; 401 alwaysCreate_ = rhs.alwaysCreate_; 400 402 } 401 403 … … 404 406 CbcBranchToFixLots::clone() const 405 407 { 406 return new CbcBranchToFixLots(*this); 407 } 408 409 // Assignment operator 410 CbcBranchToFixLots & 411 CbcBranchToFixLots::operator=( const CbcBranchToFixLots& rhs) 412 { 413 if (this!=&rhs) { 414 CbcBranchCut::operator=(rhs); 415 djTolerance_ = rhs.djTolerance_; 416 fractionFixed_ = rhs.fractionFixed_; 417 int numberColumns = model_>getNumCols(); 408 return new CbcBranchToFixLots(*this); 409 } 410 411 // Assignment operator 412 CbcBranchToFixLots & 413 CbcBranchToFixLots::operator=( const CbcBranchToFixLots & rhs) 414 { 415 if (this != &rhs) { 416 CbcBranchCut::operator=(rhs); 417 djTolerance_ = rhs.djTolerance_; 418 fractionFixed_ = rhs.fractionFixed_; 419 int numberColumns = model_>getNumCols(); 420 delete [] mark_; 421 mark_ = CoinCopyOfArray(rhs.mark_, numberColumns); 422 matrixByRow_ = rhs.matrixByRow_; 423 depth_ = rhs.depth_; 424 numberClean_ = rhs.numberClean_; 425 alwaysCreate_ = rhs.alwaysCreate_; 426 } 427 return *this; 428 } 429 430 // Destructor 431 CbcBranchToFixLots::~CbcBranchToFixLots () 432 { 418 433 delete [] mark_; 419 mark_ = CoinCopyOfArray(rhs.mark_,numberColumns); 420 matrixByRow_=rhs.matrixByRow_; 421 depth_ = rhs.depth_; 422 numberClean_ = rhs.numberClean_; 423 alwaysCreate_ = rhs.alwaysCreate_; 424 } 425 return *this; 426 } 427 428 // Destructor 429 CbcBranchToFixLots::~CbcBranchToFixLots () 430 { 431 delete [] mark_; 432 } 433 CbcBranchingObject * 434 CbcBranchToFixLots::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int /*way*/) 435 { 436 // by default way must be 1 437 //assert (way==1); 438 //OsiSolverInterface * solver = model_>solver(); 439 const double * solution = model_>testSolution(); 440 const double * lower = solver>getColLower(); 441 const double * upper = solver>getColUpper(); 442 const double * dj = solver>getReducedCost(); 443 int i; 444 int numberIntegers = model_>numberIntegers(); 445 const int * integerVariable = model_>integerVariable(); 446 double integerTolerance = 447 model_>getDblParam(CbcModel::CbcIntegerTolerance); 448 // make smaller ? 449 double tolerance = CoinMin(1.0e8,integerTolerance); 450 // How many fixed are we aiming at 451 int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers)*fractionFixed_); 452 int nSort=0; 453 int numberFixed=0; 454 int numberColumns = solver>getNumCols(); 455 int * sort = new int[numberColumns]; 456 double * dsort = new double[numberColumns]; 457 if (djTolerance_!=1.234567) { 458 int type = shallWe(); 459 assert (type); 460 // Take clean first 461 if (type==1) { 462 for (i=0;i<numberIntegers;i++) { 463 int iColumn = integerVariable[i]; 464 if (upper[iColumn]>lower[iColumn]) { 465 if (!mark_!mark_[iColumn]) { 466 if(solution[iColumn]<lower[iColumn]+tolerance) { 467 if (dj[iColumn]>djTolerance_) { 468 dsort[nSort]=dj[iColumn]; 469 sort[nSort++]=iColumn; 470 } 471 } else if (solution[iColumn]>upper[iColumn]tolerance) { 472 if (dj[iColumn]<djTolerance_) { 473 dsort[nSort]=dj[iColumn]; 474 sort[nSort++]=iColumn; 475 } 476 } 477 } 478 } else { 479 numberFixed++; 480 } 481 } 482 // sort 483 CoinSort_2(dsort,dsort+nSort,sort); 484 nSort= CoinMin(nSort,wantedFixednumberFixed); 485 } else if (type<10) { 486 int i; 487 //const double * rowLower = solver>getRowLower(); 488 const double * rowUpper = solver>getRowUpper(); 489 // Row copy 490 const double * elementByRow = matrixByRow_.getElements(); 491 const int * column = matrixByRow_.getIndices(); 492 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 493 const int * rowLength = matrixByRow_.getVectorLengths(); 494 const double * columnLower = solver>getColLower(); 495 const double * columnUpper = solver>getColUpper(); 496 const double * solution = solver>getColSolution(); 497 int numberColumns = solver>getNumCols(); 498 int numberRows = solver>getNumRows(); 499 for (i=0;i<numberColumns;i++) { 500 sort[i]=i; 501 if (columnLower[i]!=columnUpper[i]){ 502 dsort[i]=1.0e100; 503 } else { 504 dsort[i]=1.0e50; 505 numberFixed++; 506 } 507 } 508 for (i=0;i<numberRows;i++) { 509 double rhsValue = rowUpper[i]; 510 bool oneRow=true; 511 // check elements 512 int numberUnsatisfied=0; 513 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) { 514 int iColumn = column[j]; 515 double value = elementByRow[j]; 516 double solValue = solution[iColumn]; 517 if (columnLower[iColumn]!=columnUpper[iColumn]) { 518 if (solValue<1.0integerTolerance&&solValue>integerTolerance) 519 numberUnsatisfied++; 520 if (value!=1.0) { 521 oneRow=false; 522 break; 523 } 524 } else { 525 rhsValue = value*floor(solValue+0.5); 526 } 527 } 528 if (oneRow&&rhsValue<=1.0+tolerance) { 529 if (!numberUnsatisfied) { 530 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) { 531 int iColumn = column[j]; 532 if (dsort[iColumn]>1.0e50){ 533 dsort[iColumn]=0; 534 nSort++; 535 } 536 } 537 } 538 } 539 } 540 // sort 541 CoinSort_2(dsort,dsort+numberColumns,sort); 434 } 435 CbcBranchingObject * 436 CbcBranchToFixLots::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * /*info*/, int /*way*/) 437 { 438 // by default way must be 1 439 //assert (way==1); 440 //OsiSolverInterface * solver = model_>solver(); 441 const double * solution = model_>testSolution(); 442 const double * lower = solver>getColLower(); 443 const double * upper = solver>getColUpper(); 444 const double * dj = solver>getReducedCost(); 445 int i; 446 int numberIntegers = model_>numberIntegers(); 447 const int * integerVariable = model_>integerVariable(); 448 double integerTolerance = 449 model_>getDblParam(CbcModel::CbcIntegerTolerance); 450 // make smaller ? 451 double tolerance = CoinMin(1.0e8, integerTolerance); 452 // How many fixed are we aiming at 453 int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_); 454 int nSort = 0; 455 int numberFixed = 0; 456 int numberColumns = solver>getNumCols(); 457 int * sort = new int[numberColumns]; 458 double * dsort = new double[numberColumns]; 459 if (djTolerance_ != 1.234567) { 460 int type = shallWe(); 461 assert (type); 462 // Take clean first 463 if (type == 1) { 464 for (i = 0; i < numberIntegers; i++) { 465 int iColumn = integerVariable[i]; 466 if (upper[iColumn] > lower[iColumn]) { 467 if (!mark_  !mark_[iColumn]) { 468 if (solution[iColumn] < lower[iColumn] + tolerance) { 469 if (dj[iColumn] > djTolerance_) { 470 dsort[nSort] = dj[iColumn]; 471 sort[nSort++] = iColumn; 472 } 473 } else if (solution[iColumn] > upper[iColumn]  tolerance) { 474 if (dj[iColumn] < djTolerance_) { 475 dsort[nSort] = dj[iColumn]; 476 sort[nSort++] = iColumn; 477 } 478 } 479 } 480 } else { 481 numberFixed++; 482 } 483 } 484 // sort 485 CoinSort_2(dsort, dsort + nSort, sort); 486 nSort = CoinMin(nSort, wantedFixed  numberFixed); 487 } else if (type < 10) { 488 int i; 489 //const double * rowLower = solver>getRowLower(); 490 const double * rowUpper = solver>getRowUpper(); 491 // Row copy 492 const double * elementByRow = matrixByRow_.getElements(); 493 const int * column = matrixByRow_.getIndices(); 494 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 495 const int * rowLength = matrixByRow_.getVectorLengths(); 496 const double * columnLower = solver>getColLower(); 497 const double * columnUpper = solver>getColUpper(); 498 const double * solution = solver>getColSolution(); 499 int numberColumns = solver>getNumCols(); 500 int numberRows = solver>getNumRows(); 501 for (i = 0; i < numberColumns; i++) { 502 sort[i] = i; 503 if (columnLower[i] != columnUpper[i]) { 504 dsort[i] = 1.0e100; 505 } else { 506 dsort[i] = 1.0e50; 507 numberFixed++; 508 } 509 } 510 for (i = 0; i < numberRows; i++) { 511 double rhsValue = rowUpper[i]; 512 bool oneRow = true; 513 // check elements 514 int numberUnsatisfied = 0; 515 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 516 int iColumn = column[j]; 517 double value = elementByRow[j]; 518 double solValue = solution[iColumn]; 519 if (columnLower[iColumn] != columnUpper[iColumn]) { 520 if (solValue < 1.0  integerTolerance && solValue > integerTolerance) 521 numberUnsatisfied++; 522 if (value != 1.0) { 523 oneRow = false; 524 break; 525 } 526 } else { 527 rhsValue = value * floor(solValue + 0.5); 528 } 529 } 530 if (oneRow && rhsValue <= 1.0 + tolerance) { 531 if (!numberUnsatisfied) { 532 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 533 int iColumn = column[j]; 534 if (dsort[iColumn] > 1.0e50) { 535 dsort[iColumn] = 0; 536 nSort++; 537 } 538 } 539 } 540 } 541 } 542 // sort 543 CoinSort_2(dsort, dsort + numberColumns, sort); 544 } else { 545 // new way 546 for (i = 0; i < numberIntegers; i++) { 547 int iColumn = integerVariable[i]; 548 if (upper[iColumn] > lower[iColumn]) { 549 if (!mark_  !mark_[iColumn]) { 550 double distanceDown = solution[iColumn]  lower[iColumn]; 551 double distanceUp = upper[iColumn]  solution[iColumn]; 552 double distance = CoinMin(distanceDown, distanceUp); 553 if (distance > 0.001 && distance < 0.5) { 554 dsort[nSort] = distance; 555 sort[nSort++] = iColumn; 556 } 557 } 558 } 559 } 560 // sort 561 CoinSort_2(dsort, dsort + nSort, sort); 562 int n = 0; 563 double sum = 0.0; 564 for (int k = 0; k < nSort; k++) { 565 sum += dsort[k]; 566 if (sum <= djTolerance_) 567 n = k; 568 else 569 break; 570 } 571 nSort = CoinMin(n, numberClean_ / 1000000); 572 } 542 573 } else { 543 // new way544 for (i=0;i<numberIntegers;i++) {545 int iColumn = integerVariable[i];546 if (upper[iColumn]>lower[iColumn]) {547 if (!mark_!mark_[iColumn]) {548 double distanceDown=solution[iColumn]lower[iColumn];549 double distanceUp=upper[iColumn]solution[iColumn];550 double distance = CoinMin(distanceDown,distanceUp);551 if (distance>0.001&&distance<0.5) {552 dsort[nSort]=distance;553 sort[nSort++]=iColumn;554 }555 }556 }557 }558 // sort559 CoinSort_2(dsort,dsort+nSort,sort);560 int n=0;561 double sum=0.0;562 for (int k=0;k<nSort;k++) {563 sum += dsort[k];564 if (sum<=djTolerance_)565 n=k;566 else567 break;568 }569 nSort = CoinMin(n,numberClean_/1000000);570 }571 } else {572 574 #define FIX_IF_LESS 0.1 573 // 3 in same row and sum <FIX_IF_LESS?574 int numberRows = matrixByRow_.getNumRows();575 const double * solution = model_>testSolution();576 const int * column = matrixByRow_.getIndices();577 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();578 const int * rowLength = matrixByRow_.getVectorLengths();579 double bestSum=1.0;580 int nBest=1;581 int kRow=1;582 OsiSolverInterface * solver = model_>solver();583 for (int i=0;i<numberRows;i++) {584 int numberUnsatisfied=0;585 double sum=0.0;586 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {587 588 589 590 if (solValue>1.0e5&&solValue<FIX_IF_LESS) {591 592 593 594 595 }596 if (numberUnsatisfied>=3&&sum<FIX_IF_LESS) {597 598 if (numberUnsatisfied>nBest599 (numberUnsatisfied==nBest&&sum<bestSum)) {600 nBest=numberUnsatisfied;601 bestSum=sum;602 kRow=i;603 604 }605 }606 assert (nBest>0);607 for (int j=rowStart[kRow];j<rowStart[kRow]+rowLength[kRow];j++) {608 int iColumn = column[j];609 if (solver>isInteger(iColumn)) {610 611 if (solValue>1.0e5&&solValue<FIX_IF_LESS) {612 sort[nSort++]=iColumn;613 614 }615 }616 }617 OsiRowCut down;618 down.setLb(COIN_DBL_MAX);619 double rhs=0.0;620 for (i=0;i<nSort;i++) {621 int iColumn = sort[i];622 double distanceDown=solution[iColumn]lower[iColumn];623 double distanceUp=upper[iColumn]solution[iColumn];624 if(distanceDown<distanceUp) {625 rhs += lower[iColumn];626 dsort[i]=1.0;627 } else {628 rhs = upper[iColumn];629 dsort[i]=1.0;630 }631 }632 down.setUb(rhs);633 down.setRow(nSort,sort,dsort);634 down.setEffectiveness(COIN_DBL_MAX); // so will persist635 delete [] sort;636 delete [] dsort;637 // up is same  just with rhs changed638 OsiRowCut up = down;639 up.setLb(rhs +1.0);640 up.setUb(COIN_DBL_MAX);641 // Say can fix one way642 CbcCutBranchingObject * newObject =643 new CbcCutBranchingObject(model_,down,up,true);644 if (model_>messageHandler()>logLevel()>1)645 printf("creating cut in CbcBranchCut\n");646 return newObject;575 // 3 in same row and sum <FIX_IF_LESS? 576 int numberRows = matrixByRow_.getNumRows(); 577 const double * solution = model_>testSolution(); 578 const int * column = matrixByRow_.getIndices(); 579 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 580 const int * rowLength = matrixByRow_.getVectorLengths(); 581 double bestSum = 1.0; 582 int nBest = 1; 583 int kRow = 1; 584 OsiSolverInterface * solver = model_>solver(); 585 for (int i = 0; i < numberRows; i++) { 586 int numberUnsatisfied = 0; 587 double sum = 0.0; 588 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 589 int iColumn = column[j]; 590 if (solver>isInteger(iColumn)) { 591 double solValue = solution[iColumn]; 592 if (solValue > 1.0e5 && solValue < FIX_IF_LESS) { 593 numberUnsatisfied++; 594 sum += solValue; 595 } 596 } 597 } 598 if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) { 599 // possible 600 if (numberUnsatisfied > nBest  601 (numberUnsatisfied == nBest && sum < bestSum)) { 602 nBest = numberUnsatisfied; 603 bestSum = sum; 604 kRow = i; 605 } 606 } 607 } 608 assert (nBest > 0); 609 for (int j = rowStart[kRow]; j < rowStart[kRow] + rowLength[kRow]; j++) { 610 int iColumn = column[j]; 611 if (solver>isInteger(iColumn)) { 612 double solValue = solution[iColumn]; 613 if (solValue > 1.0e5 && solValue < FIX_IF_LESS) { 614 sort[nSort++] = iColumn; 615 } 616 } 617 } 618 } 619 OsiRowCut down; 620 down.setLb(COIN_DBL_MAX); 621 double rhs = 0.0; 622 for (i = 0; i < nSort; i++) { 623 int iColumn = sort[i]; 624 double distanceDown = solution[iColumn]  lower[iColumn]; 625 double distanceUp = upper[iColumn]  solution[iColumn]; 626 if (distanceDown < distanceUp) { 627 rhs += lower[iColumn]; 628 dsort[i] = 1.0; 629 } else { 630 rhs = upper[iColumn]; 631 dsort[i] = 1.0; 632 } 633 } 634 down.setUb(rhs); 635 down.setRow(nSort, sort, dsort); 636 down.setEffectiveness(COIN_DBL_MAX); // so will persist 637 delete [] sort; 638 delete [] dsort; 639 // up is same  just with rhs changed 640 OsiRowCut up = down; 641 up.setLb(rhs + 1.0); 642 up.setUb(COIN_DBL_MAX); 643 // Say can fix one way 644 CbcCutBranchingObject * newObject = 645 new CbcCutBranchingObject(model_, down, up, true); 646 if (model_>messageHandler()>logLevel() > 1) 647 printf("creating cut in CbcBranchCut\n"); 648 return newObject; 647 649 } 648 650 /* Does a lot of the work, … … 650 652 10 if branching on ones away from bound 651 653 */ 652 int 654 int 653 655 CbcBranchToFixLots::shallWe() const 654 656 { 655 int returnCode=0; 656 OsiSolverInterface * solver = model_>solver(); 657 int numberRows = matrixByRow_.getNumRows(); 658 //if (numberRows!=solver>getNumRows()) 659 //return 0; 660 const double * solution = model_>testSolution(); 661 const double * lower = solver>getColLower(); 662 const double * upper = solver>getColUpper(); 663 const double * dj = solver>getReducedCost(); 664 int i; 665 int numberIntegers = model_>numberIntegers(); 666 const int * integerVariable = model_>integerVariable(); 667 if (numberClean_>1000000) { 668 int wanted = numberClean_%1000000; 669 int * sort = new int[numberIntegers]; 670 double * dsort = new double[numberIntegers]; 671 int nSort=0; 672 for (i=0;i<numberIntegers;i++) { 673 int iColumn = integerVariable[i]; 674 if (upper[iColumn]>lower[iColumn]) { 675 if (!mark_!mark_[iColumn]) { 676 double distanceDown=solution[iColumn]lower[iColumn]; 677 double distanceUp=upper[iColumn]solution[iColumn]; 678 double distance = CoinMin(distanceDown,distanceUp); 679 if (distance>0.001&&distance<0.5) { 680 dsort[nSort]=distance; 681 sort[nSort++]=iColumn; 682 } 683 } 684 } 685 } 686 // sort 687 CoinSort_2(dsort,dsort+nSort,sort); 688 int n=0; 689 double sum=0.0; 690 for (int k=0;k<nSort;k++) { 691 sum += dsort[k]; 692 if (sum<=djTolerance_) 693 n=k; 694 else 695 break; 696 } 697 delete [] sort; 698 delete [] dsort; 699 return (n>=wanted) ? 10 : 0; 700 } 701 double integerTolerance = 702 model_>getDblParam(CbcModel::CbcIntegerTolerance); 703 // make smaller ? 704 double tolerance = CoinMin(1.0e8,integerTolerance); 705 // How many fixed are we aiming at 706 int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers)*fractionFixed_); 707 if (djTolerance_<1.0e10) { 708 int nSort=0; 709 int numberFixed=0; 710 for (i=0;i<numberIntegers;i++) { 711 int iColumn = integerVariable[i]; 712 if (upper[iColumn]>lower[iColumn]) { 713 if (!mark_!mark_[iColumn]) { 714 if(solution[iColumn]<lower[iColumn]+tolerance) { 715 if (dj[iColumn]>djTolerance_) { 716 nSort++; 717 } 718 } else if (solution[iColumn]>upper[iColumn]tolerance) { 719 if (dj[iColumn]<djTolerance_) { 720 nSort++; 721 } 722 } 723 } 724 } else { 725 numberFixed++; 726 } 727 } 728 if (numberFixed+nSort<wantedFixed&&!alwaysCreate_) { 729 returnCode = 0; 730 } else if (numberFixed<wantedFixed) { 731 returnCode = 1; 657 int returnCode = 0; 658 OsiSolverInterface * solver = model_>solver(); 659 int numberRows = matrixByRow_.getNumRows(); 660 //if (numberRows!=solver>getNumRows()) 661 //return 0; 662 const double * solution = model_>testSolution(); 663 const double * lower = solver>getColLower(); 664 const double * upper = solver>getColUpper(); 665 const double * dj = solver>getReducedCost(); 666 int i; 667 int numberIntegers = model_>numberIntegers(); 668 const int * integerVariable = model_>integerVariable(); 669 if (numberClean_ > 1000000) { 670 int wanted = numberClean_ % 1000000; 671 int * sort = new int[numberIntegers]; 672 double * dsort = new double[numberIntegers]; 673 int nSort = 0; 674 for (i = 0; i < numberIntegers; i++) { 675 int iColumn = integerVariable[i]; 676 if (upper[iColumn] > lower[iColumn]) { 677 if (!mark_  !mark_[iColumn]) { 678 double distanceDown = solution[iColumn]  lower[iColumn]; 679 double distanceUp = upper[iColumn]  solution[iColumn]; 680 double distance = CoinMin(distanceDown, distanceUp); 681 if (distance > 0.001 && distance < 0.5) { 682 dsort[nSort] = distance; 683 sort[nSort++] = iColumn; 684 } 685 } 686 } 687 } 688 // sort 689 CoinSort_2(dsort, dsort + nSort, sort); 690 int n = 0; 691 double sum = 0.0; 692 for (int k = 0; k < nSort; k++) { 693 sum += dsort[k]; 694 if (sum <= djTolerance_) 695 n = k; 696 else 697 break; 698 } 699 delete [] sort; 700 delete [] dsort; 701 return (n >= wanted) ? 10 : 0; 702 } 703 double integerTolerance = 704 model_>getDblParam(CbcModel::CbcIntegerTolerance); 705 // make smaller ? 706 double tolerance = CoinMin(1.0e8, integerTolerance); 707 // How many fixed are we aiming at 708 int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_); 709 if (djTolerance_ < 1.0e10) { 710 int nSort = 0; 711 int numberFixed = 0; 712 for (i = 0; i < numberIntegers; i++) { 713 int iColumn = integerVariable[i]; 714 if (upper[iColumn] > lower[iColumn]) { 715 if (!mark_  !mark_[iColumn]) { 716 if (solution[iColumn] < lower[iColumn] + tolerance) { 717 if (dj[iColumn] > djTolerance_) { 718 nSort++; 719 } 720 } else if (solution[iColumn] > upper[iColumn]  tolerance) { 721 if (dj[iColumn] < djTolerance_) { 722 nSort++; 723 } 724 } 725 } 726 } else { 727 numberFixed++; 728 } 729 } 730 if (numberFixed + nSort < wantedFixed && !alwaysCreate_) { 731 returnCode = 0; 732 } else if (numberFixed < wantedFixed) { 733 returnCode = 1; 734 } else { 735 returnCode = 0; 736 } 737 } 738 if (numberClean_) { 739 // see how many rows clean 740 int i; 741 //const double * rowLower = solver>getRowLower(); 742 const double * rowUpper = solver>getRowUpper(); 743 // Row copy 744 const double * elementByRow = matrixByRow_.getElements(); 745 const int * column = matrixByRow_.getIndices(); 746 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 747 const int * rowLength = matrixByRow_.getVectorLengths(); 748 const double * columnLower = solver>getColLower(); 749 const double * columnUpper = solver>getColUpper(); 750 const double * solution = solver>getColSolution(); 751 int numberClean = 0; 752 bool someToDoYet = false; 753 int numberColumns = solver>getNumCols(); 754 char * mark = new char[numberColumns]; 755 int numberFixed = 0; 756 for (i = 0; i < numberColumns; i++) { 757 if (columnLower[i] != columnUpper[i]) { 758 mark[i] = 0; 759 } else { 760 mark[i] = 1; 761 numberFixed++; 762 } 763 } 764 int numberNewFixed = 0; 765 for (i = 0; i < numberRows; i++) { 766 double rhsValue = rowUpper[i]; 767 bool oneRow = true; 768 // check elements 769 int numberUnsatisfied = 0; 770 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 771 int iColumn = column[j]; 772 double value = elementByRow[j]; 773 double solValue = solution[iColumn]; 774 if (columnLower[iColumn] != columnUpper[iColumn]) { 775 if (solValue < 1.0  integerTolerance && solValue > integerTolerance) 776 numberUnsatisfied++; 777 if (value != 1.0) { 778 oneRow = false; 779 break; 780 } 781 } else { 782 rhsValue = value * floor(solValue + 0.5); 783 } 784 } 785 if (oneRow && rhsValue <= 1.0 + tolerance) { 786 if (numberUnsatisfied) { 787 someToDoYet = true; 788 } else { 789 numberClean++; 790 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 791 int iColumn = column[j]; 792 if (columnLower[iColumn] != columnUpper[iColumn] && !mark[iColumn]) { 793 mark[iColumn] = 1; 794 numberNewFixed++; 795 } 796 } 797 } 798 } 799 } 800 delete [] mark; 801 //printf("%d clean, %d old fixed, %d new fixed\n", 802 // numberClean,numberFixed,numberNewFixed); 803 if (someToDoYet && numberClean < numberClean_ 804 && numberNewFixed + numberFixed < wantedFixed) { 805 } else if (numberFixed < wantedFixed) { 806 returnCode = 2; 807 } else { 808 } 809 } 810 return returnCode; 811 } 812 double 813 CbcBranchToFixLots::infeasibility(const OsiBranchingInformation * /*info*/, 814 int &preferredWay) const 815 { 816 preferredWay = 1; 817 CbcNode * node = model_>currentNode(); 818 int depth; 819 if (node) 820 depth = CoinMax(node>depth(), 0); 821 else 822 return 0.0; 823 if (depth_ < 0) { 824 return 0.0; 825 } else if (depth_ > 0) { 826 if ((depth % depth_) != 0) 827 return 0.0; 828 } 829 if (djTolerance_ != 1.234567) { 830 if (!shallWe()) 831 return 0.0; 832 else 833 return 1.0e20; 732 834 } else { 733 returnCode = 0; 734 } 735 } 736 if (numberClean_) { 737 // see how many rows clean 738 int i; 739 //const double * rowLower = solver>getRowLower(); 740 const double * rowUpper = solver>getRowUpper(); 741 // Row copy 742 const double * elementByRow = matrixByRow_.getElements(); 743 const int * column = matrixByRow_.getIndices(); 744 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 745 const int * rowLength = matrixByRow_.getVectorLengths(); 746 const double * columnLower = solver>getColLower(); 747 const double * columnUpper = solver>getColUpper(); 748 const double * solution = solver>getColSolution(); 749 int numberClean=0; 750 bool someToDoYet=false; 751 int numberColumns = solver>getNumCols(); 752 char * mark = new char[numberColumns]; 753 int numberFixed=0; 754 for (i=0;i<numberColumns;i++) { 755 if (columnLower[i]!=columnUpper[i]){ 756 mark[i]=0; 757 } else { 758 mark[i]=1; 759 numberFixed++; 760 } 761 } 762 int numberNewFixed=0; 763 for (i=0;i<numberRows;i++) { 764 double rhsValue = rowUpper[i]; 765 bool oneRow=true; 766 // check elements 767 int numberUnsatisfied=0; 768 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) { 769 int iColumn = column[j]; 770 double value = elementByRow[j]; 771 double solValue = solution[iColumn]; 772 if (columnLower[iColumn]!=columnUpper[iColumn]) { 773 if (solValue<1.0integerTolerance&&solValue>integerTolerance) 774 numberUnsatisfied++; 775 if (value!=1.0) { 776 oneRow=false; 777 break; 778 } 779 } else { 780 rhsValue = value*floor(solValue+0.5); 781 } 782 } 783 if (oneRow&&rhsValue<=1.0+tolerance) { 784 if (numberUnsatisfied) { 785 someToDoYet=true; 786 } else { 787 numberClean++; 788 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) { 789 int iColumn = column[j]; 790 if (columnLower[iColumn]!=columnUpper[iColumn]&&!mark[iColumn]){ 791 mark[iColumn]=1; 792 numberNewFixed++; 793 } 794 } 795 } 796 } 797 } 798 delete [] mark; 799 //printf("%d clean, %d old fixed, %d new fixed\n", 800 // numberClean,numberFixed,numberNewFixed); 801 if (someToDoYet&&numberClean<numberClean_ 802 &&numberNewFixed+numberFixed<wantedFixed) { 803 } else if (numberFixed<wantedFixed) { 804 returnCode = 2; 805 } else { 806 } 807 } 808 return returnCode; 809 } 810 double 811 CbcBranchToFixLots::infeasibility(const OsiBranchingInformation * /*info*/, 812 int &preferredWay) const 813 { 814 preferredWay=1; 815 CbcNode * node = model_>currentNode(); 816 int depth; 817 if (node) 818 depth=CoinMax(node>depth(),0); 819 else 820 return 0.0; 821 if (depth_<0) { 822 return 0.0; 823 } else if (depth_>0) { 824 if ((depth%depth_)!=0) 825 return 0.0; 826 } 827 if (djTolerance_!=1.234567) { 828 if (!shallWe()) 829 return 0.0; 830 else 831 return 1.0e20; 832 } else { 833 // See if 3 in same row and sum <FIX_IF_LESS? 834 int numberRows = matrixByRow_.getNumRows(); 835 const double * solution = model_>testSolution(); 836 const int * column = matrixByRow_.getIndices(); 837 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 838 const int * rowLength = matrixByRow_.getVectorLengths(); 839 double bestSum=1.0; 840 int nBest=1; 835 // See if 3 in same row and sum <FIX_IF_LESS? 836 int numberRows = matrixByRow_.getNumRows(); 837 const double * solution = model_>testSolution(); 838 const int * column = matrixByRow_.getIndices(); 839 const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts(); 840 const int * rowLength = matrixByRow_.getVectorLengths(); 841 double bestSum = 1.0; 842 int nBest = 1; 843 OsiSolverInterface * solver = model_>solver(); 844 for (int i = 0; i < numberRows; i++) { 845 int numberUnsatisfied = 0; 846 double sum = 0.0; 847 for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { 848 int iColumn = column[j]; 849 if (solver>isInteger(iColumn)) { 850 double solValue = solution[iColumn]; 851 if (solValue > 1.0e5 && solValue < FIX_IF_LESS) { 852 numberUnsatisfied++; 853 sum += solValue; 854 } 855 } 856 } 857 if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) { 858 // possible 859 if (numberUnsatisfied > nBest  860 (numberUnsatisfied == nBest && sum < bestSum)) { 861 nBest = numberUnsatisfied; 862 bestSum = sum; 863 } 864 } 865 } 866 if (nBest > 0) 867 return 1.0e20; 868 else 869 return 0.0; 870 } 871 } 872 // Redoes data when sequence numbers change 873 void 874 CbcBranchToFixLots::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns) 875 { 876 model_ = model; 877 if (mark_) { 878 OsiSolverInterface * solver = model_>solver(); 879 int numberColumnsNow = solver>getNumCols(); 880 char * temp = new char[numberColumnsNow]; 881 memset(temp, 0, numberColumnsNow); 882 for (int i = 0; i < numberColumns; i++) { 883 int j = originalColumns[i]; 884 temp[i] = mark_[j]; 885 } 886 delete [] mark_; 887 mark_ = temp; 888 } 841 889 OsiSolverInterface * solver = model_>solver(); 842 for (int i=0;i<numberRows;i++) { 843 int numberUnsatisfied=0; 844 double sum=0.0; 845 for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) { 846 int iColumn = column[j]; 847 if (solver>isInteger(iColumn)) { 848 double solValue = solution[iColumn]; 849 if (solValue>1.0e5&&solValue<FIX_IF_LESS) { 850 numberUnsatisfied++; 851 sum += solValue; 852 } 853 } 854 } 855 if (numberUnsatisfied>=3&&sum<FIX_IF_LESS) { 856 // possible 857 if (numberUnsatisfied>nBest 858 (numberUnsatisfied==nBest&&sum<bestSum)) { 859 nBest=numberUnsatisfied; 860 bestSum=sum; 861 } 862 } 863 } 864 if (nBest>0) 865 return 1.0e20; 866 else 867 return 0.0; 868 } 869 } 870 // Redoes data when sequence numbers change 871 void 872 CbcBranchToFixLots::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns) 873 { 874 model_=model; 875 if (mark_) { 876 OsiSolverInterface * solver = model_>solver(); 877 int numberColumnsNow = solver>getNumCols(); 878 char * temp = new char[numberColumnsNow]; 879 memset(temp,0,numberColumnsNow); 880 for (int i=0;i<numberColumns;i++) { 881 int j = originalColumns[i]; 882 temp[i]=mark_[j]; 883 } 884 delete [] mark_; 885 mark_=temp; 886 } 887 OsiSolverInterface * solver = model_>solver(); 888 matrixByRow_ = *solver>getMatrixByRow(); 890 matrixByRow_ = *solver>getMatrixByRow(); 889 891 } 890 892 … … 892 894 */ 893 895 CbcBranchAllDifferent::CbcBranchAllDifferent () 894 : CbcBranchCut(),895 numberInSet_(0),896 which_(NULL)896 : CbcBranchCut(), 897 numberInSet_(0), 898 which_(NULL) 897 899 { 898 900 } 899 901 900 902 /* Useful constructor  passed set of variables 901 */ 903 */ 902 904 CbcBranchAllDifferent::CbcBranchAllDifferent (CbcModel * model, int numberInSet, 903 904 : CbcBranchCut(model)905 { 906 numberInSet_=numberInSet;907 which_ = CoinCopyOfArray(members,numberInSet_);908 } 909 // Copy constructor 905 const int * members) 906 : CbcBranchCut(model) 907 { 908 numberInSet_ = numberInSet; 909 which_ = CoinCopyOfArray(members, numberInSet_); 910 } 911 // Copy constructor 910 912 CbcBranchAllDifferent::CbcBranchAllDifferent ( const CbcBranchAllDifferent & rhs) 911 :CbcBranchCut(rhs)912 { 913 numberInSet_=rhs.numberInSet_;914 which_ = CoinCopyOfArray(rhs.which_,numberInSet_);913 : CbcBranchCut(rhs) 914 { 915 numberInSet_ = rhs.numberInSet_; 916 which_ = CoinCopyOfArray(rhs.which_, numberInSet_); 915 917 } 916 918 … … 919 921 CbcBranchAllDifferent::clone() const 920 922 { 921 return new CbcBranchAllDifferent(*this); 922 } 923 924 // Assignment operator 925 CbcBranchAllDifferent & 926 CbcBranchAllDifferent::operator=( const CbcBranchAllDifferent& rhs) 927 { 928 if (this!=&rhs) { 929 CbcBranchCut::operator=(rhs); 923 return new CbcBranchAllDifferent(*this); 924 } 925 926 // Assignment operator 927 CbcBranchAllDifferent & 928 CbcBranchAllDifferent::operator=( const CbcBranchAllDifferent & rhs) 929 { 930 if (this != &rhs) { 931 CbcBranchCut::operator=(rhs); 932 delete [] which_; 933 numberInSet_ = rhs.numberInSet_; 934 which_ = CoinCopyOfArray(rhs.which_, numberInSet_); 935 } 936 return *this; 937 } 938 939 // Destructor 940 CbcBranchAllDifferent::~CbcBranchAllDifferent () 941 { 930 942 delete [] which_; 931 numberInSet_=rhs.numberInSet_; 932 which_ = CoinCopyOfArray(rhs.which_,numberInSet_); 933 } 934 return *this; 935 } 936 937 // Destructor 938 CbcBranchAllDifferent::~CbcBranchAllDifferent () 939 { 940 delete [] which_; 941 } 942 CbcBranchingObject * 943 } 944 CbcBranchingObject * 943 945 CbcBranchAllDifferent::createCbcBranch(OsiSolverInterface * /*solver*/ 944 ,const OsiBranchingInformation * /*info*/,945 int /*way*/) 946 { 947 // by default way must be 1948 //assert (way==1);949 const double * solution = model_>testSolution();950 double * values = new double[numberInSet_];951 int * which = new int[numberInSet_];952 int i;953 for (i=0;i<numberInSet_;i++) {954 int iColumn = which_[i];955 values[i]=solution[iColumn];956 which[i]=iColumn;957 }958 CoinSort_2(values,values+numberInSet_,which);959 double last = 1.0;960 double closest=1.0;961 int worst=1;962 for (i=0;i<numberInSet_;i++) {963 if (values[i]last<closest) {964 closest=values[i]last;965 worst=i1;966 }967 last=values[i];968 }969 assert (closest<=0.99999);970 OsiRowCut down;971 down.setLb(COIN_DBL_MAX);972 down.setUb(1.0);973 int pair[2];974 double elements[]={1.0,1.0};975 pair[0]=which[worst];976 pair[1]=which[worst+1];977 delete [] values;978 delete [] which;979 down.setRow(2,pair,elements);980 // up is same  just with rhs changed981 OsiRowCut up = down;982 up.setLb(1.0);983 up.setUb(COIN_DBL_MAX);984 // Say is not a fix type branch985 CbcCutBranchingObject * newObject =986 new CbcCutBranchingObject(model_,down,up,false);987 if (model_>messageHandler()>logLevel()>1)988 printf("creating cut in CbcBranchCut\n");989 return newObject;990 } 991 double 946 , const OsiBranchingInformation * /*info*/, 947 int /*way*/) 948 { 949 // by default way must be 1 950 //assert (way==1); 951 const double * solution = model_>testSolution(); 952 double * values = new double[numberInSet_]; 953 int * which = new int[numberInSet_]; 954 int i; 955 for (i = 0; i < numberInSet_; i++) { 956 int iColumn = which_[i]; 957 values[i] = solution[iColumn]; 958 which[i] = iColumn; 959 } 960 CoinSort_2(values, values + numberInSet_, which); 961 double last = 1.0; 962 double closest = 1.0; 963 int worst = 1; 964 for (i = 0; i < numberInSet_; i++) { 965 if (values[i]  last < closest) { 966 closest = values[i]  last; 967 worst = i  1; 968 } 969 last = values[i]; 970 } 971 assert (closest <= 0.99999); 972 OsiRowCut down; 973 down.setLb(COIN_DBL_MAX); 974 down.setUb(1.0); 975 int pair[2]; 976 double elements[] = {1.0, 1.0}; 977 pair[0] = which[worst]; 978 pair[1] = which[worst+1]; 979 delete [] values; 980 delete [] which; 981 down.setRow(2, pair, elements); 982 // up is same  just with rhs changed 983 OsiRowCut up = down; 984 up.setLb(1.0); 985 up.setUb(COIN_DBL_MAX); 986 // Say is not a fix type branch 987 CbcCutBranchingObject * newObject = 988 new CbcCutBranchingObject(model_, down, up, false); 989 if (model_>messageHandler()>logLevel() > 1) 990 printf("creating cut in CbcBranchCut\n"); 991 return newObject; 992 } 993 double 992 994 CbcBranchAllDifferent::infeasibility(const OsiBranchingInformation * /*info*/, 993 994 { 995 preferredWay=1;996 //OsiSolverInterface * solver = model_>solver();997 const double * solution = model_>testSolution();998 //const double * lower = solver>getColLower();999 //const double * upper = solver>getColUpper();1000 double * values = new double[numberInSet_];1001 int i;1002 for (i=0;i<numberInSet_;i++) {1003 int iColumn = which_[i];1004 values[i]=solution[iColumn];1005 }1006 std::sort(values,values+numberInSet_);1007 double last = 1.0;1008 double closest=1.0;1009 for (i=0;i<numberInSet_;i++) {1010 if (values[i]last<closest) {1011 closest=values[i]last;1012 }1013 last=values[i];1014 }1015 delete [] values;1016 if (closest>0.99999)1017 return 0.0;1018 else1019 return 0.5*(1.0closest);1020 } 995 int &preferredWay) const 996 { 997 preferredWay = 1; 998 //OsiSolverInterface * solver = model_>solver(); 999 const double * solution = model_>testSolution(); 1000 //const double * lower = solver>getColLower(); 1001 //const double * upper = solver>getColUpper(); 1002 double * values = new double[numberInSet_]; 1003 int i; 1004 for (i = 0; i < numberInSet_; i++) { 1005 int iColumn = which_[i]; 1006 values[i] = solution[iColumn]; 1007 } 1008 std::sort(values, values + numberInSet_); 1009 double last = 1.0; 1010 double closest = 1.0; 1011 for (i = 0; i < numberInSet_; i++) { 1012 if (values[i]  last < closest) { 1013 closest = values[i]  last; 1014 } 1015 last = values[i]; 1016 } 1017 delete [] values; 1018 if (closest > 0.99999) 1019 return 0.0; 1020 else 1021 return 0.5*(1.0  closest); 1022 }
Note: See TracChangeset
for help on using the changeset viewer.