00001
00014 #include "OSBearcatSolverXij.h"
00015
00016 #include "OSErrorClass.h"
00017 #include "OSDataStructures.h"
00018
00019 #include "OSInstance.h"
00020 #include "OSCoinSolver.h"
00021 #include "OSConfig.h"
00022 #include "OSResult.h"
00023
00024 #include "OSiLReader.h"
00025 #include "OSiLWriter.h"
00026 #include "OSoLReader.h"
00027 #include "OSoLWriter.h"
00028 #include "OSrLReader.h"
00029 #include "OSrLWriter.h"
00030 #include "OSInstance.h"
00031 #include "OSFileUtil.h"
00032 #include "OSStringUtil.h"
00033
00034 #include "CoinTime.hpp"
00035
00036 #include "ClpFactorization.hpp"
00037 #include "ClpNetworkMatrix.hpp"
00038 #include "OsiClpSolverInterface.hpp"
00039
00040 #include <iostream>
00041
00042 #include <algorithm>
00043
00044
00045 #ifdef HAVE_CMATH
00046 # include <cmath>
00047 #else
00048 # ifdef HAVE_MATH_H
00049 # include <math.h>
00050 # else
00051 # error "don't have header file for math"
00052 # endif
00053 #endif
00054
00055 #ifdef HAVE_CTIME
00056 # include <ctime>
00057 #else
00058 # ifdef HAVE_TIME_H
00059 # include <time.h>
00060 # else
00061 # error "don't have header file for time"
00062 # endif
00063 #endif
00064
00065 using std::ostringstream;
00066
00067
00068 OSBearcatSolverXij::OSBearcatSolverXij() {
00069 std::cout << "INSIDE OSBearcatSolverXij CONSTRUCTOR with OSOption argument" << std::endl;
00070 }
00071
00072 OSBearcatSolverXij::OSBearcatSolverXij(OSOption *osoption) {
00073 std::cout << "INSIDE OSBearcatSolverXij CONSTRUCTOR with OSOption argument" << std::endl;
00074
00075 m_hubPoint = NULL;
00076
00077 m_bestIPValue = OSDBL_MAX;
00078 m_bestLPValue = -OSDBL_MAX;
00079
00080 m_upperBoundL = NULL;
00081 m_upperBoundLMax = -OSINT_MAX;
00082 m_minDemand = OSINT_MAX;
00083
00084 m_u = NULL;
00085 m_v = NULL;
00086 m_g = NULL;
00087 m_px = NULL;
00088 m_tx =NULL;
00089 m_varIdx = NULL;
00090
00091 m_optL = NULL;
00092 m_optD = NULL;
00093 m_vv = NULL;
00094 m_vvpnt = NULL;
00095
00096 m_demand = NULL;
00097 m_cost = NULL;
00098
00099 m_rc = NULL;
00100
00101 m_routeCapacity = NULL;
00102 m_routeMinPickup = NULL;
00103
00104 m_osoption = osoption;
00105
00106 m_multiCommodCutLimit = 250;
00107 m_numMultCuts = 0;
00108
00109
00110 }
00111
00112 void OSBearcatSolverXij::initializeDataStructures(){
00113
00114 int k;
00115 int i;
00116 int l;
00117 int tmpVal;
00118
00119 try{
00120
00121
00122
00123 getOptions( m_osoption);
00124
00125 if(m_cost == NULL) throw ErrorClass("Option file did not contain cost data");
00126
00127 getVariableIndexMap();
00128
00129
00130 m_maxMasterRows = m_maxBmatrixCon + m_numNodes;
00131
00132 m_upperBoundL = new int[ m_numHubs];
00133 m_lowerBoundL = new int[ m_numHubs];
00134
00135 m_hubPoint = new int[ m_numHubs];
00136
00137 permuteHubs();
00138
00139
00140 for(k = 0; k < m_numHubs; k++){
00141
00142
00143 tmpVal = 0;
00144 for(i = 0; i < m_numHubs; i++)
00145 if( i != k) tmpVal += m_routeCapacity[ i];
00146
00147 m_lowerBoundL[ k] = std::max( m_routeMinPickup[ k], (m_totalDemand - tmpVal) ) ;
00148
00149 m_upperBoundL[ k] = m_routeCapacity[ k];
00150
00151
00152 if(m_upperBoundL[ k] > m_totalDemand) m_upperBoundL[ k] = m_totalDemand;
00153 if( m_upperBoundL[ k] > m_upperBoundLMax) m_upperBoundLMax = m_upperBoundL[ k];
00154
00155 }
00156
00157
00158
00159
00160 m_varIdx = new int[ m_upperBoundLMax + 1];
00161
00162
00163 m_u = new double*[ m_numNodes];
00164 m_v = new double*[ m_numNodes];
00165 m_g = new double*[ m_numNodes];
00166
00167 m_px = new int*[ m_numNodes];
00168 m_tx = new int*[ m_numNodes];
00169
00170
00171
00181 for (i = 0; i < m_numNodes; i++) {
00182
00183
00184 m_u[ i] = new double[ m_upperBoundLMax + 1];
00185 m_v[ i] = new double[ m_upperBoundLMax + 1];
00186
00187
00188
00189 for(l = 0; l <= m_upperBoundLMax; l++){
00190
00191 m_u[ i][l] = OSDBL_MAX;
00192 m_v[ i][l] = OSDBL_MAX;
00193 }
00194
00195 m_g[ i] = new double[ m_numNodes];
00196 m_px[ i] = new int[ m_upperBoundLMax + 1];
00197 m_tx[ i] = new int[m_upperBoundLMax + 1];
00198
00199
00200 }
00201
00202
00203
00204 m_optL = new int[ m_numHubs];
00205 m_optD = new int[ m_numHubs];
00206
00207 m_vv = new double*[ m_numHubs];
00208 m_vvpnt = new int*[ m_numHubs];
00209 m_rc = new double*[ m_numHubs];
00210
00211 for (k = 0; k < m_numHubs; k++) {
00212
00213
00214 m_vv[ k] = new double[ m_totalDemand + 1];
00215 m_vvpnt[ k] = new int[ m_totalDemand + 1];
00216
00217
00218
00219
00220 m_rc[ k] = new double[ m_upperBoundL[ k]*(m_numNodes*m_numNodes - m_numNodes)];
00221
00222
00223 }
00224
00225 m_optValHub = new double[ m_numHubs];
00226
00227 m_variableNames = new std::string[ m_numNodes*(m_numNodes - 1)];
00228
00229 createVariableNames();
00230
00231
00232
00233 m_pntAmatrix = new int[ m_numNodes - m_numHubs + 1];
00234
00235
00236
00237
00238
00239 m_Amatrix = new int[ (m_numNodes - m_numHubs)*(m_numNodes - 1) ];
00240 createAmatrix();
00241
00242
00243
00244 int numVar = m_numNodes*m_numNodes - m_numNodes ;
00245 m_tmpScatterArray = new int[ numVar ];
00246 for(i = 0; i < numVar; i++){
00247
00248 m_tmpScatterArray[ i] = 0;
00249
00250 }
00251
00252
00253 m_newColumnNonz = new int[ m_numHubs] ;
00254 m_costVec = new double[ m_numHubs];
00255 m_newColumnRowIdx = new int*[ m_numHubs];
00256 m_newColumnRowValue = new double*[ m_numHubs];
00257
00258 for (k = 0; k < m_numHubs; k++) {
00259
00260
00261 m_newColumnRowValue[ k] = new double[ m_maxBmatrixCon + m_numNodes];
00262 m_newColumnRowIdx[ k] = new int[ m_maxBmatrixCon + m_numNodes];
00263
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 m_newRowNonz = new int[ 100] ;
00277 m_newRowColumnIdx = new int*[ 100] ;
00278 m_newRowColumnValue = new double*[ 100] ;
00279 m_newRowUB = new double[ 100];
00280 m_newRowLB = new double[ 100];
00281
00282
00283
00284
00285 for (k = 0; k < 100; k++) {
00286
00287
00288 m_newRowColumnValue[ k] = new double[ m_maxMasterColumns];
00289 m_newRowColumnIdx[ k] = new int[ m_maxMasterColumns];
00290
00291 }
00292
00293
00294 m_convexityRowIndex = new int[ m_maxMasterColumns];
00295
00296
00297 branchCutIndexes = new int[ m_maxMasterColumns];
00298 branchCutValues = new double[ m_maxMasterColumns];
00299
00300 m_thetaPnt = new int[ m_maxMasterColumns + 1];
00301 for(i = 0; i <= m_maxMasterColumns; i++){
00302 m_thetaPnt[ i] = 0;
00303 }
00304 m_thetaCost = new double[ m_maxMasterColumns];
00305 m_thetaIndex = new int[ m_maxThetaNonz];
00306 m_numThetaVar = 0;
00307 m_numThetaNonz = 0;
00308 m_thetaPnt[ m_numThetaVar] = 0;
00309
00310
00311
00312
00313
00314 m_pntBmatrix = new int[ m_maxBmatrixCon];
00315
00316 m_BmatrixIdx = new int[ m_maxBmatrixNonz];
00317 m_BmatrixRowIndex = new int[ m_maxBmatrixCon];
00318 for(i = 0; i < m_maxBmatrixCon; i++) m_BmatrixRowIndex[ i] = -1;
00319
00320
00321 m_BmatrixVal = new double[ m_maxBmatrixNonz];
00322
00323
00324 m_numBmatrixCon = 0;
00325 m_numBmatrixNonz = 0;
00326 m_pntBmatrix[ m_numBmatrixCon] = 0;
00327
00328 ;
00329
00330
00331 m_separationIndexMap = new int[m_numNodes*(m_numNodes - 1)];
00332
00333 for(i = 0; i < m_numNodes*(m_numNodes - 1); i++){
00334
00335 m_separationIndexMap[ i] = OSINT_MAX;
00336
00337 }
00338
00339
00340
00341
00342
00343 getSeparationInstance();
00344 for(k = 0; k < m_numHubs; k++){
00345
00346 m_multCommodCutSolvers.push_back( getMultiCommodInstance( k) );
00347
00348 }
00349
00350 } catch (const ErrorClass& eclass) {
00351
00352 throw ErrorClass(eclass.errormsg);
00353
00354 }
00355
00356
00357 }
00358
00359
00360 OSBearcatSolverXij::~OSBearcatSolverXij(){
00361
00362 std::cout << "INSIDE ~OSBearcatSolverXij DESTRUCTOR" << std::endl;
00363
00364
00365
00366
00367 int i;
00368
00369 delete[] m_routeCapacity;
00370 m_routeCapacity = NULL;
00371
00372
00373 delete[] m_routeMinPickup;
00374 m_routeMinPickup = NULL;
00375
00376 for(i = 0; i < m_numNodes; i++){
00377
00378
00379
00380 delete[] m_v[i];
00381 delete[] m_g[i];
00382 delete[] m_px[i];
00383 delete[] m_tx[i];
00384 delete[] m_u[i];
00385
00386
00387 }
00388
00389 delete[] m_u;
00390 m_u= NULL;
00391
00392 delete[] m_v;
00393 m_v= NULL;
00394
00395 delete[] m_g;
00396 m_g= NULL;
00397
00398 delete[] m_px;
00399 m_px= NULL;
00400
00401 delete[] m_tx;
00402 m_tx= NULL;
00403
00404
00405
00406 if(m_demand != NULL){
00407
00408 delete[] m_demand;
00409 }
00410
00411
00412 if(m_varIdx != NULL){
00413 delete[] m_varIdx;
00414 m_varIdx = NULL;
00415
00416 }
00417
00418 if(m_cost != NULL ){
00419 delete[] m_cost;
00420 m_cost = NULL;
00421 }
00422
00423 for(i = 0; i < m_numHubs; i++){
00424
00425 delete[] m_vv[i];
00426 delete[] m_vvpnt[i];
00427 delete[] m_rc[ i];
00428
00429
00430 }
00431 delete[] m_optL;
00432 m_optL = NULL;
00433 delete[] m_optD;
00434 m_optD = NULL;
00435 delete[] m_vv;
00436 m_vv = NULL;
00437 delete[] m_vvpnt;
00438 m_vvpnt = NULL;
00439
00440 delete[] m_rc;
00441 m_rc = NULL;
00442
00443 delete[] m_upperBoundL;
00444 m_upperBoundL = NULL;
00445
00446 delete[] m_lowerBoundL;
00447 m_lowerBoundL = NULL;
00448
00449 delete[] m_hubPoint;
00450 m_hubPoint = NULL;
00451
00452 delete[] m_optValHub;
00453 m_optValHub = NULL;
00454
00455 delete[] m_variableNames;
00456 m_variableNames = NULL;
00457
00458 delete[] m_pntAmatrix;
00459 m_pntAmatrix = NULL;
00460
00461 delete[] m_Amatrix;
00462 m_Amatrix = NULL;
00463
00464 delete[] m_tmpScatterArray;
00465 m_tmpScatterArray = NULL;
00466
00467 delete[] m_newColumnNonz ;
00468 m_newColumnNonz = NULL;
00469 delete[] m_costVec ;
00470 m_costVec = NULL;
00471
00472 for(i = 0; i < m_numHubs; i++){
00473
00474 delete[] m_newColumnRowIdx[i];
00475 delete[] m_newColumnRowValue[i];
00476 }
00477
00478 delete[] m_newColumnRowIdx;
00479 m_newColumnRowIdx = NULL;
00480
00481 delete[] m_newColumnRowValue;
00482 m_newColumnRowValue = NULL;
00483
00484
00485 delete[] m_convexityRowIndex;
00486 m_convexityRowIndex = NULL;
00487
00488
00489
00490 delete[] m_newRowNonz;
00491 m_newRowNonz = NULL;
00492
00493 delete[] m_newRowUB ;
00494 m_newRowUB = NULL;
00495
00496 delete[] m_newRowLB ;
00497 m_newRowLB = NULL;
00498
00499
00500 for (i = 0; i < m_numHubs; i++) {
00501
00502 delete[] m_newRowColumnValue[ i];
00503 delete[] m_newRowColumnIdx[ i];
00504
00505 }
00506
00507 delete[] m_newRowColumnIdx;
00508 m_newRowColumnIdx = NULL;
00509
00510 delete[] m_newRowColumnValue;
00511 m_newRowColumnValue = NULL;
00512
00513
00514 delete[] branchCutIndexes ;
00515 branchCutIndexes = NULL;
00516
00517 delete[] branchCutValues ;
00518 branchCutValues = NULL;
00519
00520
00521 delete[] m_thetaPnt;
00522 m_thetaPnt = NULL;
00523
00524 delete[] m_thetaIndex;
00525 m_thetaIndex = NULL;
00526
00527
00528 delete[] m_thetaCost;
00529 m_thetaCost = NULL;
00530
00531
00532 delete[] m_pntBmatrix ;
00533 m_pntBmatrix = NULL;
00534
00535 delete[] m_BmatrixIdx ;
00536 m_BmatrixIdx = NULL;
00537
00538 delete[] m_BmatrixVal ;
00539 m_BmatrixVal = NULL;
00540
00541 delete[] m_BmatrixRowIndex ;
00542 m_BmatrixRowIndex = NULL;
00543
00544
00545
00546
00547 delete[] m_separationIndexMap;
00548 m_separationIndexMap = NULL;
00549
00550 delete m_separationClpModel;
00551 m_separationClpModel = NULL;
00552
00553 delete m_osinstanceSeparation;
00554 m_osinstanceSeparation = NULL;
00555
00556 std::vector<CoinSolver*>::iterator vit;
00557 for(vit = m_multCommodCutSolvers.begin(); vit < m_multCommodCutSolvers.end(); vit++){
00558
00559 delete *vit;
00560 }
00561
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 void OSBearcatSolverXij::getOptL( double** c) {
00571
00572
00573
00574 int k;
00575 int d;
00576 int d1;
00577 int kountVar;
00578 double testVal;
00579 int l;
00580
00581 double trueMin;
00582
00583 bool isFeasible;
00584 isFeasible = false;
00585
00586 kountVar = 0;
00587
00588
00589
00590 m_vv[ m_hubPoint[0] ][ 0] = 0;
00591 for(d = 1; d <= m_totalDemand; d++){
00592
00593 m_vv[ m_hubPoint[0] ][ d] = OSDBL_MAX;
00594
00595 }
00596
00597 for(k = 1; k < m_numHubs - 1; k++){
00598 for(d = 0; d <= m_totalDemand; d++){
00599
00600 m_vv[ m_hubPoint[ k] ][ d] = OSDBL_MAX;
00601
00602 }
00603 }
00604
00605
00606
00607
00608 int dlower;
00609 dlower = 0;
00610
00611 for(k = 1; k < m_numHubs; k++){
00612
00613 dlower += m_lowerBoundL[ m_hubPoint[k - 1] ];
00614
00615
00616 for(d = dlower; d <= m_totalDemand; d++){
00617
00618 m_vv[ m_hubPoint[ k] ][ d] = OSDBL_MAX;
00619
00620
00621
00622 for(d1 = 0; d1 <= d; d1++){
00623
00624 l = d - d1;
00625
00626
00627
00628 if( (m_vv[ m_hubPoint[ k - 1] ][ d1] < OSDBL_MAX) && (l <= m_upperBoundL[ m_hubPoint[ k - 1] ]) && (l >= m_lowerBoundL[ m_hubPoint[k - 1] ]) ){
00629
00630
00631
00632
00633
00634
00635 testVal = qrouteCost( m_hubPoint[ k - 1], l, c[ m_hubPoint[ k - 1] ], &kountVar);
00636
00637
00638
00639
00640 if( m_vv[ m_hubPoint[ k-1] ][ d1] + testVal < m_vv[ m_hubPoint[ k] ][ d] ){
00641
00642 m_vv[ m_hubPoint[ k] ][ d] = m_vv[ m_hubPoint[ k-1] ][ d1] + testVal;
00643
00644 m_vvpnt[ m_hubPoint[ k] ][ d] = d1;
00645
00646 }
00647
00648
00649 }
00650
00651 }
00652
00653 }
00654
00655
00656
00657 }
00658
00659 trueMin = OSDBL_MAX;
00660
00661
00662
00663
00664
00665
00666
00667
00668 for(d = dlower; d < m_totalDemand; d++){
00669
00670
00671 l = m_totalDemand - d;
00672
00673 if(m_vv[ m_hubPoint[ m_numHubs - 1] ][ d] < OSDBL_MAX && l <= m_upperBoundL[ m_hubPoint[ m_numHubs - 1] ] && l >= m_lowerBoundL[ m_hubPoint[ m_numHubs - 1] ]){
00674
00675
00676
00677
00678
00679 isFeasible = true;
00680
00681
00682 testVal = qrouteCost(m_hubPoint[m_numHubs -1] , l, c[ m_hubPoint[ m_numHubs -1] ], &kountVar);
00683
00684
00685
00686
00687 if(m_vv[ m_hubPoint[ m_numHubs - 1] ][ d] + testVal < trueMin){
00688
00689 trueMin = m_vv[ m_hubPoint[ m_numHubs -1] ][ d] + testVal;
00690 m_optD[ m_hubPoint[ m_numHubs -1] ] = d;
00691 m_optL[ m_hubPoint[ m_numHubs -1] ] = l;
00692
00693 }
00694
00695
00696 }
00697 }
00698
00699
00700
00701 if( isFeasible == false){
00702
00703 std::cout << "NOT ENOUGH CAPACITY " << std::endl;
00704 for(k = 0; k < m_numHubs; k++) std::cout << " k perm = " << m_hubPoint[ k ]<< std::endl;
00705 throw ErrorClass( "NOT ENOUGH CAPACITY ");
00706 }
00707
00708 k = m_numHubs - 1;
00709
00710 while( k - 1 >= 0) {
00711
00712 m_optD[ m_hubPoint[ k - 1] ] = m_vvpnt[ m_hubPoint[ k] ][ m_optD[ m_hubPoint[ k] ] ];
00713
00714 m_optL[ m_hubPoint[ k - 1] ] = m_optD[ m_hubPoint[ k ] ] - m_optD[ m_hubPoint[ k - 1] ] ;
00715
00716 k--;
00717
00718 }
00719
00720 }
00721
00722
00723
00724
00725
00726
00727 double OSBearcatSolverXij::qrouteCost(const int& k, const int& l, const double* c, int* kountVar){
00728
00729
00730
00731
00732 double rcost;
00733 rcost = OSDBL_MAX;
00734
00735
00736
00737 if(l <= 0){
00738
00739 std::cout << "LVALUE NEGATIVE OR ZERO " << l << std::endl;
00740 exit( 1);
00741 }
00742
00743
00744
00745 if(l > m_upperBoundL[ k]){
00746
00747 std::cout << "LVALUE BIGGER THAN UPPER BOUND " << l << std::endl;
00748 exit( 1);
00749 }
00750
00751
00752
00753
00754
00755 int startPnt = (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
00756 c+= startPnt ;
00757
00758
00759
00760 *kountVar = 0;
00761 int bestLastNode;
00762
00763 bestLastNode = OSINT_MAX;
00764 int i;
00765 int j;
00766 int l1;
00767 int l2;
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 for(i = m_numHubs; i < m_numNodes; i++){
00783
00784
00785 for(l1 = m_minDemand; l1 <= l; l1++){
00786
00787
00788 m_u[i][l1] = OSDBL_MAX;
00789
00790 m_v[i][l1] = OSDBL_MAX;
00791 m_px[i][l1] = -1;
00792
00793
00794 if(l1 == *(m_demand + i) ){
00795
00796 m_px[i][l1] = k;
00797
00798
00799 m_u[i][l1] = *(c + k*(m_numNodes - 1) + i - 1);
00800
00801
00802
00803 }
00804
00805 }
00806 }
00807
00808
00809
00810
00811
00812
00813
00814 if(l == m_minDemand){
00815
00816 for(i = m_numHubs; i < m_numNodes; i++){
00817
00818
00819 if( m_u[i][l] + *(c + i*(m_numNodes-1) + k ) < rcost){
00820
00821 rcost = m_u[i][l] + *(c + i*(m_numNodes-1) + k );
00822
00823
00824
00825
00826
00827 bestLastNode = i;
00828 }
00829
00830 }
00831
00832
00833
00834 *(m_varIdx + (*kountVar)++) = startPnt + bestLastNode*(m_numNodes - 1) + k ;
00835 *(m_varIdx + (*kountVar)++) = startPnt + k*(m_numNodes - 1) + bestLastNode - 1;
00836
00837
00838 return rcost;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 for(l2 = m_minDemand + 1; l2 <= l; l2++){
00851
00852 for(i = m_numHubs; i < m_numNodes; i++) {
00853
00854
00855 if( *(m_demand + i) < l2 ){
00856
00857 for(j = m_numHubs; j < i; j++){
00858
00859
00860
00861
00862 l1 = l2 - *(m_demand + i);
00863
00864 if( m_px[j][ l1 ] != i ){
00865
00866
00867 m_g[j][i] = m_u[ j][ l1 ] + *(c + j*(m_numNodes-1) + i - 1) ;
00868
00869
00870
00871
00872 }else{
00873
00874 m_g[j][i] = m_v[ j][ l1] + *(c + j*(m_numNodes-1) + i - 1) ;
00875
00876
00877
00878 }
00879
00880
00881
00882 if(m_g[j][i] < m_u[i][l2] ){
00883
00884 m_u[i][l2] = m_g[j][i];
00885 m_px[i][l2] = j;
00886
00887 }
00888
00889
00890
00891 }
00892
00893
00894 for(j = i + 1; j < m_numNodes; j++){
00895
00896
00897
00898 l1 = l2 - *(m_demand + i);
00899
00900 if( m_px[j][ l1 ] != i ){
00901
00902
00903 m_g[j][i] = m_u[ j][ l1 ] + *(c + j*(m_numNodes-1) + i ) ;
00904
00905
00906 }else{
00907
00908 m_g[j][i] = m_v[ j][ l1] + *(c + j*(m_numNodes-1) + i ) ;
00909
00910 }
00911
00912
00913
00914 if(m_g[j][i] < m_u[i][l2] ){
00915
00916 m_u[i][l2] = m_g[j][i];
00917 m_px[i][l2] = j;
00918
00919 }
00920
00921
00922 }
00923
00924
00925
00926
00927
00928 for(j =m_numHubs; j < m_numNodes; j++){
00929
00930 if(j != i){
00931
00932 if( (m_g[j][i] < m_v[i][l2] ) && (m_px[i][l2] != j) ){
00933
00934
00935
00936 m_v[i][l2] = m_g[j][i];
00937 m_tx[i][l2] = j;
00938
00939
00940 }
00941
00942 }
00943
00944
00945 }
00946
00947
00948 if(l2 == l ){
00949
00950 if( m_u[i][l2] + *(c + i*(m_numNodes-1) + k ) < rcost){
00951
00952 rcost = m_u[i][l2] + *(c + i*(m_numNodes-1) + k );
00953
00954 bestLastNode = i;
00955 }
00956
00957 }
00958
00959
00960 }
00961
00962
00963 }
00964
00965
00966 }
00967
00968
00969
00970
00971
00972
00973
00974
00975 int currentNode;
00976 int successorNode;
00977 int lvalue;
00978
00979
00980
00981
00982
00983
00984
00985 *(m_varIdx + (*kountVar)++) = startPnt + bestLastNode*(m_numNodes - 1) + k ;
00986
00987
00988
00989
00990 if( bestLastNode == OSINT_MAX) return OSDBL_MAX;
00991
00992
00993 successorNode = k;
00994 currentNode = bestLastNode;
00995
00996 lvalue = l ;
00997
00998
00999
01000
01001 while(currentNode != k){
01002
01003 if(*kountVar == m_upperBoundLMax + 1) return OSDBL_MAX;
01004 if( m_px[ currentNode][ lvalue ] != successorNode){
01005
01006
01007
01008
01009 successorNode = currentNode;
01010 currentNode = m_px[ currentNode][ lvalue ];
01011
01012
01013 if(currentNode - successorNode > 0){
01014
01015
01016
01017
01018 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode;
01019
01020
01021 }else{
01022
01023
01024
01025
01026 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode - 1 ;
01027
01028 }
01029
01030
01031 }else{
01032
01033
01034
01035 successorNode = currentNode;
01036 currentNode = m_tx[ currentNode][ lvalue ];
01037
01038 if(currentNode - successorNode > 0){
01039
01040
01041
01042 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode;
01043
01044 }else{
01045
01046
01047 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode - 1 ;
01048
01049 }
01050
01051 }
01052
01053
01054
01055
01056 lvalue = lvalue - *(m_demand + successorNode);
01057
01058
01059
01060 }
01061
01062
01063
01064
01065
01066
01067 return rcost;
01068
01069 }
01070
01071
01072
01073
01074 void OSBearcatSolverXij::getColumns(const double* yA, const int numARows,
01075 const double* yB, const int numBRows,
01076 int &numNewColumns, int* &numNonzVec, double* &costVec,
01077 int** &rowIdxVec, double** &valuesVec, double &lowerBound)
01078 {
01079
01080
01081
01082 int i;
01083 int j;
01084 int numCoulpingConstraints;
01085 numCoulpingConstraints = m_numNodes - m_numHubs;
01086
01087 int numVar;
01088 numVar = m_numNodes*m_numNodes - m_numHubs;
01089 int numNonz;
01090
01091 try{
01092
01093
01094
01095 if(numARows != m_numNodes) throw ErrorClass("inconsistent row count in getColumns");
01096
01097
01098
01099
01100 calcReducedCost( yA, yB );
01101
01102 int kountVar;
01103 double testVal;
01104 testVal = 0;
01105 int k;
01106 int startPntInc;
01107 int rowCount;
01108 double rowValue;
01109
01111
01112 double cpuTime;
01113 double start = CoinCpuTime();
01114 getOptL( m_rc);
01115 cpuTime = CoinCpuTime() - start;
01116 std::cout << "DYNAMIC PROGRAMMING CPU TIME " << cpuTime << std::endl;
01117 m_lowerBnd = 0.0;
01118 for(k = 0; k < m_numHubs; k++){
01119
01120
01121
01122 startPntInc = (m_optL[ k] - 1)*(m_numNodes*m_numNodes - m_numNodes);
01123
01124 std::cout << " whichBlock = " << k << " L = " << m_optL[ k] << std::endl;
01125
01126 testVal += m_optL[ k];
01127
01128 kountVar = 0;
01129
01131 m_optValHub[ k] = qrouteCost(k, m_optL[ k], m_rc[ k], &kountVar);
01132
01133 m_optValHub[ k] -= yA[ k + numCoulpingConstraints];
01134
01135 std::cout << "Best Reduced Cost Hub " << k << " = " << m_optValHub[ k] << std::endl;
01136 m_lowerBnd += m_optValHub[ k];
01137
01138
01139
01140
01141
01142 m_costVec[ k] = 0.0;
01143
01144 for(j = 0; j < kountVar; j++){
01145
01146
01147
01148
01149 m_tmpScatterArray[ m_varIdx[ j] - startPntInc ] += 1;
01150
01151
01152
01153
01154 m_costVec[ k] += m_cost[ m_varIdx[ j] - startPntInc ];
01155
01156 }
01157
01158
01159
01160 numNonz = 0;
01161
01162 for(i = 0; i < numCoulpingConstraints; i++){
01163
01164 rowCount = 0;
01165
01166 for(j = m_pntAmatrix[ i]; j < m_pntAmatrix[ i + 1]; j++){
01167
01168
01169
01170
01171 rowCount += m_tmpScatterArray[ m_Amatrix[ j] ];
01172
01173
01174 }
01175
01176 if(rowCount > 0){
01177
01178
01179 m_newColumnRowIdx[ k][ numNonz] = i;
01180 m_newColumnRowValue[ k][ numNonz] = rowCount;
01181 numNonz++;
01182 }
01183
01184
01185 }
01186
01187
01188 m_newColumnRowIdx[ k][ numNonz] = m_numNodes - m_numHubs + k;
01189 m_newColumnRowValue[ k][ numNonz++] = 1.0;
01190
01191
01192
01193
01194
01195 for(i = 0; i < m_numBmatrixCon; i++){
01196
01197 if(m_BmatrixRowIndex[ i] == -1 || m_BmatrixRowIndex[ i] == k ){
01198
01199
01200 rowValue = 0;
01201
01202 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
01203
01204
01205
01206
01207
01208
01209
01210
01211 rowValue += m_tmpScatterArray[ m_BmatrixIdx[ j] ]*m_BmatrixVal[ j];
01212
01213
01214 }
01215
01216 if( rowValue > m_osDecompParam.zeroTol || rowValue < -m_osDecompParam.zeroTol){
01217
01218
01219 m_newColumnRowIdx[ k][ numNonz] = i + m_numNodes;
01220 m_newColumnRowValue[ k][ numNonz++] = rowValue;
01221
01222 }
01223
01224 }
01225
01226
01227 }
01228
01229 m_newColumnNonz[ k] = numNonz;
01230
01231
01232
01233
01234
01235
01236 for(j = 0; j < kountVar; j++){
01237
01238
01239
01240 m_thetaIndex[ m_numThetaNonz++ ] = m_varIdx[ j] - startPntInc ;
01241 m_tmpScatterArray[ m_varIdx[ j] - startPntInc ] = 0;
01242
01243
01244
01245 }
01246
01247
01248
01249
01250 intVarSet.insert ( std::pair<int,double>( m_numThetaVar, 1.0) );
01251 m_convexityRowIndex[ m_numThetaVar] = k;
01252 m_costVec[ k] = m_optL[ k]*m_costVec[ k];
01253 m_thetaCost[ m_numThetaVar++ ] = m_costVec[ k];
01254 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
01255
01256
01257
01258
01259
01260
01261
01294
01295
01296
01297
01298 }
01299
01300
01301
01302 numNonzVec = m_newColumnNonz;
01303 costVec = m_costVec;
01304 rowIdxVec = m_newColumnRowIdx;
01305 valuesVec = m_newColumnRowValue;
01306 std::cout << "Lower Bound = " << m_lowerBnd << std::endl;
01307
01308
01309 if(testVal != m_totalDemand) {
01310
01311 std::cout << "TOTAL DEMAND = " << m_totalDemand << std::endl;
01312 std::cout << "Test Value = " << testVal << std::endl;
01313 throw ErrorClass( "inconsistent demand calculation" );
01314 }
01315
01316
01317
01318
01319
01320
01321 } catch (const ErrorClass& eclass) {
01322
01323 throw ErrorClass(eclass.errormsg);
01324
01325 }
01326
01327
01328
01329 numNewColumns = m_numHubs;
01330 lowerBound = m_lowerBnd;
01331
01332 std::cout << "LEAVING GET COLUMNS" << std::endl;
01333 return;
01334
01335 }
01336
01337
01338
01632 OSInstance* OSBearcatSolverXij::getInitialRestrictedMaster( ){
01633
01634 getInitialSolution();
01635
01636 std::cout << "Executing OSBearcatSolverXij::getInitialRestrictedMaster( )" << std::endl;
01637
01638
01639 int numVarArt;
01640
01641 numVarArt = m_numNodes;
01642
01643 int numXVar;
01644 numXVar = m_numNodes*m_numNodes - m_numNodes;
01645
01646 double* xVar = NULL;
01647 xVar = new double[ numXVar];
01648
01649 int i;
01650 int k;
01651 std::string testFileName;
01652 std::string osil;
01653
01654 std::map<int, std::map<int, std::vector<int> > >::iterator mit;
01655 std::map<int, std::vector<int> >::iterator mit2;
01656 std::vector<int>::iterator vit;
01657
01658 m_osinstanceMaster = NULL;
01659
01660
01661
01662 int kountNonz;
01663 int kount;
01664 m_numberOfSolutions = 1;
01665 int numThetaVar = m_numberOfSolutions*m_numHubs;
01666
01667 double *values = new double[ m_numberOfSolutions*(m_numNodes-m_numHubs) + numThetaVar + numVarArt];
01668 int *indexes = new int[ m_numberOfSolutions*(m_numNodes-m_numHubs) + numThetaVar + numVarArt] ;
01669 int *starts = new int[ numThetaVar + 1 + numVarArt];
01670 kount = 0;
01671 starts[ 0] = 0;
01672 int startsIdx;
01673 startsIdx = 0;
01674 startsIdx++;
01675
01676 double tspObjValue;
01677 double demandSum;
01678
01679 SparseVector *objcoeff = NULL;
01680
01681 for(i = 0; i < numVarArt; i++){
01682 m_convexityRowIndex[ m_numThetaVar] = -1;
01683 m_thetaPnt[ m_numThetaVar++] = 0;
01684
01685 }
01686 try {
01687
01688
01689 m_osinstanceMaster = new OSInstance();
01690 m_osinstanceMaster->setInstanceDescription("The Initial Restricted Master");
01691
01692
01693
01694 m_osinstanceMaster->setVariableNumber( m_numberOfSolutions*m_numHubs + numVarArt);
01695
01696
01697 m_osinstanceMaster->setObjectiveNumber( 1);
01698
01699 objcoeff = new SparseVector( m_numberOfSolutions*m_numHubs + numVarArt);
01700
01701
01702 m_osinstanceMaster->setConstraintNumber( m_numNodes);
01703
01704
01705
01706 int varNumber;
01707 varNumber = 0;
01708 std::string masterVarName;
01709 kountNonz = 0;
01710
01711 for(i = 0; i < m_numNodes; i++){
01712
01713 objcoeff->indexes[ varNumber ] = varNumber ;
01714
01715
01716
01717
01718
01719 objcoeff->values[ varNumber ] = m_osDecompParam.artVarCoeff;
01720
01721 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt("AP", i ) ,
01722 0, 1.0, 'C');
01723
01724 values[ kountNonz] = 1;
01725 indexes[ kountNonz++] = i ;
01726 starts[ startsIdx++] = kountNonz;
01727
01728 }
01729
01730 m_bestIPValue = 0;
01731 mit = m_initSolMap.find( 0);
01732 if(mit == m_initSolMap.end() ) throw ErrorClass("Problem finding first solution in m_initSolMap");
01733
01734 CoinSolver *solver = NULL;
01735 solver = getTSP(m_numNodes, m_cost);
01736
01737
01738 for(k = 0; k < m_numHubs; k++){
01739
01740 mit2 = mit->second.find( k);
01741 if(mit2 == mit->second.end() ) throw ErrorClass("Problem finding hub k in the solution map");
01742
01743 tspObjValue = getRouteDistance(m_numNodes, mit2->first, solver,
01744 mit2->second, xVar);
01745 demandSum = 0;
01746
01747 for ( vit = mit2->second.begin() ; vit != mit2->second.end(); vit++ ) {
01748
01749 demandSum += m_demand[ *vit];
01750 values[ kountNonz] = 1;
01751 indexes[ kountNonz++] = *vit - m_numHubs ;
01752
01753 }
01754
01755
01756
01757 for(i = 0; i < numXVar; i++){
01758
01759
01760 if(xVar[ i] > .1) {
01761 m_thetaIndex[ m_numThetaNonz++ ] = i;
01762
01763 }
01764 }
01765
01766
01767
01768 values[ kountNonz] = 1;
01769 indexes[ kountNonz++] = m_numNodes - m_numHubs + k ;
01770
01771
01772
01773
01774 m_convexityRowIndex[ m_numThetaVar] = k;
01775 m_thetaCost[ m_numThetaVar++ ] = demandSum*tspObjValue;
01776 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
01777
01778 masterVarName = makeStringFromInt("theta(", k);
01779 masterVarName += makeStringFromInt(",", 0);
01780 masterVarName += ")";
01781 intVarSet.insert ( std::pair<int,double>(varNumber, 1.0) );
01782 m_osinstanceMaster->addVariable(varNumber++, masterVarName, 0, 1, 'C');
01783
01784 std::cout << "Optimal Objective Value = " << demandSum*tspObjValue << std::endl;
01785
01786
01787 objcoeff->indexes[ k + numVarArt ] = k + numVarArt ;
01788 objcoeff->values[ k + numVarArt ] = demandSum*tspObjValue;
01789
01790 m_bestIPValue += demandSum*tspObjValue;
01791
01792 std::cout << "m_bestIPValue = " << m_bestIPValue << std::endl;
01793 starts[ startsIdx++] = kountNonz;
01794
01795 }
01796 std::cout << " m_numThetaVar " << m_numThetaVar << std::endl;
01797
01798
01799
01800 for( i = 0; i < m_numNodes - m_numHubs ; i++){
01801
01802 m_osinstanceMaster->addConstraint(i, makeStringFromInt("visitNode_", i + m_numHubs) , 1.0, 1.0, 0);
01803 }
01804
01805 kount = 0;
01806
01807
01808 for( i = m_numNodes - m_numHubs; i < m_numNodes ; i++){
01809
01810 m_osinstanceMaster->addConstraint(i, makeStringFromInt("convexityRowRoute_", kount++ ) , 1.0, 1.0, 0);
01811 }
01812
01813 m_osinstanceMaster->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
01814
01815
01816
01817 m_osinstanceMaster->setLinearConstraintCoefficients(kountNonz , true,
01818 values, 0, kountNonz - 1, indexes, 0, kountNonz - 1, starts, 0, startsIdx);
01819
01820
01821 std::cout << m_osinstanceMaster->printModel( ) << std::endl;
01822 std::cout << "NONZ = " << kountNonz << std::endl;
01823
01824
01825 delete objcoeff;
01826 objcoeff = NULL;
01827 delete[] xVar;
01828 xVar = NULL;
01829 delete solver->osinstance;
01830 delete solver;
01831
01832
01833
01834
01835 } catch (const ErrorClass& eclass) {
01836 std::cout << std::endl << std::endl << std::endl;
01837
01838 if(objcoeff != NULL) delete objcoeff;
01839 if(xVar != NULL) delete xVar;
01840
01841 throw ErrorClass(eclass.errormsg);
01842 }
01843
01844 return m_osinstanceMaster;
01845 }
01846
01847
01848
01849 void OSBearcatSolverXij::getOptions(OSOption *osoption) {
01850
01851
01852 std::cout << "Executing getOptions(OSOption *osoption)" << std::endl;
01853
01854 try{
01855
01856 int i;
01857
01858
01859 std::vector<SolverOption*> solverOptions;
01860 std::vector<SolverOption*>::iterator vit;
01861 std::vector<int>::iterator vit2;
01862 std::vector<int >demand;
01863 std::vector<std::string >nodeName;
01864 std::vector<int >routeCapacity;
01865 std::vector<int >routeMinPickup;
01866 std::vector<double >arcCost;
01867 std::vector<double >::iterator vit3;
01868 std::vector<std::string>::iterator vit4;
01869
01870
01871 m_numberOfSolutions = 0;
01872 solverOptions = osoption->getSolverOptions("routeSolver");
01873 if (solverOptions.size() == 0) throw ErrorClass( "options for routeSolver not available");
01874
01875
01876 int tmpVal;
01877 double tmpCost;
01878
01879
01880 std::string routeString;
01881 std::string solutionString;
01882 std::string::size_type pos1;
01883 std::string::size_type pos2;
01884 std::string::size_type pos3;
01885
01886
01887 std::map<int, std::map<int, std::vector<int> > >::iterator mit;
01888 std::map<int, std::vector<int> >::iterator mit2;
01889 int solutionNumber;
01890 int routeNumber;
01891
01892
01893 for (vit = solverOptions.begin(); vit != solverOptions.end(); vit++) {
01894
01895
01896
01897
01898
01899
01900
01901 if( (*vit)->name.find("numHubs") != std::string::npos){
01902
01903
01904 std::istringstream hubBuffer( (*vit)->value);
01905 hubBuffer >> m_numHubs;
01906 std::cout << "numHubs = " << m_numHubs << std::endl;
01907
01908 }else{
01909
01910 if((*vit)->name.find("numNodes") != std::string::npos){
01911
01912
01913 std::istringstream numNodesBuffer( (*vit)->value);
01914 numNodesBuffer >> m_numNodes;
01915 std::cout << "numNodes = " << m_numNodes << std::endl;
01916
01917 }else{
01918 if((*vit)->name.find("totalDemand") != std::string::npos){
01919
01920
01921 std::istringstream totalDemandBuffer( (*vit)->value);
01922 totalDemandBuffer >> m_totalDemand;
01923 std::cout << "m_totalDemand = " << m_totalDemand << std::endl;
01924
01925 }else{
01926 if((*vit)->name.find("routeMinPickup") != std::string::npos){
01927
01928
01929 std::istringstream routeMinPickupBuffer( (*vit)->value);
01930 routeMinPickupBuffer >> tmpVal;
01931 routeMinPickup.push_back( tmpVal);
01932
01933
01934 }else{
01935 if( (*vit)->name.find("demand") != std::string::npos ){
01936
01937
01938 std::istringstream demandBuffer( (*vit)->value);
01939 demandBuffer >> tmpVal;
01940 if(tmpVal <= 0 && demand.size() > (unsigned int) m_numHubs) throw ErrorClass("must have strictly positive demand");
01941 if(tmpVal < m_minDemand && demand.size() > (unsigned int) m_numHubs ) m_minDemand = tmpVal;
01942 demand.push_back( tmpVal);
01943 nodeName.push_back( (*vit)->description);
01944
01945
01946 }else{
01947 if((*vit)->name.find("routeCapacity") != std::string::npos ){
01948 std::istringstream routeCapacityBuffer( (*vit)->value);
01949 routeCapacityBuffer >> tmpVal;
01950 routeCapacity.push_back( tmpVal);
01951 std::cout << "m_routeCapacity = " << tmpVal << std::endl;
01952
01953 }else{
01954
01955 if((*vit)->name.find("osilFile") != std::string::npos ){
01956 m_initOSiLFile = (*vit)->value;
01957 std::cout << "m_initOSiLFile = " << m_initOSiLFile << std::endl;
01958
01959 }else{
01960
01961 if( (*vit)->name.find("restrictedMasterSolution") != std::string::npos ){
01962
01963
01964
01965
01966
01967
01968 pos1 = (*vit)->category.find( ":");
01969 if(pos1 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
01970
01971
01972 solutionString = (*vit)->category.substr( 0, pos1);
01973 routeString = (*vit)->category.substr( pos1 + 1);
01974
01975 pos2 = solutionString.find( "n");
01976 if(pos2 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
01977
01978 std::istringstream solutionBuffer( solutionString.substr( pos2 + 1) );
01979 solutionBuffer >> solutionNumber;
01980
01981
01982
01983 pos3 = routeString.find( "e");
01984 if(pos3 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
01985 std::istringstream routeBuffer( routeString.substr( pos3 + 1) );
01986 routeBuffer >> routeNumber;
01987
01988 std::istringstream nodeBuffer( (*vit)->value);
01989 nodeBuffer >> tmpVal;
01990
01991 mit = m_initSolMap.find( solutionNumber );
01992
01993 if( mit != m_initSolMap.end() ){
01994
01995
01996
01997 mit2 = mit->second.find( routeNumber);
01998
01999 if(mit2 != mit->second.end() ){
02000
02001
02002
02003 mit2->second.push_back( tmpVal);
02004
02005
02006 }else{
02007
02008
02009 std::vector<int> tmpVec;
02010 tmpVec.push_back( tmpVal) ;
02011 mit->second.insert( std::pair<int,std::vector<int> >(routeNumber, tmpVec) );
02012
02013
02014 }
02015
02016 }else{
02017
02018 std::vector<int> tmpVec;
02019 tmpVec.push_back( tmpVal) ;
02020
02021 std::map<int, std::vector<int> > tmpMap;
02022 tmpMap.insert( std::pair<int,std::vector<int> >(routeNumber, tmpVec) );
02023 m_initSolMap.insert( std::pair<int, std::map<int, std::vector<int> > >(solutionNumber, tmpMap) ) ;
02024
02025 }
02026 }
02027 else{
02028 if( (*vit)->name.find("maxMasterColumns") != std::string::npos){
02029
02030
02031 std::istringstream maxMasterColumns( (*vit)->value);
02032 maxMasterColumns >> m_maxMasterColumns;
02033 std::cout << "m_maxMasterColumn = " << m_maxMasterColumns << std::endl;
02034
02035 }else{
02036 if( (*vit)->name.find("maxThetaNonz") != std::string::npos){
02037
02038 std::istringstream maxThetaNonz( (*vit)->value);
02039 maxThetaNonz >> m_maxThetaNonz;
02040 std::cout << "m_maxThetaNonz = " << m_maxThetaNonz << std::endl;
02041
02042 }else{
02043 if( (*vit)->name.find("use1OPTstart") != std::string::npos){
02044 m_use1OPTstart = false;
02045 if ( (*vit)->value.find("true") != std::string::npos ) m_use1OPTstart = true;
02046 std::cout << "m_use1OPTstart = " << m_use1OPTstart << std::endl;
02047
02048 }else{
02049 if( (*vit)->name.find("maxBmatrixCon") != std::string::npos ){
02050
02051 std::istringstream maxBmatrixCon( (*vit)->value);
02052 maxBmatrixCon >> m_maxBmatrixCon;
02053 std::cout << "m_maxBmatrixCon = " << m_maxBmatrixCon << std::endl;
02054
02055 }else{
02056 if( (*vit)->name.find("maxBmatrixNonz") != std::string::npos ){
02057
02058 std::istringstream maxBmatrixNonz( (*vit)->value);
02059 maxBmatrixNonz >> m_maxBmatrixNonz;
02060 std::cout << "m_maxBmatrixNonz = " << m_maxBmatrixNonz << std::endl;
02061
02062
02063 }else{
02064
02065 if( (*vit)->name.find("cost") != std::string::npos ){
02066
02067
02068 std::istringstream costBuffer( (*vit)->value);
02069 costBuffer >> tmpCost;
02070 arcCost.push_back( tmpCost);
02071
02072 }
02073 }
02074 }
02075 }
02076 }
02077 }
02078 }
02079 }
02080 }
02081 }
02082 }
02083 }
02084 }
02085 }
02086
02087 }
02088
02089
02090
02091 i = 0;
02092 m_routeCapacity = new int[ m_numHubs];
02093 if( (unsigned int)m_numHubs != routeCapacity.size( ) ) throw ErrorClass("inconsistent number of HUBS");
02094 for (vit2 = routeCapacity.begin(); vit2 != routeCapacity.end(); vit2++) {
02095
02096 *(m_routeCapacity + i++) = *vit2;
02097
02098 std::cout << "ROUTE CAP = " << *vit2 << std::endl;
02099
02100 }
02101 routeCapacity.clear();
02102
02103
02104
02105 i = 0;
02106 m_routeMinPickup = new int[ m_numHubs];
02107 if( (unsigned int)m_numHubs != routeMinPickup.size( ) ) throw ErrorClass("inconsistent number of HUBS");
02108
02109 for(int k = 0; k < m_numHubs; k++){
02110 m_routeMinPickup[ k] = 1;
02111 }
02112 for (vit2 = routeMinPickup.begin(); vit2 != routeMinPickup.end(); vit2++) {
02113
02114 *(m_routeMinPickup + i++) = *vit2;
02115
02116 }
02117 routeMinPickup.clear();
02118
02119
02120
02121 i = 0;
02122 m_demand = new int[ m_numNodes];
02123 if( (unsigned int)m_numNodes != demand.size( ) )
02124 throw ErrorClass("inconsistent number of demand nodes");
02125 for (vit2 = demand.begin(); vit2 != demand.end(); vit2++) {
02126
02127 *(m_demand + i++) = *vit2;
02128
02129 }
02130 demand.clear();
02131
02132
02133 i = 0;
02134 m_nodeName = new std::string[ m_numNodes];
02135
02136 for (vit4 = nodeName.begin(); vit4 != nodeName.end(); vit4++) {
02137
02138 *(m_nodeName + i++) = *vit4;
02139
02140 }
02141 nodeName.clear();
02142
02143
02144
02145
02146 m_cost = NULL;
02147 m_costSetInOption = false;
02148 if(arcCost.size() != (unsigned int)(m_numNodes*m_numNodes - m_numNodes) )
02149 throw ErrorClass("input cost vector not consistent with number of nodes");
02150 if(arcCost.size() >= 1){
02151 m_costSetInOption = true;
02152 i = 0;
02153 m_cost = new double[ m_numNodes*m_numNodes - m_numNodes ];
02154 for (vit3 = arcCost.begin(); vit3 != arcCost.end(); vit3++) {
02155
02156 *(m_cost + i++) = *vit3;
02157
02158 }
02159 arcCost.clear();
02160 }
02161
02162
02163 m_numberOfSolutions = m_initSolMap.size();
02164
02165
02166 } catch (const ErrorClass& eclass) {
02167
02168 throw ErrorClass(eclass.errormsg);
02169
02170 }
02171
02172 }
02173
02174
02175
02176 void OSBearcatSolverXij::getCutsTheta(const double* theta, const int numTheta,
02177 int &numNewRows, int* &numNonz, int** &colIdx,
02178 double** &values, double* &rowLB, double* &rowUB) {
02179
02180
02181
02182
02183 int i;
02184 int j;
02185 int k;
02186 int index;
02187 int rowKount;
02188 int tmpKount;
02189 int indexAdjust = m_numNodes - m_numHubs;
02190 double* tmpRhs;
02191 int numSepRows = m_osinstanceSeparation->getConstraintNumber() ;
02192
02193 tmpRhs = new double[ numSepRows ];
02194
02195 for(i = 0; i < numSepRows; i++){
02196
02197 tmpRhs[ i] = 0;
02198 }
02199
02200 try{
02201 m_osinstanceSeparation->bConstraintsModified = true;
02202
02203 if(numTheta != m_numThetaVar ) throw
02204 ErrorClass("number of master varibles in OSBearcatSolverXij::getCuts inconsistent");
02205
02206
02207
02208
02209
02210
02211
02212
02213 for(i = 0; i < numTheta; i++){
02214
02215
02216 if(theta[ i] > m_osDecompParam.zeroTol){
02217
02218
02219 for(j = m_thetaPnt[ i ]; j < m_thetaPnt[ i + 1 ]; j++ ){
02220
02221
02222
02223
02224
02225 rowKount = m_separationIndexMap[ m_thetaIndex[ j] ];
02226
02227
02228
02229 if(rowKount < OSINT_MAX ){
02230
02231 tmpRhs[ rowKount] -= theta[ i];
02232
02233 }
02234
02235 }
02236 }
02237 }
02238
02239
02240
02241
02242 for(i = indexAdjust; i < numSepRows - 1; i++){
02243
02244 if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
02245
02246
02247
02248
02249 int tmpKount = indexAdjust;
02250 for(int i1 = m_numHubs; i1 < m_numNodes; i1++){
02251
02252
02253
02254 for(int j1 = i1+1; j1 < m_numNodes; j1++){
02255
02256 if(tmpKount == i){
02257
02258
02259
02260
02261
02262 m_BmatrixVal[ m_numBmatrixNonz ] = 1 ;
02263
02264 m_BmatrixIdx[ m_numBmatrixNonz++ ] = i1*(m_numNodes - 1) + j1 - 1 ;
02265
02266 m_BmatrixVal[ m_numBmatrixNonz ] = 1 ;
02267
02268 m_BmatrixIdx[ m_numBmatrixNonz++ ] = j1*(m_numNodes - 1) + i1 ;
02269 m_numBmatrixCon++;
02270 m_pntBmatrix[ m_numBmatrixCon ] = m_numBmatrixNonz;
02271
02272 numNewRows = 1;
02273
02274 m_newRowNonz[ 0] = 0;
02275 m_newRowUB[ 0] = 1;
02276 m_newRowLB[ 0] = 0;
02277
02278
02279
02280
02281 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02282 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02283
02284
02285 std::cout << " m_BmatrixIdx[ j] " << m_BmatrixIdx[ j] << std::endl ;
02286
02287 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 1;
02288
02289 }
02290
02291
02292
02293
02294 for(k = 0; k < m_numThetaVar ; k++){
02295
02296
02297 tmpKount = 0;
02298
02299
02300 for(j = m_thetaPnt[k]; j < m_thetaPnt[k + 1] ; j++){
02301
02302 if(m_tmpScatterArray[ m_thetaIndex[ j] ] > 0 ){
02303
02304 std::cout << " Variable " << m_variableNames[ m_thetaIndex[ j] ] << std::endl;
02305
02306 tmpKount++;
02307
02308 }
02309
02310 }
02311
02312 if(tmpKount > 0){
02313
02314
02315 m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = k ;
02316
02317 m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02318
02319
02320 }
02321
02322 }
02323
02324
02325
02326
02327
02328
02329
02330 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02331 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02332
02333 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 0;
02334
02335 }
02336
02337 numNonz = m_newRowNonz;
02338 colIdx = m_newRowColumnIdx;
02339 values = m_newRowColumnValue;
02340 rowUB = m_newRowUB;
02341 rowLB = m_newRowLB;
02342
02343 delete[] tmpRhs;
02344 tmpRhs = NULL;
02345
02346
02347
02348 m_numThetaVar++;
02349 m_convexityRowIndex[ m_numThetaVar] = -1;
02350 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02351
02352
02353
02354 return;
02355
02356 }
02357
02358 tmpKount++;
02359
02360 }
02361
02362 }
02363
02364
02365 }
02366
02367 m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
02368 m_separationClpModel->setRowLower(i, tmpRhs[ i] );
02369
02370 }
02371
02372
02373
02374
02375
02376 std::vector<int> dualIdx;
02377 std::vector<int>::iterator vit1;
02378 std::vector<int>::iterator vit2;
02379
02380
02381
02382
02383 for(k = 0; k < indexAdjust; k++){
02384
02385
02386
02387 m_separationClpModel->setRowUpper(k, 0.0);
02388
02389
02390 m_separationClpModel->setLogLevel( 0);
02391
02392 m_separationClpModel->primal();
02393
02394 if(m_separationClpModel->getObjValue() > m_osDecompParam.zeroTol){
02395 std::cout << "DOING SEPARATION FOR NODE " << k + m_numHubs << std::endl;
02396 std::cout << "SEPERATION OBJ VALUE = " << m_separationClpModel->getObjValue() << std::endl;
02397 numNewRows = 1;
02398
02399 for(i = 0; i < m_numNodes - m_numHubs ; i++){
02400
02401 if( m_separationClpModel->getRowPrice()[ i] - m_osDecompParam.zeroTol <= -1) dualIdx.push_back( i) ;
02402 }
02403
02404 for (vit1 = dualIdx.begin(); vit1 != dualIdx.end(); vit1++) {
02405
02406 i = *vit1 + m_numHubs;
02407
02408 for (vit2 = dualIdx.begin(); vit2 != dualIdx.end(); vit2++) {
02409
02410 j = *vit2 + m_numHubs;
02411
02412 if( i > j ){
02413
02414 index = i*(m_numNodes -1) + j;
02415 std::cout << "CUT VARIABLE = " << m_variableNames[ index ] <<std::endl;
02416 m_BmatrixVal[ m_numBmatrixNonz ] = 1 ;
02417 m_BmatrixIdx[ m_numBmatrixNonz++ ] = index ;
02418
02419 }else{
02420
02421 if( i < j ){
02422
02423 index = i*(m_numNodes -1) + j - 1;
02424 std::cout << "CUT VARIABLE = " << m_variableNames[ index ] <<std::endl;
02425 m_BmatrixVal[ m_numBmatrixNonz ] = 1 ;
02426 m_BmatrixIdx[ m_numBmatrixNonz++ ] = index ;
02427
02428 }
02429 }
02430
02431 }
02432 }
02433
02434
02435 m_numBmatrixCon++;
02436 m_pntBmatrix[ m_numBmatrixCon ] = m_numBmatrixNonz;
02437
02438
02439
02440
02441
02442
02443 for(i = indexAdjust; i < numSepRows - 1; i++){
02444
02445 m_separationClpModel->setRowUpper(i, 0.0 );
02446 m_separationClpModel->setRowLower(i, 0.0 );
02447
02448
02449 }
02450 m_separationClpModel->setRowUpper(k, 1.0);
02451 delete[] tmpRhs;
02452 tmpRhs = NULL;
02453
02454
02455 m_newRowNonz[ 0] = 0;
02456 m_newRowUB[ 0] = dualIdx.size() - 1;
02457 m_newRowLB[ 0] = 0;
02458
02459 dualIdx.clear();
02460
02461
02462
02463
02464 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02465 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02466
02467 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 1;
02468
02469 }
02470
02471
02472
02473
02474 for(i = 0; i < m_numThetaVar ; i++){
02475
02476
02477 tmpKount = 0;
02478 for(j = m_thetaPnt[i]; j < m_thetaPnt[i + 1] ; j++){
02479
02480 if(m_tmpScatterArray[ m_thetaIndex[ j] ] > 0 ){
02481
02482 tmpKount++;
02483
02484 }
02485
02486 }
02487
02488 if(tmpKount > 0){
02489
02490
02491 m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = i ;
02492
02493 m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02494
02495
02496 }
02497
02498 }
02499
02500
02501
02502
02503 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02504 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02505
02506 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 0;
02507
02508 }
02509
02510
02511
02512 numNonz = m_newRowNonz;
02513 colIdx = m_newRowColumnIdx;
02514 values = m_newRowColumnValue;
02515 rowUB = m_newRowUB;
02516 rowLB = m_newRowLB;
02517 m_numThetaVar++;
02518 m_convexityRowIndex[ m_numThetaVar] = -1;
02519 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02520
02521
02522
02523 return;
02524
02525
02526
02527 }
02528 m_separationClpModel->setRowUpper(k, 1.0);
02529 dualIdx.clear();
02530
02531 }
02532
02533
02534
02535
02536 for(i = indexAdjust; i < numSepRows - 1; i++){
02537
02538 m_separationClpModel->setRowUpper(i, 0.0 );
02539 m_separationClpModel->setRowLower(i, 0.0 );
02540
02541
02542 }
02543
02544 delete[] tmpRhs;
02545 tmpRhs = NULL;
02546
02547 } catch (const ErrorClass& eclass) {
02548
02549 throw ErrorClass(eclass.errormsg);
02550
02551 }
02552
02553
02554
02555 }
02556
02557
02558 void OSBearcatSolverXij::getCutsMultiCommod(const double* theta, const int numTheta,
02559 int &numNewRows, int* &numNonz, int** &colIdx,
02560 double** &values, double* &rowLB, double* &rowUB) {
02561
02562
02563
02564
02565 numNewRows = 0;
02566
02567
02568
02569 int i;
02570 int j;
02571 int k;
02572 int ivalue;
02573 int jvalue;
02574 int thetaIdx;
02575 int inodenum;
02576 int jnodenum;
02577 int j1;
02578 int j2;
02579 int kount;
02580 double wVal;
02581 double uVal;
02582 bool foundCut;
02583 double objVal;
02584
02585 int ckijIndex;
02586 int numNonHubs;
02587 numNonHubs = m_numNodes - m_numHubs;
02588
02589 int numVar;
02590 double rowValue;
02591
02592 double* scatterValues;
02593 int numXijVar = m_numNodes*m_numNodes - m_numNodes;
02594 scatterValues = new double[ numXijVar ];
02595 for(i = 0; i < numXijVar; i++ )scatterValues[ i] = 0;
02596
02597 double tmpCoeff;
02598
02599 double *wcoeff = NULL;
02600 wcoeff = new double[ numNonHubs];
02601 CoinSolver *solver;
02602
02603 std::cout << std::endl << std::endl;
02604 std::cout << "INSIDE getCutsMultiCommod " << std::endl;
02605 std::cout << std::endl << std::endl;
02606
02607 std::map<int, std::vector<std::pair<int,double> > > xVarMap;
02608 std::map<int, std::vector<std::pair<int,double> > >::iterator mit;
02609 std::vector<std::pair<int,double> >::iterator vit;
02610
02611 std::map<std::pair<int, int>,int>xVarIndexMap;
02612 std::pair<int,int> indexPair;
02613 ostringstream cutString;
02614
02615
02616
02617
02618
02619
02620
02648
02649
02650 try{
02651
02652 for(i = 0; i < numTheta; i++){
02653 xVarMap[ m_convexityRowIndex[ i] ] ;
02654
02655 if(theta[ i] > m_osDecompParam.zeroTol){
02656
02657
02658 for(j = m_thetaPnt[ i ]; j < m_thetaPnt[ i + 1 ]; j++ ){
02659
02660 mit = xVarMap.find( m_convexityRowIndex[ i]) ;
02661
02662 if(mit != xVarMap.end() ){
02663
02664 mit->second.push_back( std::pair<int, double>( m_thetaIndex[ j], theta[ i]) );
02665
02666 }
02667 }
02668 }
02669 }
02670
02671
02672
02673
02674 for(k = 0; k < m_numHubs; k++){
02675
02676
02677 mit = xVarMap.find( k) ;
02678
02679 solver = m_multCommodCutSolvers[ k];
02680
02681 numVar = solver->osiSolver->getNumCols();
02682 for(i = 0; i < numVar; i++ ) solver->osiSolver->setObjCoeff( i, 0);
02683
02684 for(i = 0; i < numNonHubs; i++) wcoeff[ i ] = 0;
02685
02686 if(mit != xVarMap.end() ){
02687
02688 std::cout << "CONVEXITY ROW " << " = " << mit->first << std::endl;
02689
02690 for(vit = mit->second.begin(); vit < mit->second.end(); vit++){
02691
02692
02693
02694 ivalue = vit->first /(m_numNodes - 1);
02695
02696 jvalue = vit->first - ivalue*(m_numNodes - 1);
02697
02698 if( jvalue >= ivalue ){
02699
02700
02701 inodenum = ivalue;
02702 jnodenum = jvalue + 1;
02703
02704
02705 }else{
02706
02707
02708
02709 inodenum = ivalue;
02710 jnodenum = jvalue;
02711 }
02712
02713 if(jnodenum != k){
02714
02715
02716 wcoeff[ jnodenum - m_numHubs ] += vit->second;
02717
02718 if( inodenum == k ){
02719 ckijIndex = jnodenum - m_numHubs;
02720 } else{
02721
02722 inodenum -= m_numHubs;
02723 jnodenum -= m_numHubs;
02724
02725
02726 if( jnodenum > inodenum) ckijIndex = inodenum*(numNonHubs - 1) + jnodenum - 1 ;
02727 else ckijIndex = inodenum*(numNonHubs - 1) + jnodenum ;
02728
02729
02730 ckijIndex += numNonHubs ;
02731
02732 }
02733
02734
02735 ckijIndex += numNonHubs;
02736
02737 tmpCoeff = solver->osiSolver->getObjCoefficients()[ ckijIndex] ;
02738
02739
02740 tmpCoeff = tmpCoeff - vit->second;
02741 if( ckijIndex > numVar - 1) throw ErrorClass( "problem with ckijIndex calculation");
02742
02743 solver->osiSolver->setObjCoeff( ckijIndex, tmpCoeff );
02744 }
02745
02746 }
02747
02748 }
02749 foundCut = false;
02750
02751 for(i = 0; i < numNonHubs; i++){
02752
02753
02754 solver->osiSolver->setObjCoeff( i, wcoeff[ i ] );
02755
02756
02757 solver->solve();
02758
02759
02760
02761 if(solver->osiSolver->getObjValue() > .1){
02762 objVal = 0;
02763 std::cout << "Separation Obj Value = " <<
02764 solver->osiSolver->getObjValue() << " Node " << m_nodeName[i + m_numHubs] << std::endl;
02765
02766 foundCut = true;
02767 m_newRowNonz[ numNewRows ] = 0;
02768
02769
02770 cutString.str("");
02771 cutString << "";
02772
02773
02774 kount = numNonHubs;
02775
02776 wVal = solver->osiSolver->getColSolution()[ i];
02777 objVal += wVal*solver->osiSolver->getObjCoefficients()[ i];
02778
02779 if(wVal < m_osDecompParam.zeroTol )throw ErrorClass("problem with wVal in generating a multicommodity cut");
02780
02781
02782 for(j2 = m_numHubs; j2 < m_numNodes; j2++){
02783
02784 indexPair.first = k;
02785 indexPair.second = j2;
02786
02787 uVal = solver->osiSolver->getColSolution()[ kount];
02788 objVal += uVal*solver->osiSolver->getObjCoefficients()[ kount];
02789
02790
02791
02792
02793 if (j2 == (i + m_numHubs) ){
02794
02795 if( (wVal - uVal) > m_osDecompParam.zeroTol || (uVal - wVal) > m_osDecompParam.zeroTol ){
02796
02797 cutString << " =";
02798 cutString << (wVal - uVal);
02799 cutString << "*" ;
02800
02801
02802
02803
02804
02805 m_BmatrixVal[ m_numBmatrixNonz ] = (wVal - uVal)/wVal ;
02806
02807
02808 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02809 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02810 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02811 }else{
02812 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02813 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02814 }
02815
02816 }
02817
02818 }else{
02819
02820 if( (-uVal > m_osDecompParam.zeroTol) || (uVal > m_osDecompParam.zeroTol) ){
02821
02822 cutString << " ";
02823 cutString << - uVal;
02824 cutString << "*" ;
02825
02826
02827
02828
02829
02830
02831 m_BmatrixVal[ m_numBmatrixNonz ] = -uVal/wVal ;
02832
02833
02834
02835 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02836 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02837 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02838 }else{
02839 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02840 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02841 }
02842 }
02843
02844 }
02845
02846 kount++;
02847 }
02848
02849
02850 for(j1 = m_numHubs; j1 < m_numNodes; j1++){
02851
02852
02853
02854
02855 for(j2 = m_numHubs; j2 < j1; j2++){
02856
02857 indexPair.first = j1;
02858 indexPair.second = j2;
02859
02860 uVal = solver->osiSolver->getColSolution()[ kount];
02861 objVal += uVal*solver->osiSolver->getObjCoefficients()[ kount];
02862
02863
02864
02865 if (j2 == (i + m_numHubs) ){
02866
02867
02868 if( (wVal - uVal) > m_osDecompParam.zeroTol || (uVal - wVal) > m_osDecompParam.zeroTol ){
02869
02870 cutString << " +";
02871 cutString << (wVal - uVal) ;
02872 cutString << "*" ;
02873
02874
02875
02876
02877 m_BmatrixVal[ m_numBmatrixNonz ] = (wVal - uVal)/wVal ;
02878
02879
02880
02881 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02882 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02883 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02884 }else{
02885 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02886 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02887 }
02888
02889 }
02890
02891 }else{
02892
02893 if( (-uVal > m_osDecompParam.zeroTol) || (uVal > m_osDecompParam.zeroTol) ){
02894
02895 cutString << " ";
02896 cutString << - uVal;
02897 cutString << "*" ;
02898
02899
02900
02901
02902
02903 m_BmatrixVal[ m_numBmatrixNonz ] = -uVal/wVal ;
02904
02905
02906
02907 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02908 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02909 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02910 }else{
02911 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02912 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02913 }
02914 }
02915 }
02916 kount++;
02917 }
02918
02919
02920 for(j2 = j1 + 1; j2 < m_numNodes; j2++){
02921
02922 indexPair.first = j1;
02923 indexPair.second = j2;
02924
02925 uVal = solver->osiSolver->getColSolution()[ kount];
02926 objVal += uVal*solver->osiSolver->getObjCoefficients()[ kount];
02927
02928
02929
02930 if (j2 == (i + m_numHubs) ){
02931
02932 if( (wVal - uVal) > m_osDecompParam.zeroTol || (uVal - wVal) > m_osDecompParam.zeroTol ){
02933
02934 cutString << " +";
02935 cutString << (wVal - uVal);
02936 cutString << "*" ;
02937
02938
02939
02940
02941 m_BmatrixVal[ m_numBmatrixNonz ] = (wVal - uVal)/wVal ;
02942
02943
02944
02945 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02946 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02947 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02948 }else{
02949 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02950 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02951 }
02952 }
02953
02954 }else{
02955
02956 if( (-uVal > m_osDecompParam.zeroTol) || (uVal > m_osDecompParam.zeroTol) ){
02957
02958 cutString << " ";
02959 cutString << - uVal;
02960 cutString << "*" ;
02961
02962
02963
02964
02965 m_BmatrixVal[ m_numBmatrixNonz ] = -uVal/wVal ;
02966
02967
02968 if(m_xVarIndexMap.find( indexPair) == m_xVarIndexMap.end() ){
02969 std::cout << " Getting ready to call ErrorClass: kount = " << kount << std::endl;
02970 throw ErrorClass( "index mapping problem in generating multicommodity cut");
02971 }else{
02972 m_BmatrixIdx[ m_numBmatrixNonz++ ] = m_xVarIndexMap[ indexPair];
02973 cutString << m_variableNames[ m_xVarIndexMap[ indexPair] ];
02974 }
02975 }
02976 }
02977 kount++;
02978 }
02979 }
02980 cutString << std::endl;
02981
02982
02983
02984
02985
02986
02987 m_numBmatrixCon++;
02988 m_pntBmatrix[ m_numBmatrixCon ] = m_numBmatrixNonz;
02989
02990
02991
02992
02993
02994
02995 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02996 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02997
02998 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 1;
02999 scatterValues[ m_BmatrixIdx[ j] ] = m_BmatrixVal[ j];
03000
03001
03002 }
03003
03004
03005
03006
03007
03008 if(numTheta != m_numThetaVar)throw
03009 ErrorClass( "Inconsistent Number of theta variables in multicommondity cut separation problem" );
03010
03011
03012 for(thetaIdx = 0; thetaIdx < m_numThetaVar ; thetaIdx++){
03013
03014
03015 if(m_convexityRowIndex[ thetaIdx] == k){
03016
03017
03018 rowValue = 0;
03019 for(j = m_thetaPnt[ thetaIdx]; j < m_thetaPnt[ thetaIdx + 1] ; j++){
03020
03021
03022
03023 rowValue += m_tmpScatterArray[ m_thetaIndex[ j] ]*scatterValues[ m_thetaIndex[ j] ];
03024
03025 }
03026
03027 if(rowValue > m_osDecompParam.zeroTol || -rowValue > m_osDecompParam.zeroTol){
03028
03029 m_newRowColumnIdx[ numNewRows][ m_newRowNonz[ numNewRows ] ] = thetaIdx ;
03030 m_newRowColumnValue[ numNewRows][ m_newRowNonz[ numNewRows]++ ] = rowValue;
03031 }
03032
03033
03034 }
03035
03036
03037 }
03038
03039 m_newRowLB[ numNewRows] = -OSDBL_MAX;
03040 m_newRowUB[ numNewRows] = 0;
03041 numNewRows++;
03042
03043
03044
03045 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
03046 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
03047
03048 m_tmpScatterArray[ m_BmatrixIdx[ j] ] = 0;
03049 scatterValues[ m_BmatrixIdx[ j] ] = 0;
03050
03051 }
03052
03053
03054
03055
03056
03057
03058
03059
03060 m_BmatrixRowIndex[ m_numBmatrixCon - 1] = k;
03062
03063 }
03064
03065 solver->osiSolver->setObjCoeff( i, 0 );
03066
03067
03068
03069 }
03070 std::cout << std::endl << std::endl;
03071
03072
03073
03074 for(i = 0; i < numVar; i++ ) solver->osiSolver->setObjCoeff( i, 0 );
03075
03076
03077 }
03078
03079 delete[] wcoeff;
03080 wcoeff = NULL;
03081
03082 delete[] scatterValues;
03083 scatterValues = NULL;
03084
03085 numNonz = m_newRowNonz;
03086 colIdx = m_newRowColumnIdx;
03087 values = m_newRowColumnValue;
03088 rowUB = m_newRowUB;
03089 rowLB = m_newRowLB;
03090
03091 for(i = 0; i < numNewRows; i++){
03092
03093
03094
03095 m_numThetaVar++;
03096 m_convexityRowIndex[ m_numThetaVar] = -1;
03097 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
03098 }
03099
03100 return;
03101
03102
03103 } catch (const ErrorClass& eclass) {
03104 if(wcoeff != NULL){
03105 delete[] wcoeff;
03106 wcoeff = NULL;
03107 }
03108
03109
03110
03111 if(scatterValues != NULL) {
03112 delete[] scatterValues;
03113 scatterValues = NULL;
03114 }
03115
03116
03117 throw ErrorClass(eclass.errormsg);
03118
03119 }
03120
03121
03122 }
03123
03124 void OSBearcatSolverXij::getCutsX(const double* x, const int numX,
03125 int &numNewRows, int* &numNonz, int** &colIdx,
03126 double** &values, double* &rowLB, double* &rowUB) {
03127
03128
03129
03130 int i;
03131 int j;
03132 int k;
03133 int index;
03134 int rowKount;
03135
03136
03137 int indexAdjust = m_numNodes - m_numHubs;
03138 double* tmpRhs;
03139 int numSepRows = m_osinstanceSeparation->getConstraintNumber() ;
03140
03141 tmpRhs = new double[ numSepRows ];
03142
03143 for(i = 0; i < numSepRows; i++){
03144
03145 tmpRhs[ i] = 0;
03146 }
03147
03148 try{
03149 m_osinstanceSeparation->bConstraintsModified = true;
03150
03151 for(i = 0; i < numX; i++){
03152
03153
03154 if(x[ i] > m_osDecompParam.zeroTol){
03155
03156
03157 rowKount = m_separationIndexMap[ i ];
03158
03159 if(rowKount < OSINT_MAX ){
03160
03161 tmpRhs[ rowKount] -= x[ i];
03162
03163 }
03164
03165 }
03166 }
03167
03168 for(i = indexAdjust; i < numSepRows - 1; i++){
03169
03170 if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
03171
03172
03173
03174
03175
03176 int tmpKount = indexAdjust;
03177 for(int i1 = m_numHubs; i1 < m_numNodes; i1++){
03178
03179 for(int j1 = i1+1; j1 < m_numNodes; j1++){
03180
03181 if(tmpKount == i){
03182
03183 numNewRows = 1;
03184
03185 m_newRowNonz[ 0] = 2;
03186 m_newRowUB[ 0] = 1;
03187 m_newRowLB[ 0] = 0;
03188
03189 m_newRowColumnIdx[ 0][ 0 ] = i1*(m_numNodes - 1) + j1 - 1;
03190 m_newRowColumnIdx[ 0][ 1 ] = j1*(m_numNodes - 1) + i1;
03191 m_newRowColumnValue[ 0][ 0] = 1;
03192 m_newRowColumnValue[ 0][ 1] = 1;
03193
03194 numNonz = m_newRowNonz;
03195 colIdx = m_newRowColumnIdx;
03196 values = m_newRowColumnValue;
03197 rowUB = m_newRowUB;
03198 rowLB = m_newRowLB;
03199
03200 delete[] tmpRhs;
03201 tmpRhs = NULL;
03202 return;
03203
03204
03205
03206 }
03207
03208 tmpKount++;
03209
03210 }
03211
03212 }
03213
03214
03215 }
03216
03217 m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
03218 m_separationClpModel->setRowLower(i, tmpRhs[ i] );
03219
03220 }
03221
03222
03223
03224
03225
03226 std::vector<int> dualIdx;
03227 std::vector<int>::iterator vit1;
03228 std::vector<int>::iterator vit2;
03229
03230
03231
03232
03233 for(k = 0; k < indexAdjust; k++){
03234 std::cout << std::endl << std::endl;
03235
03236
03237 m_separationClpModel->setRowUpper(k, 0.0);
03238
03239
03240 m_separationClpModel->primal();
03241
03242 if(m_separationClpModel->getObjValue() > m_osDecompParam.zeroTol){
03243 std::cout << "DOING SEPARATION FOR NODE " << k + m_numHubs << std::endl;
03244 std::cout << "SEPERATION OBJ = " << m_separationClpModel->getObjValue() << std::endl;
03245 numNewRows = 1;
03246 m_newRowNonz[ 0] = 0;
03247 m_newRowLB[ 0] = 0;
03248
03249 for(i = 0; i < m_numNodes - m_numHubs ; i++){
03250
03251 if( m_separationClpModel->getRowPrice()[ i] - m_osDecompParam.zeroTol <= -1) dualIdx.push_back( i) ;
03252 }
03253
03254 for (vit1 = dualIdx.begin(); vit1 != dualIdx.end(); vit1++) {
03255
03256 i = *vit1 + m_numHubs;
03257
03258 for (vit2 = dualIdx.begin(); vit2 != dualIdx.end(); vit2++) {
03259
03260 j = *vit2 + m_numHubs;
03261
03262 if( i > j ){
03263
03264 index = i*(m_numNodes -1) + j;
03265 std::cout << "CUT VARIABLE = " << m_variableNames[ index] <<std::endl;
03266 m_newRowColumnValue[ 0][ m_newRowNonz[ 0] ] = 1.0;
03267 m_newRowColumnIdx[ 0][ m_newRowNonz[ 0]++ ] = index;
03268
03269 }else{
03270
03271 if( i < j ){
03272
03273 index = i*(m_numNodes -1) + j - 1;
03274 std::cout << "CUT VARIABLE = " << m_variableNames[ index] <<std::endl;
03275 m_newRowColumnValue[ 0][ m_newRowNonz[ 0] ] = 1.0;
03276 m_newRowColumnIdx[ 0][ m_newRowNonz[ 0]++ ] = index;
03277
03278 }
03279 }
03280
03281 }
03282 }
03283
03284
03285 m_newRowUB[ 0] = dualIdx.size() - 1;
03286
03287 dualIdx.clear();
03288
03289
03290 for(i = indexAdjust; i < numSepRows - 1; i++){
03291
03292 m_separationClpModel->setRowUpper(i, 0.0 );
03293 m_separationClpModel->setRowLower(i, 0.0 );
03294
03295
03296 }
03297 m_separationClpModel->setRowUpper(k, 1.0);
03298 delete[] tmpRhs;
03299 tmpRhs = NULL;
03300
03301
03302 numNonz = m_newRowNonz;
03303 colIdx = m_newRowColumnIdx;
03304 values = m_newRowColumnValue;
03305 rowUB = m_newRowUB;
03306 rowLB = m_newRowLB;
03307
03308 return;
03309
03310
03311
03312 }
03313 m_separationClpModel->setRowUpper(k, 1.0);
03314 dualIdx.clear();
03315
03316 }
03317
03318
03319
03320
03321 for(i = indexAdjust; i < numSepRows - 1; i++){
03322
03323 m_separationClpModel->setRowUpper(i, 0.0 );
03324 m_separationClpModel->setRowLower(i, 0.0 );
03325
03326
03327 }
03328
03329 delete[] tmpRhs;
03330 tmpRhs = NULL;
03331
03332 } catch (const ErrorClass& eclass) {
03333
03334 throw ErrorClass(eclass.errormsg);
03335
03336 }
03337
03338
03339 }
03340
03341
03342 void OSBearcatSolverXij::calcReducedCost( const double* yA, const double* yB){
03343
03344 int k;
03345 int i;
03346 int j;
03347 int l;
03348 int kount;
03349
03350 int tmpVal;
03351 tmpVal = m_numNodes - 1;
03352
03353 for(k = 0; k < m_numHubs; k++){
03354 kount = 0;
03355
03356 for(l = 1; l <= m_upperBoundL[ k]; l++){
03357
03358
03359 for(i = 0; i< m_numNodes; i++){
03360
03361
03362
03363 for(j = 0; j < i; j++){
03364
03365 if(j < m_numHubs){
03366
03367 m_rc[k][ kount++] = l*m_cost[ i*tmpVal + j ] ;
03368
03369 }else{
03370
03371 m_rc[k][ kount++] = l*m_cost[ i*tmpVal + j ] - yA[ j - m_numHubs] ;
03372 }
03373
03374
03375 }
03376
03377
03378
03379 for(j = i + 1; j < m_numNodes; j++){
03380
03381
03382 if(j < m_numHubs){
03383
03384 m_rc[k][ kount++] = l*m_cost[ i*tmpVal + j - 1 ];
03385
03386 } else {
03387
03388
03389 m_rc[k][ kount++] = l*m_cost[ i*tmpVal + j - 1 ] - yA[ j - m_numHubs ];
03390
03391 }
03392
03393 }
03394
03395
03396 }
03397
03398
03399 }
03400
03401
03402 }
03403
03404
03405
03406
03407 int startPnt ;
03408
03409 for(i = 0; i < m_numBmatrixCon; i++){
03410
03411
03412
03413 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
03414
03415
03416
03417 for(k = 0; k < m_numHubs; k++){
03418
03419
03420 for(l = 1; l <= m_upperBoundL[ k]; l++){
03421
03422
03423 startPnt = (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
03424
03425 if(m_BmatrixRowIndex[ i] == -1 || m_BmatrixRowIndex[ i] == k ) m_rc[ k][ startPnt + m_BmatrixIdx[ j] ] -= yB[ i]*m_BmatrixVal[ j];
03426
03427 }
03428
03429 }
03430
03431
03432 }
03433
03434 }
03435
03436 }
03437
03438
03439 void OSBearcatSolverXij::createVariableNames( ){
03440
03441 int i;
03442 int j;
03443 int kount;
03444
03445 kount = 0;
03446
03447 for(i = 0; i< m_numNodes; i++){
03448
03449
03450 for(j = 0; j < i; j++){
03451
03452 if(m_nodeName[ i] == "") m_variableNames[ kount] = makeStringFromInt("x(" , i);
03453 else m_variableNames[ kount] = "x(" + m_nodeName[ i];
03454 if(m_nodeName[ i] == "") m_variableNames[ kount] += makeStringFromInt( "," , j);
03455 else m_variableNames[ kount] += "," + m_nodeName[ j];
03456 m_variableNames[ kount] += ")";
03457
03458
03459 kount++;
03460
03461 }
03462
03463 for(j = i + 1; j < m_numNodes; j++){
03464
03465 if(m_nodeName[ i] == "") m_variableNames[ kount] = makeStringFromInt("x(" , i);
03466 else m_variableNames[ kount] = "x(" + m_nodeName[ i];
03467 if(m_nodeName[ i] == "") m_variableNames[ kount] += makeStringFromInt( "," , j);
03468 else m_variableNames[ kount] += "," + m_nodeName[ j];
03469 m_variableNames[ kount] += ")";
03470
03471
03472 kount++;
03473
03474 }
03475
03476
03477 }
03478 }
03479
03480 void OSBearcatSolverXij::createAmatrix(){
03481
03482
03483
03484
03485
03486
03487
03488 int i;
03489 int j;
03490 int numNonz;
03491
03492
03493 m_pntAmatrix[ 0] = 0;
03494 numNonz = 0;
03495
03496 for(j = m_numHubs; j < m_numNodes; j++){
03497
03498
03499 for(i = 0; i < j; i++){
03500
03501 m_Amatrix[ numNonz++] = i*(m_numNodes - 1) + j - 1 ;
03502
03503 }
03504
03505 for(i = j + 1; i < m_numNodes; i++){
03506
03507 m_Amatrix[ numNonz++] = i*(m_numNodes - 1) + j ;
03508
03509 }
03510
03511 m_pntAmatrix[ j - m_numHubs + 1] = numNonz;
03512
03513 }
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527 }
03528
03529 void OSBearcatSolverXij::pauHana( std::vector<int> &m_zOptIndexes,
03530 std::vector<double> &m_zRootLPx_vals,
03531 int numNodes, int numColsGen, std::string message){
03532
03533 std::cout << std::endl;
03534 std::cout << " PAU HANA TIME! " << std::endl;
03535
03536 double cost;
03537 cost = 0;
03538 std::vector<int>::iterator vit;
03539 try{
03540 int i;
03541 int j;
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557 double routeDemand;
03558
03559
03560 int ivalue;
03561 int jvalue;
03562
03563 for(vit = m_zOptIndexes.begin() ; vit != m_zOptIndexes.end(); vit++){
03564
03565 i = *vit;
03566 std::cout << "x variables for column " << i << " CONVEXITY ROW = "<< m_convexityRowIndex[ i] << std::endl;
03567
03568
03569
03570 routeDemand = 0;
03571
03572 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
03573
03574
03575
03576 std::cout << m_variableNames[ m_thetaIndex[ j] ] << " = " << 1 << " DISTANCE = " << m_cost[ m_thetaIndex[ j] ] << std::endl;
03577
03578 ivalue = m_thetaIndex[ j] /(m_numNodes - 1);
03579
03580 jvalue = m_thetaIndex[ j] - ivalue*(m_numNodes - 1);
03581
03582 if( jvalue >= ivalue ){
03583
03584
03585
03586 routeDemand += m_demand[ jvalue + 1];
03587
03588
03589 }else{
03590
03591
03592
03593 routeDemand += m_demand[ jvalue ];
03594 }
03595 }
03596
03597 std::cout << "route demand = " << routeDemand << std::endl << std::endl;
03598 std::cout << "distance for this route " << m_thetaCost[ i ] / routeDemand << std::endl;
03599
03600 }
03601
03602
03603
03604
03605 std::cout << std::endl << std::endl;
03606 std::cout << message << std::endl;
03607 std::cout << "LINEAR PROGRAMMING RELAXATION VALUE = " << m_rootLPValue << std::endl;
03608 std::cout << "NONLINEAR RELAXATION VALUE = " << calcNonlinearRelax( m_zRootLPx_vals) << std::endl;
03609 std::cout << "LOWER BOUND VALUE = " << m_bestLPValue << std::endl;
03610 std::cout << "FINAL BEST IP SOLUTION VALUE = " << m_bestIPValue << std::endl;
03611 std::cout << "NUMBER OF COLUMNS IN FINAL MASTER = " << m_numThetaVar << std::endl;
03612
03613
03614 std::cout << "NUMBER OF GENERATED COLUMNS = " << numColsGen << std::endl;
03615 std::cout << "NUMBER OF GENERATED CUTS = " << m_numBmatrixCon << std::endl;
03616 std::cout << "NUMBER OF NODES = " << numNodes << std::endl;
03617 std::cout << " PAU!!!" << std::endl;
03618
03619 std::cout << std::endl << std::endl;
03620
03621 std::cout << std::endl << std::endl;
03622 }catch (const ErrorClass& eclass) {
03623
03624 throw ErrorClass(eclass.errormsg);
03625
03626 }
03627
03628 }
03629
03630 double OSBearcatSolverXij::calcNonlinearRelax( std::vector<double> &m_zRootLPx_vals){
03631
03632
03633 std::vector<double>::iterator dvit;
03634 std::vector<double>::iterator dvit2;
03635 int index = 0;
03636 int i;
03637 int j;
03638 int ivalue;
03639 int jvalue;
03640 double *hubDemand = NULL;
03641 double *hubCost = NULL;
03642 hubDemand = new double[m_numHubs ];
03643 hubCost = new double[ m_numHubs];
03644
03645 double objVal = 0.0;
03646 double objValAux = 0.0;
03647
03648 std::map<int, std::vector<double> > extPointDemands;
03649 std::map<int, std::vector<double> > extPointCosts;
03650 std::map<int, std::vector<double> > extPointValues;
03651
03652 std::map<int, std::vector<double> >::iterator mit;
03653
03654 double tmpDemand;
03655 double tmpCost;
03656
03657 for(i = 0; i < m_numHubs; i++){
03658 hubDemand[ i] = 0;
03659 hubCost[ i] = 0;
03660
03661 }
03662
03663 try{
03664 for (dvit = m_zRootLPx_vals.begin(); dvit < m_zRootLPx_vals.end(); dvit++ ){
03665
03666 if(*dvit > m_osDecompParam.zeroTol){
03667
03668
03669
03670
03671 tmpDemand = 0;
03672 tmpCost = 0;
03673
03674 for(j = m_thetaPnt[ index]; j < m_thetaPnt[ index + 1] ; j++){
03675
03676
03677
03678
03679 hubCost[ m_hubPoint[ m_convexityRowIndex[ index] ] ] += m_cost[ m_thetaIndex[ j] ]*( *dvit);
03680 tmpCost += m_cost[ m_thetaIndex[ j] ];
03681
03682 ivalue = m_thetaIndex[ j] /(m_numNodes - 1);
03683 jvalue = m_thetaIndex[ j] - ivalue*(m_numNodes - 1);
03684
03685 if( jvalue >= ivalue ){
03686
03687
03688
03689 hubDemand[ m_hubPoint[ m_convexityRowIndex[ index] ] ] += m_demand[ jvalue + 1]*( *dvit);
03690 tmpDemand += m_demand[ jvalue + 1];
03691
03692
03693
03694 }else{
03695
03696
03697
03698 hubDemand[ m_hubPoint[ m_convexityRowIndex[ index] ] ] += m_demand[ jvalue ]*( *dvit);
03699 tmpDemand += m_demand[ jvalue];
03700
03701 }
03702 }
03703
03704
03705 extPointDemands[ m_convexityRowIndex[ index] ].push_back( tmpDemand);
03706 extPointCosts[ m_convexityRowIndex[ index] ].push_back( tmpCost);
03707 extPointValues[ m_convexityRowIndex[ index] ].push_back(*dvit);
03708
03709 }
03710
03711
03712
03713 index++;
03714
03715 }
03716
03717 int mapSize;
03718 objValAux = 0;
03719 for (i = 0; i < m_numHubs; i++){
03720
03721
03722 objVal += hubDemand[ m_hubPoint[ i] ]*hubCost[ m_hubPoint[ i]];
03723 tmpDemand = 0;
03724 tmpCost = 0;
03725
03726 mapSize = extPointDemands[ m_hubPoint[ i] ].size();
03727
03728
03729
03730 for (j = 0; j < mapSize; j++){
03731
03732 tmpDemand += extPointDemands[ m_hubPoint[ i] ][j]*extPointValues[ m_hubPoint[ i] ][j];
03733 tmpCost += extPointCosts[ m_hubPoint[ i] ][j]*extPointValues[ m_hubPoint[ i] ][j];
03734
03735
03736
03737 objValAux +=
03738 extPointCosts[ m_hubPoint[ i] ][j]*extPointDemands[ m_hubPoint[ i] ][j]*extPointValues[ m_hubPoint[ i] ][j];
03739
03740 }
03741
03742
03743
03744
03745
03746 }
03747
03748 std::cout << "AUXILIARY VALUE COST = " << objValAux << std::endl;
03749
03750
03751 delete[] hubDemand;
03752 hubDemand = NULL;
03753 delete[] hubCost;
03754 hubCost = NULL;
03755
03756
03757 return objVal;
03758
03759 }catch (const ErrorClass& eclass) {
03760
03761
03762 delete[] hubDemand;
03763 hubDemand = NULL;
03764 delete[] hubCost;
03765 hubCost = NULL;
03766
03767
03768 throw ErrorClass(eclass.errormsg);
03769
03770 }
03771
03772
03773 }
03774
03775
03776 OSInstance* OSBearcatSolverXij::getSeparationInstance(){
03777
03778
03779
03780
03781 m_osinstanceSeparation = NULL;
03782
03783
03784
03785
03786 int kountNonz;
03787 int kount;
03788 int startsIdx;
03789
03790 int numYvar = (m_numNodes - m_numHubs)*(m_numNodes - m_numHubs - 1);
03791 int numVvar = m_numNodes - m_numHubs;
03792
03793 int numCon = (m_numNodes - m_numHubs) + (m_numNodes - m_numHubs)*(m_numNodes - m_numHubs - 1)/2 + 1;
03794 double *values = new double[ 2*numYvar + 2*numVvar];
03795 int *indexes = new int[ 2*numYvar + 2*numVvar];
03796 int *starts = new int[ numYvar + numVvar + 1];
03797 starts[ 0] = 0;
03798 startsIdx = 0;
03799 startsIdx++;
03800 kountNonz = 0;
03801 int i;
03802 int j;
03803
03804
03805 std::string separationVarName;
03806 std::string separationConName;
03807
03808 try {
03809
03810 m_osinstanceSeparation = new OSInstance();
03811
03812
03813
03814 m_osinstanceSeparation->setInstanceDescription("The Tour Breaking Separation Problem");
03815
03816
03817
03818 m_osinstanceSeparation->setConstraintNumber( numCon);
03819
03820
03821
03822 for( i = 0; i < m_numNodes - m_numHubs ; i++){
03823
03824 m_osinstanceSeparation->addConstraint(i, makeStringFromInt("nodeRow_", i+ m_numHubs ) , 0.0, 1.0, 0);
03825
03826 }
03827
03828
03829
03830 int rowKounter;
03831 rowKounter = m_numNodes - m_numHubs;
03832
03833 for(i = m_numHubs; i < m_numNodes; i++){
03834
03835
03836
03837 for(j = i+1; j < m_numNodes; j++){
03838 separationConName = makeStringFromInt("Row_(", i);
03839 separationConName += makeStringFromInt(",", j);
03840 separationConName += ")";
03841
03842 m_osinstanceSeparation->addConstraint(rowKounter++, separationConName , 0, 0, 0);
03843 }
03844
03845 }
03846
03847
03848 m_osinstanceSeparation->addConstraint(rowKounter++, "kludgeRow" , 0, m_numNodes, 0);
03849
03850
03851 m_osinstanceSeparation->setVariableNumber( numYvar + numVvar);
03852
03853
03854
03855 std::cout << "NUMBER OF VARIABLES SET = " << numYvar + numVvar << std::endl;
03856
03857 for(i = 0; i < numVvar; i++){
03858
03859 separationVarName = makeStringFromInt("v", i + m_numHubs);
03860
03861 m_osinstanceSeparation->addVariable(i, separationVarName, 0, 1, 'C');
03862
03863 values[ kountNonz ] = -1.0;
03864 indexes[ kountNonz ] = i;
03865 kountNonz++;
03866
03867 values[ kountNonz ] = 1.0;
03868 indexes[ kountNonz ] = rowKounter - 1;
03869 kountNonz++;
03870
03871
03872
03873 starts[ startsIdx++ ] = kountNonz;
03874
03875
03876 }
03877
03878 kount = numVvar;
03879
03880 int i1;
03881 int j1;
03882 int kountCon;
03883 kountCon = m_numNodes - m_numHubs;
03884
03885 for(i1 = 0; i1 < m_numNodes - m_numHubs; i1++){
03886
03887
03888 i = i1 + m_numHubs;
03889
03890 for(j1 = i1 + 1; j1 < m_numNodes - m_numHubs; j1++){
03891
03892
03893 j = j1 + m_numHubs;
03894
03895 separationVarName = makeStringFromInt("y(", i);
03896 separationVarName += makeStringFromInt(",", j);
03897 separationVarName += ")";
03898 m_osinstanceSeparation->addVariable(kount++, separationVarName, 0, 1, 'C');
03899
03900
03901
03902
03903 m_separationIndexMap[ i*(m_numNodes - 1) + (j - 1) ] = kountCon;
03904
03905 values[ kountNonz ] = 1.0;
03906 indexes[ kountNonz ] = i1;
03907 kountNonz++;
03908
03909 values[ kountNonz ] = -1.0;
03910 indexes[ kountNonz ] = kountCon ;
03911 kountNonz++;
03912
03913 starts[ startsIdx++ ] = kountNonz;
03914
03915
03916
03917
03918 separationVarName = makeStringFromInt("y(", j );
03919 separationVarName += makeStringFromInt(",", i);
03920 separationVarName += ")";
03921 m_osinstanceSeparation->addVariable(kount++, separationVarName, 0, 1, 'C');
03922
03923 values[ kountNonz ] = 1.0;
03924 indexes[ kountNonz ] = j1;
03925 kountNonz++;
03926
03927
03928 m_separationIndexMap[ j*(m_numNodes - 1) + i ] = kountCon;
03929
03930 values[ kountNonz ] = -1.0;
03931 indexes[ kountNonz ] = kountCon ;
03932 kountNonz++;
03933
03934 starts[ startsIdx++ ] = kountNonz;
03935
03936
03937 kountCon++;
03938
03939
03940 }
03941
03942 }
03943
03944 std::cout << "NUMBER OF VARIABLES ADDED = " << kount << std::endl;
03945
03946
03947 m_osinstanceSeparation->setObjectiveNumber( 1);
03948 SparseVector *objcoeff = new SparseVector( numVvar);
03949
03950
03951 for(i = 0; i < numVvar; i++){
03952
03953 objcoeff->indexes[ i] = i;
03954 objcoeff->values[ i] = 1.0;
03955
03956 }
03957
03958
03959
03960
03961
03962 m_osinstanceSeparation->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
03963
03964
03965 m_osinstanceSeparation->setLinearConstraintCoefficients(kountNonz , true,
03966 values, 0, kountNonz - 1, indexes, 0, kountNonz - 1, starts, 0, startsIdx);
03967
03968
03969
03970
03971
03972 delete objcoeff;
03973
03974
03975
03976
03977
03978
03979 CoinPackedMatrix* matrix;
03980 bool columnMajor = true;
03981 double maxGap = 0;
03982 matrix = new CoinPackedMatrix(
03983 columnMajor,
03984 columnMajor? m_osinstanceSeparation->getConstraintNumber() : m_osinstanceSeparation->getVariableNumber(),
03985 columnMajor? m_osinstanceSeparation->getVariableNumber() : m_osinstanceSeparation->getConstraintNumber(),
03986 m_osinstanceSeparation->getLinearConstraintCoefficientNumber(),
03987 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->values : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->values,
03988 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->indexes : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->indexes,
03989 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->starts : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->starts,
03990 0, 0, maxGap );
03991
03992 ClpNetworkMatrix network( *matrix);
03993
03994 m_separationClpModel = new ClpSimplex();
03995
03996
03997 m_separationClpModel->setOptimizationDirection( 1);
03998 m_separationClpModel->loadProblem( network, m_osinstanceSeparation->getVariableLowerBounds(),
03999 m_osinstanceSeparation->getVariableUpperBounds(),
04000 m_osinstanceSeparation->getDenseObjectiveCoefficients()[0],
04001 m_osinstanceSeparation->getConstraintLowerBounds(), m_osinstanceSeparation->getConstraintUpperBounds()
04002 );
04003
04004 m_separationClpModel->factorization()->maximumPivots(200 + m_separationClpModel->numberRows() / 100);
04005
04006
04007 delete matrix;
04008
04009 }catch (const ErrorClass& eclass) {
04010
04011 throw ErrorClass(eclass.errormsg);
04012
04013 }
04014
04015 return NULL;
04016 }
04017
04018
04019
04020 int OSBearcatSolverXij::getBranchingVar(const double* theta, const int numThetaVar ) {
04021
04022 int varIdx;
04023 varIdx = -1;
04024 int i;
04025 int j;
04026 int numVar = m_numNodes*m_numNodes - m_numHubs ;
04027
04028 double from1Distance;
04029 double from0Distance;
04030 double fraction;
04031 double minFraction;
04032
04033 double *xvalues;
04034
04035
04036 xvalues = new double[ numVar];
04037 for(i = 0; i < numVar; i++){
04038 xvalues[ i] = 0;
04039 }
04040
04041 try{
04042 if(numThetaVar != m_numThetaVar) throw ErrorClass("inconsistent number of variables in getBranchingVar");
04043
04044 for(i = 0; i < m_numThetaVar; i++){
04045
04046 if( ( theta[ i ] > m_osDecompParam.zeroTol ) && ( theta[ i ] < 1 - m_osDecompParam.zeroTol ) ){
04047
04048 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
04049
04050 xvalues[ m_thetaIndex[ j] ] += theta[ i ] ;
04051
04052 }
04053
04054 }
04055
04056
04057 }
04058
04059
04060 minFraction = 1.0;
04061
04062
04063 for(i = 0; i < m_numHubs; i++){
04064
04065 for( j = 0; j < i; j++){
04066
04067
04068 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
04069 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
04070 fraction = std::max(from1Distance, from0Distance);
04071
04072 if(fraction < minFraction){
04073
04074 minFraction = fraction;
04075 varIdx = i*(m_numNodes - 1) + j;
04076 }
04077
04078 }
04079
04080 for(j = i + 1; j < m_numNodes; j++){
04081
04082
04083
04084 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
04085 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
04086 fraction = std::max(from1Distance, from0Distance);
04087
04088 if(fraction < minFraction) {
04089
04090 minFraction = fraction;
04091 varIdx = i*(m_numNodes - 1) + j - 1;
04092 }
04093
04094
04095 }
04096
04097 }
04098
04099
04100
04101 if(minFraction > 1 - m_osDecompParam.zeroTol){
04102
04103 for(i = m_numHubs; i < m_numNodes; i++){
04104
04105 for( j = 0; j < i; j++){
04106
04107
04108 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
04109 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
04110 fraction = std::max(from1Distance, from0Distance);
04111
04112 if(fraction < minFraction) {
04113
04114 minFraction = fraction;
04115 varIdx = i*(m_numNodes - 1) + j ;
04116 }
04117
04118 }
04119
04120 for(j = i + 1; j < m_numNodes; j++){
04121
04122
04123
04124 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
04125 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
04126 fraction = std::max(from1Distance, from0Distance);
04127
04128 if(fraction < minFraction) {
04129
04130 minFraction = fraction;
04131 varIdx = i*(m_numNodes - 1) + j - 1;
04132 }
04133
04134 }
04135
04136 }
04137
04138 }
04139
04140
04141 delete[] xvalues;
04142
04143 xvalues = NULL;
04144
04145 return varIdx;
04146
04147 }catch (const ErrorClass& eclass) {
04148
04149 delete[] xvalues;
04150 xvalues = NULL;
04151
04152 throw ErrorClass(eclass.errormsg);
04153
04154 }
04155
04156
04157 }
04158
04159
04160
04161 int OSBearcatSolverXij::getBranchingVar(const int* thetaIdx, const double* theta,
04162 const int numThetaVar) {
04163
04164 int varIdx;
04165 varIdx = -1;
04166 int i;
04167 int j;
04168 int numVar = m_numNodes*m_numNodes - m_numHubs ;
04169 double from1Distance;
04170 double from0Distance;
04171 double fraction;
04172 double minFraction;
04173
04174 double *xvalues;
04175
04176
04177 xvalues = new double[ numVar];
04178 for(i = 0; i < numVar; i++){
04179 xvalues[ i] = 0;
04180 }
04181
04182 try{
04183
04184
04185 for(i = 0; i < numThetaVar; i++){
04186
04187 if( ( theta[ i ] > m_osDecompParam.zeroTol ) && ( theta[ i ] < 1 - m_osDecompParam.zeroTol ) ){
04188
04189 for(j = m_thetaPnt[ thetaIdx[ i] ]; j < m_thetaPnt[ thetaIdx[ i] + 1] ; j++){
04190
04191 xvalues[ m_thetaIndex[ j] ] += theta[ i ] ;
04192
04193 }
04194
04195 }
04196
04197
04198 }
04199
04200
04201
04202 minFraction = 1.0;
04203
04204
04205 for(i = 0; i < m_numHubs; i++){
04206
04207 for( j = 0; j < i; j++){
04208
04209
04210 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
04211 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
04212 fraction = std::max(from1Distance, from0Distance);
04213
04214 if(fraction < minFraction){
04215
04216 minFraction = fraction;
04217 varIdx = i*(m_numNodes - 1) + j;
04218 }
04219
04220 }
04221
04222 for(j = i + 1; j < m_numNodes; j++){
04223
04224
04225
04226 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
04227 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
04228 fraction = std::max(from1Distance, from0Distance);
04229
04230 if(fraction < minFraction) {
04231
04232 minFraction = fraction;
04233 varIdx = i*(m_numNodes - 1) + j - 1;
04234 }
04235
04236
04237 }
04238
04239 }
04240
04241
04242
04243 std::cout << "MIN FRACTION = " << minFraction << std::endl;
04244
04245 if(minFraction > 1 - m_osDecompParam.zeroTol){
04246
04247 for(i = m_numHubs; i < m_numNodes; i++){
04248
04249
04250
04251 for( j = 0; j < i; j++){
04252
04253
04254 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
04255 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
04256 fraction = std::max(from1Distance, from0Distance);
04257
04258 if(fraction < minFraction) {
04259
04260 minFraction = fraction;
04261 varIdx = i*(m_numNodes - 1) + j ;
04262 }
04263
04264 }
04265
04266 for(j = i + 1; j < m_numNodes; j++){
04267
04268
04269
04270 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
04271 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
04272 fraction = std::max(from1Distance, from0Distance);
04273
04274 if(fraction < minFraction) {
04275
04276 minFraction = fraction;
04277 varIdx = i*(m_numNodes - 1) + j - 1;
04278 }
04279
04280 }
04281
04282 }
04283
04284 }
04285
04286
04287
04288 delete[] xvalues;
04289 xvalues = NULL;
04290
04291 return varIdx;
04292
04293 }catch (const ErrorClass& eclass) {
04294
04295 delete[] xvalues;
04296 xvalues = NULL;
04297
04298 throw ErrorClass(eclass.errormsg);
04299
04300 }
04301
04302
04303 }
04304
04305
04306 void OSBearcatSolverXij::getBranchingCut(const double* thetaVar, const int numThetaVar,
04307 const std::map<int, int> &varConMap, int &varIdx, int &numNonz,
04308 int* &indexes, double* &values) {
04309
04310
04311 int i;
04312 int j;
04313 int kount;
04314 numNonz = 0;
04315
04316
04317
04318 try{
04319
04320 if(numThetaVar != m_numThetaVar) throw ErrorClass("inconsistent number of variables in getBranchingCut");
04321
04322
04323 varIdx = getBranchingVar(thetaVar, numThetaVar );
04324 std::cout << "VARIABLE INDEX = " << varIdx << std::endl;
04325 std::cout << "Branching on Variable: " << m_variableNames[ varIdx] << std::endl;
04326
04327
04328
04329
04330 if( varConMap.find( varIdx) == varConMap.end() ){
04331
04332 for(i = 0; i < m_numThetaVar; i++){
04333
04334 kount = 0;
04335
04336 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
04337
04338 if ( m_thetaIndex[ j] == varIdx) kount++ ;
04339
04340 }
04341
04342
04343
04344 if(kount > 0){
04345
04346 branchCutIndexes[ numNonz] = i;
04347 branchCutValues[ numNonz++] = kount ;
04348
04349 }
04350
04351 }
04352
04353
04354
04355 m_BmatrixVal[ m_numBmatrixNonz] = 1;
04356 m_BmatrixIdx[ m_numBmatrixNonz++] = varIdx;
04357 m_numBmatrixCon++;
04358 m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
04359
04360
04361
04362
04363 m_numThetaVar++;
04364 m_convexityRowIndex[ m_numThetaVar] = -1;
04365 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
04366
04367
04368
04369
04370 }
04371
04372
04373
04374 indexes = branchCutIndexes;
04375 values = branchCutValues;
04376
04377 return;
04378
04379 }catch (const ErrorClass& eclass) {
04380
04381 throw ErrorClass(eclass.errormsg);
04382
04383 }
04384
04385 }
04386
04387
04388 void OSBearcatSolverXij::getBranchingCut(const int* thetaIdx, const double* thetaVar,
04389 const int numThetaVar, const std::map<int, int> &varConMap,
04390 int &varIdx, int &numNonz, int* &indexes, double* &values) {
04391
04392
04393 int i;
04394 int j;
04395 int kount;
04396 numNonz = 0;
04397
04398
04399
04400 try{
04401
04402
04403
04404 varIdx = getBranchingVar(thetaIdx, thetaVar, numThetaVar );
04405
04406 std::cout << "Branching on Variable: " << m_variableNames[ varIdx] << std::endl;
04407
04408
04409
04410
04411 if( varConMap.find( varIdx) == varConMap.end() ){
04412
04413
04414
04415
04416
04417
04418 for(i = 0; i < m_numThetaVar; i++){
04419
04420 kount = 0;
04421
04422 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
04423
04424 if ( m_thetaIndex[ j] == varIdx) kount++ ;
04425
04426 }
04427
04428
04429
04430 if(kount > 0){
04431
04432 branchCutIndexes[ numNonz] = i;
04433 branchCutValues[ numNonz++] = kount ;
04434
04435 }
04436
04437 }
04438
04439
04440
04441 m_BmatrixVal[ m_numBmatrixNonz] = 1.0;
04442 m_BmatrixIdx[ m_numBmatrixNonz++] = varIdx;
04443 m_numBmatrixCon++;
04444 m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
04445
04446
04447
04448
04449 m_numThetaVar++;
04450 m_convexityRowIndex[ m_numThetaVar] = -1;
04451 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
04452
04453
04454
04455
04456 }
04457
04458
04459
04460 indexes = branchCutIndexes;
04461 values = branchCutValues;
04462
04463 return;
04464
04465 }catch (const ErrorClass& eclass) {
04466
04467 throw ErrorClass(eclass.errormsg);
04468
04469 }
04470
04471 }
04472
04473
04474 void OSBearcatSolverXij::getInitialSolution(){
04475
04476 int k;
04477 double *routeDemand;
04478 routeDemand = NULL;
04479 routeDemand = new double[ m_numHubs];
04480 std::map<int, std::vector<int> > routeMap;
04481 std::vector<int>::iterator vit;
04482 bool isFeasible;
04483
04484
04485 isFeasible = true;
04486 try{
04487
04488 routeMap = m_initSolMap[ 0];
04489
04490 for(k = 0; k < m_numHubs; k++){
04491
04492 routeDemand[ k] = 0;
04493 for(vit = routeMap[k].begin(); vit!=routeMap[k].end(); ++vit){
04494
04495
04496 routeDemand[ k] += m_demand[ *vit];
04497 }
04498
04499 if(routeDemand[k] > m_routeCapacity[ k] ){
04500
04501 isFeasible = false;
04502 break;
04503
04504 }
04505 }
04506
04507 delete[] routeDemand;
04508 routeDemand = NULL;
04509
04510 if(isFeasible == false) getFeasibleSolution();
04511
04512 OneOPT();
04513
04514
04515 }catch (const ErrorClass& eclass) {
04516
04517 if(routeDemand == NULL){
04518
04519 delete[] routeDemand;
04520 routeDemand = NULL;
04521 }
04522
04523 throw ErrorClass(eclass.errormsg);
04524
04525 }
04526
04527
04528 }
04529
04530
04531 void OSBearcatSolverXij::resetMaster( std::map<int, int> &inVars, OsiSolverInterface *si){
04532
04533 int i;
04534 int j;
04535
04536 int kount;
04537 int numNonz;
04538
04539 std::map<int, int>::iterator mit;
04540
04541 int numVars = inVars.size();
04542 int numVarArt;
04543
04544
04545
04546 numVarArt = m_numNodes + m_numBmatrixCon;
04547
04548
04549 std::vector<double> valuesVec;
04550 double *values = NULL;
04551
04552 std::vector<int> indexesVec;
04553 int *indexes = NULL ;
04554
04555 int *starts = new int[ numVars + 1 + numVarArt];
04556
04557 int startsIdx;
04558
04559
04560
04561
04562 int* thetaPntTmp;
04563 int* thetaIndexTmp;
04564 int* tmpConvexity = new int[ m_numThetaVar];
04565
04566
04567 numNonz = 0;
04568
04569 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04570
04571 numNonz += m_thetaPnt[mit->first + 1 ] - m_thetaPnt[ mit->first ];
04572 }
04573
04574
04575 thetaPntTmp = new int[ numVars + 1];
04576 thetaIndexTmp = new int[ numNonz];
04577
04578
04579
04580 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04581
04582
04583
04584 if( m_convexityRowIndex[ mit->first] == -1) throw ErrorClass( "we have an artificial variable in reset master");
04585
04586
04587 }
04588
04589
04590 kount = 0;
04591 numNonz = 0;
04592 thetaPntTmp[ kount] = 0;
04593
04594 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04595
04596
04597
04598 kount++;
04599
04600 for(i = m_thetaPnt[ mit->first ]; i < m_thetaPnt[mit->first + 1 ]; i++){
04601
04602 thetaIndexTmp[ numNonz++] = m_thetaIndex[ i];
04603
04604
04605
04606 }
04607
04608 thetaPntTmp[ kount] = numNonz;
04609
04610
04611
04612
04613
04614 inVars[ mit->first] = numVarArt + kount - 1 ;
04615
04616 }
04617
04618
04619
04620
04621
04622
04623
04624 for(i = 0; i < m_numThetaVar; i++) tmpConvexity[ i] = m_convexityRowIndex[ i];
04625
04626
04627
04628 m_numThetaVar = 0;
04629 m_numThetaNonz = 0;
04630 for(i = 0; i < numVarArt; i++){
04631
04632 m_convexityRowIndex[ m_numThetaVar] = -1;
04633 m_thetaPnt[ m_numThetaVar++] = 0;
04634
04635
04636 }
04637
04638
04639 intVarSet.clear();
04640 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04641
04642
04643 intVarSet.insert ( std::pair<int,double>(mit->second, 1.0) );
04644
04645
04646
04647
04648 m_convexityRowIndex[ m_numThetaVar] = tmpConvexity[ mit->first];
04649
04650 m_thetaPnt[ m_numThetaVar++ ] = m_numThetaNonz;
04651
04652 for(j = thetaPntTmp[ mit->second - numVarArt]; j < thetaPntTmp[ mit->second - numVarArt + 1 ]; j++){
04653
04654
04655 m_thetaIndex[ m_numThetaNonz ] = thetaIndexTmp[ m_numThetaNonz] ;
04656 m_numThetaNonz++;
04657
04658 }
04659
04660 }
04661
04662 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672 si->writeLp( "gailTest" );
04673
04674
04675
04676
04677
04678 numNonz = 0;
04679 startsIdx = 0;
04680 starts[ startsIdx++] = numNonz;
04681
04682 for(i = 0; i < numVarArt; i++){
04683 numNonz++;
04684 starts[ startsIdx++] = numNonz;
04685 valuesVec.push_back( 1.0);
04686 indexesVec.push_back( i);
04687
04688 }
04689
04690
04691 int rowCount;
04692
04693 int numAmatrixRows;
04694 numAmatrixRows = m_numNodes - m_numHubs;
04695
04696 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04697
04698
04699 valuesVec.push_back( 1.0);
04700 indexesVec.push_back( numAmatrixRows + m_convexityRowIndex[ mit->second] );
04701
04702 numNonz++;
04703
04704 for(j = m_thetaPnt[ mit->second ]; j < m_thetaPnt[ mit->second + 1 ]; j++){
04705
04706 m_tmpScatterArray[ m_thetaIndex[ j] ]++;
04707
04708
04709
04710 }
04711
04712
04713
04714
04715 for(i = 0; i < numAmatrixRows; i++){
04716
04717 rowCount = 0;
04718
04719 for(j = m_pntAmatrix[ i]; j < m_pntAmatrix[ i + 1]; j++){
04720
04721
04722
04723
04724 rowCount += m_tmpScatterArray[ m_Amatrix[ j] ];
04725
04726
04727 }
04728
04729 if(rowCount > 0){
04730
04731 numNonz++;
04732
04733
04734 valuesVec.push_back( rowCount);
04735 indexesVec.push_back( i);
04736
04737
04738 }
04739
04740
04741 }
04742
04743
04744
04745 for(i = 0; i < m_numBmatrixCon; i++){
04746
04747 rowCount = 0;
04748
04749 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
04750
04751
04752
04753
04754 rowCount += m_tmpScatterArray[ m_BmatrixIdx[ j] ];
04755
04756
04757 }
04758
04759 if(rowCount > 0){
04760 numNonz++;
04761
04762
04763
04764 valuesVec.push_back( rowCount);
04765 indexesVec.push_back( i + m_numNodes);
04766 }
04767
04768
04769 }
04770
04771
04772
04773
04774 for(j = m_thetaPnt[ mit->second ]; j < m_thetaPnt[ mit->second + 1 ]; j++){
04775
04776 m_tmpScatterArray[ m_thetaIndex[ j] ] = 0;
04777
04778 }
04779
04780 starts[ startsIdx++] = numNonz;
04781
04782 }
04783
04784
04785
04786 values = new double[ numNonz];
04787 indexes = new int[ numNonz];
04788
04789 if( (unsigned int)numNonz != valuesVec.size() ) throw ErrorClass("dimension problem in reset");
04790 if( (unsigned int)numNonz != indexesVec.size() ) throw ErrorClass("dimension problem in reset");
04791
04792 for(i = 0; i < numNonz; i++){
04793
04794 values[ i] = valuesVec[i];
04795 indexes[ i] = indexesVec[i];
04796
04797 }
04798
04799
04800
04801
04802
04803
04804
04805 delete m_osinstanceMaster;
04806 m_osinstanceMaster = NULL;
04807
04808
04809 m_osinstanceMaster = new OSInstance();
04810 m_osinstanceMaster->setInstanceDescription("The Restricted Master");
04811
04812
04813
04814 m_osinstanceMaster->setVariableNumber( numVars + numVarArt );
04815
04816
04817
04818
04819 SparseVector *objcoeff = new SparseVector( numVars + numVarArt);
04820
04821
04822
04823
04824 m_osinstanceMaster->setConstraintNumber( m_numNodes + m_numBmatrixCon);
04825
04826
04827
04828
04829 int varNumber;
04830 varNumber = 0;
04831
04832
04833
04834 for(i = 0; i < numVarArt; i++){
04835
04836 objcoeff->indexes[ varNumber ] = varNumber ;
04837
04838 objcoeff->values[ varNumber ] = m_osDecompParam.artVarCoeff;
04839
04840 m_thetaCost[ varNumber] = m_osDecompParam.artVarCoeff;
04841
04842 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt("x", i ) ,
04843 0, 1.0, 'C');
04844
04845
04846 }
04847
04848
04849 kount = 0;
04850 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04851
04852 objcoeff->indexes[ varNumber ] = varNumber ;
04853
04854 objcoeff->values[ varNumber ] = si->getObjCoefficients()[ mit->first] ;
04855
04856 m_thetaCost[ varNumber] = si->getObjCoefficients()[ mit->first];
04857
04858 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt("x", kount + numVarArt ) ,
04859 0, 1.0, 'C');
04860
04861 kount++;
04862
04863
04864
04865 }
04866
04867
04868
04869 for(i = 0; i < m_numNodes; i++){
04870
04871 m_osinstanceMaster->addConstraint(i, makeStringFromInt("con", i),
04872 1.0, 1.0, 0);
04873
04874 }
04875
04876
04877 for(i = m_numNodes; i < m_numBmatrixCon + m_numNodes; i++){
04878
04879 m_osinstanceMaster->addConstraint(i, makeStringFromInt("con", i),
04880 si->getRowLower()[ i], si->getRowUpper()[ i], 0);
04881
04882
04883 }
04884
04885
04886
04887 m_osinstanceMaster->setObjectiveNumber( 1);
04888 m_osinstanceMaster->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
04889
04890
04891 m_osinstanceMaster->setLinearConstraintCoefficients(numNonz , true,
04892 values, 0, numNonz - 1, indexes, 0, numNonz - 1, starts, 0, startsIdx);
04893
04894
04895
04896
04897
04898 delete[] tmpConvexity;
04899 tmpConvexity = NULL;
04900 delete[] thetaPntTmp;
04901 thetaPntTmp = NULL;
04902 delete[] thetaIndexTmp;
04903 thetaIndexTmp = NULL;
04904 delete objcoeff;
04905 objcoeff = NULL;
04906 }
04907
04908
04909
04910 double OSBearcatSolverXij::getRouteDistance(int numNodes, int hubIndex,
04911 CoinSolver* solver, std::vector<int> zk, double* xVar){
04912
04913 int i;
04914 int j;
04915 int numVar;
04916 numVar = numNodes*numNodes - numNodes;
04917
04918 int kount;
04919 double objValue;
04920 std::vector<int>::iterator vit;
04921 std::map<std::pair<int, int>, int > cutMap;
04922 std::map<std::pair<int, int>, int >::iterator mit;
04923 std::vector<IndexValuePair*> primalValPair;
04924
04925
04926
04927
04928
04929 for(i = 0; i < numVar; i++) xVar[ i] = 0;
04930
04931 int numNewRows;
04932 int* numRowNonz = NULL;
04933 int** colIdx = NULL;
04934 double** rowValues = NULL ;
04935 double* rowLB;
04936 double* rowUB;
04937
04938
04939
04940 OsiSolverInterface *si = solver->osiSolver;
04941 try{
04942
04943
04944 si->setRowUpper(hubIndex, 1.0);
04945 si->setRowUpper(hubIndex + numNodes, 1.0);
04946 si->setRowLower(hubIndex, 1.0);
04947 si->setRowLower(hubIndex + numNodes, 1.0);
04948
04949
04950
04951 kount = zk.size();
04952
04953 int idx1;
04954 int idx2;
04955
04956 for(i = 0; i < kount ; i++){
04957
04958
04959 si->setRowUpper(zk[ i], 1.0);
04960 si->setRowUpper(zk[ i] + numNodes, 1.0);
04961 si->setRowLower(zk[ i], 1.0);
04962 si->setRowLower(zk[ i] + numNodes, 1.0);
04963
04964 idx1 = hubIndex;
04965 idx2 = zk[i ];
04966
04967
04968 if( idx1 > idx2 ){
04969 si->setColUpper(idx1*(numNodes -1) + idx2, 1.0);
04970 }else{
04971
04972 if( idx1 < idx2 ){
04973
04974 si->setColUpper(idx1*(numNodes -1) + idx2 - 1, 1.0);
04975
04976 }
04977 }
04978
04979 idx1 = zk[ i];
04980 idx2 = hubIndex;
04981
04982
04983 if( idx1 > idx2 ){
04984
04985 si->setColUpper(idx1*(numNodes -1) + idx2, 1.0);
04986
04987 }else{
04988
04989 if( idx1 < idx2 ){
04990
04991 si->setColUpper(idx1*(numNodes -1) + idx2 - 1, 1.0);
04992
04993 }
04994 }
04995
04996 for(j = i + 1; j < kount; j++){
04997
04998 idx1 = zk[i];
04999 idx2 = zk[j];
05000
05001
05002 if( idx1 > idx2 ){
05003
05004 si->setColUpper(idx1*(numNodes -1) + idx2, 1.0);
05005
05006 }else{
05007
05008 if( idx1 < idx2 ){
05009
05010 si->setColUpper(idx1*(numNodes -1) + idx2 - 1, 1.0);
05011 }
05012 }
05013
05014
05015 idx1 = zk[j];
05016 idx2 = zk[i];
05017
05018
05019 if( idx1 > idx2 ){
05020 si->setColUpper(idx1*(numNodes -1) + idx2, 1.0);
05021 }else{
05022
05023 if( idx1 < idx2 ){
05024
05025 si->setColUpper(idx1*(numNodes -1) + idx2 - 1, 1.0);
05026 }
05027 }
05028 }
05029 }
05030
05031 solver->solve();
05032
05033
05034
05035 if(solver->osresult->getSolutionStatusType( 0 ) != "optimal" ) throw ErrorClass("Trouble with integer program used to construct initial master");
05036 objValue = solver->osresult->getObjValue(0, 0) ;
05037
05038 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
05039
05040
05041 bool isCutAdded;
05042 isCutAdded = true;
05043 while(isCutAdded == true){
05044
05045 isCutAdded = false;
05046
05047 for(i = 0; i < numVar; i++) xVar[ primalValPair[ i]->idx ] = primalValPair[ i]->value;
05048
05049 numNewRows = 0;
05050 getCutsX(xVar, numVar, numNewRows, numRowNonz,
05051 colIdx,rowValues, rowLB, rowUB);
05052
05053 if(numNewRows >= 1){
05054 isCutAdded = true;
05055 std::cout << "WE HAVE A CUT " << std::endl;
05056 std::cout << "EXPRESS CUT IN X(I, J) SPACE" << std::endl;
05057
05058
05059 for(i = 0; i < numNewRows; i++){
05060
05061 std::cout << "CUT UPPER BOUND = " << rowUB[ i] << std::endl;
05062 si->addRow(numRowNonz[ i], colIdx[ i], rowValues[ i], rowLB[ i], rowUB[ i] ) ;
05063 }
05064
05065 std::cout << "A CUT WAS ADDED, CALL SOLVE AGAIN" << std::endl;
05066 solver->solve();
05067 if(solver->osresult->getSolutionStatusType( 0 ) != "optimal" ) throw ErrorClass("Trouble with integer program used to construct initial master");
05068 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
05069 std::cout << "New Solution Status = " << solver->osresult->getSolutionStatusType( 0 ) << std::endl;
05070 std::cout << "Optimal Objective Value = " << solver->osresult->getObjValue(0, 0) << std::endl;
05071
05072
05073
05074
05075 }
05076
05077 }
05078
05079 objValue = solver->osresult->getObjValue(0, 0) ;
05080
05081 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
05082
05083
05084
05085 std::cout << "Objective Function Value = " << objValue << std::endl;
05086
05087
05088 for(i = 0; i < numVar; i++) si->setColUpper(i, 0);
05089 for(i = 0; i < 2*numNodes; i++) si->setRowUpper(i, 0);
05090 for(i = 0; i < 2*numNodes; i++) si->setRowLower(i, 0);
05091
05092 return objValue;
05093
05094
05095 } catch (const ErrorClass& eclass) {
05096
05097 std::cout << std::endl << std::endl << std::endl;
05098
05099 if( xVar != NULL)
05100 delete xVar;
05101
05102 throw ErrorClass(eclass.errormsg);
05103 }
05104
05105 }
05106
05107
05108
05109 CoinSolver* OSBearcatSolverXij::getTSP(int numNodes, double* cost){
05110
05111
05112 int i;
05113 int j;
05114 int numVar;
05115 numVar = numNodes*numNodes - numNodes;
05116 int numNonz;
05117 int kount;
05118
05119 std::vector<int>::iterator vit;
05120 double* rhsVec;
05121 CoinSolver *solver = NULL;
05122 std::map<std::pair<int, int>, int > cutMap;
05123 std::map<std::pair<int, int>, int >::iterator mit;
05124
05125
05126 int numCuts;
05127
05128 rhsVec = new double[ 2*numNodes];
05129
05130 for(i = 0; i < 2*numNodes; i++){
05131
05132
05133
05134 rhsVec[ i] = 0;
05135 }
05136
05137
05138
05139
05140 numCuts = 0;
05141 std::pair <int,int> pairIJ;
05142 std::pair <int,int> pairJI;
05143
05144 for(i = 0; i < numNodes - 1; i++){
05145
05146
05147 for(j = i + 1; j < numNodes; j++){
05148
05149
05150 pairIJ = std::make_pair(i, j);
05151 pairJI = std::make_pair(j, i);
05152
05153 cutMap[pairIJ ] = 2*numNodes + numCuts;
05154 cutMap[pairJI ] = 2*numNodes + numCuts;
05155 numCuts++;
05156
05157 }
05158 }
05159
05160
05161
05162 OSInstance *osinstance = new OSInstance();
05163 try{
05164
05165 osinstance->setInstanceSource("generated from OSBearcatSoleverXij");
05166 osinstance->setInstanceDescription("Find the minimum tour for a route");
05167 osinstance->setVariableNumber( numVar);
05168
05169 for(i = 0; i < numVar; i++){
05170
05171 osinstance->addVariable(i, m_variableNames[ i], 0, 0, 'B');
05172
05173 }
05174
05175 osinstance->setObjectiveNumber( 1);
05176
05177
05178 SparseVector *objcoeff = new SparseVector( numVar);
05179
05180 for(i = 0; i < numVar; i++){
05181
05182 objcoeff->indexes[ i] = i;
05183 objcoeff->values[ i] = cost[ i];
05184
05185 }
05186
05187 osinstance->addObjective(-1, "minimizeDistance", "min", 0.0, 1.0, objcoeff);
05188 objcoeff->bDeleteArrays = true;
05189 delete objcoeff;
05190
05191 osinstance->setConstraintNumber( 2*numNodes + numCuts);
05192
05193
05194 for(i = 0; i < numNodes; i++){
05195
05196 osinstance->addConstraint(i, makeStringFromInt("enter_node_", i) , rhsVec[i], rhsVec[i], 0);
05197
05198 }
05199
05200 for(i = numNodes; i < 2*numNodes; i++){
05201
05202 osinstance->addConstraint(i, makeStringFromInt("leave_node_", i - numNodes) , rhsVec[i], rhsVec[i], 0);
05203
05204 }
05205
05206
05207
05208 for(i = 0; i < numCuts; i++){
05209
05210 osinstance->addConstraint(2*numNodes + i, makeStringFromInt("XijCut_", i) , 0, 1, 0);
05211
05212 }
05213
05214
05215
05216 numNonz = numVar*numVar - numVar + 2*numCuts;
05217
05218
05219 double *values = new double[ numNonz];
05220 int *rowIndexes = new int[ numNonz];
05221 int *starts = new int[ numVar + 1];
05222
05223
05224 kount = 0;
05225 numNonz = 0;
05226 starts[ kount++] = 0;
05227 for(i = 0; i < numNodes; i++){
05228
05229 for(j = 0; j < i; j++){
05230
05231
05232 rowIndexes[ numNonz] = j;
05233 values[ numNonz++] = 1.0;
05234
05235 rowIndexes[ numNonz] = numNodes + i;
05236 values[ numNonz++] = 1.0;
05237
05238
05239 pairIJ = std::make_pair(i, j);
05240 mit = cutMap.find( pairIJ);
05241 if(mit != cutMap.end() ){
05242
05243 rowIndexes[ numNonz] = mit->second;
05244 values[ numNonz++] = 1.0;
05245 }
05246
05247
05248 starts[ kount++] = numNonz;
05249
05250
05251 }
05252
05253 for(j = i+1; j < numNodes; j++){
05254
05255
05256 rowIndexes[ numNonz] = j;
05257 values[ numNonz++] = 1.0;
05258
05259 rowIndexes[ numNonz] = numNodes + i;
05260 values[ numNonz++] = 1.0;
05261
05262
05263 pairIJ = std::make_pair(i, j);
05264 mit = cutMap.find( pairIJ);
05265 if(mit != cutMap.end() ){
05266
05267 rowIndexes[ numNonz] = mit->second;
05268 values[ numNonz++] = 1.0;
05269 }
05270
05271
05272 starts[ kount++] = numNonz;
05273
05274 }
05275
05276
05277 }
05278
05279 osinstance->setLinearConstraintCoefficients(numNonz, true, values, 0, numNonz - 1,
05280 rowIndexes, 0, numNonz - 1, starts, 0, numVar);
05281
05282
05283
05284
05285 solver = new CoinSolver();
05286 solver->sSolverName ="cbc";
05287 solver->osinstance = osinstance;
05288 solver->osoption = m_osoption;
05289 solver->buildSolverInstance();
05290 solver->osoption = m_osoption;
05291
05292 delete[] rhsVec;
05293 rhsVec = NULL;
05294
05295 return solver;
05296
05297
05298
05299 } catch (const ErrorClass& eclass) {
05300
05301 std::cout << std::endl << std::endl << std::endl;
05302
05303 if(rhsVec != NULL){
05304 delete[] rhsVec;
05305 rhsVec = NULL;
05306 }
05307
05308
05309 throw ErrorClass(eclass.errormsg);
05310 }
05311
05312
05313 }
05314
05315
05316 bool OSBearcatSolverXij::OneOPT(){
05317
05318 int k;
05319 int kprime;
05320 double *routeCost = NULL;
05321 int *routeDemand = NULL;
05322 double *xVar = NULL;
05323 int numXVar = m_numNodes*m_numNodes - m_numNodes;
05324 double routeCostInf;
05325
05326 routeCostInf = OSINT_MAX;
05327 double feasMult = 10000;
05328
05329 routeCost = new double[m_numHubs];
05330 routeDemand = new int[m_numHubs];
05331 xVar = new double[ numXVar];
05332
05333
05334
05335 std::map<int, std::vector<int> > routeMap;
05336 std::vector<int> tmpVec;
05337 std::vector<int>::iterator vit;
05338 std::vector<int>::iterator vit2;
05339
05340 routeMap = m_initSolMap[ 0];
05341 CoinSolver *solver = NULL;
05342
05343 double totalCost;
05344 bool foundMoBetta;
05345 bool foundLocalImprovement;
05346
05347 try{
05348
05349 solver = getTSP(m_numNodes, m_cost);
05350
05351 totalCost = 0;
05352 for(k = 0; k < m_numHubs; k++){
05353
05354 routeDemand[ k] = 0;
05355 for(vit = routeMap[k].begin(); vit!=routeMap[k].end(); ++vit){
05356
05357 std::cout << "node i = " << *vit << " demand " << m_demand[ *vit] << std::endl;
05358 routeDemand[ k] += m_demand[ *vit];
05359 }
05360
05361 if(routeDemand[k] <= m_routeCapacity[ k] ){
05362
05363 routeCost[ k] = getRouteDistance(m_numNodes, k, solver,
05364 routeMap[k], xVar)*routeDemand[ k];
05365
05366
05367 std::cout << "rout = " << k << " cost " << routeCost[ k] << std::endl;
05368 totalCost += routeCost[ k];
05369 }else{
05370 std::cout << "rout demand " << routeDemand[k] << " route capacity = " << m_routeCapacity[ k] << std::endl;
05371 routeCost[ k] = routeCostInf;
05372 totalCost += routeCost[ k];
05373
05374 }
05375
05376
05377 }
05378
05379
05380 foundMoBetta = true;
05381 double improvement;
05382
05383 double tmpCostk;
05384 double tmpCostkPrime;
05385 double optCostk;
05386 double optCostkPrime;
05387 double tmpVal;
05388 int tmpIdx;
05389 std::vector<int>::iterator vitIdx;
05390
05391 while(foundMoBetta == true){
05392 foundMoBetta = false;
05393
05394 for(k = 0; k < m_numHubs; k++){
05395
05396 foundLocalImprovement = false;
05397
05398 for(kprime = 0; kprime < m_numHubs; kprime++){
05399
05400 if(kprime != k && routeCost[ kprime] < routeCostInf){
05401
05402
05403 improvement = 0;
05404 optCostk = routeCostInf;
05405 optCostkPrime = routeCostInf;
05406
05407 for(vit = routeMap[k].begin(); vit!=routeMap[k].end(); ++vit){
05408
05409 foundLocalImprovement = false;
05410
05411
05412 if( m_demand[ *vit] + routeDemand[ kprime] <= m_routeCapacity[ kprime] ){
05413
05414 tmpCostk = routeCostInf;
05415 tmpCostkPrime = routeCostInf;
05416
05417
05418
05419
05420 routeMap[ kprime].push_back( *vit);
05421
05422 tmpCostkPrime = getRouteDistance(m_numNodes, kprime, solver,
05423 routeMap[kprime], xVar)*(routeDemand[ kprime] + m_demand[ *vit] );
05424
05425
05426 routeMap[ kprime].pop_back( );
05427
05428
05429
05430 if(routeCost[k] == routeCostInf ){
05431
05432
05433
05434
05435
05436 if( routeDemand[ k] - m_demand[ *vit] <= m_routeCapacity[ k]) {
05437
05438 for(vit2 = routeMap[k].begin(); vit2 != routeMap[k].end(); vit2++){
05439
05440 if(vit != vit2) tmpVec.push_back( *vit2);
05441
05442 }
05443
05444 tmpCostk = getRouteDistance(m_numNodes, k, solver,
05445 tmpVec, xVar)*(routeDemand[ k] - m_demand[ *vit] );
05446
05447 tmpVec.clear();
05448
05449 }
05450
05451 tmpVal = std::max(*vit, routeDemand[ k] - m_demand[ *vit])*feasMult
05452 + ( routeCost[kprime] - tmpCostkPrime);
05453
05454 if( tmpVal > improvement) {
05455 foundLocalImprovement = true;
05456 improvement = tmpVal;
05457 tmpIdx = *vit;
05458 vitIdx = vit;
05459 optCostk = tmpCostk;
05460 optCostkPrime = tmpCostkPrime;
05461
05462 }
05463
05464
05465 }else{
05466
05467
05468
05469
05470 for(vit2 = routeMap[k].begin(); vit2 != routeMap[k].end(); vit2++){
05471
05472 if(vit != vit2) tmpVec.push_back( *vit2);
05473
05474 }
05475
05476 tmpCostk = getRouteDistance(m_numNodes, k, solver,
05477 tmpVec, xVar)*(routeDemand[ k] - m_demand[ *vit] );
05478
05479 tmpVec.clear();
05480
05481 if( ( (routeCost[k] + routeCost[kprime]) -
05482 ( tmpCostkPrime + tmpCostk ) ) > improvement ) {
05483
05484 improvement = (routeCost[k] + routeCost[kprime]) -
05485 ( tmpCostkPrime + tmpCostk );
05486
05487 foundLocalImprovement = true;
05488 tmpIdx = *vit;
05489 vitIdx = vit;
05490 optCostk = tmpCostk;
05491 optCostkPrime = tmpCostkPrime;
05492
05493
05494
05495 }
05496 }
05497 }
05498
05499 if(foundLocalImprovement == true)break;
05500 }
05501
05502
05503
05504
05505 if( foundLocalImprovement == true) {
05506
05507
05508 std::cout << "index = " << tmpIdx << std::endl;
05509
05510 routeMap[ kprime].push_back( tmpIdx);
05511
05512 routeDemand[ kprime] += m_demand[ tmpIdx];
05513
05514 routeCost[ kprime] = optCostkPrime;
05515
05516
05517
05518
05519
05520
05521 std::cout << "tmpIdx = " << tmpIdx << std::endl;
05522 std::cout << "vitIdx = " << *vitIdx << std::endl;
05523 routeMap[ k].erase( vitIdx);
05524
05525 routeDemand[ k] -= m_demand[ tmpIdx];
05526
05527 routeCost[ k] = optCostk;
05528
05529
05530
05531
05532
05533
05534 foundMoBetta = true;
05535
05536 }
05537 }
05538 }
05539 }
05540
05541
05542 }
05543
05544
05545
05546 totalCost = 0;
05547 for(k = 0; k < m_numHubs; k++){
05548
05549 std::cout << std::endl << std::endl;
05550
05551 std::cout << "ROUTE " << k << " Total Demand = " << routeDemand[ k] << std::endl;
05552 std::cout << "ROUTE " << k << " Total Cost = " << routeCost[ k] << std::endl;
05553 std::cout << "ROUTE " << k << " Nodes " << std::endl;
05554
05555
05556
05557
05558 totalCost += routeCost[ k];
05559 }
05560
05561 std::cout << "Total Cost = " << totalCost << std::endl;
05562
05563 m_initSolMap[ 0] = routeMap;
05564
05565
05566
05567 delete[] routeCost;
05568 routeCost = NULL;
05569 delete[] routeDemand;
05570 routeDemand = NULL;
05571 delete[] xVar;
05572 xVar = NULL;
05573 delete solver->osinstance;
05574 delete solver;
05575
05576 if( totalCost >= routeCostInf )return false;
05577 else return true;
05578
05579
05580 } catch (const ErrorClass& eclass) {
05581
05582 std::cout << std::endl << std::endl << std::endl;
05583
05584 if(routeCost != NULL){
05585 delete[] routeCost;
05586 routeCost = NULL;
05587 }
05588
05589 if(routeDemand != NULL){
05590 delete[] routeDemand;
05591 routeDemand = NULL;
05592 }
05593
05594 if(xVar != NULL){
05595 delete[] xVar;
05596 xVar = NULL;
05597 }
05598
05599
05600
05601
05602 throw ErrorClass(eclass.errormsg);
05603 }
05604
05605 }
05606
05607
05608
05609
05610
05611 CoinSolver* OSBearcatSolverXij::getMultiCommodInstance(int hubIndex){
05612
05613
05614 int i;
05615 int j;
05616 int numVar;
05617 int numNonHubs;
05618 numNonHubs = m_numNodes - m_numHubs;
05619
05620 numVar = numNonHubs;
05621
05622 numVar += numNonHubs;
05623
05624 numVar += numNonHubs*numNonHubs - numNonHubs;
05625 int numNonz;
05626 int kount;
05627 int numCon;
05628 CoinSolver *solver = NULL;
05629 SparseVector *objcoeff = NULL;
05630
05631 numCon = numNonHubs + (numNonHubs*numNonHubs - numNonHubs) + 1;
05632
05633
05634
05635 OSInstance *osinstance = new OSInstance();
05636 try{
05637
05638 osinstance->setInstanceSource("generated from OSBearcatSoleverXij");
05639 osinstance->setInstanceDescription("Instance for finding a multicommodity cut");
05640 osinstance->setVariableNumber( numVar);
05641
05642 numVar = 0;
05643
05644 for(i = m_numHubs; i < m_numNodes; i++){
05645
05646 if(m_nodeName[ i] != "")
05647 osinstance->addVariable(numVar++, "w[" + m_nodeName[ i] +"]", 0, OSDBL_MAX, 'C');
05648 else
05649 osinstance->addVariable(numVar++, makeStringFromInt("w[", i) +"]", 0, OSDBL_MAX, 'C');
05650
05651 m_tmpVarMap.insert( std::pair<int,std::string>(numVar, "w[" + m_nodeName[ i] +"]" ) );
05652
05653 }
05654
05655
05656
05657 for(j = m_numHubs; j < m_numNodes; j++){
05658
05659 if(m_nodeName[ hubIndex ] != "" && m_nodeName[ j] != "")
05660 osinstance->addVariable(numVar++, "u[" + m_nodeName[ hubIndex] + "," + m_nodeName[ j] +"]", 0, OSDBL_MAX, 'C');
05661 else
05662 osinstance->addVariable(numVar++, makeStringFromInt("u[", hubIndex) + makeStringFromInt(",", j) +"]", 0, OSDBL_MAX, 'C');
05663
05664 m_tmpVarMap.insert( std::pair<int,std::string>(numVar, m_nodeName[ hubIndex] + "," + m_nodeName[ j] +"]") );
05665
05666
05667 }
05668
05669 for(i = m_numHubs; i < m_numNodes; i++){
05670
05671
05672 for(j = m_numHubs; j < i; j++){
05673
05674
05675
05676 if(m_nodeName[ i] != "" && m_nodeName[ j] != "")
05677 osinstance->addVariable(numVar++, "u[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]", 0, OSDBL_MAX, 'C');
05678 else
05679 osinstance->addVariable(numVar++, makeStringFromInt("u[", i) + makeStringFromInt(",", j) +"]", 0, OSDBL_MAX, 'C');
05680
05681
05682 m_tmpVarMap.insert( std::pair<int,std::string>(numVar, "u[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]") );
05683
05684 }
05685
05686 for(j = i + 1; j < m_numNodes; j++){
05687
05688 if(m_nodeName[ i] != "" && m_nodeName[ j] != "")
05689 osinstance->addVariable(numVar++, "u[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]", 0, OSDBL_MAX, 'C');
05690 else
05691 osinstance->addVariable(numVar++, makeStringFromInt("u[", i) + makeStringFromInt(",", j) +"]", 0, OSDBL_MAX, 'C');
05692
05693 m_tmpVarMap.insert( std::pair<int,std::string>(numVar, "u[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]") );
05694
05695
05696 }
05697
05698 }
05699
05700
05701
05702 osinstance->setObjectiveNumber( 1);
05703
05704
05705
05706 objcoeff = new SparseVector( numVar);
05707
05708 for(i = 0; i < numVar; i++){
05709
05710 objcoeff->indexes[ i] = i;
05711 objcoeff->values[ i] = 0;
05712
05713 }
05714
05715 osinstance->addObjective(-1, "cutViolation", "max", 0.0, 1.0, objcoeff);
05716 objcoeff->bDeleteArrays = true;
05717 delete objcoeff;
05718
05719 osinstance->setConstraintNumber( numCon );
05720
05721 numCon = 0;
05722 for(i = m_numHubs; i < m_numNodes; i++){
05723
05724 if(m_nodeName[ hubIndex] != "" && m_nodeName[ i] != "")
05725 osinstance->addConstraint(numCon++, "dualCon[" + m_nodeName[ hubIndex] + "," + m_nodeName[ i] + "]", -OSDBL_MAX, 0, 0);
05726 else
05727 osinstance->addConstraint(numCon++, makeStringFromInt("dualCon[", hubIndex) + makeStringFromInt(",", i) +"]", -OSDBL_MAX, 0, 0);
05728 }
05729
05730
05731 for(i = m_numHubs; i < m_numNodes; i++){
05732
05733
05734 for(j = m_numHubs; j < i; j++){
05735
05736 if(m_nodeName[ i] != "" && m_nodeName[ j] != "")
05737 osinstance->addConstraint(numCon++, "dualCon[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]", -OSDBL_MAX, 0, 0);
05738 else
05739 osinstance->addConstraint(numCon++, makeStringFromInt("dualCon[", i) + makeStringFromInt(",", j) +"]", -OSDBL_MAX, 0, 0);
05740
05741
05742 }
05743
05744 for(j = i + 1; j < m_numNodes; j++){
05745
05746 if(m_nodeName[ i] != "" && m_nodeName[ j] != "")
05747 osinstance->addConstraint(numCon++, "dualCon[" + m_nodeName[ i] + "," + m_nodeName[ j] +"]", -OSDBL_MAX, 0, 0);
05748 else
05749 osinstance->addConstraint(numCon++, makeStringFromInt("dualCon[", i) + makeStringFromInt(",", j) +"]", -OSDBL_MAX, 0, 0);
05750
05751
05752 }
05753
05754 }
05755
05756 double upperBound;
05757 upperBound = numVar - numNonHubs ;
05758 upperBound = 100;
05759 osinstance->addConstraint(numCon++, "boundConstraint", -OSDBL_MAX, upperBound, 0);
05760
05761
05762 numCon = numNonHubs + (numNonHubs*numNonHubs - numNonHubs) + 1;
05763 numNonz = 2*numNonHubs;
05764 numNonz += 3*(numNonHubs*numNonHubs - numNonHubs);
05765 numNonz += (numNonHubs*numNonHubs - numNonHubs) + numNonHubs;
05766
05767
05768 double *values = new double[ numNonz];
05769 int *columnIndexes = new int[ numNonz];
05770
05771 int *starts = new int[ numCon + 1];
05772
05773
05774 kount = 0;
05775 numNonz = 0;
05776 starts[ kount++] = 0;
05777
05778
05780
05781
05782 int uijKount;
05783 uijKount = numNonHubs;
05784
05785 for(j = m_numHubs; j < m_numNodes; j++){
05786
05787
05788
05789 columnIndexes[ numNonz] = j - m_numHubs ;
05790 values[ numNonz++] = 1.0;
05791
05792
05793 columnIndexes[ numNonz] = uijKount ;
05794 values[ numNonz++] = -1.0;
05795
05796 starts[ kount++] = numNonz;
05797 uijKount++;
05798 }
05799
05800
05801 for(i = m_numHubs; i < m_numNodes; i++){
05802
05803
05804 for(j = m_numHubs; j < i; j++){
05805
05806
05807
05808 columnIndexes[ numNonz] = i - m_numHubs ;
05809 values[ numNonz++] = -1.0;
05810
05811
05812 columnIndexes[ numNonz] = j - m_numHubs ;
05813 values[ numNonz++] = 1.0;
05814
05815
05816 columnIndexes[ numNonz] = uijKount ;
05817 values[ numNonz++] = -1.0;
05818
05819
05820 starts[ kount++] = numNonz;
05821 uijKount++;
05822
05823
05824 }
05825
05826 for(j = i + 1; j < m_numNodes; j++){
05827
05828
05829
05830 columnIndexes[ numNonz] = i - m_numHubs ;
05831 values[ numNonz++] = -1.0;
05832
05833
05834 columnIndexes[ numNonz] = j - m_numHubs ;
05835 values[ numNonz++] = 1.0;
05836
05837
05838 columnIndexes[ numNonz] = uijKount ;
05839 values[ numNonz++] = -1.0;
05840
05841
05842 starts[ kount++] = numNonz;
05843 uijKount++;
05844
05845
05846 }
05847
05848 }
05849
05850
05851 for(i = numNonHubs; i < numVar; i++ ){
05852
05853
05854 columnIndexes[ numNonz] = i ;
05855 values[ numNonz++] = 1.0;
05856
05857 }
05858
05859 starts[ kount++] = numNonz;
05860 osinstance->setLinearConstraintCoefficients(numNonz, false, values, 0, numNonz - 1,
05861 columnIndexes, 0, numNonz - 1, starts, 0, numVar);
05862
05863
05864
05865
05866 solver = new CoinSolver();
05867 solver->sSolverName ="clp";
05868 solver->osinstance = osinstance;
05869 solver->buildSolverInstance();
05870 solver->osoption = m_osoption;
05871
05872
05873 return solver;
05874
05875
05876
05877 } catch (const ErrorClass& eclass) {
05878
05879 if( objcoeff != NULL ){
05880 delete objcoeff;
05881 objcoeff = NULL;
05882 }
05883
05884 throw ErrorClass(eclass.errormsg);
05885 }
05886
05887
05888 }
05889
05890
05891
05892 void OSBearcatSolverXij::getFeasibleSolution(){
05893
05894 int i;
05895 int k;
05896 int numVar;
05897 int numNonHubs;
05898 numNonHubs = m_numNodes - m_numHubs;
05899
05900 numVar = m_numHubs*numNonHubs;
05901
05902 int numNonz;
05903 int kount;
05904
05905 CoinSolver *solver = NULL;
05906 SparseVector *objcoeff = NULL;
05907
05908 std::pair<int,int> indexPair1;
05909 std::pair<int,int> indexPair2;
05910
05911 std::map<int, std::vector<int> > routeMap;
05912
05913 OSInstance *osinstance = new OSInstance();
05914 try{
05915
05916 osinstance->setInstanceSource("generated from OSBearcatSoleverXij");
05917 osinstance->setInstanceDescription("Generalized Assignment Instance for finding a feasible solution");
05918 osinstance->setVariableNumber( numVar);
05919
05920 numVar = 0;
05921
05922 for(k = 0; k < m_numHubs; k++){
05923
05924 for(i = m_numHubs; i < m_numNodes; i++){
05925
05926 if( m_nodeName[ k] != "" && m_nodeName[ i] != "")
05927 osinstance->addVariable(numVar++, "x(" + m_nodeName[ k] + "," + m_nodeName[ i] +")", 0, 1, 'B');
05928 else
05929 osinstance->addVariable(numVar++, makeStringFromInt("x(" ,k) + makeStringFromInt(",", i) +")", 0, 1, 'B');
05930
05931 }
05932
05933 }
05934
05935
05936 osinstance->setObjectiveNumber( 1);
05937
05938
05939
05940 objcoeff = new SparseVector( numVar);
05941
05942 kount = 0;
05943 for(k = 0; k < m_numHubs; k++){
05944
05945 indexPair1.first = k;
05946 indexPair2.second = k;
05947
05948 for(i = m_numHubs; i < m_numNodes; i++){
05949
05950 indexPair1.second = i;
05951 indexPair2.first = i;
05952 objcoeff->indexes[ kount] = kount;
05953
05954 if( (m_xVarIndexMap.find( indexPair1) == m_xVarIndexMap.end() ) ||
05955 (m_xVarIndexMap.find( indexPair2) == m_xVarIndexMap.end() ) ){
05956 throw ErrorClass("Index problem in generalized assignment problem to find feasible solution");
05957 }
05958
05959 objcoeff->values[ kount++] = (m_cost[ m_xVarIndexMap[ indexPair1] ] +
05960 m_cost[ m_xVarIndexMap[ indexPair2] ])*m_demand[i] ;
05961
05962 }
05963
05964 }
05965
05966 osinstance->addObjective(-1, "feasibililtyObj", "min", 0.0, 1.0, objcoeff);
05967 objcoeff->bDeleteArrays = true;
05968 delete objcoeff;
05969 objcoeff = NULL;
05970
05971 osinstance->setConstraintNumber( m_numNodes );
05972
05973
05974 for(k = 0; k < m_numHubs; k++){
05975
05976 if(m_nodeName[ k] != "" )
05977 osinstance->addConstraint(k, "capacityCon[" + m_nodeName[ k] + "]", 0, m_routeCapacity[ k], 0);
05978 else
05979 osinstance->addConstraint(k, makeStringFromInt("dualCon[", k) +"]", 0, m_routeCapacity[ k], 0);
05980 }
05981
05982
05983 for(i = m_numHubs; i < m_numNodes; i++){
05984
05985 if(m_nodeName[ i] != "" )
05986 osinstance->addConstraint(i, "assingCon[" + m_nodeName[ i] +"]", 1, 1, 0);
05987 else
05988 osinstance->addConstraint(i, makeStringFromInt("assignCon[", i) +"]", 1, 1, 0);
05989
05990 }
05991
05992
05993
05994
05995 numNonz = 2*numVar;
05996
05997
05998 double *values = new double[ numNonz];
05999 int *rowIndexes = new int[ numNonz];
06000 int *starts = new int[ numVar + 1];
06001
06002
06003 kount = 0;
06004 numNonz = 0;
06005 starts[ kount++] = 0;
06006
06007
06009
06010
06011 for(k = 0; k < m_numHubs; k++){
06012
06013
06014 for(i = m_numHubs; i < m_numNodes; i++){
06015
06016
06017 rowIndexes[ numNonz] = k ;
06018 values[ numNonz++] = m_demand[ i];
06019
06020 rowIndexes[ numNonz] = i ;
06021 values[ numNonz++] = 1.0;
06022
06023 starts[ kount++] = numNonz;
06024
06025 }
06026 }
06027
06028
06029 osinstance->setLinearConstraintCoefficients(numNonz, true, values, 0, numNonz - 1,
06030 rowIndexes, 0, numNonz - 1, starts, 0, numVar);
06031
06032
06033
06034
06035
06036 solver = new CoinSolver();
06037 solver->sSolverName ="cbc";
06038 solver->osinstance = osinstance;
06039 solver->buildSolverInstance();
06040 solver->osoption = m_osoption;
06041 solver->solve();
06042
06043
06044 OSResult *osresult;
06045 osresult = solver->osresult;
06046 std::string solStatus;
06047 std::vector<IndexValuePair*> primalValPair;
06048 int vecSize;
06049 double optSolValue;
06050
06051 solStatus = osresult->getSolutionStatusType( 0 );
06052
06053 if( solStatus.find("ptimal") != std::string::npos ){
06054
06055 optSolValue = osresult->getOptimalObjValue( -1, 0);
06056 std::cout << "OPTIMAL SOLUTION VALUE " << optSolValue << std::endl;
06057 }else{
06058 throw ErrorClass("There is no feasible solution to this problem!");
06059 }
06060
06061 primalValPair = osresult->getOptimalPrimalVariableValues( 0);
06062 vecSize = primalValPair.size();
06063
06064
06065 kount = 0;
06066 for(k = 0; k < m_numHubs; k++){
06067
06068 indexPair1.first = k;
06069 std::cout << std::endl << std::endl;
06070 for(i = m_numHubs; i < m_numNodes; i++){
06071
06072 indexPair1.second = i;
06073 if(primalValPair[ kount ]->value > m_osDecompParam.zeroTol) {
06074
06075 std::cout << "Variable = " << m_variableNames[ m_xVarIndexMap[ indexPair1] ]
06076 << " value = " << primalValPair[ kount ]->value << std::endl;
06077
06078 routeMap[k].push_back( i);
06079 }
06080
06081 kount++;
06082 }
06083
06084
06085 }
06086
06087 m_initSolMap[ 0] = routeMap;
06088 delete solver;
06089 solver = NULL;
06090
06091
06092 } catch (const ErrorClass& eclass) {
06093
06094 if( objcoeff != NULL ){
06095 delete objcoeff;
06096 objcoeff = NULL;
06097 }
06098
06099 throw ErrorClass(eclass.errormsg);
06100 }
06101
06102
06103 }
06104
06105 void OSBearcatSolverXij::getVariableIndexMap(){
06106
06107 int i;
06108 int j;
06109 int kount;
06110 std::pair<int,int> indexPair;
06111
06112 kount = 0;
06113 for(i = 0; i < m_numNodes; i++){
06114
06115 for(j = 0; j < i; j++){
06116
06117 indexPair.first = i;
06118 indexPair.second = j;
06119 m_xVarIndexMap[ indexPair] = kount;
06120 kount++;
06121 }
06122
06123 for(j = i + 1; j < m_numNodes; j++){
06124
06125 indexPair.first = i;
06126 indexPair.second = j;
06127 m_xVarIndexMap[ indexPair] = kount;
06128 kount++;
06129 }
06130 }
06131
06132
06133 }
06134
06135
06136 void OSBearcatSolverXij::permuteHubs(){
06137
06138 int k1;
06139 int k2;
06140
06141 double tmpVal;
06142 double *tmpCap;
06143 int tmpIdx;
06144 tmpCap = new double[ m_numHubs];
06145
06146 for(k1 = 0; k1 < m_numHubs; k1++) tmpCap[ k1] = m_routeCapacity[ k1];
06147 for(k1 = 0; k1 < m_numHubs; k1++) m_hubPoint[ k1] = k1;
06148
06149 for(k1 = 0; k1 < m_numHubs - 1; k1++){
06150
06151
06152 for(k2 = k1 + 1; k2 < m_numHubs; k2++){
06153
06154 if( tmpCap[ k2 ] < tmpCap[ k1 ] ){
06155
06156
06157 tmpVal = tmpCap[ k1 ];
06158 tmpCap[ k1 ] = tmpCap[ k2 ];
06159 tmpCap[ k2 ] = tmpVal;
06160
06161 tmpIdx = m_hubPoint[ k1];
06162 m_hubPoint[ k1] = m_hubPoint[ k2];
06163 m_hubPoint[ k2] = tmpIdx;
06164
06165 }
06166
06167 }
06168 }
06169
06170 for(k1 = 0; k1 < m_numHubs; k1++) std::cout << "m_hubPoint = " << m_hubPoint[ k1] << std::endl;
06171 for(k1 = 0; k1 < m_numHubs; k1++) std::cout << "tmp Cap = " << tmpCap[ k1] << std::endl;
06172 for(k1 = 0; k1 < m_numHubs; k1++) std::cout << "hub capacity = " << m_routeCapacity[ m_hubPoint[ k1] ]<< std::endl;
06173
06174 delete[] tmpCap;
06175 tmpCap = NULL;
06176
06177 }
06178
06179
06180
06181
06182
06183
06184