 Timestamp:
 Dec 8, 2009 7:23:08 PM (12 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

branches/sandbox/Cbc/src/CbcSolver.cpp
r1377 r1381 49 49 #define CBCVERSION "2.4.01" 50 50 #endif 51 //#define ORBITAL 52 #ifdef ORBITAL 53 #include "CbcOrbital.hpp" 54 #endif 51 55 //#define USER_HAS_FAKE_CLP 52 56 //#define USER_HAS_FAKE_CBC 53 54 57 //#define CLP_MALLOC_STATISTICS 55 56 58 #ifdef CLP_MALLOC_STATISTICS 57 59 #include <malloc.h> … … 76 78 } 77 79 } 78 # 80 #ifdef DEBUG_MALLOC 79 81 void *p; 80 82 if (malloc_counts_on) … … 82 84 else 83 85 p = malloc(size); 84 # 86 #else 85 87 void * p = malloc(size); 86 # 88 #endif 87 89 //char * xx = (char *) p; 88 90 //memset(xx,0,size); … … 93 95 void operator delete (void *p) throw() 94 96 { 95 # 97 #ifdef DEBUG_MALLOC 96 98 if (malloc_counts_on) 97 99 stolen_from_ekk_freeBase(p); 98 100 else 99 101 free(p); 100 # 102 #else 101 103 free(p); 102 # 104 #endif 103 105 } 104 106 static void malloc_stats2() … … 114 116 // print results 115 117 } 116 #else //CLP_MALLOC_STATISTICS118 #else 117 119 //void stolen_from_ekk_memory(void * dummy,int type) 118 120 //{ 119 121 //} 120 122 //bool malloc_counts_on=false; 121 #endif //CLP_MALLOC_STATISTICS 122 123 #endif 123 124 //#define DMALLOC 124 125 #ifdef DMALLOC 125 126 #include "dmalloc.h" 126 127 #endif 127 128 128 #ifdef WSSMP_BARRIER 129 129 #define FOREIGN_BARRIER 130 130 #endif 131 132 131 #ifdef UFL_BARRIER 133 132 #define FOREIGN_BARRIER 134 133 #endif 135 136 134 #ifdef TAUCS_BARRIER 137 135 #define FOREIGN_BARRIER 138 136 #endif 139 140 137 static int initialPumpTune = 1; 141 138 #include "CoinWarmStartBasis.hpp" … … 145 142 #include "OsiRowCut.hpp" 146 143 #include "OsiColCut.hpp" 147 148 144 #ifndef COIN_HAS_LINK 149 145 #define COIN_HAS_LINK … … 152 148 #include "CbcLinked.hpp" 153 149 #endif 154 155 150 #include "CglPreProcess.hpp" 156 151 #include "CglCutGenerator.hpp" … … 167 162 #include "CglLandP.hpp" 168 163 #include "CglResidualCapacity.hpp" 169 170 164 #ifdef ZERO_HALF_CUTS 171 165 #include "CglZeroHalf.hpp" … … 197 191 198 192 #include "OsiClpSolverInterface.hpp" 199 193 #include "CbcSolver.hpp" 200 194 //#define IN_BRANCH_AND_BOUND (0x01000000262144) 201 195 #define IN_BRANCH_AND_BOUND (0x0100000026214412810242048) 202 196 //#define IN_BRANCH_AND_BOUND (0x01000000262144128) 197 CbcSolver::CbcSolver() 198 : babModel_(NULL), 199 userFunction_(NULL), 200 statusUserFunction_(NULL), 201 originalSolver_(NULL), 202 originalCoinModel_(NULL), 203 cutGenerator_(NULL), 204 numberUserFunctions_(0), 205 numberCutGenerators_(0), 206 startTime_(CoinCpuTime()), 207 parameters_(NULL), 208 numberParameters_(0), 209 doMiplib_(false), 210 noPrinting_(false), 211 readMode_(1) 212 { 213 callBack_ = new CbcStopNow(); 214 fillParameters(); 215 } 216 CbcSolver::CbcSolver(const OsiClpSolverInterface & solver) 217 : babModel_(NULL), 218 userFunction_(NULL), 219 statusUserFunction_(NULL), 220 originalSolver_(NULL), 221 originalCoinModel_(NULL), 222 cutGenerator_(NULL), 223 numberUserFunctions_(0), 224 numberCutGenerators_(0), 225 startTime_(CoinCpuTime()), 226 parameters_(NULL), 227 numberParameters_(0), 228 doMiplib_(false), 229 noPrinting_(false), 230 readMode_(1) 231 { 232 callBack_ = new CbcStopNow(); 233 model_ = CbcModel(solver); 234 fillParameters(); 235 } 236 CbcSolver::CbcSolver(const CbcModel & solver) 237 : babModel_(NULL), 238 userFunction_(NULL), 239 statusUserFunction_(NULL), 240 originalSolver_(NULL), 241 originalCoinModel_(NULL), 242 cutGenerator_(NULL), 243 numberUserFunctions_(0), 244 numberCutGenerators_(0), 245 startTime_(CoinCpuTime()), 246 parameters_(NULL), 247 numberParameters_(0), 248 doMiplib_(false), 249 noPrinting_(false), 250 readMode_(1) 251 { 252 callBack_ = new CbcStopNow(); 253 model_ = solver; 254 fillParameters(); 255 } 256 CbcSolver::~CbcSolver() 257 { 258 int i; 259 for (i = 0; i < numberUserFunctions_; i++) 260 delete userFunction_[i]; 261 delete [] userFunction_; 262 for (i = 0; i < numberCutGenerators_; i++) 263 delete cutGenerator_[i]; 264 delete [] cutGenerator_; 265 delete [] statusUserFunction_; 266 delete originalSolver_; 267 delete originalCoinModel_; 268 delete babModel_; 269 delete [] parameters_; 270 delete callBack_; 271 } 272 // Copy constructor 273 CbcSolver::CbcSolver ( const CbcSolver & rhs) 274 : model_(rhs.model_), 275 babModel_(NULL), 276 userFunction_(NULL), 277 statusUserFunction_(NULL), 278 numberUserFunctions_(rhs.numberUserFunctions_), 279 startTime_(CoinCpuTime()), 280 parameters_(NULL), 281 numberParameters_(rhs.numberParameters_), 282 doMiplib_(rhs.doMiplib_), 283 noPrinting_(rhs.noPrinting_), 284 readMode_(rhs.readMode_) 285 { 286 fillParameters(); 287 if (rhs.babModel_) 288 babModel_ = new CbcModel(*rhs.babModel_); 289 userFunction_ = new CbcUser * [numberUserFunctions_]; 290 int i; 291 for (i = 0; i < numberUserFunctions_; i++) 292 userFunction_[i] = rhs.userFunction_[i]>clone(); 293 for (i = 0; i < numberParameters_; i++) 294 parameters_[i] = rhs.parameters_[i]; 295 for (i = 0; i < numberCutGenerators_; i++) 296 cutGenerator_[i] = rhs.cutGenerator_[i]>clone(); 297 callBack_ = rhs.callBack_>clone(); 298 originalSolver_ = NULL; 299 if (rhs.originalSolver_) { 300 OsiSolverInterface * temp = rhs.originalSolver_>clone(); 301 originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp); 302 assert (originalSolver_); 303 } 304 originalCoinModel_ = NULL; 305 if (rhs.originalCoinModel_) 306 originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_); 307 } 308 // Assignment operator 309 CbcSolver & 310 CbcSolver::operator=(const CbcSolver & rhs) 311 { 312 if (this != &rhs) { 313 int i; 314 for (i = 0; i < numberUserFunctions_; i++) 315 delete userFunction_[i]; 316 delete [] userFunction_; 317 for (i = 0; i < numberCutGenerators_; i++) 318 delete cutGenerator_[i]; 319 delete [] cutGenerator_; 320 delete [] statusUserFunction_; 321 delete originalSolver_; 322 delete originalCoinModel_; 323 statusUserFunction_ = NULL; 324 delete babModel_; 325 delete [] parameters_; 326 delete callBack_; 327 numberUserFunctions_ = rhs.numberUserFunctions_; 328 startTime_ = rhs.startTime_; 329 numberParameters_ = rhs.numberParameters_; 330 for (i = 0; i < numberParameters_; i++) 331 parameters_[i] = rhs.parameters_[i]; 332 for (i = 0; i < numberCutGenerators_; i++) 333 cutGenerator_[i] = rhs.cutGenerator_[i]>clone(); 334 noPrinting_ = rhs.noPrinting_; 335 readMode_ = rhs.readMode_; 336 doMiplib_ = rhs.doMiplib_; 337 model_ = rhs.model_; 338 if (rhs.babModel_) 339 babModel_ = new CbcModel(*rhs.babModel_); 340 else 341 babModel_ = NULL; 342 userFunction_ = new CbcUser * [numberUserFunctions_]; 343 for (i = 0; i < numberUserFunctions_; i++) 344 userFunction_[i] = rhs.userFunction_[i]>clone(); 345 callBack_ = rhs.callBack_>clone(); 346 originalSolver_ = NULL; 347 if (rhs.originalSolver_) { 348 OsiSolverInterface * temp = rhs.originalSolver_>clone(); 349 originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp); 350 assert (originalSolver_); 351 } 352 originalCoinModel_ = NULL; 353 if (rhs.originalCoinModel_) 354 originalCoinModel_ = new CoinModel(*rhs.originalCoinModel_); 355 } 356 return *this; 357 } 358 // Get int value 359 int CbcSolver::intValue(CbcOrClpParameterType type) const 360 { 361 return parameters_[whichParam(type, numberParameters_, parameters_)].intValue(); 362 } 363 // Set int value 364 void CbcSolver::setIntValue(CbcOrClpParameterType type, int value) 365 { 366 parameters_[whichParam(type, numberParameters_, parameters_)].setIntValue(value); 367 } 368 // Get double value 369 double CbcSolver::doubleValue(CbcOrClpParameterType type) const 370 { 371 return parameters_[whichParam(type, numberParameters_, parameters_)].doubleValue(); 372 } 373 // Set double value 374 void CbcSolver::setDoubleValue(CbcOrClpParameterType type, double value) 375 { 376 parameters_[whichParam(type, numberParameters_, parameters_)].setDoubleValue(value); 377 } 378 // User function (NULL if no match) 379 CbcUser * CbcSolver::userFunction(const char * name) const 380 { 381 int i; 382 for (i = 0; i < numberUserFunctions_; i++) { 383 if (!strcmp(name, userFunction_[i]>name().c_str())) 384 break; 385 } 386 if (i < numberUserFunctions_) 387 return userFunction_[i]; 388 else 389 return NULL; 390 } 391 void CbcSolver::fillParameters() 392 { 393 int maxParam = 200; 394 CbcOrClpParam * parameters = new CbcOrClpParam [maxParam]; 395 numberParameters_ = 0 ; 396 establishParams(numberParameters_, parameters) ; 397 assert (numberParameters_ <= maxParam); 398 parameters_ = new CbcOrClpParam [numberParameters_]; 399 int i; 400 for (i = 0; i < numberParameters_; i++) 401 parameters_[i] = parameters[i]; 402 delete [] parameters; 403 const char dirsep = CoinFindDirSeparator(); 404 std::string directory; 405 std::string dirSample; 406 std::string dirNetlib; 407 std::string dirMiplib; 408 if (dirsep == '/') { 409 directory = "./"; 410 dirSample = "../../Data/Sample/"; 411 dirNetlib = "../../Data/Netlib/"; 412 dirMiplib = "../../Data/miplib3/"; 413 } else { 414 directory = ".\\"; 415 dirSample = "..\\..\\..\\..\\Data\\Sample\\"; 416 dirNetlib = "..\\..\\..\\..\\Data\\Netlib\\"; 417 dirMiplib = "..\\..\\..\\..\\Data\\miplib3\\"; 418 } 419 std::string defaultDirectory = directory; 420 std::string importFile = ""; 421 std::string exportFile = "default.mps"; 422 std::string importBasisFile = ""; 423 std::string importPriorityFile = ""; 424 std::string debugFile = ""; 425 std::string printMask = ""; 426 std::string exportBasisFile = "default.bas"; 427 std::string saveFile = "default.prob"; 428 std::string restoreFile = "default.prob"; 429 std::string solutionFile = "stdout"; 430 std::string solutionSaveFile = "solution.file"; 431 int doIdiot = 1; 432 int outputFormat = 2; 433 int substitution = 3; 434 int dualize = 3; 435 int preSolve = 5; 436 int doSprint = 1; 437 int testOsiParameters = 1; 438 int createSolver = 0; 439 ClpSimplex * lpSolver; 440 OsiClpSolverInterface * clpSolver; 441 if (model_.solver()) { 442 clpSolver = dynamic_cast<OsiClpSolverInterface *> (model_.solver()); 443 assert (clpSolver); 444 lpSolver = clpSolver>getModelPtr(); 445 assert (lpSolver); 446 } else { 447 lpSolver = new ClpSimplex(); 448 clpSolver = new OsiClpSolverInterface(lpSolver, true); 449 createSolver = 1 ; 450 } 451 parameters_[whichParam(CLP_PARAM_ACTION_BASISIN, numberParameters_, parameters_)].setStringValue(importBasisFile); 452 parameters_[whichParam(CBC_PARAM_ACTION_PRIORITYIN, numberParameters_, parameters_)].setStringValue(importPriorityFile); 453 parameters_[whichParam(CLP_PARAM_ACTION_BASISOUT, numberParameters_, parameters_)].setStringValue(exportBasisFile); 454 parameters_[whichParam(CLP_PARAM_ACTION_DEBUG, numberParameters_, parameters_)].setStringValue(debugFile); 455 parameters_[whichParam(CLP_PARAM_ACTION_PRINTMASK, numberParameters_, parameters_)].setStringValue(printMask); 456 parameters_[whichParam(CLP_PARAM_ACTION_DIRECTORY, numberParameters_, parameters_)].setStringValue(directory); 457 parameters_[whichParam(CLP_PARAM_ACTION_DIRSAMPLE, numberParameters_, parameters_)].setStringValue(dirSample); 458 parameters_[whichParam(CLP_PARAM_ACTION_DIRNETLIB, numberParameters_, parameters_)].setStringValue(dirNetlib); 459 parameters_[whichParam(CBC_PARAM_ACTION_DIRMIPLIB, numberParameters_, parameters_)].setStringValue(dirMiplib); 460 parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver>dualBound()); 461 parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver>dualTolerance()); 462 parameters_[whichParam(CLP_PARAM_ACTION_EXPORT, numberParameters_, parameters_)].setStringValue(exportFile); 463 parameters_[whichParam(CLP_PARAM_INT_IDIOT, numberParameters_, parameters_)].setIntValue(doIdiot); 464 parameters_[whichParam(CLP_PARAM_ACTION_IMPORT, numberParameters_, parameters_)].setStringValue(importFile); 465 parameters_[whichParam(CLP_PARAM_DBL_PRESOLVETOLERANCE, numberParameters_, parameters_)].setDoubleValue(1.0e8); 466 int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_); 467 int value = 1; 468 clpSolver>messageHandler()>setLogLevel(1) ; 469 lpSolver>setLogLevel(1); 470 parameters_[iParam].setIntValue(value); 471 iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_); 472 model_.messageHandler()>setLogLevel(value); 473 parameters_[iParam].setIntValue(value); 474 parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver>factorizationFrequency()); 475 parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver>maximumIterations()); 476 parameters_[whichParam(CLP_PARAM_INT_OUTPUTFORMAT, numberParameters_, parameters_)].setIntValue(outputFormat); 477 parameters_[whichParam(CLP_PARAM_INT_PRESOLVEPASS, numberParameters_, parameters_)].setIntValue(preSolve); 478 parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver>perturbation()); 479 parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver>primalTolerance()); 480 parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver>infeasibilityCost()); 481 parameters_[whichParam(CLP_PARAM_ACTION_RESTORE, numberParameters_, parameters_)].setStringValue(restoreFile); 482 parameters_[whichParam(CLP_PARAM_ACTION_SAVE, numberParameters_, parameters_)].setStringValue(saveFile); 483 //parameters_[whichParam(CLP_PARAM_DBL_TIMELIMIT,numberParameters_,parameters_)].setDoubleValue(1.0e8); 484 parameters_[whichParam(CBC_PARAM_DBL_TIMELIMIT_BAB, numberParameters_, parameters_)].setDoubleValue(1.0e8); 485 parameters_[whichParam(CLP_PARAM_ACTION_SOLUTION, numberParameters_, parameters_)].setStringValue(solutionFile); 486 parameters_[whichParam(CLP_PARAM_ACTION_SAVESOL, numberParameters_, parameters_)].setStringValue(solutionSaveFile); 487 parameters_[whichParam(CLP_PARAM_INT_SPRINT, numberParameters_, parameters_)].setIntValue(doSprint); 488 parameters_[whichParam(CLP_PARAM_INT_SUBSTITUTION, numberParameters_, parameters_)].setIntValue(substitution); 489 parameters_[whichParam(CLP_PARAM_INT_DUALIZE, numberParameters_, parameters_)].setIntValue(dualize); 490 parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust()); 491 parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes()); 492 parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong()); 493 parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight)); 494 parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance)); 495 parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement)); 496 parameters_[whichParam(CBC_PARAM_INT_TESTOSI, numberParameters_, parameters_)].setIntValue(testOsiParameters); 497 parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_)].setIntValue(1003); 498 initialPumpTune = 1003; 499 #ifdef CBC_THREAD 500 parameters_[whichParam(CBC_PARAM_INT_THREADS, numberParameters_, parameters_)].setIntValue(0); 501 #endif 502 // Set up likely cut generators and defaults 503 parameters_[whichParam(CBC_PARAM_STR_PREPROCESS, numberParameters_, parameters_)].setCurrentOption("sos"); 504 parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValue(1057); 505 parameters_[whichParam(CBC_PARAM_INT_CUTPASSINTREE, numberParameters_, parameters_)].setIntValue(1); 506 parameters_[whichParam(CBC_PARAM_INT_MOREMIPOPTIONS, numberParameters_, parameters_)].setIntValue(1); 507 parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValue(100); 508 parameters_[whichParam(CBC_PARAM_STR_CUTSSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on"); 509 parameters_[whichParam(CBC_PARAM_STR_HEURISTICSTRATEGY, numberParameters_, parameters_)].setCurrentOption("on"); 510 parameters_[whichParam(CBC_PARAM_STR_NODESTRATEGY, numberParameters_, parameters_)].setCurrentOption("fewest"); 511 parameters_[whichParam(CBC_PARAM_STR_GOMORYCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 512 parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 513 parameters_[whichParam(CBC_PARAM_STR_KNAPSACKCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 514 #ifdef ZERO_HALF_CUTS 515 parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption("off"); 516 #endif 517 parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption("off"); 518 parameters_[whichParam(CBC_PARAM_STR_CLIQUECUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 519 parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 520 parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption("ifmove"); 521 parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption("root"); 522 parameters_[whichParam(CBC_PARAM_STR_LANDPCUTS, numberParameters_, parameters_)].setCurrentOption("off"); 523 parameters_[whichParam(CBC_PARAM_STR_RESIDCUTS, numberParameters_, parameters_)].setCurrentOption("off"); 524 parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].setCurrentOption("on"); 525 parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].setCurrentOption("on"); 526 parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].setCurrentOption("on"); 527 parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].setCurrentOption("on"); 528 parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters_, parameters_)].setCurrentOption("off"); 529 parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters_, parameters_)].setCurrentOption("off"); 530 parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters_, parameters_)].setCurrentOption("off"); 531 parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].setCurrentOption("off"); 532 parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].setCurrentOption("off"); 533 parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].setCurrentOption("off"); 534 parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].setCurrentOption("off"); 535 parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].setCurrentOption("off"); 536 parameters_[whichParam(CBC_PARAM_STR_LOCALTREE, numberParameters_, parameters_)].setCurrentOption("off"); 537 parameters_[whichParam(CBC_PARAM_STR_COSTSTRATEGY, numberParameters_, parameters_)].setCurrentOption("off"); 538 if (createSolver) 539 delete clpSolver; 540 } 203 541 542 /* 543 Initialise a subset of the parameters prior to processing any input from 544 the user. 204 545 546 Why this choice of subset? 547 */ 548 /*! 549 \todo Guard/replace clpspecific code 550 */ 551 void CbcSolver::fillValuesInSolver() 552 { 553 OsiSolverInterface * solver = model_.solver(); 554 OsiClpSolverInterface * clpSolver = 555 dynamic_cast< OsiClpSolverInterface*> (solver); 556 assert (clpSolver); 557 ClpSimplex * lpSolver = clpSolver>getModelPtr(); 205 558 559 /* 560 Why are we reaching into the underlying solver(s) for these settings? 561 Shouldn't CbcSolver have its own defaults, which are then imposed on the 562 underlying solver? 563 564 Coming at if from the other side, if CbcSolver had the capability to use 565 multiple solvers then it definitely makes sense to acquire the defaults from 566 the solver (on the assumption that we haven't processed command line 567 parameters yet, which can then override the defaults). But then it's more of 568 a challenge to avoid solverspecific coding here. 569 */ 570 noPrinting_ = (lpSolver>logLevel() == 0); 571 CoinMessageHandler * generalMessageHandler = clpSolver>messageHandler(); 572 generalMessageHandler>setPrefix(true); 573 574 lpSolver>setPerturbation(50); 575 lpSolver>messageHandler()>setPrefix(false); 576 577 parameters_[whichParam(CLP_PARAM_DBL_DUALBOUND, numberParameters_, parameters_)].setDoubleValue(lpSolver>dualBound()); 578 parameters_[whichParam(CLP_PARAM_DBL_DUALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver>dualTolerance()); 579 /* 580 Why are we doing this? We read the log level from parameters_, set it into 581 the message handlers for cbc and the underlying solver. Then we read the 582 log level back from the handlers and use it to set the values in 583 parameters_! 584 */ 585 int iParam = whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_); 586 int value = parameters_[iParam].intValue(); 587 clpSolver>messageHandler()>setLogLevel(value) ; 588 lpSolver>setLogLevel(value); 589 iParam = whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_); 590 value = parameters_[iParam].intValue(); 591 model_.messageHandler()>setLogLevel(value); 592 parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].setIntValue(model_.logLevel()); 593 parameters_[whichParam(CLP_PARAM_INT_SOLVERLOGLEVEL, numberParameters_, parameters_)].setIntValue(lpSolver>logLevel()); 594 parameters_[whichParam(CLP_PARAM_INT_MAXFACTOR, numberParameters_, parameters_)].setIntValue(lpSolver>factorizationFrequency()); 595 parameters_[whichParam(CLP_PARAM_INT_MAXITERATION, numberParameters_, parameters_)].setIntValue(lpSolver>maximumIterations()); 596 parameters_[whichParam(CLP_PARAM_INT_PERTVALUE, numberParameters_, parameters_)].setIntValue(lpSolver>perturbation()); 597 parameters_[whichParam(CLP_PARAM_DBL_PRIMALTOLERANCE, numberParameters_, parameters_)].setDoubleValue(lpSolver>primalTolerance()); 598 parameters_[whichParam(CLP_PARAM_DBL_PRIMALWEIGHT, numberParameters_, parameters_)].setDoubleValue(lpSolver>infeasibilityCost()); 599 parameters_[whichParam(CBC_PARAM_INT_NUMBERBEFORE, numberParameters_, parameters_)].setIntValue(model_.numberBeforeTrust()); 600 parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].setIntValue(model_.getMaximumNodes()); 601 parameters_[whichParam(CBC_PARAM_INT_STRONGBRANCHING, numberParameters_, parameters_)].setIntValue(model_.numberStrong()); 602 parameters_[whichParam(CBC_PARAM_DBL_INFEASIBILITYWEIGHT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcInfeasibilityWeight)); 603 parameters_[whichParam(CBC_PARAM_DBL_INTEGERTOLERANCE, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcIntegerTolerance)); 604 parameters_[whichParam(CBC_PARAM_DBL_INCREMENT, numberParameters_, parameters_)].setDoubleValue(model_.getDblParam(CbcModel::CbcCutoffIncrement)); 605 } 606 // Add user function 607 void 608 CbcSolver::addUserFunction(CbcUser * function) 609 { 610 CbcUser ** temp = new CbcUser * [numberUserFunctions_+1]; 611 int i; 612 for (i = 0; i < numberUserFunctions_; i++) 613 temp[i] = userFunction_[i]; 614 delete [] userFunction_; 615 userFunction_ = temp; 616 userFunction_[numberUserFunctions_++] = function>clone(); 617 delete [] statusUserFunction_; 618 statusUserFunction_ = NULL; 619 } 620 // Set user call back 621 void 622 CbcSolver::setUserCallBack(CbcStopNow * function) 623 { 624 delete callBack_; 625 callBack_ = function>clone(); 626 } 627 // Copy of model on initial load (will contain output solutions) 628 void 629 CbcSolver::setOriginalSolver(OsiClpSolverInterface * originalSolver) 630 { 631 delete originalSolver_; 632 OsiSolverInterface * temp = originalSolver>clone(); 633 originalSolver_ = dynamic_cast<OsiClpSolverInterface *> (temp); 634 assert (originalSolver_); 635 636 } 637 // Copy of model on initial load 638 void 639 CbcSolver::setOriginalCoinModel(CoinModel * originalCoinModel) 640 { 641 delete originalCoinModel_; 642 originalCoinModel_ = new CoinModel(*originalCoinModel); 643 } 644 // Add cut generator 645 void 646 CbcSolver::addCutGenerator(CglCutGenerator * generator) 647 { 648 CglCutGenerator ** temp = new CglCutGenerator * [numberCutGenerators_+1]; 649 int i; 650 for (i = 0; i < numberCutGenerators_; i++) 651 temp[i] = cutGenerator_[i]; 652 delete [] cutGenerator_; 653 cutGenerator_ = temp; 654 cutGenerator_[numberCutGenerators_++] = generator>clone(); 655 } 656 // User stuff (base class) 657 CbcUser::CbcUser() 658 : coinModel_(NULL), 659 userName_("null") 660 { 661 } 662 CbcUser::~CbcUser() 663 { 664 delete coinModel_; 665 } 666 // Copy constructor 667 CbcUser::CbcUser ( const CbcUser & rhs) 668 { 669 if (rhs.coinModel_) 670 coinModel_ = new CoinModel(*rhs.coinModel_); 671 else 672 coinModel_ = NULL; 673 userName_ = rhs.userName_; 674 } 675 // Assignment operator 676 CbcUser & 677 CbcUser::operator=(const CbcUser & rhs) 678 { 679 if (this != &rhs) { 680 if (rhs.coinModel_) 681 coinModel_ = new CoinModel(*rhs.coinModel_); 682 else 683 coinModel_ = NULL; 684 userName_ = rhs.userName_; 685 } 686 return *this; 687 } 688 /* Updates model_ from babModel_ according to returnMode 689 returnMode  690 0 model and solver untouched  babModel updated 691 1 model updated  just with solution basis etc 692 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing!) 693 */ 694 void 695 CbcSolver::updateModel(ClpSimplex * model2, int returnMode) 696 { 697 if (!returnMode) 698 return; 699 if (returnMode == 2 && babModel_) 700 model_ = *babModel_; 701 if (model2) { 702 // Only continuous valid 703 // update with basis etc 704 // map states 705 /* clp status 706 1  unknown e.g. before solve or if postSolve says not optimal 707 0  optimal 708 1  primal infeasible 709 2  dual infeasible 710 3  stopped on iterations or time 711 4  stopped due to errors 712 5  stopped by event handler (virtual int ClpEventHandler::event()) */ 713 /* cbc status 714 1 before branchAndBound 715 0 finished  check isProvenOptimal or isProvenInfeasible to see if solution found 716 (or check value of best solution) 717 1 stopped  on maxnodes, maxsols, maxtime 718 2 difficulties so run was abandoned 719 (5 event user programmed event occurred) */ 720 /* clp secondary status of problem  may get extended 721 0  none 722 1  primal infeasible because dual limit reached OR probably primal 723 infeasible but can't prove it (main status 4) 724 2  scaled problem optimal  unscaled problem has primal infeasibilities 725 3  scaled problem optimal  unscaled problem has dual infeasibilities 726 4  scaled problem optimal  unscaled problem has primal and dual infeasibilities 727 5  giving up in primal with flagged variables 728 6  failed due to empty problem check 729 7  postSolve says not optimal 730 8  failed due to bad element check 731 9  status was 3 and stopped on time 732 100 up  translation of enum from ClpEventHandler 733 */ 734 /* cbc secondary status of problem 735 1 unset (status_ will also be 1) 736 0 search completed with solution 737 1 linear relaxation not feasible (or worse than cutoff) 738 2 stopped on gap 739 3 stopped on nodes 740 4 stopped on time 741 5 stopped on user event 742 6 stopped on solutions 743 7 linear relaxation unbounded 744 */ 745 int iStatus = model2>status(); 746 int iStatus2 = model2>secondaryStatus(); 747 if (iStatus == 0) { 748 iStatus2 = 0; 749 } else if (iStatus == 1) { 750 iStatus = 0; 751 iStatus2 = 1; // say infeasible 752 } else if (iStatus == 2) { 753 iStatus = 0; 754 iStatus2 = 7; // say unbounded 755 } else if (iStatus == 3) { 756 iStatus = 1; 757 if (iStatus2 == 9) 758 iStatus2 = 4; 759 else 760 iStatus2 = 3; // Use nodes  as closer than solutions 761 } else if (iStatus == 4) { 762 iStatus = 2; // difficulties 763 iStatus2 = 0; 764 } 765 model_.setProblemStatus(iStatus); 766 model_.setSecondaryStatus(iStatus2); 767 OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver()); 768 ClpSimplex * lpSolver = clpSolver>getModelPtr(); 769 if (model2 != lpSolver) { 770 lpSolver>moveInfo(*model2); 771 } 772 clpSolver>setWarmStart(NULL); // synchronize bases 773 if (originalSolver_) { 774 ClpSimplex * lpSolver2 = originalSolver_>getModelPtr(); 775 assert (model2 != lpSolver2); 776 lpSolver2>moveInfo(*model2); 777 originalSolver_>setWarmStart(NULL); // synchronize bases 778 } 779 } else if (returnMode == 1) { 780 OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model_.solver()); 781 ClpSimplex * lpSolver = clpSolver>getModelPtr(); 782 if (babModel_) { 783 model_.moveInfo(*babModel_); 784 int numberColumns = babModel_>getNumCols(); 785 if (babModel_>bestSolution()) 786 model_.setBestSolution(babModel_>bestSolution(), numberColumns, babModel_>getMinimizationObjValue()); 787 OsiClpSolverInterface * clpSolver1 = dynamic_cast< OsiClpSolverInterface*> (babModel_>solver()); 788 ClpSimplex * lpSolver1 = clpSolver1>getModelPtr(); 789 if (lpSolver1 != lpSolver && model_.bestSolution()) { 790 lpSolver>moveInfo(*lpSolver1); 791 } 792 } 793 clpSolver>setWarmStart(NULL); // synchronize bases 794 } 795 if (returnMode == 2) { 796 delete babModel_; 797 babModel_ = NULL; 798 } 799 } 800 // Stop now stuff (base class) 801 CbcStopNow::CbcStopNow() 802 { 803 } 804 CbcStopNow::~CbcStopNow() 805 { 806 } 807 // Copy constructor 808 CbcStopNow::CbcStopNow ( const CbcStopNow & ) 809 { 810 } 811 // Assignment operator 812 CbcStopNow & 813 CbcStopNow::operator=(const CbcStopNow & rhs) 814 { 815 if (this != &rhs) { 816 } 817 return *this; 818 } 819 // Clone 820 CbcStopNow * 821 CbcStopNow::clone() const 822 { 823 return new CbcStopNow(*this); 824 } 825 #ifndef NEW_STYLE_SOLVER 826 #define NEW_STYLE_SOLVER 0 827 #endif 206 828 #ifdef CPX_KEEP_RESULTS 207 829 #define CBC_OTHER_SOLVER 1 208 830 #endif 209 210 831 #ifdef COIN_HAS_CPX 211 832 #include "OsiCpxSolverInterface.hpp" 212 833 #endif 213 214 834 #ifdef CBC_OTHER_SOLVER 215 835 #if CBC_OTHER_SOLVER==1 216 836 #include "OsiCpxSolverInterface.hpp" 217 837 #endif 218 #endif 219 838 #undef NEW_STYLE_SOLVER 839 #define NEW_STYLE_SOLVER 0 840 #endif 220 841 #ifdef COIN_HAS_ASL 221 842 #include "Cbc_ampl.h" 222 843 #endif 223 224 844 static double totalTime = 0.0; 225 845 static void statistics(ClpSimplex * originalModel, ClpSimplex * model); … … 227 847 std::string & check); 228 848 static void generateCode(CbcModel * model, const char * fileName, int type, int preProcess); 229 230 // dummy fake main programs for UserClp and UserCbc 849 //#ifdef NDEBUG 850 //#undef NDEBUG 851 //#endif 852 // define (probably dummy fake main programs for UserClp and UserCbc 231 853 void fakeMain (ClpSimplex & model, OsiSolverInterface & osiSolver, CbcModel & babSolver); 232 854 void fakeMain2 (ClpSimplex & model, OsiClpSolverInterface & osiSolver, int options); 233 855 234 856 // Allow for interrupts 235 // But is this threadsafe ? (so switched off by option)857 // But is this threadsafe ? (so switched off by option) 236 858 237 859 #include "CoinSignal.hpp" … … 247 869 } 248 870 } 249 250 871 //#define CBC_SIG_TRAP 251 872 #ifdef CBC_SIG_TRAP … … 258 879 } 259 880 #endif 260 881 #if 0 882 /* Updates model_ from babModel_ according to returnMode 883 returnMode  884 0 model and solver untouched 885 1 model updated  just with solution basis etc 886 */ 887 static void updateModel(CbcModel & model_, int returnMode) 888 { 889 if (!returnMode) 890 return; 891 assert (returnMode == 1); 892 } 893 #endif 261 894 int CbcOrClpRead_mode = 1; 262 895 FILE * CbcOrClpReadCommand = stdin; 263 896 extern int CbcOrClpEnvironmentIndex; 264 897 static bool noPrinting = false; 265 266 898 #ifndef CBC_OTHER_SOLVER 899 #if NEW_STYLE_SOLVER 900 int * CbcSolver::analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment, 901 bool changeInt, CoinMessageHandler * generalMessageHandler) 902 #else 267 903 static int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment, 268 904 bool changeInt, CoinMessageHandler * generalMessageHandler) 905 #endif 269 906 { 907 #if NEW_STYLE_SOLVER==0 270 908 bool noPrinting_ = noPrinting; 909 #endif 271 910 OsiSolverInterface * solver = solverMod>clone(); 272 911 char generalPrint[200]; … … 566 1205 } 567 1206 } 568 #endif // ifndef CBC_OTHER_SOLVER 569 1207 #endif 1208 #if 1 1209 #include "ClpSimplexOther.hpp" 570 1210 571 1211 // Crunch down model … … 573 1213 crunchIt(ClpSimplex * model) 574 1214 { 1215 #if 0 1216 model>dual(); 1217 #else 575 1218 int numberColumns = model>numberColumns(); 576 1219 int numberRows = model>numberRows(); … … 605 1248 delete [] whichRow; 606 1249 delete [] whichColumn; 1250 #endif 607 1251 } 608 609 1252 /* 610 1253 On input … … 618 1261 2 cleanup afterwards if using 2 619 1262 On output  number fixed 620 */621 /*622 A heuristic applicable to resource allocation problems where you can attain623 feasibility by adding more resource. Increases resources until a feasible624 solution is found, with some eye to the cost. Applicationspecific. Should625 be given a hard look with an eye to developing a rule of thumb for applicability.626  lh, 091208 627 1263 */ 628 1264 static OsiClpSolverInterface * … … 1665 2301 return NULL; 1666 2302 } 1667 2303 #endif 1668 2304 #ifdef COIN_HAS_LINK 1669 2305 /* Returns OsiSolverInterface (User should delete) … … 2165 2801 } 2166 2802 } 2167 #endif //COIN_HAS_LINK 2168 2169 /* 2170 Debug checks on special ordered sets. 2171 */ 2803 #if NEW_STYLE_SOLVER 2804 // Fills in original solution (coinModel length) 2805 static void 2806 afterKnapsack(const CoinModel & coinModel2, const int * whichColumn, const int * knapsackStart, 2807 const int * knapsackRow, int numberKnapsack, 2808 const double * knapsackSolution, double * solution, int logLevel) 2809 { 2810 CoinModel coinModel = coinModel2; 2811 int numberColumns = coinModel.numberColumns(); 2812 int iColumn; 2813 // associate all columns to stop possible error messages 2814 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 2815 coinModel.associateElement(coinModel.columnName(iColumn), 1.0); 2816 } 2817 CoinZeroN(solution, numberColumns); 2818 int nCol = knapsackStart[0]; 2819 for (iColumn = 0; iColumn < nCol; iColumn++) { 2820 int jColumn = whichColumn[iColumn]; 2821 solution[jColumn] = knapsackSolution[iColumn]; 2822 } 2823 int * buildRow = new int [numberColumns]; // wild overkill 2824 double * buildElement = new double [numberColumns]; 2825 int iKnapsack; 2826 for (iKnapsack = 0; iKnapsack < numberKnapsack; iKnapsack++) { 2827 int k = 1; 2828 double value = 0.0; 2829 for (iColumn = knapsackStart[iKnapsack]; iColumn < knapsackStart[iKnapsack+1]; iColumn++) { 2830 if (knapsackSolution[iColumn] > 1.0e5) { 2831 if (k >= 0) { 2832 printf("Two nonzero values for knapsack %d at (%d,%g) and (%d,%g)\n", iKnapsack, 2833 k, knapsackSolution[k], iColumn, knapsackSolution[iColumn]); 2834 abort(); 2835 } 2836 k = iColumn; 2837 value = floor(knapsackSolution[iColumn] + 0.5); 2838 assert (fabs(value  knapsackSolution[iColumn]) < 1.0e5); 2839 } 2840 } 2841 if (k >= 0) { 2842 int iRow = knapsackRow[iKnapsack]; 2843 int nCreate = 10000; 2844 int nel = coinModel.expandKnapsack(iRow, nCreate, NULL, NULL, buildRow, buildElement, k  knapsackStart[iKnapsack]); 2845 assert (nel); 2846 if (logLevel > 0) 2847 printf("expanded column %d in knapsack %d has %d nonzero entries:\n", 2848 k  knapsackStart[iKnapsack], iKnapsack, nel); 2849 for (int i = 0; i < nel; i++) { 2850 int jColumn = buildRow[i]; 2851 double value = buildElement[i]; 2852 if (logLevel > 0) 2853 printf("%d  original %d has value %g\n", i, jColumn, value); 2854 solution[jColumn] = value; 2855 } 2856 } 2857 } 2858 delete [] buildRow; 2859 delete [] buildElement; 2860 #if 0 2861 for (iColumn = 0; iColumn < numberColumns; iColumn++) { 2862 if (solution[iColumn] > 1.0e5 && coinModel.isInteger(iColumn)) 2863 printf("%d %g\n", iColumn, solution[iColumn]); 2864 } 2865 #endif 2866 } 2867 #endif 2868 #endif 2869 #if 0 2870 static int outDupRow(OsiSolverInterface * solver) 2871 { 2872 CglDuplicateRow dupCuts(solver); 2873 CglTreeInfo info; 2874 info.level = 0; 2875 info.pass = 0; 2876 int numberRows = solver>getNumRows(); 2877 info.formulation_rows = numberRows; 2878 info.inTree = false; 2879 info.strengthenRow = NULL; 2880 info.pass = 0; 2881 OsiCuts cs; 2882 dupCuts.generateCuts(*solver, cs, info); 2883 const int * duplicate = dupCuts.duplicate(); 2884 // Get rid of duplicate rows 2885 int * which = new int[numberRows]; 2886 int numberDrop = 0; 2887 for (int iRow = 0; iRow < numberRows; iRow++) { 2888 if (duplicate[iRow] == 2  duplicate[iRow] >= 0) 2889 which[numberDrop++] = iRow; 2890 } 2891 if (numberDrop) { 2892 solver>deleteRows(numberDrop, which); 2893 } 2894 delete [] which; 2895 // see if we have any column cuts 2896 int numberColumnCuts = cs.sizeColCuts() ; 2897 const double * columnLower = solver>getColLower(); 2898 const double * columnUpper = solver>getColUpper(); 2899 for (int k = 0; k < numberColumnCuts; k++) { 2900 OsiColCut * thisCut = cs.colCutPtr(k) ; 2901 const CoinPackedVector & lbs = thisCut>lbs() ; 2902 const CoinPackedVector & ubs = thisCut>ubs() ; 2903 int j ; 2904 int n ; 2905 const int * which ; 2906 const double * values ; 2907 n = lbs.getNumElements() ; 2908 which = lbs.getIndices() ; 2909 values = lbs.getElements() ; 2910 for (j = 0; j < n; j++) { 2911 int iColumn = which[j] ; 2912 if (values[j] > columnLower[iColumn]) 2913 solver>setColLower(iColumn, values[j]) ; 2914 } 2915 n = ubs.getNumElements() ; 2916 which = ubs.getIndices() ; 2917 values = ubs.getElements() ; 2918 for (j = 0; j < n; j++) { 2919 int iColumn = which[j] ; 2920 if (values[j] < columnUpper[iColumn]) 2921 solver>setColUpper(iColumn, values[j]) ; 2922 } 2923 } 2924 return numberDrop; 2925 } 2926 #endif 2172 2927 #ifdef COIN_DEVELOP 2173 2928 void checkSOS(CbcModel * babModel, const OsiSolverInterface * solver) … … 2266 3021 } 2267 3022 } 2268 #endif // COIN_DEVELOP3023 #endif 2269 3024 } 2270 2271 static int dummyCallBack(CbcModel * /*model*/, int /*whereFrom*/) 2272 { 2273 return 0; 2274 } 2275 2276 /* 2277 Various overloads of callCbc1, in rough order, followed by the main definition. 2278 */ 2279 2280 int callCbc1(const std::string input2, CbcModel & babSolver) 2281 { 2282 char * input3 = CoinStrdup(input2.c_str()); 2283 int returnCode = callCbc1(input3, babSolver); 2284 free(input3); 2285 return returnCode; 2286 } 2287 2288 int callCbc1(const char * input2, CbcModel & model) 2289 { 2290 return callCbc1(input2, model, dummyCallBack); 2291 } 2292 2293 int callCbc1(const std::string input2, CbcModel & babSolver, int callBack(CbcModel * currentSolver, int whereFrom)) 2294 { 2295 char * input3 = CoinStrdup(input2.c_str()); 2296 int returnCode = callCbc1(input3, babSolver, callBack); 2297 free(input3); 2298 return returnCode; 2299 } 2300 3025 #if NEW_STYLE_SOLVER==0 2301 3026 int callCbc1(const char * input2, CbcModel & model, int callBack(CbcModel * currentSolver, int whereFrom)) 2302 3027 { … … 2356 3081 return returnCode; 2357 3082 } 2358 2359 3083 int callCbc1(const std::string input2, CbcModel & babSolver) 3084 { 3085 char * input3 = CoinStrdup(input2.c_str()); 3086 int returnCode = callCbc1(input3, babSolver); 3087 free(input3); 3088 return returnCode; 3089 } 2360 3090 int callCbc(const char * input2, CbcModel & babSolver) 2361 3091 { … … 2398 3128 return returnCode; 2399 3129 } 2400 3130 static int dummyCallBack(CbcModel * /*model*/, int /*whereFrom*/) 3131 { 3132 return 0; 3133 } 2401 3134 int CbcMain1 (int argc, const char *argv[], 2402 3135 CbcModel & model) 2403 3136 { 2404 3137 return CbcMain1(argc, argv, model, dummyCallBack); 3138 } 3139 int callCbc1(const std::string input2, CbcModel & babSolver, int callBack(CbcModel * currentSolver, int whereFrom)) 3140 { 3141 char * input3 = CoinStrdup(input2.c_str()); 3142 int returnCode = callCbc1(input3, babSolver, callBack); 3143 free(input3); 3144 return returnCode; 3145 } 3146 int callCbc1(const char * input2, CbcModel & model) 3147 { 3148 return callCbc1(input2, model, dummyCallBack); 2405 3149 } 2406 3150 int CbcMain (int argc, const char *argv[], … … 2559 3303 parameters[whichParam(CBC_PARAM_STR_COSTSTRATEGY, numberParameters, parameters)].setCurrentOption("off"); 2560 3304 } 3305 #endif 2561 3306 /* 1  add heuristics to model 2562 3307 2  do heuristics (and set cutoff and best solution) 2563 3308 3  for miplib test so skip some 2564 3309 */ 3310 #if NEW_STYLE_SOLVER==0 2565 3311 static int doHeuristics(CbcModel * model, int type) 3312 #else 3313 int 3314 CbcSolver::doHeuristics(CbcModel * model, int type) 3315 #endif 2566 3316 { 3317 #if NEW_STYLE_SOLVER==0 2567 3318 CbcOrClpParam * parameters_ = parameters; 2568 3319 int numberParameters_ = numberParameters; 2569 3320 bool noPrinting_ = noPrinting; 3321 #endif 2570 3322 char generalPrint[10000]; 2571 3323 CoinMessages generalMessages = model>messages(); … … 2750 3502 } 2751 3503 heuristic4.setHeuristicName("feasibility pump"); 3504 //#define ROLF 3505 #ifdef ROLF 3506 CbcHeuristicFPump pump(*model); 3507 pump.setMaximumTime(60); 3508 pump.setMaximumPasses(100); 3509 pump.setMaximumRetries(1); 3510 pump.setFixOnReducedCosts(0); 3511 pump.setHeuristicName("Feasibility pump"); 3512 pump.setFractionSmall(1.0); 3513 pump.setWhen(13); 3514 model>addHeuristic(&pump); 3515 #else 2752 3516 model>addHeuristic(&heuristic4); 3517 #endif 2753 3518 } 2754 3519 if (useRounding >= type && useRounding >= kType && useRounding <= kType + 1) { … … 3023 3788 std::string& dirMiplib, int testSwitch, 3024 3789 double * stuff); 3025 3790 #if NEW_STYLE_SOLVER 3791 /* This takes a list of commands, does "stuff" and returns 3792 returnMode  3793 0 model and solver untouched  babModel updated 3794 1 model updated  just with solution basis etc 3795 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) 3796 */ 3797 int 3798 CbcSolver::solve(const char * input2, int returnMode) 3799 { 3800 char * input = CoinStrdup(input2); 3801 int length = strlen(input); 3802 bool blank = input[0] == '0'; 3803 int n = blank ? 0 : 1; 3804 for (int i = 0; i < length; i++) { 3805 if (blank) { 3806 // look for next non blank 3807 if (input[i] == ' ') { 3808 continue; 3809 } else { 3810 n++; 3811 blank = false; 3812 } 3813 } else { 3814 // look for next blank 3815 if (input[i] != ' ') { 3816 continue; 3817 } else { 3818 blank = true; 3819 } 3820 } 3821 } 3822 char ** argv = new char * [n+2]; 3823 argv[0] = CoinStrdup("cbc"); 3824 int i = 0; 3825 while (input[i] == ' ') 3826 i++; 3827 for (int j = 0; j < n; j++) { 3828 int saveI = i; 3829 for (; i < length; i++) { 3830 // look for next blank 3831 if (input[i] != ' ') { 3832 continue; 3833 } else { 3834 break; 3835 } 3836 } 3837 char save = input[i]; 3838 input[i] = '\0'; 3839 argv[j+1] = CoinStrdup(input + saveI); 3840 input[i] = save; 3841 while (input[i] == ' ') 3842 i++; 3843 } 3844 argv[n+1] = CoinStrdup("quit"); 3845 free(input); 3846 int returnCode = solve(n + 2, const_cast<const char **>(argv), returnMode); 3847 for (int k = 0; k < n + 2; k++) 3848 free(argv[k]); 3849 delete [] argv; 3850 return returnCode; 3851 } 3852 #endif 3026 3853 /* Meaning of whereFrom: 3027 3854 1 after initial solve by dualsimplex etc … … 3033 3860 */ 3034 3861 3862 #if NEW_STYLE_SOLVER==0 3035 3863 int CbcMain1 (int argc, const char *argv[], 3036 3864 CbcModel & model, 3037 3865 int callBack(CbcModel * currentSolver, int whereFrom)) 3866 #else 3867 /* This takes a list of commands, does "stuff" and returns 3868 returnMode  3869 0 model and solver untouched  babModel updated 3870 1 model updated  just with solution basis etc 3871 2 model updated i.e. as babModel (babModel NULL) 3872 */ 3873 int 3874 CbcSolver::solve (int argc, const char *argv[], int returnMode) 3875 #endif 3038 3876 { 3877 #if NEW_STYLE_SOLVER==0 3039 3878 CbcOrClpParam * parameters_ = parameters; 3040 3879 int numberParameters_ = numberParameters; … … 3045 3884 int statusUserFunction_[1]; 3046 3885 int numberUserFunctions_ = 1; // to allow for ampl 3886 #else 3887 delete babModel_; 3888 babModel_ = NULL; 3889 CbcOrClpRead_mode = 1; 3890 delete [] statusUserFunction_; 3891 statusUserFunction_ = new int [numberUserFunctions_]; 3892 int iUser; 3893 #endif 3047 3894 // Statistics 3048 3895 double statistics_seconds = 0.0, statistics_obj = 0.0; … … 3084 3931 noPrinting = true; 3085 3932 #endif 3933 #if NEW_STYLE_SOLVER==0 3086 3934 bool noPrinting_ = noPrinting; 3935 #endif 3087 3936 // Say not in integer 3088 3937 int integerStatus = 1; … … 3156 4005 int * knapsackRow = NULL; 3157 4006 int numberKnapsack = 0; 4007 #if NEW_STYLE_SOLVER 4008 int numberInputs = 0; 4009 readMode_ = CbcOrClpRead_mode; 4010 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 4011 int status = userFunction_[iUser]>importData(this, argc, const_cast<char **>(argv)); 4012 if (status >= 0) { 4013 if (!status) { 4014 numberInputs++; 4015 statusUserFunction_[iUser] = 1; 4016 goodModel = true; 4017 solver = model_.solver(); 4018 #ifndef CBC_OTHER_SOLVER 4019 clpSolver = dynamic_cast< OsiClpSolverInterface*> (solver); 4020 lpSolver = clpSolver>getModelPtr(); 4021 #endif 4022 } else { 4023 printf("Bad input from user function %s\n", userFunction_[iUser]>name().c_str()); 4024 abort(); 4025 } 4026 } 4027 } 4028 if (numberInputs > 1) { 4029 printf("Two or more user inputs!\n"); 4030 abort(); 4031 } 4032 if (originalCoinModel_) 4033 complicatedInteger = 1; 4034 testOsiParameters = intValue(CBC_PARAM_INT_TESTOSI); 4035 if (noPrinting_) { 4036 model_.messageHandler()>setLogLevel(0); 4037 setCbcOrClpPrinting(false); 4038 } 4039 CbcOrClpRead_mode = readMode_; 4040 #endif 3158 4041 #ifdef COIN_HAS_ASL 3159 4042 ampl_info info; … … 4581 5464 babModel_>setSecondaryStatus(iStatus2); 4582 5465 } 5466 #if NEW_STYLE_SOLVER 5467 int returnCode = callBack_>callBack(&model_, 1); 5468 #else 4583 5469 int returnCode = callBack(&model, 1); 5470 #endif 4584 5471 if (returnCode) { 4585 5472 // exit if user wants 5473 #if NEW_STYLE_SOLVER 5474 updateModel(model2, returnMode); 5475 #else 4586 5476 delete babModel_; 4587 5477 babModel_ = NULL; 5478 #endif 4588 5479 return returnCode; 4589 5480 } … … 4599 5490 model2 = lpSolver; 4600 5491 } 5492 #if NEW_STYLE_SOLVER 5493 updateModel(model2, returnMode); 5494 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 5495 if (statusUserFunction_[iUser]) 5496 userFunction_[iUser]>exportSolution(this, 1); 5497 } 5498 #endif 4601 5499 #ifdef COIN_HAS_ASL 4602 5500 if (statusUserFunction_[0]) { … … 4863 5761 #endif 4864 5762 } 5763 #if NEW_STYLE_SOLVER 5764 int returnCode = callBack_>callBack(&model_, 6); 5765 #else 4865 5766 int returnCode = callBack(&model, 6); 5767 #endif 4866 5768 if (returnCode) { 4867 5769 // exit if user wants 5770 #if NEW_STYLE_SOLVER 5771 updateModel(NULL, returnMode); 5772 #else 4868 5773 delete babModel_; 4869 5774 babModel_ = NULL; 5775 #endif 4870 5776 return returnCode; 4871 5777 } … … 5168 6074 model_.setSecondaryStatus(iStatus2); 5169 6075 si>setWarmStart(NULL); 6076 #if NEW_STYLE_SOLVER 6077 int returnCode = callBack_>callBack(&model_, 1); 6078 #else 5170 6079 int returnCode = callBack(&model_, 1); 6080 #endif 5171 6081 if (returnCode) { 5172 6082 // exit if user wants 6083 #if NEW_STYLE_SOLVER 6084 updateModel(NULL, returnMode); 6085 #else 5173 6086 delete babModel_; 5174 6087 babModel_ = NULL; 6088 #endif 5175 6089 return returnCode; 5176 6090 } … … 5602 6516 solver2>setHintParam(OsiDoInBranchAndCut, false, OsiHintDo) ; 5603 6517 } 6518 #if NEW_STYLE_SOLVER 6519 if (!solver2) { 6520 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 6521 if (statusUserFunction_[iUser]) 6522 userFunction_[iUser]>exportSolution(this, 11, "infeasible/unbounded by preprocessing"); 6523 } 6524 } 6525 #endif 5604 6526 #ifdef COIN_HAS_ASL 5605 6527 if (!solver2 && statusUserFunction_[0]) { … … 5637 6559 babModel_>setProblemStatus(1); 5638 6560 } 6561 #if NEW_STYLE_SOLVER 6562 int returnCode = callBack_>callBack(babModel_, 2); 6563 #else 5639 6564 int returnCode = callBack(babModel_, 2); 6565 #endif 5640 6566 if (returnCode) { 5641 6567 // exit if user wants 6568 #if NEW_STYLE_SOLVER 6569 updateModel(NULL, returnMode); 6570 #else 5642 6571 delete babModel_; 5643 6572 babModel_ = NULL; 6573 #endif 5644 6574 return returnCode; 5645 6575 } … … 6233 7163 } 6234 7164 if (type == CBC_PARAM_ACTION_BAB) { 7165 #if NEW_STYLE_SOLVER 7166 { 7167 CbcSolverUsefulData info; 7168 bool useInfo = false; 7169 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 7170 if (statusUserFunction_[iUser]) { 7171 userFunction_[iUser]>fillInformation(this, info); 7172 useInfo = true; 7173 } 7174 } 7175 if (useInfo) { 7176 priorities = info.priorities_; 7177 branchDirection = info.branchDirection_; 7178 pseudoDown = info.pseudoDown_; 7179 pseudoUp = info.pseudoUp_; 7180 solutionIn = info.primalSolution_; 7181 if (info.priorities_) { 7182 int numberColumns = originalCoinModel_ ? originalCoinModel_>numberColumns() : 7183 lpSolver>getNumCols(); 7184 prioritiesIn = reinterpret_cast<int *> (malloc(numberColumns * sizeof(int))); 7185 memcpy(prioritiesIn, info.priorities_, numberColumns*sizeof(int)); 7186 } 7187 sosPriority = info.sosPriority_; 7188 } 7189 } 7190 #endif 6235 7191 #ifdef COIN_HAS_ASL 6236 7192 if (statusUserFunction_[0]) { … … 7161 8117 babModel_>setThreadMode(numberThreads / 100); 7162 8118 #endif 8119 #if NEW_STYLE_SOLVER 8120 int returnCode = callBack_>callBack(babModel_, 3); 8121 #else 7163 8122 int returnCode = callBack(babModel_, 3); 8123 #endif 7164 8124 if (returnCode) { 7165 8125 // exit if user wants 8126 #if NEW_STYLE_SOLVER 8127 updateModel(NULL, returnMode); 8128 #else 7166 8129 delete babModel_; 7167 8130 babModel_ = NULL; 8131 #endif 7168 8132 return returnCode; 7169 8133 } … … 7368 8332 printHistory("branch.log"); 7369 8333 #endif 8334 #if NEW_STYLE_SOLVER 8335 returnCode = callBack_>callBack(babModel_, 4); 8336 #else 7370 8337 returnCode = callBack(babModel_, 4); 8338 #endif 7371 8339 if (returnCode) { 7372 8340 // exit if user wants 8341 #if NEW_STYLE_SOLVER 8342 updateModel(NULL, returnMode); 8343 #else 7373 8344 model_.moveInfo(*babModel_); 7374 8345 delete babModel_; 7375 8346 babModel_ = NULL; 8347 #endif 7376 8348 return returnCode; 7377 8349 } … … 7733 8705 } 7734 8706 assert (saveSolver>isProvenOptimal()); 8707 #if NEW_STYLE_SOLVER==0 7735 8708 #ifndef CBC_OTHER_SOLVER 7736 8709 // and original solver … … 7754 8727 assert (originalSolver>isProvenOptimal()); 7755 8728 #endif 8729 #endif 7756 8730 babModel_>assignSolver(saveSolver); 7757 8731 memcpy(bestSolution, babModel_>solver()>getColSolution(), n*sizeof(double)); … … 7761 8735 memcpy(bestSolution, babModel_>solver()>getColSolution(), n*sizeof(double)); 7762 8736 } 8737 #if NEW_STYLE_SOLVER==0 7763 8738 if (returnMode == 1) { 7764 8739 model_.deleteSolutions(); 7765 8740 model_.setBestSolution(bestSolution, n, babModel_>getMinimizationObjValue()); 7766 8741 } 8742 #endif 7767 8743 babModel_>deleteSolutions(); 7768 8744 babModel_>setBestSolution(bestSolution, n, babModel_>getMinimizationObjValue()); 8745 #if NEW_STYLE_SOLVER==0 7769 8746 #ifndef CBC_OTHER_SOLVER 7770 8747 // and put back in very original solver … … 7810 8787 } 7811 8788 #endif 8789 #endif 7812 8790 checkSOS(babModel_, babModel_>solver()); 7813 8791 } else if (model_.bestSolution() && type == CBC_PARAM_ACTION_BAB && model_.getMinimizationObjValue() < 1.0e50 && preProcess) { … … 7823 8801 babModel_>setMinimizationObjValue(model_.getMinimizationObjValue()); 7824 8802 memcpy(bestSolution, babModel_>solver()>getColSolution(), n*sizeof(double)); 8803 #if NEW_STYLE_SOLVER==0 7825 8804 #ifndef CBC_OTHER_SOLVER 7826 8805 // and put back in very original solver … … 7844 8823 delete basis; 7845 8824 } 8825 #endif 7846 8826 #endif 7847 8827 } … … 7910 8890 << CoinMessageEol; 7911 8891 } 8892 #if NEW_STYLE_SOLVER 8893 int returnCode = callBack_>callBack(babModel_, 5); 8894 #else 7912 8895 int returnCode = callBack(babModel_, 5); 8896 #endif 7913 8897 if (returnCode) { 7914 8898 // exit if user wants 8899 #if NEW_STYLE_SOLVER 8900 updateModel(NULL, returnMode); 8901 #else 7915 8902 model_.moveInfo(*babModel_); 7916 8903 delete babModel_; 7917 8904 babModel_ = NULL; 8905 #endif 7918 8906 return returnCode; 7919 8907 } 8908 #if NEW_STYLE_SOLVER 8909 if (bestSolution && numberKnapsack) { 8910 // expanded knapsack 8911 assert (originalCoinModel_); 8912 // Fills in original solution (coinModel length  rest junk) 8913 clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel_>solver()); 8914 lpSolver = clpSolver>getModelPtr(); 8915 int numberColumns2 = lpSolver>numberColumns(); 8916 assert (numberColumns2 > originalCoinModel_>numberColumns()); 8917 double * primalSolution = new double [numberColumns2]; 8918 memset(primalSolution, 0, numberColumns2*sizeof(double)); 8919 afterKnapsack(saveTightenedModel, whichColumn, knapsackStart, 8920 knapsackRow, numberKnapsack, 8921 lpSolver>primalColumnSolution(), primalSolution, 1); 8922 memcpy(lpSolver>primalColumnSolution(), primalSolution, numberColumns2*sizeof(double)); 8923 delete [] primalSolution; 8924 } 8925 updateModel(NULL, returnMode); 8926 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 8927 if (statusUserFunction_[iUser]) 8928 userFunction_[iUser]>exportSolution(this, 2); 8929 } 8930 #endif 8931 #ifdef COIN_HAS_ASL 8932 #if NEW_STYLE_SOLVER 8933 if (statusUserFunction_[0]) { 8934 clpSolver = dynamic_cast< OsiClpSolverInterface*> (babModel_>solver()); 8935 lpSolver = clpSolver>getModelPtr(); 8936 double value = babModel_>getObjValue() * lpSolver>getObjSense(); 8937 char buf[300]; 8938 int pos = 0; 8939 if (iStat == 0) { 8940 if (babModel_>getObjValue() < 1.0e40) { 8941 pos += sprintf(buf + pos, "optimal," ); 8942 } else { 8943 // infeasible 8944 iStat = 1; 8945 pos += sprintf(buf + pos, "infeasible,"); 8946 } 8947 } else if (iStat == 1) { 8948 if (iStat2 != 6) 8949 iStat = 3; 8950 else 8951 iStat = 4; 8952 pos += sprintf(buf + pos, "stopped on %s,", minor[iStat2].c_str()); 8953 } else if (iStat == 2) { 8954 iStat = 7; 8955 pos += sprintf(buf + pos, "stopped on difficulties,"); 8956 } else if (iStat == 5) { 8957 iStat = 3; 8958 pos += sprintf(buf + pos, "stopped on ctrlc,"); 8959 } else if (iStat == 6) { 8960 // bab infeasible 8961 pos += sprintf(buf + pos, "integer infeasible,"); 8962 iStat = 1; 8963 } else { 8964 pos += sprintf(buf + pos, "status unknown,"); 8965 iStat = 6; 8966 } 8967 info.problemStatus = iStat; 8968 info.objValue = value; 8969 if (babModel_>getObjValue() < 1.0e40) { 8970 int precision = ampl_obj_prec(); 8971 if (precision > 0) 8972 pos += sprintf(buf + pos, " objective %.*g", precision, 8973 value); 8974 else 8975 pos += sprintf(buf + pos, " objective %g", value); 8976 } 8977 sprintf(buf + pos, "\n%d nodes, %d iterations, %g seconds", 8978 babModel_>getNodeCount(), 8979 babModel_>getIterationCount(), 8980 totalTime); 8981 if (bestSolution) { 8982 free(info.primalSolution); 8983 if (!numberKnapsack) { 8984 info.primalSolution = reinterpret_cast<double *> (malloc(n * sizeof(double))); 8985 CoinCopyN(lpSolver>primalColumnSolution(), n, info.primalSolution); 8986 int numberRows = lpSolver>numberRows(); 8987 free(info.dualSolution); 8988 info.dualSolution = reinterpret_cast<double *> (malloc(numberRows * sizeof(double))); 8989 CoinCopyN(lpSolver>dualRowSolution(), numberRows, info.dualSolution); 8990 } else { 8991 // expanded knapsack 8992 info.dualSolution = NULL; 8993 int numberColumns = saveCoinModel.numberColumns(); 8994 info.primalSolution = reinterpret_cast<double *> (malloc(numberColumns * sizeof(double))); 8995 // Fills in original solution (coinModel length) 8996 afterKnapsack(saveTightenedModel, whichColumn, knapsackStart, 8997 knapsackRow, numberKnapsack, 8998 lpSolver>primalColumnSolution(), info.primalSolution, 1); 8999 } 9000 } else { 9001 info.primalSolution = NULL; 9002 info.dualSolution = NULL; 9003 } 9004 // put buffer into info 9005 strcpy(info.buffer, buf); 9006 } 9007 #endif 9008 #endif 7920 9009 } else { 7921 9010 std::cout << "Model strengthened  now has " << clpSolver>getNumRows() … … 9150 10239 } 9151 10240 #endif 10241 #if NEW_STYLE_SOLVER 10242 if (goodModel) { 10243 std::string name = CoinReadGetString(argc, argv); 10244 if (name != "EOL") { 10245 int length = name.size(); 10246 int percent = name.find('%'); 10247 std::string command = name; 10248 std::string options = ""; 10249 if (percent<length && percent>0) { 10250 command = name.substr(0, percent); 10251 options = name.substr(percent + 1); 10252 } 10253 CbcUser * userCode = userFunction(command.c_str()); 10254 if (userCode) 10255 userCode>solve(this, options.c_str()); 10256 } else { 10257 parameters_[iParam].printString(); 10258 } 10259 } 10260 #endif 9152 10261 break; 9153 10262 case CBC_PARAM_ACTION_USERCBC: … … 9755 10864 //dmalloc_shutdown(); 9756 10865 #endif 10866 #if NEW_STYLE_SOLVER 10867 updateModel(NULL, returnMode); 10868 for (iUser = 0; iUser < numberUserFunctions_; iUser++) { 10869 if (statusUserFunction_[iUser]) 10870 userFunction_[iUser]>exportData(this); 10871 } 10872 sprintf(generalPrint, "Total time %.2f", CoinCpuTime()  startTime_); 10873 #else 9757 10874 if (babModel_) { 9758 10875 model_.moveInfo(*babModel_); … … 9784 10901 model_.solver()>setWarmStart(NULL); 9785 10902 sprintf(generalPrint, "Total time %.2f", CoinCpuTime()  time0); 10903 #endif 9786 10904 generalMessageHandler>message(CLP_GENERAL, generalMessages) 9787 10905 << generalPrint
Note: See TracChangeset
for help on using the changeset viewer.