00001
00012 #include "OSColGenApp.h"
00013 #include "OSErrorClass.h"
00014 #include "OSDataStructures.h"
00015 #include "OSBearcatSolverXij.h"
00016 #include "OSConfig.h"
00017 #include "OSResult.h"
00018 #include "OSOption.h"
00019 #include "OSiLReader.h"
00020 #include "OSiLWriter.h"
00021 #include "OSoLReader.h"
00022 #include "OSoLWriter.h"
00023 #include "OSrLReader.h"
00024 #include "OSrLWriter.h"
00025 #include "OSInstance.h"
00026 #include "OSFileUtil.h"
00027 #include "OSDecompSolverFactory.h"
00028
00029
00030
00031 #ifdef COIN_HAS_COUENNE
00032 #include "OSCouenneSolver.h"
00033 #endif
00034
00035 #ifdef COIN_HAS_IPOPT
00036 #include "OSIpoptSolver.h"
00037 #endif
00038
00039
00040
00041
00042 #include <vector>
00043 #include <map>
00044 #include <sstream>
00045
00046 using std::ostringstream;
00047
00048
00049
00050
00051 OSColGenApp::OSColGenApp():
00052 m_osinstanceMaster(NULL) {
00053 std::cout << "INSIDE OSColGenApp CONSTRUCTOR" << std::endl;
00054
00055 }
00056
00057
00058 OSColGenApp::OSColGenApp( OSOption *osoption) {
00059 std::cout << "INSIDE OSColGenApp CONSTRUCTOR" << std::endl;
00060
00061
00062
00063
00064
00065 m_calledBranchAndBound = false;
00066
00067
00068
00069 m_osDecompParam.nodeLimit = 1000;
00070 m_osDecompParam.columnLimit = 20000;
00071 m_osDecompParam.masterColumnResetValue = 5000;
00072 m_osDecompParam.zeroTol = .0001;
00073 m_osDecompParam.artVarCoeff = 1000000;
00074 m_osDecompParam.optTolPerCent = 0;
00075
00076 m_osoption = osoption;
00077
00078 getOptions( m_osoption);
00079
00080
00081 m_osinstanceMaster = NULL;
00082 m_osrouteSolver = NULL;
00083
00084 m_osrouteSolver = NULL;
00085 m_factoryInit = new OSDecompFactoryInitializer();
00086 std::cout << "CREATE THE FACTORY " << std::endl;
00087 m_osrouteSolver = OSDecompSolverFactory::factories[ "OSBearcatSolverXij"]->create();
00088 std::cout << "FINISH FACTORY CREATION " << std::endl;
00089 std::cout << "SET FACTORY OPTION " << std::endl;
00090 m_osrouteSolver->m_osoption = m_osoption;
00091 std::cout << "FINISH SET FACTORY OPTION " << std::endl;
00092
00093
00094
00095 m_osrouteSolver->m_osDecompParam = m_osDecompParam;
00096 m_osrouteSolver->initializeDataStructures();
00097
00098
00099
00100 m_zUB = OSDBL_MAX;
00101 m_zLB = -OSDBL_MAX;
00102
00103
00104 m_numColumnsOld = 0;
00105
00106
00107
00108 }
00109
00110
00111 OSColGenApp::~OSColGenApp(){
00112
00113 std::cout << "INSIDE ~OSColGenApp DESTRUCTOR" << std::endl;
00114
00115
00116
00117
00118 if( m_osinstanceMaster != NULL) delete m_osinstanceMaster;
00119
00120 if( m_osrouteSolver != NULL) delete m_osrouteSolver;
00121
00122
00123
00124 delete m_factoryInit;
00125
00126 }
00127
00128
00129 void OSColGenApp::getInitialRestrictedMaster( ){
00130
00131 m_osinstanceMaster = m_osrouteSolver->getInitialRestrictedMaster( );
00132
00133
00134 }
00135
00136
00137 void OSColGenApp::getCuts(const double* thetaVar, const int numThetaVar,
00138 int &numNewRows, int* &numNonz, int** &colIdx,
00139 double** &values, double* &rowLB, double* &rowUB) {
00140
00141 m_osrouteSolver->getCutsTheta( thetaVar, numThetaVar,
00142 numNewRows, numNonz, colIdx, values, rowLB, rowUB);
00143
00144 m_calledBranchAndBound = false;
00145
00146 if(numNewRows == 0 && m_calledBranchAndBound == false
00147 && m_osrouteSolver->m_numMultCuts <= m_osrouteSolver->m_multiCommodCutLimit) {
00148 m_osrouteSolver->getCutsMultiCommod( thetaVar, numThetaVar,
00149 numNewRows, numNonz, colIdx, values, rowLB, rowUB);
00150
00151
00152 m_osrouteSolver->m_numMultCuts += numNewRows;
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 }
00170
00171
00172 }
00173
00174
00175 void OSColGenApp::getColumns(const double* yA, const int numARows,
00176 const double* yB, const int numBRows,
00177 int &numNewColumns, int* &numNonz, double* &cost,
00178 int** &rowIdx, double** &values, double &lowerBound) {
00179
00180 m_osrouteSolver->getColumns(yA, numARows,
00181 yB, numBRows, numNewColumns, numNonz,
00182 cost, rowIdx, values, lowerBound);
00183
00184
00185
00186
00187 }
00188
00189 void OSColGenApp::getOptions(OSOption *osoption) {
00190
00191
00192
00193
00194 try{
00195
00196 std::vector<SolverOption*> solverOptions;
00197 std::vector<SolverOption*>::iterator vit;
00198
00199 solverOptions = osoption->getSolverOptions("OSDecompSolver");
00200 if (solverOptions.size() == 0) throw ErrorClass( "options for OSDecompSolver not available");
00201
00202
00203 for (vit = solverOptions.begin(); vit != solverOptions.end(); vit++) {
00204
00205 if((*vit)->name.find("columnLimit") != std::string::npos){
00206
00207
00208 std::istringstream columnLimitBuffer( (*vit)->value);
00209 columnLimitBuffer >> m_osDecompParam.columnLimit;
00210 std::cout << "columnLimit = " << m_osDecompParam.columnLimit << std::endl;
00211
00212 }else{
00213
00214 if( (*vit)->name.find("artVarCoeff") != std::string::npos ){
00215
00216 std::istringstream artVarCoeffBuffer( (*vit)->value);
00217 artVarCoeffBuffer >> m_osDecompParam.artVarCoeff;
00218 std::cout << "artVarCoeff = " << m_osDecompParam.artVarCoeff << std::endl;
00219
00220 }else{
00221
00222 if( (*vit)->name.find("zeroTol") != std::string::npos){
00223
00224 std::istringstream zeroTolBuffer( (*vit)->value);
00225 zeroTolBuffer >> m_osDecompParam.zeroTol;
00226 std::cout << "zeroTol = " << m_osDecompParam.zeroTol << std::endl;
00227
00228 }else{
00229
00230
00231 if( (*vit)->name.find("nodeLimit") != std::string::npos){
00232
00233 std::istringstream nodeLimitBuffer( (*vit)->value);
00234 nodeLimitBuffer >> m_osDecompParam.nodeLimit;
00235 std::cout << "nodeLimit = " << m_osDecompParam.nodeLimit << std::endl;
00236
00237 }else{
00238
00239 if( (*vit)->name.find("masterColumnResetValue") != std::string::npos){
00240
00241 std::istringstream masterColumnResetValueBuffer( (*vit)->value);
00242 masterColumnResetValueBuffer >> m_osDecompParam.masterColumnResetValue;
00243 std::cout << "masterColumnResetValue = " << m_osDecompParam.masterColumnResetValue << std::endl;
00244 }else{
00245
00246 if( (*vit)->name.find("optTolPerCent") != std::string::npos){
00247
00248 std::istringstream optTolPerCentBuffer( (*vit)->value);
00249 optTolPerCentBuffer >> m_osDecompParam.optTolPerCent;
00250 std::cout << "masterColumnResetValue = " << m_osDecompParam.optTolPerCent<< std::endl;
00251 }
00252 }
00253 }
00254 }
00255 }
00256 }
00257 }
00258
00259 } catch (const ErrorClass& eclass) {
00260
00261 throw ErrorClass(eclass.errormsg);
00262
00263 }
00264
00265 }
00266
00267
00268 void OSColGenApp::solve(){
00269
00270
00271
00272 int *cbasis = NULL;
00273 int *rbasis = NULL;
00274 int *new_cbasis = NULL;
00275
00276
00277
00278 std::set<std::pair<int, double> >::iterator sit;
00279 std::vector<int>::iterator vit;
00280 std::map<int, int>::iterator mit;
00281
00282 int numCols;
00283 int numRows;
00284 int i;
00285
00286
00287 m_zUB = m_osrouteSolver->m_bestIPValue;
00288
00289
00290
00291 m_numColumnsGenerated = 0;
00292 m_numNodesGenerated = 0;
00293 std::cout << " m_zUB " << m_zUB << std::endl;
00294
00295 try{
00296
00297
00298
00299 m_solver = new CoinSolver();
00300
00301
00302
00303
00304
00305 m_solver->sSolverName ="clp";
00306
00307 m_solver->osinstance = m_osinstanceMaster;
00308
00309
00310 m_solver->osoption = m_osoption;
00311 m_solver->buildSolverInstance();
00312
00313
00314
00315 m_si = m_solver->osiSolver;
00316
00317 m_yA = new double[m_osinstanceMaster->getConstraintNumber() ];
00318
00319
00320 m_yB = new double[ m_osrouteSolver->m_maxBmatrixCon];
00321
00322
00323 m_maxCols = m_osrouteSolver->m_maxMasterColumns;
00324 m_maxRows = m_osrouteSolver->m_maxMasterRows;
00325
00326 m_theta = new double[ m_maxCols];
00327
00328
00329
00330 solveRestrictedMasterRelaxation();
00331
00332
00333 numCols = m_si->getNumCols();
00334 numRows = m_si->getNumRows();
00335
00336
00337 cbasis = new int[ numCols];
00338 rbasis = new int[ numRows ];
00339 m_si->getBasisStatus( cbasis, rbasis);
00340
00341 for(i = 0; i < numCols; i++){
00342
00343 if(cbasis[ i] == 1) m_zOptRootLP.push_back( i);
00344
00345 *(m_theta + i) = m_si->getColSolution()[i];
00346
00347 m_zRootLPx_vals.push_back( *(m_theta + i) );
00348
00350 int j;
00351 if( *(m_theta + i) > m_osDecompParam.zeroTol){
00352 std::cout << "x variables for column " << i << std::endl;
00353 for(j = m_osrouteSolver->m_thetaPnt[ i]; j < m_osrouteSolver->m_thetaPnt[ i + 1] ; j++){
00354 std::cout << m_osrouteSolver->m_variableNames[ m_osrouteSolver->m_thetaIndex[ j] ] << " = " << *(m_theta + i) << std::endl;
00355 }
00356 }
00358
00359
00360 }
00361 m_zLB = m_si->getObjValue();
00362 m_zRootLP = m_si->getObjValue();
00363
00364 std::cout << "optimal LP value at root node = " << m_zLB << std::endl;
00365
00366
00367
00368
00369
00370 for ( sit = m_osrouteSolver->intVarSet.begin() ;
00371 sit != m_osrouteSolver->intVarSet.end(); sit++ ){
00372
00373 m_si->setInteger( sit->first);
00374
00375 }
00376
00377 CbcModel model( *m_si);
00378 OsiSolverInterface *ipSolver = model.solver();
00379 std::cout << "start solving master as integer program " << std::endl;
00380 ipSolver->branchAndBound();
00381 std::cout << "done solving master as integer program " << std::endl;
00382
00383
00384
00385 if( ipSolver->getObjValue() < m_zUB) m_zUB = ipSolver->getObjValue() ;
00386
00387
00388 numCols = m_si->getNumCols();
00389
00390 for(i = 0; i < numCols; i++){
00391
00392
00393 if( model.getColSolution()[i] > m_osDecompParam.zeroTol){
00394
00395 m_zOptIndexes.push_back( i) ;
00396
00397 }
00398
00399 }
00400
00401 for ( sit = m_osrouteSolver->intVarSet.begin() ;
00402 sit != m_osrouteSolver->intVarSet.end(); sit++ ){
00403
00404 m_si->setContinuous( sit->first);
00405 m_si->setColUpper( sit->first, sit->second);
00406
00407 }
00408
00409 std::cout << "OPTIMAL LP VALUE = " << m_zLB << std::endl;
00410 std::cout << "CURRENT BEST IP VALUE = " << m_zUB << std::endl;
00411
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00430
00431 m_osrouteSolver->m_rootLPValue = m_zRootLP;
00432
00433
00434 m_message = "";
00435 std::cout << "START BRANCH AND BOUND = " << std::endl;
00436 if(m_zLB + m_osDecompParam.zeroTol < m_zUB) branchAndBound();
00437
00438
00439
00440
00441 std::cout << "FINISH BRANCH AND BOUND = " << std::endl;
00442 printTreeInfo();
00443 m_osrouteSolver->m_bestLPValue = m_zLB;
00444 m_osrouteSolver->m_bestIPValue = m_zUB;
00445 if(m_message == "") m_message = "******** WE ARE OPTIMAL *******";
00446 m_osrouteSolver->pauHana( m_zOptIndexes, m_zRootLPx_vals,
00447 m_numNodesGenerated, m_numColumnsGenerated, m_message);
00448
00449
00450 delete m_solver;
00451
00452 delete[] m_yA;
00453 m_yA = NULL;
00454
00455 delete[] m_yB;
00456 m_yB = NULL;
00457
00458 delete[] m_theta;
00459 m_theta = NULL;
00460
00461
00462 delete[] cbasis;
00463 cbasis = NULL;
00464 if(new_cbasis != NULL) delete[] new_cbasis;
00465 new_cbasis = NULL;
00466 delete[] rbasis;
00467 rbasis = NULL;
00468
00469
00470 } catch (const ErrorClass& eclass) {
00471
00472 delete m_solver;
00473
00474 delete[] m_yA;
00475 m_yA = NULL;
00476
00477 delete[] m_yB;
00478 m_yB = NULL;
00479
00480 delete[] m_theta;
00481 m_theta = NULL;
00482
00483
00484
00485 delete[] cbasis;
00486 cbasis = NULL;
00487 if(new_cbasis != NULL) delete[] new_cbasis;
00488 new_cbasis = NULL;
00489 delete[] rbasis;
00490 rbasis = NULL;
00491
00492 throw ErrorClass(eclass.errormsg);
00493
00494 }
00495
00496 }
00497
00498
00499 void OSColGenApp::solveRestrictedMasterRelaxation( ){
00500
00501 int i;
00502 int k;
00503
00504 int numARows;
00505
00506 int numBRows;
00507 int numCols;
00508
00509
00510 int numNewColumns;
00511 int* numNonz = NULL;
00512 double* cost = NULL;
00513 int** rowIdx = NULL;
00514 double** values = NULL ;
00515 double lowerBound;
00516
00517
00518 double collb;
00519 double colub;
00520
00521 collb = 0.0;
00522 colub = 1.0;
00523
00524
00525 double bigM = m_osDecompParam.artVarCoeff;
00526
00527 int numNewRows;
00528 int* numRowNonz = NULL;
00529 int** colIdx = NULL;
00530 double** rowValues = NULL ;
00531 double* rowLB;
00532 double* rowUB;
00533
00534
00535
00536 int rowArtIdx;
00537 double rowArtVal;
00538
00539 bool isCutAdded;
00540
00541
00542
00543 try{
00544 numARows = m_osrouteSolver->m_numNodes;
00545
00546
00547 isCutAdded = true;
00548
00549 while(isCutAdded == true ){
00550
00551 isCutAdded = false;
00552
00553 std::cout << "CALL Solve " << " Number of columns = " << m_si->getNumCols() << std::endl;
00554
00555
00556 m_solver->solve();
00557
00558 std::cout << "Solution Status = " << m_solver->osresult->getSolutionStatusType( 0 ) << std::endl;
00559
00560
00561 if(m_si->getNumRows() != numARows + m_osrouteSolver->m_numBmatrixCon ) {
00562 std::cout << "m_si->getNumRows() = " << m_si->getNumRows() << std::endl;
00563 std::cout << "numARows = " << numARows << std::endl;
00564 std::cout << "m_numBmatrixCon = " << m_osrouteSolver->m_numBmatrixCon << std::endl;
00565 throw ErrorClass("detect a row number inconsistency in solveRestrictedMasterRelaxation");
00566 }
00567
00568
00569
00570 if(m_si->getRowPrice() == NULL )
00571 throw ErrorClass("problem getting dual values in solveRestrictedMasterRelaxation");
00572
00573
00574 numBRows = m_osrouteSolver->m_numBmatrixCon;
00575
00576 for(i = 0; i < numARows; i++){
00577
00578 *(m_yA + i) = m_si->getRowPrice()[ i];
00579
00580 }
00581
00582 for(i = numARows; i < numARows + numBRows; i++){
00583
00584 *(m_yB + i - numARows) = m_si->getRowPrice()[ i];
00585
00586 }
00587
00588 lowerBound = -1;
00589 int loopKount = 0;
00592 while(lowerBound < -m_osDecompParam.zeroTol && loopKount < m_osDecompParam.columnLimit){
00593 loopKount++;
00594
00595
00596
00597 getColumns(m_yA, numARows, m_yB, numBRows, numNewColumns,
00598 numNonz, cost, rowIdx, values, lowerBound);
00599
00600 std::cout << "Lower Bound = " << lowerBound << std::endl;
00601
00602
00603
00604 for(k = 0; k < numNewColumns; k++){
00605
00606 m_si->addCol( numNonz[ k], rowIdx[k], values[k],
00607 collb, colub, cost[ k]) ;
00608
00609
00610 m_numColumnsGenerated++;
00611
00612 }
00613
00614 std::cout << " OBJ VALUE = " << m_si->getObjValue() << std::endl;
00615
00616 std::cout << "m_zUB = " << m_zUB << std::endl;
00617
00618 if(lowerBound + m_si->getObjValue() > (1 - m_osDecompParam.optTolPerCent)*m_zUB) break;
00619
00620 std::cout << std::endl << std::endl << std::endl;
00621 std::cout << "CALL Solve " << " Number of columns = " << m_si->getNumCols() << std::endl;
00622 m_solver->solve();
00623
00624 std::cout << "Solution Status = " << m_solver->osresult->getSolutionStatusType( 0 ) << std::endl;
00625 std::cout << "Number of solver interface columns = " << m_si->getNumCols() << std::endl;
00626
00627
00628 numCols = m_si->getNumCols();
00629
00630 if( numCols != m_osrouteSolver->m_numThetaVar ) throw ErrorClass("number variables in solver not consistent with master");
00631 if( numCols + m_osrouteSolver->m_numHubs >= m_maxCols) {
00632
00633 m_message = " ***** COLUMN LIMIT EXCEEDED -- INSIDE solveRestrictedMasterRelaxation ****";
00634 printTreeInfo();
00635 m_osrouteSolver->m_bestLPValue = m_zLB;
00636 m_osrouteSolver->m_bestIPValue = m_zUB;
00637 m_osrouteSolver->pauHana( m_zOptIndexes, m_zRootLPx_vals,
00638 m_numNodesGenerated, m_numColumnsGenerated, m_message);
00639 throw ErrorClass("we ran out of columns");
00640 }
00641
00642 for(i = 0; i < numARows; i++){
00643
00644 *(m_yA + i) = m_si->getRowPrice()[ i];
00645
00646 }
00647
00648 for(i = numARows; i < numARows + numBRows; i++){
00649
00650 *(m_yB + i - numARows) = m_si->getRowPrice()[ i];
00651
00652 }
00653
00654 }
00656
00657 if( loopKount >= m_osDecompParam.columnLimit)throw ErrorClass("we exceeded loop kount in column generation");
00658
00659
00660 numCols = m_si->getNumCols();
00661 for(i=0; i < numCols; i++){
00662 *(m_theta + i) = m_si->getColSolution()[i];
00663 }
00664
00665
00666 numNewRows = 0;
00667
00668
00669 if(m_si->getObjValue() < (1 - m_osDecompParam.optTolPerCent)*m_zUB)
00670 getCuts(m_theta, numCols, numNewRows, numRowNonz,
00671 colIdx,rowValues, rowLB, rowUB);
00672
00673
00674 if( numNewRows >= 1 ){
00675
00676 isCutAdded = true;
00677
00678 for(i = 0; i < numNewRows; i++){
00679
00680 m_si->addRow(numRowNonz[ i], colIdx[ i], rowValues[ i], rowLB[ i], rowUB[ i] ) ;
00681
00682
00683
00684
00685
00686
00687 rowArtVal = -1.0;
00688 rowArtIdx = m_si->getNumRows() - 1;
00689
00690
00691
00692 rowArtVal = 1.0;
00693
00694 m_si->addCol(1, &rowArtIdx, &rowArtVal, 0, 1, bigM);
00695 m_numColumnsGenerated++;
00696
00697 }
00698
00699 std::cout << std::endl;
00700 std::cout << "CUTS WERE ADDED CALL SOLVE" << std::endl;
00701 m_solver->solve();
00702
00703 }
00704
00705
00706
00707
00708 }
00709
00710
00711
00712 } catch (const ErrorClass& eclass) {
00713
00714 throw ErrorClass(eclass.errormsg);
00715
00716 }
00717
00718
00719 }
00720
00721
00722 bool OSColGenApp::isInteger( const double *thetaVar, const int numThetaVar,
00723 const double tol){
00724
00725
00726 bool isInt;
00727 isInt = true;
00728 int i;
00729
00730 try{
00731
00732 for(i = 0; i < numThetaVar; i++){
00733
00734 if( (thetaVar[ i] > tol) && (thetaVar[ i] < 1 - tol) ){
00735
00736 isInt = false;
00737 break;
00738 }
00739
00740 }
00741
00742 return isInt;
00743
00744 } catch (const ErrorClass& eclass) {
00745
00746 throw ErrorClass(eclass.errormsg);
00747
00748 }
00749
00750
00751
00752 }
00753
00754
00755 void OSColGenApp::printDebugInfo( ){
00756
00757 int numCols;
00758 int numRows;
00759 std::set<std::pair<int, double> >::iterator sit;
00760 int i;
00761
00762 numCols = m_si->getNumCols();
00763
00764
00765 for(i = 0; i < numCols; i++){
00766
00767 std::cout << "PROCESSING THETA COLUMN " << i << " value = " << m_si->getColSolution()[i] << std::endl;
00768
00769 for(int j = m_osrouteSolver->m_thetaPnt[ i]; j < m_osrouteSolver->m_thetaPnt[ i + 1]; j++ ){
00770
00771
00772
00773 }
00774 }
00775
00776 numRows = m_si->getNumRows();
00777
00778 for(i = m_osrouteSolver->m_numNodes; i < numRows; i++){
00779
00780 std::cout << "PROCESSING ROW " << i << std::endl;
00781
00782 for(int j = m_osrouteSolver->m_pntBmatrix[ i - m_osrouteSolver->m_numNodes]; j < m_osrouteSolver->m_pntBmatrix[ i + 1 - m_osrouteSolver->m_numNodes]; j++ ){
00783
00784
00785
00786 }
00787 }
00788
00789
00790
00791 for ( sit = m_osrouteSolver->intVarSet.begin() ;
00792 sit != m_osrouteSolver->intVarSet.end(); sit++ ){
00793
00794
00795
00796 }
00797 }
00798
00799
00800 bool OSColGenApp::branchAndBound( ){
00801
00802 m_calledBranchAndBound = true;
00803
00808 std::map<int, int> varConMap;
00809
00810 std::vector<OSNode*> nodeVec;
00811 std::vector<OSNode*>::iterator vit;
00812
00813
00814 std::map<int, OSNode*>::iterator mit;
00815 int bestNodeID;
00816 double bestNodeBound;
00817
00818
00819 OSNode *osnode = NULL;
00820 OSNode *osnodeLeftChild = NULL;
00821 OSNode *osnodeRightChild = NULL;
00822
00823 bool bandbWorked;
00824 bandbWorked = true;
00825 int numCols;
00826 int rowIdx;
00827 rowIdx = 0;
00828
00829 bool leftNodeCreated = false;
00830 bool rightNodeCreated = false;
00831
00832
00833
00834 try{
00835
00836
00837 numCols = m_si->getNumCols();
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 createBranchingCut(m_theta, numCols, varConMap, rowIdx);
00848
00849
00850
00852
00853 osnodeLeftChild = createChild(osnode, varConMap, rowIdx, 1, 1);
00854 if(osnodeLeftChild != NULL){
00855
00856
00857
00858 osnodeLeftChild->nodeID = m_numNodesGenerated;
00859 osnodeLeftChild->parentID = 0;
00860
00861 m_nodeMap.insert ( std::pair<int, OSNode*>(osnodeLeftChild->nodeID, osnodeLeftChild) );
00862
00863 }
00864
00866
00868
00869 osnodeRightChild = createChild(osnode, varConMap, rowIdx, 0, 0);
00870 if(osnodeRightChild != NULL){
00871
00872
00873
00874 osnodeRightChild->nodeID = m_numNodesGenerated;
00875 osnodeRightChild->parentID = 0;
00876
00877 m_nodeMap.insert ( std::pair<int, OSNode*>(osnodeRightChild->nodeID, osnodeRightChild) );
00878 }
00879
00881
00882
00883
00884
00885 std::cout << "ENTERING THE WHILE IN BRANCH AND BOUND" << std::endl;
00886 std::cout << "m_numNodesGenerated = " << m_numNodesGenerated << std::endl;
00887
00888 while( m_nodeMap.size() > 0 ){
00889
00890 if(m_numNodesGenerated > m_osDecompParam.nodeLimit ){
00891 m_message = "******* NODE LIMIT EXCEEDED *******";
00892 return false;
00893 }
00894
00895
00896 if( m_si->getNumCols() > m_maxCols ){
00897 m_message = "******* COLUMN LIMIT EXCEEDED *******";
00898 return false;
00899 }
00900
00901
00902
00903
00904 if( (m_numColumnsGenerated - m_numColumnsOld) >
00905 m_osDecompParam.masterColumnResetValue) {
00906 m_numColumnsOld = m_numColumnsGenerated;
00907 std::cout << "DOING A MASTER RESET IN BRANCH AND BOUND" << std::endl;
00908 std::cout << "NUMBER OF COLUMNS BEFORE RESET = " << m_si->getNumCols() << std::endl;
00909 resetMaster();
00910 std::cout << "NUMBER OF COLUMNS AFTER RESET = " << m_si->getNumCols() << std::endl;
00911
00912
00913
00914
00915 }
00916
00917 leftNodeCreated = false;
00918 rightNodeCreated = false;
00919
00920
00921
00922
00923
00924
00925 bestNodeID = -1;
00926 bestNodeBound = OSDBL_MAX;
00927
00928
00929 for (mit = m_nodeMap.begin(); mit != m_nodeMap.end(); mit++ ){
00930
00931
00932
00933
00934
00935 if( mit->second->lpValue < bestNodeBound) {
00936
00937 bestNodeBound = mit->second->lpValue;
00938 bestNodeID = mit->first;
00939
00940
00941
00942 }
00943
00944 }
00945
00946
00947 mit = m_nodeMap.find( bestNodeID );
00948 if(mit == m_nodeMap.end() ) throw ErrorClass("a node selection problem in branch and bound");
00949 osnode = mit->second;
00950
00951 if( osnode->lpValue < (1 - m_osDecompParam.optTolPerCent)*m_zUB - m_osDecompParam.zeroTol){
00952
00953
00954
00955 std::cout << "CREATE A BRANCHING CUT " << std::endl;
00956 createBranchingCut(osnode->thetaIdx, osnode->theta, osnode->thetaNumNonz,
00957 varConMap, rowIdx);
00958
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00972
00973 std::cout << "BEST NODE ID " << bestNodeID << std::endl;
00974 std::cout << "NODE LP VALUE = " << osnode->lpValue << std::endl;
00975
00976 checkNodeConsistency( rowIdx, osnode);
00977
00978
00979
00980 osnodeLeftChild = createChild(osnode, varConMap, rowIdx, 1, 1);
00981 if(osnodeLeftChild != NULL){
00982
00983
00984
00985 osnodeLeftChild->nodeID = m_numNodesGenerated;
00986 osnodeLeftChild->parentID = osnode->nodeID;
00987 leftNodeCreated = true;
00988 }
00989
00990
00991 osnodeRightChild = createChild(osnode, varConMap, rowIdx, 0, 0);
00992 if(osnodeRightChild != NULL){
00993
00994
00995
00996 osnodeRightChild->nodeID = m_numNodesGenerated;
00997 osnodeRightChild->parentID = osnode->nodeID;
00998 rightNodeCreated = true;
00999 }
01000
01001
01002
01003 m_nodeMap.erase( mit);
01004 delete osnode;
01005
01006
01007
01008
01009 if( leftNodeCreated == true)
01010 m_nodeMap.insert ( std::pair<int, OSNode*>(osnodeLeftChild->nodeID, osnodeLeftChild) ) ;
01011
01012 if( rightNodeCreated == true)
01013 m_nodeMap.insert ( std::pair<int, OSNode*>(osnodeRightChild->nodeID, osnodeRightChild) ) ;
01014
01015
01016 }else{
01017
01018
01019 std::cout << "FATHAM BY UPPER BOUND " << std::endl;
01020
01021 m_nodeMap.erase( mit);
01022 delete osnode;
01023
01024 }
01025
01026
01027
01028
01029 }
01030
01031
01032
01033 if(m_numNodesGenerated > 0){
01034
01035 m_zLB = (1 - m_osDecompParam.optTolPerCent)*m_zUB;
01036 }else{
01037
01038 m_zLB = m_zUB;
01039 }
01040
01041
01042
01043
01044 return bandbWorked;
01045
01046 } catch (const ErrorClass& eclass) {
01047
01048 throw ErrorClass(eclass.errormsg);
01049
01050 }
01051
01052 }
01053
01054 OSNode* OSColGenApp::createChild(const OSNode *osnodeParent, std::map<int, int> &varConMap,
01055 const int rowIdx, const double rowLB, const double rowUB){
01056
01057 m_numNodesGenerated++;
01058
01059 OSNode *osnodeChild;
01060 osnodeChild = NULL;
01061 int numRows;
01062 int numCols;
01063
01064 int tmpColNum ;
01065 int tmpRowNum ;
01066
01067 std::map<int, int>::iterator mit;
01068
01069
01070
01071 int i;
01072 int k;
01073 int childRowIdxNumNonz;
01074 childRowIdxNumNonz = 0;
01075
01076
01077
01078 int thetaNumNonz;
01079
01080
01081 try{
01082
01083 if(osnodeParent != NULL) childRowIdxNumNonz = osnodeParent->rowIdxNumNonz + 1;
01084 else childRowIdxNumNonz = 1;
01085
01086
01087
01088 if(osnodeParent != NULL){
01089 for(i = 0; i < osnodeParent->rowIdxNumNonz; i++){
01090
01091
01092 m_si->setRowLower( osnodeParent->rowIdx[ i], osnodeParent->rowLB[ i]);
01093 m_si->setRowUpper( osnodeParent->rowIdx[ i], osnodeParent->rowUB[ i]);
01094
01095
01096 }
01097 }
01098
01099 m_si->setRowLower( rowIdx, rowLB);
01100 m_si->setRowUpper( rowIdx, rowUB);
01101
01102
01103
01104
01105
01106
01107
01108 std::cout << "CALL SOLVE FROM CREATE CHILD " << std::endl;
01109
01110 if(osnodeParent != NULL){
01111
01112 tmpColNum = m_si->getNumCols() ;
01113 tmpRowNum = m_si->getNumRows() ;
01114 int *tmpColParent = new int[ tmpColNum];
01115 int *tmpRowParent = new int[ tmpRowNum ];
01116
01117 for(k = 0; k < tmpColNum; k++){
01118
01119 if( m_si->getObjCoefficients()[k] >=
01120 m_osDecompParam.artVarCoeff - m_osDecompParam.zeroTol)
01121 tmpColParent[ k ] = 3;
01122
01123
01124 else tmpColParent[ k] = 0;
01125
01126 }
01127
01128 for(k = 0; k < tmpRowNum; k++){
01129
01130 tmpRowParent[ k] = 0;
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 m_si->setBasisStatus(tmpColParent, tmpRowParent);
01148 solveRestrictedMasterRelaxation( );
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01175
01176 delete[] tmpColParent;
01177 tmpColParent = NULL;
01178 delete[] tmpRowParent;
01179 tmpRowParent = NULL;
01180
01181
01182
01183 } else {
01184
01185 solveRestrictedMasterRelaxation( );
01186 }
01187
01188
01189 std::cout << std::endl << std::endl;
01190 std::cout << "FINISH SOLVING THE MASTER " << std::endl;
01191
01192
01193
01194
01195
01196 if( osnodeParent != NULL){
01197 for(i = 0; i < osnodeParent->rowIdxNumNonz; i++){
01198
01199
01200 m_si->setRowLower( osnodeParent->rowIdx[ i], 0);
01201 m_si->setRowUpper( osnodeParent->rowIdx[ i], 1);
01202
01203
01204 }
01205 }
01206
01207 m_si->setRowLower( rowIdx, 0);
01208 m_si->setRowUpper( rowIdx, 1);
01209
01210
01211
01212
01213 std::cout << std::endl << std::endl;
01214 std::cout << "MESSAGE: START CREATION OF A CHILD NODE" << std::endl;
01215 std::cout << "LB " << rowLB << " UB = " << rowUB << std::endl;
01216 std::cout << "MESSAGE: LP RELAXATION VALUE OF POTENTIAL CHILD NODE " << m_si->getObjValue() << std::endl;
01217 std::cout << "MESSAGE: OPTIMALITY STATUS OF NODE IS " << m_si->isProvenOptimal() << std::endl;
01218
01219 if( m_si->getObjValue() < (1 - m_osDecompParam.optTolPerCent)*m_zUB - m_osDecompParam.zeroTol && m_si->isProvenOptimal() == 1) {
01220
01221 std::cout << "MESSAGE: WE CANNOT FATHOM THE CHILD BASED ON UPPER BOUND " << std::endl;
01222 numCols = m_si->getNumCols();
01223 numRows = m_si->getNumRows();
01224 thetaNumNonz = 0;
01225
01226 for(i = 0; i < numCols; i++){
01227
01228 *(m_theta + i) = m_si->getColSolution()[i];
01229 if( *(m_theta + i) > m_osDecompParam.zeroTol) thetaNumNonz++;
01230
01231 }
01232 if( isInteger( m_theta, numCols, m_osDecompParam.zeroTol) == true){
01233
01234 std::cout << "MESSAGE: WE HAVE AN INTEGRALITY FATHOM " << m_zUB << std::endl;
01235 if( m_zUB > m_si->getObjValue() ){
01236
01237 m_zUB = m_si->getObjValue() ;
01238
01239 if( m_zOptIndexes.size() > 0) m_zOptIndexes.clear();
01240
01241 for(i = 0; i < numCols; i++){
01242
01243 if( *(m_theta + i) > m_osDecompParam.zeroTol) m_zOptIndexes.push_back( i) ;
01244
01245 }
01246 }
01247
01248 }else{
01249
01250 std::cout << "MESSAGE: WE ARE CREATING A CHILD NODE WITH NUMBER COLUMNS = "<< numCols << std::endl;
01251 osnodeChild = new OSNode(childRowIdxNumNonz, thetaNumNonz );
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283 if(osnodeParent == NULL){
01284 osnodeChild->rowIdx[ 0] = rowIdx;
01285 if(rowLB <= m_osDecompParam.zeroTol) osnodeChild->rowLB[ 0] = 0;
01286 else osnodeChild->rowLB[ 0] = 1;
01287
01288 if(rowUB <= m_osDecompParam.zeroTol) osnodeChild->rowUB[ 0] = 0;
01289 else osnodeChild->rowUB[ 0] = 1;
01290
01291
01292 }else{
01293
01294 for(i = 0; i < osnodeParent->rowIdxNumNonz; i++){
01295
01296 osnodeChild->rowIdx[ i] = osnodeParent->rowIdx[ i];
01297 osnodeChild->rowLB[ i] = osnodeParent->rowLB[ i];
01298 osnodeChild->rowUB[ i] = osnodeParent->rowUB[ i];
01299
01300 }
01301
01302
01303 osnodeChild->rowIdx[ childRowIdxNumNonz - 1] = rowIdx;
01304
01305
01306
01307 if(rowLB <= m_osDecompParam.zeroTol) osnodeChild->rowLB[ childRowIdxNumNonz - 1 ] = 0;
01308 else osnodeChild->rowLB[ childRowIdxNumNonz - 1 ] = 1;
01309
01310 if(rowUB <= m_osDecompParam.zeroTol) osnodeChild->rowUB[ childRowIdxNumNonz - 1 ] = 0;
01311 else osnodeChild->rowUB[ childRowIdxNumNonz - 1 ] = 1;
01312
01313
01314
01315 }
01316
01317 osnodeChild->lpValue = m_si->getObjValue();
01318
01319 thetaNumNonz = 0;
01320 for(i = 0; i < numCols; i++){
01321
01322 if( *(m_theta + i) > m_osDecompParam.zeroTol){
01323
01324 osnodeChild->thetaIdx[ thetaNumNonz] = i;
01325 osnodeChild->theta[ thetaNumNonz] = *(m_theta + i);
01326
01327 thetaNumNonz++;
01328
01329
01330
01331
01332 }
01333
01334
01335
01336 if(m_si->getReducedCost()[i] < (m_zUB - osnodeChild->lpValue) ) osnodeChild->reducedCostIdx.insert( i);
01337
01338 }
01339 }
01340 }
01341
01342 std::cout << std::endl << std::endl;
01343 return osnodeChild;
01344
01345 } catch (const ErrorClass& eclass) {
01346
01347
01348 throw ErrorClass(eclass.errormsg);
01349
01350 }
01351
01352 }
01353
01354
01355 void OSColGenApp::createBranchingCut(const int* thetaIdx, const double* theta,
01356 const int numThetaVar, std::map<int, int> &varConMap, int &rowIdx){
01357
01358 int varIdx;
01359 int numNonz;
01360 int* indexes;
01361 double* values;
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 double bigM = m_osDecompParam.artVarCoeff;
01374 double rowArtVal ;
01375
01376 std::map<int, int>::iterator mit;
01377
01378
01379
01380
01381
01382
01383
01384 m_osrouteSolver->getBranchingCut(thetaIdx, theta, numThetaVar,
01385 varConMap, varIdx, numNonz, indexes, values);
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402 if( numNonz >0){
01403
01404
01405
01406
01407 m_si->addRow(numNonz, indexes, values, 0, 1) ;
01408
01409
01410
01411 rowArtVal = -1.0;
01412 rowIdx = m_si->getNumRows() - 1;
01413
01414
01415
01416
01417 rowArtVal = 1.0;
01418 m_si->addCol(1, &rowIdx, &rowArtVal, 0, 1.0, bigM);
01419
01420 m_numColumnsGenerated++;
01421
01422
01423 varConMap.insert( std::pair<int, int>(varIdx , rowIdx) );
01424
01425 m_rowIdxVarMap.insert( std::pair<int, int>(rowIdx , varIdx) );
01426
01427
01428
01429 } else{
01430
01431
01432
01433
01434 mit = varConMap.find( varIdx);
01435 if( mit == varConMap.end() ) throw ErrorClass("in branchAndBound getBranchingCut() returned inconsistent value for varIdx");
01436 else rowIdx = mit->second;
01437
01438
01439 }
01440
01441
01442
01443 }
01444
01445
01446
01447 void OSColGenApp::createBranchingCut(const double* theta,
01448 const int numThetaVar, std::map<int, int> &varConMap, int &rowIdx){
01449
01450 int varIdx;
01451 int numNonz;
01452 int* indexes;
01453 double* values;
01454
01455
01456
01457 double bigM = m_osDecompParam.artVarCoeff;
01458 double rowArtVal ;
01459
01460 std::map<int, int>::iterator mit;
01461
01462
01463 m_osrouteSolver->getBranchingCut( theta, numThetaVar,
01464 varConMap, varIdx, numNonz, indexes, values);
01465
01466
01467 std::cout << "varIDX2 = " << varIdx << std::endl;
01468 std::cout << "numNonz2 = " << numNonz << std::endl;
01469
01470
01471
01472
01473
01475
01476
01477
01478
01479
01480
01481
01482
01483 if( numNonz >0){
01484
01485
01486
01487 m_si->addRow(numNonz, indexes, values, 0, 1) ;
01488
01489
01490
01491 rowArtVal = -1.0;
01492 rowIdx = m_si->getNumRows() - 1;
01493
01494
01495
01496
01497 rowArtVal = 1.0;
01498
01499 m_si->addCol(1, &rowIdx, &rowArtVal, 0, 1.0, bigM);
01500
01501 m_numColumnsGenerated++;
01502
01503
01504 varConMap.insert ( std::pair<int,int>(varIdx , rowIdx) );
01505 m_rowIdxVarMap.insert( std::pair<int, int>(rowIdx , varIdx) );
01506
01507
01508
01509 } else{
01510
01511
01512
01513
01514 mit = varConMap.find( varIdx);
01515 if( mit == varConMap.end() ) throw ErrorClass("in branchAndBound getBranchingCut() returned inconsistent value for varIdx");
01516 else rowIdx = mit->second;
01517
01518
01519 }
01520
01521
01522
01523 }
01524
01525
01526 void OSColGenApp::resetMaster(){
01527
01528
01530
01531
01532 std::map<int, int>::iterator mit;
01533 std::set<int>::iterator sit;
01534 std::vector<int>::iterator vit;
01535 std::vector<std::pair<int, int> >::iterator vit2;
01536 std::map<int, OSNode*>::iterator mit2;
01537 int i;
01538 int kount = 0;
01539
01540
01541 inVars.clear();
01542
01543 try{
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553 for(vit = m_zOptRootLP.begin() ; vit != m_zOptRootLP.end(); vit++){
01554
01555 inVars.insert( std::pair<int, int>(*vit, kount++) );
01556
01557 }
01558
01559
01560
01561
01562 for(vit = m_zOptIndexes.begin() ; vit != m_zOptIndexes.end(); vit++){
01563
01564 if( inVars.find( *vit ) == inVars.end() ) inVars.insert( std::pair<int, int>(*vit, kount++) );
01565
01566
01567
01568
01569
01570
01571 }
01572
01573
01574
01575
01576
01577 double tmpEps = OSDBL_MAX;
01578 for(mit2 = m_nodeMap.begin(); mit2 !=m_nodeMap.end(); mit2++){
01579
01580 std::cout << "NUMBER OF REDUCED COSTS = " << mit2->second->reducedCostIdx.size() << std::endl;
01581 for(sit = mit2->second->reducedCostIdx.begin();
01582 sit != mit2->second->reducedCostIdx.end(); sit++){
01583
01584 if( ( inVars.find( *sit ) == inVars.end() )
01585 && (m_si->getObjCoefficients()[*sit] < m_osDecompParam.artVarCoeff)
01586 && (m_si->getReducedCost()[*sit] < tmpEps )
01587 )
01588 inVars.insert( std::pair<int, int>(*sit, kount++) );
01589
01590
01591 }
01592
01593
01594 for(i = 0; i < mit2->second->thetaNumNonz; i++){
01595
01596 if( inVars.find( mit2->second->thetaIdx[ i] ) == inVars.end() )
01597
01598 inVars.insert( std::pair<int, int>(mit2->second->thetaIdx[ i], kount++) );
01599
01600 }
01601
01602 }
01603
01604
01605
01606
01607 std::cout << "NUMBER OF COLUMNS = " << inVars.size() << std::endl;
01608 std::cout << "CALLING osroute solver reset " << std::endl;
01609 m_osrouteSolver->resetMaster( inVars, m_si );
01610
01611
01612
01613
01614 int numVars = m_si->getNumCols();
01615 double *tmpVals = NULL;
01616 tmpVals = new double[ numVars];
01617
01618 for(i = 0; i < numVars; i++) tmpVals[ i ] = 0;
01619
01620 for(mit = inVars.begin(); mit != inVars.end(); mit++){
01621
01622 tmpVals[ mit->second] = m_theta[ mit->first] ;
01623 }
01624
01625
01626 for(i = 0; i < numVars; i++) m_theta[ i] = tmpVals[ i] ;
01627
01628
01629
01630 for(mit2 = m_nodeMap.begin(); mit2 !=m_nodeMap.end(); mit2++){
01631
01632
01633 for(i = 0; i < mit2->second->thetaNumNonz; i++){
01634
01635
01636 if( inVars.find( mit2->second->thetaIdx[ i] ) == inVars.end() ) throw ErrorClass("index problem in resetMaster");
01637
01638
01639 mit2->second->thetaIdx[ i] = inVars[ mit2->second->thetaIdx[ i] ] ;
01640
01641
01642
01643 }
01644
01645
01646 for(vit2 = mit2->second->colBasisStatus.begin();
01647 vit2 != mit2->second->colBasisStatus.end(); vit2++){
01648
01649 (*vit2).first = inVars[ (*vit2).first ] ;
01650
01651
01652 }
01653
01654
01655 std::set<int> tmpSet;
01656 for(sit = mit2->second->reducedCostIdx.begin();
01657 sit != mit2->second->reducedCostIdx.end(); sit++){
01658
01659 tmpSet.insert( inVars[ *sit ] );
01660 }
01661
01662 mit2->second->reducedCostIdx.clear();
01663
01664 for(sit = tmpSet.begin(); sit != tmpSet.end(); sit++){
01665
01666
01667
01668 if( inVars.find( *sit) != inVars.end() )
01669 mit2->second->reducedCostIdx.insert( *sit );
01670 }
01671 tmpSet.clear();
01672
01673
01674 }
01675
01676
01677 for(vit = m_zOptIndexes.begin() ; vit != m_zOptIndexes.end(); vit++) *vit = inVars[ *vit ];
01678
01679
01680
01681 for(vit = m_zOptRootLP.begin() ; vit != m_zOptRootLP.end(); vit++) *vit = inVars[ *vit ];
01682
01684
01685 delete m_solver;
01686 m_osinstanceMaster = m_osrouteSolver->m_osinstanceMaster;
01687 m_solver = new CoinSolver();
01688
01689
01690
01691 m_solver->sSolverName ="cbc";
01692
01693 m_solver->osinstance = m_osrouteSolver->m_osinstanceMaster;
01694 m_solver->osoption = m_osoption;
01695
01696 m_solver->buildSolverInstance();
01697
01698
01699 m_si = m_solver->osiSolver;
01700
01701 if(m_si->getNumCols() != m_osrouteSolver->m_osinstanceMaster->getVariableNumber() )
01702 throw ErrorClass("there is an inconsistency in the the model rebuid in resetMaster");
01703
01704 std::cout << "OSINTANCE NUMBER OF COLUMNS = " << m_osrouteSolver->m_osinstanceMaster->getVariableNumber() << std::endl;
01705 std::cout << "OSINTANCE NUMBER OF ROWS = " << m_osrouteSolver->m_osinstanceMaster->getConstraintNumber() << std::endl;
01706 std::cout << "SOLVER INTERFACE NUMBER OF COLUMNS = " << m_si->getNumCols() << std::endl;
01707 std::cout << "SOLVER INTERFACE NUMBER OF ROWS = " <<m_si->getNumRows() << std::endl;
01708
01709
01710
01711
01712
01713
01714 double lpVal;
01715
01716 for(mit2 = m_nodeMap.begin(); mit2 !=m_nodeMap.end(); mit2++){
01717
01718 lpVal = 0;
01719
01720 for(i = 0; i < mit2->second->thetaNumNonz; i++){
01721
01722 lpVal += m_si->getObjCoefficients()[ mit2->second->thetaIdx[ i] ]*mit2->second->theta[ i];
01723
01724
01725 }
01726
01727 if( ( lpVal - mit2->second->lpValue > m_osDecompParam.zeroTol ) ||
01728 (mit2->second->lpValue - lpVal > m_osDecompParam.zeroTol ) ) throw ErrorClass( "uh oh, problem with node lp value" );
01729
01730
01731 }
01732
01733
01734
01735
01736
01737
01738 delete[] tmpVals;
01739 tmpVals = NULL;
01740
01741 } catch (const ErrorClass& eclass) {
01742
01743 throw ErrorClass(eclass.errormsg);
01744
01745 }
01746
01747
01748 }
01749
01750 void OSColGenApp::printTreeInfo(){
01751
01752 std::map<int, OSNode*>::iterator mit;
01753 int i;
01754
01755 std::cout << std::endl << std::endl;
01756
01757 std::cout << "NUMBER OF REMAINING DANGLING NODES = " << m_nodeMap.size() << std::endl;
01758
01759 if( m_nodeMap.size() > 0) m_zLB = OSDBL_MAX;
01760
01761 for ( mit = m_nodeMap.begin() ;
01762 mit != m_nodeMap.end(); mit++ ){
01763
01764 std::cout << "NODE ID VALUE = " << mit->second->nodeID << " " ;
01765 std::cout << " NODE LP VALUE = " << mit->second->lpValue << std::endl;
01766
01767 for(i = 0; i < mit->second->rowIdxNumNonz; i++){
01768
01769 std::cout << "CONSTRAINT = " << mit->second->rowIdx[ i] ;
01770 std::cout << " CONSTRAINT LB = " << mit->second->rowLB[ i] ;
01771 std::cout << " CONSTRAINT UB = " << mit->second->rowUB[ i] << std::endl;
01772 }
01773
01774 if( mit->second->lpValue < m_zLB) m_zLB = mit->second->lpValue;
01775
01776
01777 }
01778 m_nodeMap.clear();
01779
01780
01781 }
01782
01783
01784 void OSColGenApp::checkNodeConsistency( const int rowIdx, const OSNode *osnode){
01785 try{
01786 if( osnode == NULL) return;
01787
01788 std::set<int> indexSet;
01789 int i;
01790 int j;
01791 int rowIdxNumNonz = 0;
01792 int thetaNumNonz = 0;
01793 rowIdxNumNonz = osnode->rowIdxNumNonz;
01794 thetaNumNonz = osnode->thetaNumNonz;
01795 std::map<int, double> varSumMap;
01796
01797 std::cout << "MESSAGE: CHECKING FOR NODE CONSISTENCY CONSTRAINT" << std::endl;
01798
01799 for(i = 0; i < thetaNumNonz; i++){
01800
01801
01802
01803 std::cout << "theta idx " << osnode->thetaIdx[ i] << " theta value " << osnode->theta[ i] << std::endl;
01804
01805 for(j = m_osrouteSolver->m_thetaPnt[ osnode->thetaIdx[ i] ]; j < m_osrouteSolver->m_thetaPnt[ osnode->thetaIdx[ i] + 1 ]; j++ ){
01806
01807 if( varSumMap.find( m_osrouteSolver->m_thetaIndex[ j] ) == varSumMap.end() ){
01808
01809 varSumMap[ m_osrouteSolver->m_thetaIndex[ j] ] = osnode->theta[ i];
01810
01811 }else{
01812
01813 varSumMap[ m_osrouteSolver->m_thetaIndex[ j] ] += osnode->theta[ i];
01814 }
01815
01816 std::cout << "xijk idx " << m_osrouteSolver->m_thetaIndex[ j] << " variable name = " <<
01817 m_osrouteSolver->m_variableNames[ m_osrouteSolver->m_thetaIndex[ j] ] << std::endl;
01818
01819 }
01820
01821 }
01822
01823
01824
01825 for(i = 0; i < rowIdxNumNonz; i++){
01826
01827 std::cout << " row number " << osnode->rowIdx[ i] << " LB = " << osnode->rowLB[ i] << " UB = "
01828 << osnode->rowUB[ i] ;
01829
01830 std::cout << " variable index = " << m_rowIdxVarMap[ osnode->rowIdx[ i] ] ;
01831
01832 std::cout << " variable name = " << m_osrouteSolver->m_variableNames[ m_rowIdxVarMap[ osnode->rowIdx[ i] ] ] ;
01833
01834 std::cout << " variable sum = " << varSumMap[ m_rowIdxVarMap[ osnode->rowIdx[ i] ]] << std::endl ;
01835
01836 if(indexSet.find( osnode->rowIdx[ i] ) == indexSet.end() ){
01837
01838 indexSet.insert( osnode->rowIdx[ i] );
01839
01840 }else{
01841
01842
01843 throw ErrorClass( "We are trying to add an existing constraint to a node" );
01844 }
01845
01846
01847
01848 }
01849
01850 } catch (const ErrorClass& eclass) {
01851
01852 throw ErrorClass(eclass.errormsg);
01853
01854 }
01855 }