00001
00014 #include "OSBearcatSolverXkij.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
00033 #include "CoinTime.hpp"
00034
00035 #include "ClpFactorization.hpp"
00036 #include "ClpNetworkMatrix.hpp"
00037 #include "OsiClpSolverInterface.hpp"
00038
00039
00040 #ifdef HAVE_CMATH
00041 # include <cmath>
00042 #else
00043 # ifdef HAVE_MATH_H
00044 # include <math.h>
00045 # else
00046 # error "don't have header file for math"
00047 # endif
00048 #endif
00049
00050 #ifdef HAVE_CTIME
00051 # include <ctime>
00052 #else
00053 # ifdef HAVE_TIME_H
00054 # include <time.h>
00055 # else
00056 # error "don't have header file for time"
00057 # endif
00058 #endif
00059
00060
00061
00062 std::string makeStringFromInt2(std::string theString, int theInt);
00063
00064
00065 OSBearcatSolverXkij::OSBearcatSolverXkij() {
00066 std::cout << "INSIDE OSBearcatSolverXkij CONSTRUCTOR with OSOption argument" << std::endl;
00067 }
00068
00069 OSBearcatSolverXkij::OSBearcatSolverXkij(OSOption *osoption) {
00070 std::cout << "INSIDE OSBearcatSolverXkij CONSTRUCTOR with OSOption argument" << std::endl;
00071
00072
00073 m_bestIPValue = OSDBL_MAX;
00074 m_bestLPValue = -OSDBL_MAX;
00075
00076 m_upperBoundL = NULL;
00077 m_upperBoundLMax = -OSINT_MAX;
00078 m_minDemand = OSINT_MAX;
00079
00080 m_u = NULL;
00081 m_v = NULL;
00082 m_g = NULL;
00083 m_px = NULL;
00084 m_tx =NULL;
00085 m_varIdx = NULL;
00086
00087 m_optL = NULL;
00088 m_optD = NULL;
00089 m_vv = NULL;
00090 m_vvpnt = NULL;
00091
00092 m_demand = NULL;
00093 m_cost = NULL;
00094
00095 m_rc = NULL;
00096
00097 m_routeCapacity = NULL;
00098 m_routeMinPickup = NULL;
00099
00100 m_osoption = osoption;
00101
00102 }
00103
00104 void OSBearcatSolverXkij::initializeDataStructures(){
00105
00106 int k;
00107 int i;
00108 int l;
00109
00110 try{
00111
00112
00113
00114 getOptions( m_osoption);
00115
00116 m_maxMasterRows = m_maxBmatrixCon + m_numNodes;
00117
00118 m_upperBoundL = new int[ m_numHubs];
00119 m_lowerBoundL = new int[ m_numHubs];
00120
00121 for(k = 0; k < m_numHubs; k++){
00122
00123 m_upperBoundL[ k] = m_routeCapacity[ k];
00124 m_lowerBoundL[ k] = m_routeMinPickup[ k];
00125
00126 if(m_upperBoundL[ k] > m_totalDemand) m_upperBoundL[ k] = m_totalDemand;
00127 if( m_upperBoundL[ k] > m_upperBoundLMax) m_upperBoundLMax = m_upperBoundL[ k];
00128
00129 }
00130
00131
00132
00133
00134 m_varIdx = new int[ m_upperBoundLMax + 1];
00135
00136
00137 m_u = new double*[ m_numNodes];
00138 m_v = new double*[ m_numNodes];
00139 m_g = new double*[ m_numNodes];
00140
00141 m_px = new int*[ m_numNodes];
00142 m_tx = new int*[ m_numNodes];
00143
00144
00145
00155 for (i = 0; i < m_numNodes; i++) {
00156
00157
00158 m_u[ i] = new double[ m_upperBoundLMax + 1];
00159 m_v[ i] = new double[ m_upperBoundLMax + 1];
00160
00161
00162
00163 for(l = 0; l <= m_upperBoundLMax; l++){
00164
00165 m_u[ i][l] = OSDBL_MAX;
00166 m_v[ i][l] = OSDBL_MAX;
00167 }
00168
00169 m_g[ i] = new double[ m_numNodes];
00170 m_px[ i] = new int[ m_upperBoundLMax + 1];
00171 m_tx[ i] = new int[m_upperBoundLMax + 1];
00172
00173
00174 }
00175
00176
00177
00178 m_optL = new int[ m_numHubs];
00179 m_optD = new int[ m_numHubs];
00180
00181 m_vv = new double*[ m_numHubs];
00182 m_vvpnt = new int*[ m_numHubs];
00183 m_cost = new double*[ m_numHubs];
00184 m_rc = new double*[ m_numHubs];
00185
00186 for (k = 0; k < m_numHubs; k++) {
00187
00188
00189 m_vv[ k] = new double[ m_totalDemand + 1];
00190 m_vvpnt[ k] = new int[ m_totalDemand + 1];
00191 m_cost[ k] = new double[ m_numNodes*m_numNodes - m_numNodes];
00192
00193
00194
00195
00196 m_rc[ k] = new double[ m_upperBoundL[ k]*(m_numNodes*m_numNodes - m_numNodes)];
00197
00198
00199 }
00200
00201 m_optValHub = new double[ m_numHubs];
00202
00203 m_variableNames = new string[ m_numNodes*(m_numNodes - 1)];
00204
00205 createVariableNames();
00206
00207
00208
00209 m_pntAmatrix = new int[ m_numNodes - m_numHubs + 1];
00210
00211
00212
00213
00214
00215 m_Amatrix = new int[ (m_numNodes - m_numHubs)*(m_numNodes - 1) ];
00216 createAmatrix();
00217
00218
00219 int numVar = m_numNodes*m_numNodes - m_numHubs ;
00220 m_tmpScatterArray = new int[ numVar ];
00221 for(i = 0; i < numVar; i++){
00222
00223 m_tmpScatterArray[ i] = 0;
00224
00225 }
00226
00227
00228 m_newColumnNonz = new int[ m_numHubs] ;
00229 m_costVec = new double[ m_numHubs];
00230 m_newColumnRowIdx = new int*[ m_numHubs];
00231 m_newColumnRowValue = new double*[ m_numHubs];
00232
00233 for (k = 0; k < m_numHubs; k++) {
00234
00235
00236 m_newColumnRowValue[ k] = new double[ m_maxBmatrixCon + m_numNodes];
00237 m_newColumnRowIdx[ k] = new int[ m_maxBmatrixCon + m_numNodes];
00238
00239 }
00240
00241
00242
00243
00244 m_newRowNonz = new int[ m_numHubs] ;
00245 m_newRowColumnIdx = new int*[ m_numHubs] ;
00246 m_newRowColumnValue = new double*[ m_numHubs] ;
00247 m_newRowUB = new double[ m_numHubs];
00248 m_newRowLB = new double[ m_numHubs];
00249
00250
00251
00252 for (k = 0; k < m_numHubs; k++) {
00253
00254 m_newRowColumnValue[ k] = new double[ m_maxMasterColumns];
00255 m_newRowColumnIdx[ k] = new int[ m_maxMasterColumns];
00256
00257 }
00258
00259
00260 convexityRowIndex = new int[ m_maxMasterColumns];
00261
00262
00263 branchCutIndexes = new int[ m_maxMasterColumns];
00264 branchCutValues = new double[ m_maxMasterColumns];
00265
00266 m_thetaPnt = new int[ m_maxMasterColumns + 1];
00267 for(i = 0; i <= m_maxMasterColumns; i++){
00268 m_thetaPnt[ i] = 0;
00269 }
00270 m_thetaCost = new double[ m_maxMasterColumns];
00271 m_thetaIndex = new int[ m_maxThetaNonz];
00272 m_numThetaVar = 0;
00273 m_numThetaNonz = 0;
00274 m_thetaPnt[ m_numThetaVar] = 0;
00275
00276
00277
00278
00279
00280 m_pntBmatrix = new int[ m_maxBmatrixCon];
00281
00282 m_Bmatrix = new int[ m_maxBmatrixNonz];
00283 m_numBmatrixCon = 0;
00284 m_numBmatrixNonz = 0;
00285 m_pntBmatrix[ m_numBmatrixCon] = 0;
00286
00287 ;
00288
00289
00290 m_separationIndexMap = new int[m_numNodes*(m_numNodes - 1)];
00291
00292 for(i = 0; i < m_numNodes*(m_numNodes - 1); i++){
00293
00294 m_separationIndexMap[ i] = OSINT_MAX;
00295
00296 }
00297
00298
00299
00300
00301
00302 getSeparationInstance();
00303 } catch (const ErrorClass& eclass) {
00304
00305 throw ErrorClass(eclass.errormsg);
00306
00307 }
00308
00309
00310 }
00311
00312
00313 OSBearcatSolverXkij::~OSBearcatSolverXkij(){
00314
00315 std::cout << "INSIDE ~OSBearcatSolverXkij DESTRUCTOR" << std::endl;
00316
00317
00318
00319
00320 int i;
00321
00322 delete[] m_routeCapacity;
00323 m_routeCapacity = NULL;
00324
00325
00326 delete[] m_routeMinPickup;
00327 m_routeMinPickup = NULL;
00328
00329 for(i = 0; i < m_numNodes; i++){
00330
00331
00332
00333 delete[] m_v[i];
00334 delete[] m_g[i];
00335 delete[] m_px[i];
00336 delete[] m_tx[i];
00337 delete[] m_u[i];
00338
00339
00340 }
00341
00342 delete[] m_u;
00343 m_u= NULL;
00344
00345 delete[] m_v;
00346 m_v= NULL;
00347
00348 delete[] m_g;
00349 m_g= NULL;
00350
00351 delete[] m_px;
00352 m_px= NULL;
00353
00354 delete[] m_tx;
00355 m_tx= NULL;
00356
00357
00358
00359 if(m_demand != NULL){
00360
00361 delete[] m_demand;
00362 }
00363
00364
00365 if(m_varIdx != NULL) delete[] m_varIdx;
00366
00367 for(i = 0; i < m_numHubs; i++){
00368
00369 delete[] m_vv[i];
00370 delete[] m_vvpnt[i];
00371 delete[] m_cost[ i];
00372 delete[] m_rc[ i];
00373
00374
00375 }
00376 delete[] m_optL;
00377 m_optL = NULL;
00378 delete[] m_optD;
00379 m_optD = NULL;
00380 delete[] m_vv;
00381 m_vv = NULL;
00382 delete[] m_vvpnt;
00383 m_vvpnt = NULL;
00384
00385 delete[] m_cost;
00386 m_cost = NULL;
00387
00388 delete[] m_rc;
00389 m_rc = NULL;
00390
00391 delete[] m_upperBoundL;
00392 m_upperBoundL = NULL;
00393
00394 delete[] m_lowerBoundL;
00395 m_lowerBoundL = NULL;
00396
00397
00398 delete[] m_optValHub;
00399 m_optValHub = NULL;
00400
00401 delete[] m_variableNames;
00402 m_variableNames = NULL;
00403
00404 delete[] m_pntAmatrix;
00405 m_pntAmatrix = NULL;
00406
00407 delete[] m_Amatrix;
00408 m_Amatrix = NULL;
00409
00410 delete[] m_tmpScatterArray;
00411 m_tmpScatterArray = NULL;
00412
00413 delete[] m_newColumnNonz ;
00414 m_newColumnNonz = NULL;
00415 delete[] m_costVec ;
00416 m_costVec = NULL;
00417
00418 for(i = 0; i < m_numHubs; i++){
00419
00420 delete[] m_newColumnRowIdx[i];
00421 delete[] m_newColumnRowValue[i];
00422 }
00423
00424 delete[] m_newColumnRowIdx;
00425 m_newColumnRowIdx = NULL;
00426
00427 delete[] m_newColumnRowValue;
00428 m_newColumnRowValue = NULL;
00429
00430
00431 delete[] convexityRowIndex;
00432 convexityRowIndex = NULL;
00433
00434
00435
00436 delete[] m_newRowNonz;
00437 m_newRowNonz = NULL;
00438
00439 delete[] m_newRowUB ;
00440 m_newRowUB = NULL;
00441
00442 delete[] m_newRowLB ;
00443 m_newRowLB = NULL;
00444
00445
00446 for (i = 0; i < m_numHubs; i++) {
00447
00448 delete[] m_newRowColumnValue[ i];
00449 delete[] m_newRowColumnIdx[ i];
00450
00451 }
00452
00453 delete[] m_newRowColumnIdx;
00454 m_newRowColumnIdx = NULL;
00455
00456 delete[] m_newRowColumnValue;
00457 m_newRowColumnValue = NULL;
00458
00459
00460 delete[] branchCutIndexes ;
00461 branchCutIndexes = NULL;
00462
00463 delete[] branchCutValues ;
00464 branchCutValues = NULL;
00465
00466
00467 delete[] m_thetaPnt;
00468 m_thetaPnt = NULL;
00469
00470 delete[] m_thetaIndex;
00471 m_thetaIndex = NULL;
00472
00473
00474 delete[] m_thetaCost;
00475 m_thetaCost = NULL;
00476
00477
00478 delete[] m_pntBmatrix ;
00479 m_pntBmatrix = NULL;
00480
00481 delete[] m_Bmatrix ;
00482 m_Bmatrix = NULL;
00483
00484
00485
00486
00487 delete[] m_separationIndexMap;
00488 m_separationIndexMap = NULL;
00489
00490 delete m_separationClpModel;
00491 m_separationClpModel = NULL;
00492
00493 delete m_osinstanceSeparation;
00494 m_osinstanceSeparation = NULL;
00495
00496 }
00497
00498
00499
00500
00501
00502
00503
00504 void OSBearcatSolverXkij::getOptL( double** c) {
00505
00506
00507
00508 int k;
00509 int d;
00510 int d1;
00511 int kountVar;
00512 double testVal;
00513 int l;
00514
00515 double trueMin;
00516
00517 bool isFeasible;
00518 isFeasible = false;
00519
00520 kountVar = 0;
00521
00522
00523 m_vv[ 0][ 0] = 0;
00524 for(d = 1; d <= m_totalDemand; d++){
00525
00526 m_vv[ 0][ d] = OSDBL_MAX;
00527
00528 }
00529
00530 for(k = 1; k < m_numHubs - 1; k++){
00531 for(d = 0; d <= m_totalDemand; d++){
00532
00533 m_vv[ k][ d] = OSDBL_MAX;
00534
00535 }
00536 }
00537
00538
00539
00540
00541 int dlower;
00542 dlower = 0;
00543
00544 for(k = 1; k < m_numHubs; k++){
00545
00546 dlower += m_lowerBoundL[ k - 1];
00547
00548
00549 for(d = dlower; d <= m_totalDemand; d++){
00550
00551 m_vv[ k][ d] = OSDBL_MAX;
00552
00553
00554 for(d1 = 0; d1 <= m_totalDemand; d1++){
00555
00556 l = d - d1;
00557
00558 if( (m_vv[ k - 1][ d1] < OSDBL_MAX) && (l <= m_upperBoundL[ k - 1]) && (l >= m_lowerBoundL[ k - 1]) ){
00559
00560
00561
00562
00563
00564
00565 testVal = qrouteCost(k - 1, l, c[ k - 1], &kountVar);
00566
00567
00568
00569
00570 if( m_vv[ k-1][ d1] + testVal < m_vv[ k][ d] ){
00571
00572 m_vv[ k][ d] = m_vv[ k-1][ d1] + testVal;
00573
00574 m_vvpnt[ k][ d] = d1;
00575
00576 }
00577
00578
00579 }
00580
00581 }
00582
00583 }
00584
00585
00586
00587 }
00588
00589 trueMin = OSDBL_MAX;
00590
00591
00592
00593
00594
00595
00596 for(d = dlower; d < m_totalDemand; d++){
00597
00598
00599 l = m_totalDemand - d;
00600
00601 if(m_vv[ m_numHubs - 1 ][ d] < OSDBL_MAX && l <= m_upperBoundL[ m_numHubs - 1] && l >= m_lowerBoundL[ m_numHubs - 1]){
00602
00603
00604
00605
00606
00607 isFeasible = true;
00608
00609
00610 testVal = qrouteCost(m_numHubs -1 , l, c[ m_numHubs -1], &kountVar);
00611
00612
00613
00614
00615 if(m_vv[ m_numHubs - 1][ d] + testVal < trueMin){
00616
00617 trueMin = m_vv[ m_numHubs -1][ d] + testVal;
00618 m_optD[ m_numHubs -1 ] = d;
00619 m_optL[ m_numHubs -1 ] = l;
00620
00621 }
00622
00623
00624 }
00625 }
00626
00627
00628
00629 if( isFeasible == false){
00630
00631 std::cout << "NOT ENOUGH CAPACITY " << std::endl;
00632 throw ErrorClass( "NOT ENOUGH CAPACITY ");
00633 }
00634
00635 k = m_numHubs -1;
00636
00637 while( k - 1 >= 0) {
00638
00639 m_optD[ k - 1 ] = m_vvpnt[ k][ m_optD[ k ] ];
00640
00641 m_optL[ k - 1 ] = m_optD[ k ] - m_optD[ k - 1 ] ;
00642
00643
00644
00645
00646
00647 k--;
00648
00649
00650 }
00651
00652 }
00653
00654
00655
00656
00657
00658
00659 double OSBearcatSolverXkij::qrouteCost(const int& k, const int& l, const double* c, int* kountVar){
00660
00661
00662
00663
00664 double rcost;
00665 rcost = OSDBL_MAX;
00666
00667
00668
00669 if(l < 0){
00670
00671 std::cout << "LVALUE NEGATIVE " << l << std::endl;
00672 exit( 1);
00673 }
00674
00675
00676
00677 if(l > m_upperBoundL[ k]){
00678
00679 std::cout << "LVALUE BIGGER THAN UPPER BOUND " << l << std::endl;
00680 exit( 1);
00681 }
00682
00683
00684
00685
00686
00687 int startPnt = (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
00688 c+= startPnt ;
00689
00690
00691
00692 *kountVar = 0;
00693 int bestLastNode;
00694
00695 bestLastNode = OSINT_MAX;
00696 int i;
00697 int j;
00698 int l1;
00699 int l2;
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 for(i = m_numHubs; i < m_numNodes; i++){
00716
00717
00718 for(l1 = m_minDemand; l1 <= l; l1++){
00719
00720 m_u[i][l1] = OSDBL_MAX;
00721 m_v[i][l1] = OSDBL_MAX;
00722 m_px[i][l1] = -1;
00723 if(l1 == *(m_demand + i) ){
00724
00725 m_px[i][l1] = k;
00726
00727
00728 m_u[i][l1] = *(c + k*(m_numNodes - 1) + i - 1);
00729
00730
00731
00732 }
00733 }
00734 }
00735
00736
00737
00738
00739
00740 if(l == m_minDemand){
00741
00742 for(i = m_numHubs; i < m_numNodes; i++){
00743
00744
00745 if( m_u[i][l] + *(c + i*(m_numNodes-1) + k ) < rcost){
00746
00747 rcost = m_u[i][l] + *(c + i*(m_numNodes-1) + k );
00748
00749
00750
00751
00752
00753 bestLastNode = i;
00754 }
00755
00756 }
00757
00758
00759
00760 *(m_varIdx + (*kountVar)++) = startPnt + bestLastNode*(m_numNodes - 1) + k ;
00761 *(m_varIdx + (*kountVar)++) = startPnt + k*(m_numNodes - 1) + bestLastNode - 1;
00762
00763
00764
00765 return rcost;
00766 }
00767
00768
00769
00770
00771
00772
00773
00774 int lowerVal = m_minDemand + 1;
00775 for(l2 = lowerVal; l2 <= l; l2++){
00776
00777 for(i = m_numHubs; i < m_numNodes; i++) {
00778
00779
00780 if( *(m_demand + i) < l2 ){
00781
00782 for(j = m_numHubs; j < i; j++){
00783
00784
00785
00786
00787 l1 = l2 - *(m_demand + i);
00788
00789 if( m_px[j][ l1 ] != i ){
00790
00791
00792 m_g[j][i] = m_u[ j][ l1 ] + *(c + j*(m_numNodes-1) + i - 1) ;
00793
00794
00795
00796
00797 }else{
00798
00799 m_g[j][i] = m_v[ j][ l1] + *(c + j*(m_numNodes-1) + i - 1) ;
00800
00801
00802
00803 }
00804
00805
00806
00807 if(m_g[j][i] < m_u[i][l2] ){
00808
00809 m_u[i][l2] = m_g[j][i];
00810 m_px[i][l2] = j;
00811
00812 }
00813
00814
00815
00816 }
00817
00818
00819 for(j = i + 1; j < m_numNodes; j++){
00820
00821
00822
00823 l1 = l2 - *(m_demand + i);
00824
00825 if( m_px[j][ l1 ] != i ){
00826
00827
00828 m_g[j][i] = m_u[ j][ l1 ] + *(c + j*(m_numNodes-1) + i ) ;
00829
00830
00831 }else{
00832
00833 m_g[j][i] = m_v[ j][ l1] + *(c + j*(m_numNodes-1) + i ) ;
00834
00835 }
00836
00837
00838
00839 if(m_g[j][i] < m_u[i][l2] ){
00840
00841 m_u[i][l2] = m_g[j][i];
00842 m_px[i][l2] = j;
00843
00844 }
00845
00846
00847 }
00848
00849
00850
00851
00852
00853 for(j =m_numHubs; j < m_numNodes; j++){
00854
00855 if(j != i){
00856
00857 if( (m_g[j][i] < m_v[i][l2] ) && (m_px[i][l2] != j) ){
00858
00859
00860
00861 m_v[i][l2] = m_g[j][i];
00862 m_tx[i][l2] = j;
00863
00864
00865 }
00866
00867 }
00868
00869
00870 }
00871
00872
00873 if(l2 == l ){
00874
00875 if( m_u[i][l2] + *(c + i*(m_numNodes-1) + k ) < rcost){
00876
00877 rcost = m_u[i][l2] + *(c + i*(m_numNodes-1) + k );
00878
00879 bestLastNode = i;
00880 }
00881
00882 }
00883
00884
00885 }
00886
00887
00888 }
00889
00890
00891 }
00892
00893
00894
00895
00896
00897
00898
00899 int currentNode;
00900 int successorNode;
00901 int lvalue;
00902
00903
00904
00905
00906
00907
00908
00909 *(m_varIdx + (*kountVar)++) = startPnt + bestLastNode*(m_numNodes - 1) + k ;
00910
00911
00912
00913
00914 if( bestLastNode == OSINT_MAX) return OSDBL_MAX;
00915
00916
00917 successorNode = k;
00918 currentNode = bestLastNode;
00919
00920 lvalue = l ;
00921
00922
00923 while(currentNode != k){
00924
00925 if( m_px[ currentNode][ lvalue ] != successorNode){
00926
00927
00928
00929
00930 successorNode = currentNode;
00931 currentNode = m_px[ currentNode][ lvalue ];
00932
00933
00934 if(currentNode - successorNode > 0){
00935
00936
00937 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode;
00938
00939
00940 }else{
00941
00942
00943 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode - 1 ;
00944
00945 }
00946
00947
00948 }else{
00949
00950
00951
00952 successorNode = currentNode;
00953 currentNode = m_tx[ currentNode][ lvalue ];
00954
00955 if(currentNode - successorNode > 0){
00956
00957 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode;
00958
00959 }else{
00960
00961 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1) + successorNode - 1 ;
00962
00963 }
00964
00965 }
00966
00967
00968 lvalue = lvalue - *(m_demand + successorNode);
00969
00970
00971
00972 }
00973
00974
00975
00976
00977
00978
00979 return rcost;
00980
00981 }
00982
00983
00984
00985
00986 void OSBearcatSolverXkij::getColumns(const double* yA, const int numARows,
00987 const double* yB, const int numBRows,
00988 int &numNewColumns, int* &numNonzVec, double* &costVec,
00989 int** &rowIdxVec, double** &valuesVec, double &lowerBound)
00990 {
00991
00992
00993
00994 int i;
00995 int j;
00996 int numCoulpingConstraints;
00997 numCoulpingConstraints = m_numNodes - m_numHubs;
00998
00999 int numVar;
01000 numVar = m_numNodes*m_numNodes - m_numHubs;
01001 int numNonz;
01002
01003 try{
01004
01005
01006
01007 if(numARows != m_numNodes) throw ErrorClass("inconsistent row count in getColumns");
01008
01009
01010
01011
01012 calcReducedCost( yA, yB );
01013
01014 int kountVar;
01015 double testVal;
01016 testVal = 0;
01017 int k;
01018 int startPntInc;
01019 int rowCount;
01020
01021
01023
01024 double cpuTime;
01025 double start = CoinCpuTime();
01026 getOptL( m_rc);
01027 cpuTime = CoinCpuTime() - start;
01028 std::cout << "DYNAMIC PROGRSMMING CPU TIME " << cpuTime << std::endl;
01029 m_lowerBnd = 0.0;
01030 for(k = 0; k < m_numHubs; k++){
01031
01032
01033
01034 startPntInc = (m_optL[ k] - 1)*(m_numNodes*m_numNodes - m_numNodes);
01035
01036 std::cout << " whichBlock = " << k << " L = " << m_optL[ k] << std::endl;
01037
01038 testVal += m_optL[ k];
01039
01040 kountVar = 0;
01041
01043 m_optValHub[ k] = qrouteCost(k, m_optL[ k], m_rc[ k], &kountVar);
01044
01045 m_optValHub[ k] -= yA[ k + numCoulpingConstraints];
01046
01047 std::cout << "Best Reduced Cost Hub " << k << " = " << m_optValHub[ k] << std::endl;
01048 m_lowerBnd += m_optValHub[ k];
01049
01050
01051
01052
01053
01054 m_costVec[ k] = 0.0;
01055
01056 for(j = 0; j < kountVar; j++){
01057
01058
01059
01060
01061 m_tmpScatterArray[ m_varIdx[ j] - startPntInc ] += 1;
01062
01063
01064
01065 m_costVec[ k] += m_cost[k][ m_varIdx[ j] - startPntInc ];
01066
01067 }
01068
01069
01070
01071 numNonz = 0;
01072
01073 for(i = 0; i < numCoulpingConstraints; i++){
01074
01075 rowCount = 0;
01076
01077 for(j = m_pntAmatrix[ i]; j < m_pntAmatrix[ i + 1]; j++){
01078
01079
01080
01081
01082 rowCount += m_tmpScatterArray[ m_Amatrix[ j] ];
01083
01084
01085 }
01086
01087 if(rowCount > 0){
01088
01089
01090 m_newColumnRowIdx[ k][ numNonz] = i;
01091 m_newColumnRowValue[ k][ numNonz] = rowCount;
01092 numNonz++;
01093 }
01094
01095
01096 }
01097
01098
01099 m_newColumnRowIdx[ k][ numNonz] = m_numNodes - m_numHubs + k;
01100 m_newColumnRowValue[ k][ numNonz++] = 1.0;
01101
01102
01103
01104
01105
01106 for(i = 0; i < m_numBmatrixCon; i++){
01107
01108 rowCount = 0;
01109
01110 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
01111
01112
01113
01114
01115 rowCount += m_tmpScatterArray[ m_Bmatrix[ j] ];
01116
01117
01118 }
01119
01120 if(rowCount > 0){
01121
01122
01123 m_newColumnRowIdx[ k][ numNonz] = i + m_numNodes;
01124 m_newColumnRowValue[ k][ numNonz++] = rowCount;
01125
01126 }
01127
01128
01129 }
01130
01131 m_newColumnNonz[ k] = numNonz;
01132
01133
01134
01135
01136 for(j = 0; j < kountVar; j++){
01137
01138
01139 m_thetaIndex[ m_numThetaNonz++ ] = m_varIdx[ j] - startPntInc ;
01140 m_tmpScatterArray[ m_varIdx[ j] - startPntInc ] = 0;
01141
01142
01143
01144 }
01145
01146
01147 intVarSet.insert ( std::pair<int,double>( m_numThetaVar, 1.0) );
01148 convexityRowIndex[ m_numThetaVar] = k;
01149 m_costVec[ k] = m_optL[ k]*m_costVec[ k];
01150 m_thetaCost[ m_numThetaVar++ ] = m_costVec[ k];
01151 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
01152
01153
01154
01155
01156
01157
01158
01191
01192
01193
01194
01195 }
01196
01197
01198
01199 numNonzVec = m_newColumnNonz;
01200 costVec = m_costVec;
01201 rowIdxVec = m_newColumnRowIdx;
01202 valuesVec = m_newColumnRowValue;
01203 std::cout << "Lower Bound = " << m_lowerBnd << std::endl;
01204
01205
01206 if(testVal != m_totalDemand) {
01207
01208 std::cout << "TOTAL DEMAND = " << m_totalDemand << std::endl;
01209 std::cout << "Test Value = " << testVal << std::endl;
01210 throw ErrorClass( "inconsistent demand calculation" );
01211 }
01212
01213
01214
01215
01216
01217
01218 } catch (const ErrorClass& eclass) {
01219
01220 throw ErrorClass(eclass.errormsg);
01221
01222 }
01223
01224
01225
01226 numNewColumns = m_numHubs;
01227 lowerBound = m_lowerBnd;
01228
01229 std::cout << "LEAVING GET COLUMNS" << std::endl;
01230 return;
01231
01232 }
01233
01234
01235
01529 OSInstance* OSBearcatSolverXkij::getInitialRestrictedMaster( ){
01530
01531
01532 std::cout << "Executing OSBearcatSolverXkij::getInitialRestrictedMaster2( )" << std::endl;
01533
01534
01535 int numVarArt;
01536
01537 numVarArt = m_numNodes;
01538
01539
01540
01541
01542 FileUtil *fileUtil = NULL;
01543 OSiLReader *osilreader = NULL;
01544 CoinSolver *solver = NULL;
01545 OSInstance *osinstance = NULL;
01546
01547
01548 int i;
01549 int j;
01550 int k;
01551 std::string testFileName;
01552 std::string osil;
01553
01554 std::map<int, std::map<int, std::vector<int> > >::iterator mit;
01555 std::map<int, std::vector<int> >::iterator mit2;
01556 std::vector<int>::iterator vit;
01557
01558
01559 fileUtil = new FileUtil();
01560
01561 m_osinstanceMaster = NULL;
01562
01563
01564
01565
01566 int kountNonz;
01567 int kount;
01568 m_numberOfSolutions = 1;
01569 int numThetaVar = m_numberOfSolutions*m_numHubs;
01570
01571 double *values = new double[ m_numberOfSolutions*(m_numNodes-m_numHubs) + numThetaVar + numVarArt];
01572 int *indexes = new int[ m_numberOfSolutions*(m_numNodes-m_numHubs) + numThetaVar + numVarArt] ;
01573 int *starts = new int[ numThetaVar + 1 + numVarArt];
01574 kount = 0;
01575 starts[ 0] = 0;
01576 int startsIdx;
01577 startsIdx = 0;
01578 startsIdx++;
01579
01580 for(i = 0; i < numVarArt; i++){
01581 convexityRowIndex[ m_numThetaVar] = -1;
01582 m_thetaPnt[ m_numThetaVar++] = 0;
01583
01584 }
01585
01586 std::vector<IndexValuePair*> primalValPair;
01587
01588
01589
01590
01591 double* xVar;
01592 int numXVar;
01593 numXVar = m_numNodes*(m_numNodes - 1);
01594 xVar = new double[ numXVar];
01595
01596 for(i = 0; i < numXVar; i++){
01597
01598 xVar[ i] = 0;
01599
01600 }
01601
01602 int numNewRows;
01603 int* numRowNonz = NULL;
01604 int** colIdx = NULL;
01605 double** rowValues = NULL ;
01606 double* rowLB;
01607 double* rowUB;
01608
01609
01610
01611
01612
01613
01614 try {
01615
01616 if(m_initOSiLFile.size() == 0) throw ErrorClass("OSiL file to generate restricted master missing");
01617 osil = fileUtil->getFileAsString( m_initOSiLFile.c_str());
01618
01619 osilreader = new OSiLReader();
01620 osinstance = osilreader->readOSiL(osil);
01621
01622
01623
01624
01625
01627
01628
01629
01630 kount = 2*m_numHubs + m_numHubs*(m_numNodes*m_numNodes - m_numNodes);
01631
01632 if(m_use1OPTstart == true){
01633 osinstance->bVariablesModified = true;
01634
01635 mit = m_initSolMap.find( 0);
01636 for ( mit2 = mit->second.begin() ; mit2 != mit->second.end(); mit2++ ){
01637
01638
01639
01640 for ( vit = mit2->second.begin() ; vit != mit2->second.end(); vit++ ){
01641
01642
01643 osinstance->instanceData->variables->var[ kount + mit2->first*m_numNodes + *vit]->lb = 1.0;
01644 std::cout << "FIXING LOWER BOUND ON VARIABLE " << osinstance->getVariableNames()[ kount + mit2->first*m_numNodes + *vit ] << std::endl;
01645
01646 }
01647
01648 }
01649 }
01650
01651
01652
01653
01654
01655
01656
01657 int idx1;
01658 int idx2;
01659 idx2 = 0;
01660
01661 for(k = 0; k < m_numHubs; k++){
01662
01663 idx1 = 0;
01664
01665 for(i = 0; i < m_numNodes; i++){
01666
01667 for(j = 0; j < i; j++){
01668
01669 m_cost[k][idx1++ ] = osinstance->instanceData->objectives->obj[0]->coef[ idx2++ ]->value;
01670 }
01671
01672 for(j = i + 1; j < m_numNodes; j++){
01673
01674 m_cost[k][idx1++ ] = osinstance->instanceData->objectives->obj[0]->coef[ idx2++ ]->value;
01675
01676 }
01677 }
01678 }
01679
01680
01681
01682
01683 std::string* varNames;
01684 varNames = osinstance->getVariableNames();
01685
01686
01687
01688 m_osinstanceMaster = new OSInstance();
01689 m_osinstanceMaster->setInstanceDescription("The Initial Restricted Master");
01690
01691
01692
01693 m_osinstanceMaster->setVariableNumber( m_numberOfSolutions*m_numHubs + numVarArt);
01694
01695
01696 m_osinstanceMaster->setObjectiveNumber( 1);
01697
01698 SparseVector *objcoeff = new SparseVector( m_numberOfSolutions*m_numHubs + numVarArt);
01699
01700
01701
01702 m_osinstanceMaster->setConstraintNumber( m_numNodes);
01703
01704
01705
01706
01707
01708 int varNumber;
01709 varNumber = 0;
01710 std::string masterVarName;
01711 kountNonz = 0;
01712
01713 for(i = 0; i < m_numNodes; i++){
01714
01715
01716 objcoeff->indexes[ varNumber ] = varNumber ;
01717
01718
01719
01720
01721
01722
01723
01724 objcoeff->values[ varNumber ] = m_osDecompParam.artVarCoeff;
01725
01726 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt2("AP", i ) ,
01727 0, 1.0, 'C');
01728
01729
01730
01731 values[ kountNonz] = 1;
01732 indexes[ kountNonz++] = i ;
01733 starts[ startsIdx++] = kountNonz;
01734
01735
01736
01737 }
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774 solver = new CoinSolver();
01775 solver->sSolverName ="cbc";
01776 solver->osinstance = osinstance;
01777 solver->buildSolverInstance();
01778 solver->osoption = m_osoption;
01779 OsiSolverInterface *si = solver->osiSolver;
01780
01781 solver->solve();
01782
01783
01784
01785
01786 std::cout << "Solution Status = " << solver->osresult->getSolutionStatusType( 0 ) << std::endl;
01787
01788
01789
01790
01791
01792
01793
01794
01795 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
01796
01797
01798 bool isCutAdded;
01799 isCutAdded = true;
01800 while(isCutAdded == true){
01801
01802 isCutAdded = false;
01803
01804 for(k = 0; k < m_numHubs; k++){
01805 numNewRows = 0;
01806
01807
01808
01809 idx1 = 2*m_numHubs + k*m_numNodes*(m_numNodes - 1);
01810 idx2 = idx1 + m_numNodes*(m_numNodes - 1);
01811
01812
01813 std::cout << "HUB " << k << " VARIABLES" << std::endl;
01814
01815
01816
01817
01818
01819
01820 for(i = idx1; i < idx2; i++){
01821 if( primalValPair[ i]->value > .01 ){
01822 std::cout << osinstance->getVariableNames()[ primalValPair[ i]->idx ] << std::endl;
01823 std::cout << m_variableNames[ primalValPair[ i]->idx - k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs ] << " " << primalValPair[ i]->value << std::endl;
01824
01825
01826
01827 xVar[ primalValPair[ i]->idx - k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs ] = primalValPair[ i]->value;
01828
01829
01830 }
01831 }
01832
01833
01834
01835
01836 getCutsX(xVar, numXVar, numNewRows, numRowNonz,
01837 colIdx,rowValues, rowLB, rowUB);
01838
01839
01840
01841 if(numNewRows >= 1){
01842 isCutAdded = true;
01843 std::cout << "WE HAVE A CUT " << std::endl;
01844 std::cout << "EXPRESS CUT IN X(I, J) SPACE" << std::endl;
01845 for(i = 0; i < numRowNonz[ 0]; i++){
01846
01847 std::cout << m_variableNames[ colIdx[0][ i] ] << std::endl;
01848
01849 }
01850
01851
01852 for(i = 0; i < numNewRows; i++){
01853
01854
01855
01856 std::cout << "EXPRESS CUT IN X(K, I, J) SPACE" << std::endl;
01857
01858 for(j = 0; j < numRowNonz[ i]; j++){
01859
01860 colIdx[ i][ j] = colIdx[ i][ j] + k*(m_numNodes - 1)*m_numNodes + 2*m_numHubs ;
01861
01862 std::cout << osinstance->getVariableNames()[ colIdx[ i][ j] ] << std::endl;
01863 }
01864
01865 std::cout << "CUT UPPER BOUND = " << rowUB[ i] << std::endl;
01866
01867
01868 si->addRow(numRowNonz[ i], colIdx[ i], rowValues[ i], rowLB[ i], rowUB[ i] ) ;
01869
01870
01871 }
01872
01873
01874
01875 }
01876
01877
01878 for(i = idx1; i < idx2; i++){
01879 if( primalValPair[ i]->value > .01 ){
01880 xVar[ primalValPair[ i]->idx - k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs ] = 0;
01881 }
01882
01883 }
01884
01885
01886
01887
01888 std::cout << "Optimal Objective Value = " << primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value << std::endl;
01889
01890
01891
01892 }
01893
01894
01895 std::cout << std::endl << std::endl;
01896 if( isCutAdded == true) {
01897
01898 std::cout << "A CUT WAS ADDED, CALL SOLVE AGAIN" << std::endl;
01899 solver->solve();
01900 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
01901 std::cout << "New Solution Status = " << solver->osresult->getSolutionStatusType( 0 ) << std::endl;
01902 std::cout << "Optimal Objective Value = " << solver->osresult->getObjValue(0, 0) << std::endl;
01903 }
01904
01905
01906 }
01907
01908
01909
01910
01911 int i1;
01912 int j1;
01913
01914 m_bestIPValue = 0;
01915
01916 for(k = 0; k < m_numHubs; k++){
01917
01918
01919
01920 idx1 = 2*m_numHubs + k*m_numNodes*(m_numNodes - 1);
01921 idx2 = idx1 + m_numNodes*(m_numNodes - 1);
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935 for(i1 = 0; i1 < m_numNodes; i1++){
01936
01937
01938 for(j1 = 0; j1 < i1; j1++){
01939
01940
01941
01942 if( primalValPair[ idx1 ]->value > .1 ){
01943
01944 m_thetaIndex[ m_numThetaNonz++ ] = primalValPair[ idx1]->idx - k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs;
01945
01946
01947 if(j1 >= m_numHubs){
01948
01949 values[ kountNonz] = 1;
01950 indexes[ kountNonz++] = j1 - m_numHubs ;
01951
01952
01953 }
01954
01955 }
01956
01957 idx1++;
01958 }
01959
01960
01961 for(j1 = i1 + 1; j1 < m_numNodes; j1++){
01962
01963
01964
01965
01966 if( primalValPair[ idx1 ]->value > .1 ){
01967
01968 m_thetaIndex[ m_numThetaNonz++ ] = primalValPair[ idx1]->idx - k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs;
01969
01970
01971
01972 if(j1 >= m_numHubs){
01973
01974 values[ kountNonz] = 1;
01975 indexes[ kountNonz++] = j1 - m_numHubs ;
01976
01977 }
01978
01979 }
01980
01981 idx1++;
01982
01983 }
01984
01985 }
01986
01987
01988
01989
01990 values[ kountNonz] = 1;
01991 indexes[ kountNonz++] = m_numNodes - m_numHubs + k ;
01992
01993
01994 std::cout << " m_numThetaVar " << m_numThetaVar << std::endl;
01995
01996 convexityRowIndex[ m_numThetaVar] = k;
01997 m_thetaCost[ m_numThetaVar++ ] = primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value;
01998 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
01999
02000 masterVarName = makeStringFromInt2("theta(", k);
02001 masterVarName += makeStringFromInt2(",", 0);
02002 masterVarName += ")";
02003 intVarSet.insert ( std::pair<int,double>(varNumber, 1.0) );
02004 m_osinstanceMaster->addVariable(varNumber++, masterVarName, 0, 1, 'C');
02005
02006 std::cout << "Optimal Objective Value = " << primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value << std::endl;
02007
02008 objcoeff->indexes[ k + numVarArt ] = k + numVarArt ;
02009 objcoeff->values[ k + numVarArt ] = primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value;
02010
02011 m_bestIPValue += primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value;
02012
02013 std::cout << "m_bestIPValue = " << m_bestIPValue << std::endl;
02014 starts[ startsIdx++] = kountNonz;
02015
02016 }
02017
02018
02019
02020
02021 for( i = 0; i < m_numNodes - m_numHubs ; i++){
02022
02023 m_osinstanceMaster->addConstraint(i, makeStringFromInt2("visitNode_", i + m_numHubs) , 1.0, 1.0, 0);
02024 }
02025
02026 kount = 0;
02027
02028
02029 for( i = m_numNodes - m_numHubs; i < m_numNodes ; i++){
02030
02031 m_osinstanceMaster->addConstraint(i, makeStringFromInt2("convexityRowRoute_", kount++ ) , 1.0, 1.0, 0);
02032 }
02033
02034 m_osinstanceMaster->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
02035
02036
02037
02038 m_osinstanceMaster->setLinearConstraintCoefficients(kountNonz , true,
02039 values, 0, kountNonz - 1, indexes, 0, kountNonz - 1, starts, 0, startsIdx);
02040
02041
02042 primalValPair.clear();
02043 delete solver;
02044 solver = NULL;
02045
02046 delete objcoeff;
02047 objcoeff = NULL;
02048 std::cout << m_osinstanceMaster->printModel( ) << std::endl;
02049 std::cout << "NONZ = " << kountNonz << std::endl;
02050
02051
02052
02053
02054
02055
02056
02057
02058 delete osilreader;
02059 osilreader = NULL;
02060
02061
02062
02063
02064
02065 } catch (const ErrorClass& eclass) {
02066 std::cout << std::endl << std::endl << std::endl;
02067 if (osilreader != NULL)
02068 delete osilreader;
02069 if (solver != NULL)
02070 delete solver;
02071
02072
02073
02074 throw ErrorClass(eclass.errormsg);
02075 }
02076
02077 delete fileUtil;
02078 fileUtil = NULL;
02079 delete[] xVar;
02080 xVar = NULL;
02081
02082 return m_osinstanceMaster;
02083 }
02084
02085
02086
02087 void OSBearcatSolverXkij::getOptions(OSOption *osoption) {
02088
02089
02090 std::cout << "Executing getOptions(OSOption *osoption)" << std::endl;
02091
02092 try{
02093
02094 int i;
02095
02096
02097 std::vector<SolverOption*> solverOptions;
02098 std::vector<SolverOption*>::iterator vit;
02099 std::vector<int>::iterator vit2;
02100 std::vector<int >demand;
02101 std::vector<int >routeCapacity;
02102 std::vector<int >routeMinPickup;
02103
02104 m_numberOfSolutions = 0;
02105 solverOptions = osoption->getSolverOptions("routeSolver");
02106 if (solverOptions.size() == 0) throw ErrorClass( "options for routeSolver not available");
02107
02108
02109 int tmpVal;
02110
02111 std::string routeString;
02112 std::string solutionString;
02113 string::size_type pos1;
02114 string::size_type pos2;
02115 string::size_type pos3;
02116
02117
02118 std::map<int, std::map<int, std::vector<int> > >::iterator mit;
02119 std::map<int, std::vector<int> >::iterator mit2;
02120 int solutionNumber;
02121 int routeNumber;
02122
02123
02124 for (vit = solverOptions.begin(); vit != solverOptions.end(); vit++) {
02125
02126
02127
02128
02129
02130
02131
02132 if( (*vit)->name.find("numHubs") != std::string::npos){
02133
02134
02135 std::istringstream hubBuffer( (*vit)->value);
02136 hubBuffer >> m_numHubs;
02137 std::cout << "numHubs = " << m_numHubs << std::endl;
02138
02139 }else{
02140
02141 if((*vit)->name.find("numNodes") != std::string::npos){
02142
02143
02144 std::istringstream numNodesBuffer( (*vit)->value);
02145 numNodesBuffer >> m_numNodes;
02146 std::cout << "numNodes = " << m_numNodes << std::endl;
02147
02148 }else{
02149 if((*vit)->name.find("totalDemand") != std::string::npos){
02150
02151
02152 std::istringstream totalDemandBuffer( (*vit)->value);
02153 totalDemandBuffer >> m_totalDemand;
02154 std::cout << "m_totalDemand = " << m_totalDemand << std::endl;
02155
02156 }else{
02157 if((*vit)->name.find("routeMinPickup") != std::string::npos){
02158
02159
02160 std::istringstream routeMinPickupBuffer( (*vit)->value);
02161 routeMinPickupBuffer >> tmpVal;
02162 routeMinPickup.push_back( tmpVal);
02163
02164
02165 }else{
02166 if( (*vit)->name.find("demand") != std::string::npos ){
02167
02168
02169 std::istringstream demandBuffer( (*vit)->value);
02170 demandBuffer >> tmpVal;
02171 if(tmpVal <= 0 && demand.size() > m_numHubs) throw ErrorClass("must have strictly positive demand");
02172 if(tmpVal < m_minDemand && demand.size() > m_numHubs ) m_minDemand = tmpVal;
02173 demand.push_back( tmpVal);
02174
02175
02176 }else{
02177 if((*vit)->name.find("routeCapacity") != std::string::npos ){
02178 std::istringstream routeCapacityBuffer( (*vit)->value);
02179 routeCapacityBuffer >> tmpVal;
02180 routeCapacity.push_back( tmpVal);
02181
02182
02183 }else{
02184
02185 if((*vit)->name.find("osilFile") != std::string::npos ){
02186 m_initOSiLFile = (*vit)->value;
02187 std::cout << "m_initOSiLFile = " << m_initOSiLFile << std::endl;
02188
02189 }else{
02190
02191 if( (*vit)->name.find("restrictedMasterSolution") != std::string::npos ){
02192
02193
02194
02195
02196
02197
02198 pos1 = (*vit)->category.find( ":");
02199 if(pos1 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
02200
02201
02202 solutionString = (*vit)->category.substr( 0, pos1);
02203 routeString = (*vit)->category.substr( pos1 + 1);
02204
02205 pos2 = solutionString.find( "n");
02206 if(pos2 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
02207
02208 std::istringstream solutionBuffer( solutionString.substr( pos2 + 1) );
02209 solutionBuffer >> solutionNumber;
02210
02211
02212
02213 pos3 = routeString.find( "e");
02214 if(pos3 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
02215 std::istringstream routeBuffer( routeString.substr( pos3 + 1) );
02216 routeBuffer >> routeNumber;
02217
02218 std::istringstream nodeBuffer( (*vit)->value);
02219 nodeBuffer >> tmpVal;
02220
02221 mit = m_initSolMap.find( solutionNumber );
02222
02223 if( mit != m_initSolMap.end() ){
02224
02225
02226
02227 mit2 = mit->second.find( routeNumber);
02228
02229 if(mit2 != mit->second.end() ){
02230
02231
02232
02233 mit2->second.push_back( tmpVal);
02234
02235
02236 }else{
02237
02238
02239 std::vector<int> tmpVec;
02240 tmpVec.push_back( tmpVal) ;
02241 mit->second.insert( std::pair<int,std::vector<int> >(routeNumber, tmpVec) );
02242
02243
02244 }
02245
02246 }else{
02247
02248 std::vector<int> tmpVec;
02249 tmpVec.push_back( tmpVal) ;
02250
02251 std::map<int, std::vector<int> > tmpMap;
02252 tmpMap.insert( std::pair<int,std::vector<int> >(routeNumber, tmpVec) );
02253 m_initSolMap.insert( std::pair<int, std::map<int, std::vector<int> > >(solutionNumber, tmpMap) ) ;
02254
02255 }
02256 }
02257 else{
02258 if( (*vit)->name.find("maxMasterColumns") != std::string::npos){
02259
02260
02261 std::istringstream maxMasterColumns( (*vit)->value);
02262 maxMasterColumns >> m_maxMasterColumns;
02263 std::cout << "m_maxMasterColumn = " << m_maxMasterColumns << std::endl;
02264
02265 }else{
02266 if( (*vit)->name.find("maxThetaNonz") != std::string::npos){
02267
02268 std::istringstream maxThetaNonz( (*vit)->value);
02269 maxThetaNonz >> m_maxThetaNonz;
02270 std::cout << "m_maxThetaNonz = " << m_maxThetaNonz << std::endl;
02271
02272 }else{
02273 if( (*vit)->name.find("use1OPTstart") != std::string::npos){
02274 m_use1OPTstart = false;
02275 if ( (*vit)->value.find("true") != std::string::npos ) m_use1OPTstart = true;
02276 std::cout << "m_use1OPTstart = " << m_use1OPTstart << std::endl;
02277
02278 }else{
02279 if( (*vit)->name.find("maxBmatrixCon") != std::string::npos ){
02280
02281 std::istringstream maxBmatrixCon( (*vit)->value);
02282 maxBmatrixCon >> m_maxBmatrixCon;
02283 std::cout << "m_maxBmatrixCon = " << m_maxBmatrixCon << std::endl;
02284
02285 }else{
02286 if( (*vit)->name.find("maxBmatrixNonz") != std::string::npos ){
02287
02288 std::istringstream maxBmatrixNonz( (*vit)->value);
02289 maxBmatrixNonz >> m_maxBmatrixNonz;
02290 std::cout << "m_maxBmatrixNonz = " << m_maxBmatrixNonz << std::endl;
02291
02292
02293 }
02294 }
02295 }
02296 }
02297 }
02298 }
02299 }
02300 }
02301 }
02302 }
02303 }
02304 }
02305 }
02306
02307 }
02308
02309
02310
02311 i = 0;
02312 m_routeCapacity = new int[ m_numHubs];
02313 if(m_numHubs != routeCapacity.size( ) ) throw ErrorClass("inconsistent number of HUBS");
02314 for (vit2 = routeCapacity.begin(); vit2 != routeCapacity.end(); vit2++) {
02315
02316 *(m_routeCapacity + i++) = *vit2;
02317
02318 }
02319 routeCapacity.clear();
02320
02321
02322
02323 i = 0;
02324 m_routeMinPickup = new int[ m_numHubs];
02325 if(m_numHubs != routeMinPickup.size( ) ) throw ErrorClass("inconsistent number of HUBS");
02326 for (vit2 = routeMinPickup.begin(); vit2 != routeMinPickup.end(); vit2++) {
02327
02328 *(m_routeMinPickup + i++) = *vit2;
02329
02330 }
02331 routeMinPickup.clear();
02332
02333
02334
02335
02336
02337 i = 0;
02338 m_demand = new int[ m_numNodes];
02339 if(m_numNodes != demand.size( ) ) throw ErrorClass("inconsistent number of demand nodes");
02340 for (vit2 = demand.begin(); vit2 != demand.end(); vit2++) {
02341
02342 *(m_demand + i++) = *vit2;
02343
02344 }
02345 demand.clear();
02346
02347
02348 m_numberOfSolutions = m_initSolMap.size();
02349
02350
02351 } catch (const ErrorClass& eclass) {
02352
02353 throw ErrorClass(eclass.errormsg);
02354
02355 }
02356
02357 }
02358
02359
02360
02361 void OSBearcatSolverXkij::getCutsTheta(const double* theta, const int numTheta,
02362 int &numNewRows, int* &numNonz, int** &colIdx,
02363 double** &values, double* &rowLB, double* &rowUB) {
02364
02365
02366
02367
02368 int i;
02369 int j;
02370 int k;
02371 int index;
02372 int rowKount;
02373 int tmpKount;
02374 int indexAdjust = m_numNodes - m_numHubs;
02375 double* tmpRhs;
02376 int numSepRows = m_osinstanceSeparation->getConstraintNumber() ;
02377
02378 tmpRhs = new double[ numSepRows ];
02379
02380 for(i = 0; i < numSepRows; i++){
02381
02382 tmpRhs[ i] = 0;
02383 }
02384
02385 try{
02386 m_osinstanceSeparation->bConstraintsModified = true;
02387
02388 if(numTheta != m_numThetaVar ) throw
02389 ErrorClass("number of master varibles in OSBearcatSolverXkij::getCuts inconsistent");
02390
02391
02392
02393
02394
02395
02396
02397
02398 for(i = 0; i < numTheta; i++){
02399
02400
02401 if(theta[ i] > m_osDecompParam.zeroTol){
02402
02403
02404 for(j = m_thetaPnt[ i ]; j < m_thetaPnt[ i + 1 ]; j++ ){
02405
02406
02407
02408
02409
02410 rowKount = m_separationIndexMap[ m_thetaIndex[ j] ];
02411
02412
02413
02414 if(rowKount < OSINT_MAX ){
02415
02416 tmpRhs[ rowKount] -= theta[ i];
02417
02418 }
02419
02420 }
02421 }
02422 }
02423
02424
02425
02426
02427 for(i = indexAdjust; i < numSepRows - 1; i++){
02428
02429 if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
02430
02431
02432
02433
02434 int tmpKount = indexAdjust;
02435 for(int i1 = m_numHubs; i1 < m_numNodes; i1++){
02436
02437
02438
02439 for(int j1 = i1+1; j1 < m_numNodes; j1++){
02440
02441 if(tmpKount == i){
02442
02443
02444
02445
02446
02447
02448 m_Bmatrix[ m_numBmatrixNonz++ ] = i1*(m_numNodes - 1) + j1 - 1 ;
02449
02450 m_Bmatrix[ m_numBmatrixNonz++ ] = j1*(m_numNodes - 1) + i1 ;
02451 m_numBmatrixCon++;
02452 m_pntBmatrix[ m_numBmatrixCon ] = m_numBmatrixNonz;
02453
02454 numNewRows = 1;
02455
02456 m_newRowNonz[ 0] = 0;
02457 m_newRowUB[ 0] = 1;
02458 m_newRowLB[ 0] = 0;
02459
02460
02461
02462
02463 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02464 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02465
02466
02467 std::cout << " m_Bmatrix[ j] " << m_Bmatrix[ j] << std::endl ;
02468
02469 m_tmpScatterArray[ m_Bmatrix[ j] ] = 1;
02470
02471 }
02472
02473
02474
02475
02476 for(k = 0; k < m_numThetaVar ; k++){
02477
02478
02479 tmpKount = 0;
02480
02481
02482 for(j = m_thetaPnt[k]; j < m_thetaPnt[k + 1] ; j++){
02483
02484 if(m_tmpScatterArray[ m_thetaIndex[ j] ] > 0 ){
02485
02486 std::cout << " Variable " << m_variableNames[ m_thetaIndex[ j] ] << std::endl;
02487
02488 tmpKount++;
02489
02490 }
02491
02492 }
02493
02494 if(tmpKount > 0){
02495
02496
02497 m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = k ;
02498
02499 m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02500
02501
02502 }
02503
02504 }
02505
02506
02507
02508
02509
02510
02511
02512 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02513 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02514
02515 m_tmpScatterArray[ m_Bmatrix[ j] ] = 0;
02516
02517 }
02518
02519 numNonz = m_newRowNonz;
02520 colIdx = m_newRowColumnIdx;
02521 values = m_newRowColumnValue;
02522 rowUB = m_newRowUB;
02523 rowLB = m_newRowLB;
02524
02525 delete[] tmpRhs;
02526 tmpRhs = NULL;
02527
02528
02529
02530 m_numThetaVar++;
02531 convexityRowIndex[ m_numThetaVar] = -1;
02532 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02533
02534
02535
02536 return;
02537
02538 }
02539
02540 tmpKount++;
02541
02542 }
02543
02544 }
02545
02546
02547 }
02548
02549 m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
02550 m_separationClpModel->setRowLower(i, tmpRhs[ i] );
02551
02552 }
02553
02554
02555
02556
02557
02558 std::vector<int> dualIdx;
02559 std::vector<int>::iterator vit1;
02560 std::vector<int>::iterator vit2;
02561
02562
02563
02564
02565 for(k = 0; k < indexAdjust; k++){
02566
02567
02568
02569 m_separationClpModel->setRowUpper(k, 0.0);
02570
02571
02572 m_separationClpModel->setLogLevel( 0);
02573
02574 m_separationClpModel->primal();
02575
02576 if(m_separationClpModel->getObjValue() > m_osDecompParam.zeroTol){
02577 std::cout << "DOING SEPARATION FOR NODE " << k + m_numHubs << std::endl;
02578 std::cout << "SEPERATION OBJ VALUE = " << m_separationClpModel->getObjValue() << std::endl;
02579 numNewRows = 1;
02580
02581 for(i = 0; i < m_numNodes - m_numHubs ; i++){
02582
02583 if( m_separationClpModel->getRowPrice()[ i] - m_osDecompParam.zeroTol <= -1) dualIdx.push_back( i) ;
02584 }
02585
02586 for (vit1 = dualIdx.begin(); vit1 != dualIdx.end(); vit1++) {
02587
02588 i = *vit1 + m_numHubs;
02589
02590 for (vit2 = dualIdx.begin(); vit2 != dualIdx.end(); vit2++) {
02591
02592 j = *vit2 + m_numHubs;
02593
02594 if( i > j ){
02595
02596 index = i*(m_numNodes -1) + j;
02597 std::cout << "CUT VARIABLE = " << m_variableNames[ index ] <<std::endl;
02598 m_Bmatrix[ m_numBmatrixNonz++ ] = index ;
02599
02600 }else{
02601
02602 if( i < j ){
02603
02604 index = i*(m_numNodes -1) + j - 1;
02605 std::cout << "CUT VARIABLE = " << m_variableNames[ index ] <<std::endl;
02606 m_Bmatrix[ m_numBmatrixNonz++ ] = index ;
02607
02608 }
02609 }
02610
02611 }
02612 }
02613
02614
02615 m_numBmatrixCon++;
02616 m_pntBmatrix[ m_numBmatrixCon ] = m_numBmatrixNonz;
02617
02618
02619
02620
02621
02622
02623 for(i = indexAdjust; i < numSepRows - 1; i++){
02624
02625 m_separationClpModel->setRowUpper(i, 0.0 );
02626 m_separationClpModel->setRowLower(i, 0.0 );
02627
02628
02629 }
02630 m_separationClpModel->setRowUpper(k, 1.0);
02631 delete[] tmpRhs;
02632 tmpRhs = NULL;
02633
02634
02635 m_newRowNonz[ 0] = 0;
02636 m_newRowUB[ 0] = dualIdx.size() - 1;
02637 m_newRowLB[ 0] = 0;
02638
02639 dualIdx.clear();
02640
02641
02642
02643
02644 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02645 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02646
02647 m_tmpScatterArray[ m_Bmatrix[ j] ] = 1;
02648
02649 }
02650
02651
02652
02653
02654 for(i = 0; i < m_numThetaVar ; i++){
02655
02656
02657 tmpKount = 0;
02658 for(j = m_thetaPnt[i]; j < m_thetaPnt[i + 1] ; j++){
02659
02660 if(m_tmpScatterArray[ m_thetaIndex[ j] ] > 0 ){
02661
02662 tmpKount++;
02663
02664 }
02665
02666 }
02667
02668 if(tmpKount > 0){
02669
02670
02671 m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = i ;
02672
02673 m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02674
02675
02676 }
02677
02678 }
02679
02680
02681
02682
02683 for(j = m_pntBmatrix[ m_numBmatrixCon - 1] ;
02684 j < m_pntBmatrix[ m_numBmatrixCon ] ; j++){
02685
02686 m_tmpScatterArray[ m_Bmatrix[ j] ] = 0;
02687
02688 }
02689
02690
02691
02692 numNonz = m_newRowNonz;
02693 colIdx = m_newRowColumnIdx;
02694 values = m_newRowColumnValue;
02695 rowUB = m_newRowUB;
02696 rowLB = m_newRowLB;
02697 m_numThetaVar++;
02698 convexityRowIndex[ m_numThetaVar] = -1;
02699 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02700
02701
02702
02703 return;
02704
02705
02706
02707 }
02708 m_separationClpModel->setRowUpper(k, 1.0);
02709 dualIdx.clear();
02710
02711 }
02712
02713
02714
02715
02716 for(i = indexAdjust; i < numSepRows - 1; i++){
02717
02718 m_separationClpModel->setRowUpper(i, 0.0 );
02719 m_separationClpModel->setRowLower(i, 0.0 );
02720
02721
02722 }
02723
02724 delete[] tmpRhs;
02725 tmpRhs = NULL;
02726
02727 } catch (const ErrorClass& eclass) {
02728
02729 throw ErrorClass(eclass.errormsg);
02730
02731 }
02732
02733
02734
02735 }
02736
02737
02738
02739
02740
02741
02742
02743 void OSBearcatSolverXkij::getCutsX(const double* x, const int numX,
02744 int &numNewRows, int* &numNonz, int** &colIdx,
02745 double** &values, double* &rowLB, double* &rowUB) {
02746
02747
02748
02749 int i;
02750 int j;
02751 int k;
02752 int index;
02753 int rowKount;
02754
02755
02756 int indexAdjust = m_numNodes - m_numHubs;
02757 double* tmpRhs;
02758 int numSepRows = m_osinstanceSeparation->getConstraintNumber() ;
02759
02760 tmpRhs = new double[ numSepRows ];
02761
02762 for(i = 0; i < numSepRows; i++){
02763
02764 tmpRhs[ i] = 0;
02765 }
02766
02767 try{
02768 m_osinstanceSeparation->bConstraintsModified = true;
02769
02770 for(i = 0; i < numX; i++){
02771
02772
02773 if(x[ i] > m_osDecompParam.zeroTol){
02774
02775
02776 rowKount = m_separationIndexMap[ i ];
02777
02778 if(rowKount < OSINT_MAX ){
02779
02780 tmpRhs[ rowKount] -= x[ i];
02781
02782 }
02783
02784 }
02785 }
02786
02787 for(i = indexAdjust; i < numSepRows - 1; i++){
02788
02789 if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
02790
02791
02792
02793
02794
02795 int tmpKount = indexAdjust;
02796 for(int i1 = m_numHubs; i1 < m_numNodes; i1++){
02797
02798 for(int j1 = i1+1; j1 < m_numNodes; j1++){
02799
02800 if(tmpKount == i){
02801
02802 numNewRows = 1;
02803
02804 m_newRowNonz[ 0] = 2;
02805 m_newRowUB[ 0] = 1;
02806 m_newRowLB[ 0] = 0;
02807
02808 m_newRowColumnIdx[ 0][ 0 ] = i1*(m_numNodes - 1) + j1 - 1;
02809 m_newRowColumnIdx[ 0][ 1 ] = j1*(m_numNodes - 1) + i1;
02810 m_newRowColumnValue[ 0][ 0] = 1;
02811 m_newRowColumnValue[ 0][ 1] = 1;
02812
02813 numNonz = m_newRowNonz;
02814 colIdx = m_newRowColumnIdx;
02815 values = m_newRowColumnValue;
02816 rowUB = m_newRowUB;
02817 rowLB = m_newRowLB;
02818
02819 delete[] tmpRhs;
02820 tmpRhs = NULL;
02821 return;
02822
02823
02824
02825 }
02826
02827 tmpKount++;
02828
02829 }
02830
02831 }
02832
02833
02834 }
02835
02836 m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
02837 m_separationClpModel->setRowLower(i, tmpRhs[ i] );
02838
02839 }
02840
02841
02842
02843
02844
02845 std::vector<int> dualIdx;
02846 std::vector<int>::iterator vit1;
02847 std::vector<int>::iterator vit2;
02848
02849
02850
02851
02852 for(k = 0; k < indexAdjust; k++){
02853 std::cout << std::endl << std::endl;
02854
02855
02856 m_separationClpModel->setRowUpper(k, 0.0);
02857
02858
02859 m_separationClpModel->primal();
02860
02861 if(m_separationClpModel->getObjValue() > m_osDecompParam.zeroTol){
02862 std::cout << "DOING SEPARATION FOR NODE " << k + m_numHubs << std::endl;
02863 std::cout << "SEPERATION OBJ = " << m_separationClpModel->getObjValue() << std::endl;
02864 numNewRows = 1;
02865 m_newRowNonz[ 0] = 0;
02866 m_newRowLB[ 0] = 0;
02867
02868 for(i = 0; i < m_numNodes - m_numHubs ; i++){
02869
02870 if( m_separationClpModel->getRowPrice()[ i] - m_osDecompParam.zeroTol <= -1) dualIdx.push_back( i) ;
02871 }
02872
02873 for (vit1 = dualIdx.begin(); vit1 != dualIdx.end(); vit1++) {
02874
02875 i = *vit1 + m_numHubs;
02876
02877 for (vit2 = dualIdx.begin(); vit2 != dualIdx.end(); vit2++) {
02878
02879 j = *vit2 + m_numHubs;
02880
02881 if( i > j ){
02882
02883 index = i*(m_numNodes -1) + j;
02884 std::cout << "CUT VARIABLE = " << m_variableNames[ index] <<std::endl;
02885 m_newRowColumnValue[ 0][ m_newRowNonz[ 0] ] = 1.0;
02886 m_newRowColumnIdx[ 0][ m_newRowNonz[ 0]++ ] = index;
02887
02888 }else{
02889
02890 if( i < j ){
02891
02892 index = i*(m_numNodes -1) + j - 1;
02893 std::cout << "CUT VARIABLE = " << m_variableNames[ index] <<std::endl;
02894 m_newRowColumnValue[ 0][ m_newRowNonz[ 0] ] = 1.0;
02895 m_newRowColumnIdx[ 0][ m_newRowNonz[ 0]++ ] = index;
02896
02897 }
02898 }
02899
02900 }
02901 }
02902
02903
02904 m_newRowUB[ 0] = dualIdx.size() - 1;
02905
02906 dualIdx.clear();
02907
02908
02909 for(i = indexAdjust; i < numSepRows - 1; i++){
02910
02911 m_separationClpModel->setRowUpper(i, 0.0 );
02912 m_separationClpModel->setRowLower(i, 0.0 );
02913
02914
02915 }
02916 m_separationClpModel->setRowUpper(k, 1.0);
02917 delete[] tmpRhs;
02918 tmpRhs = NULL;
02919
02920
02921 numNonz = m_newRowNonz;
02922 colIdx = m_newRowColumnIdx;
02923 values = m_newRowColumnValue;
02924 rowUB = m_newRowUB;
02925 rowLB = m_newRowLB;
02926
02927 return;
02928
02929
02930
02931 }
02932 m_separationClpModel->setRowUpper(k, 1.0);
02933 dualIdx.clear();
02934
02935 }
02936
02937
02938
02939
02940 for(i = indexAdjust; i < numSepRows - 1; i++){
02941
02942 m_separationClpModel->setRowUpper(i, 0.0 );
02943 m_separationClpModel->setRowLower(i, 0.0 );
02944
02945
02946 }
02947
02948 delete[] tmpRhs;
02949 tmpRhs = NULL;
02950
02951 } catch (const ErrorClass& eclass) {
02952
02953 throw ErrorClass(eclass.errormsg);
02954
02955 }
02956
02957
02958 }
02959
02960
02961 void OSBearcatSolverXkij::calcReducedCost( const double* yA, const double* yB){
02962
02963 int k;
02964 int i;
02965 int j;
02966 int l;
02967 int kount;
02968
02969 int tmpVal;
02970 tmpVal = m_numNodes - 1;
02971
02972 for(k = 0; k < m_numHubs; k++){
02973 kount = 0;
02974
02975 for(l = 1; l <= m_upperBoundL[ k]; l++){
02976
02977
02978 for(i = 0; i< m_numNodes; i++){
02979
02980
02981
02982 for(j = 0; j < i; j++){
02983
02984 if(j < m_numHubs){
02985
02986 m_rc[k][ kount++] = l*m_cost[k][ i*tmpVal + j ] ;
02987
02988 }else{
02989
02990 m_rc[k][ kount++] = l*m_cost[k][ i*tmpVal + j ] - yA[ j - m_numHubs] ;
02991 }
02992
02993
02994 }
02995
02996
02997
02998 for(j = i + 1; j < m_numNodes; j++){
02999
03000
03001 if(j < m_numHubs){
03002
03003 m_rc[k][ kount++] = l*m_cost[k][ i*tmpVal + j - 1 ];
03004
03005 } else {
03006
03007
03008 m_rc[k][ kount++] = l*m_cost[k][ i*tmpVal + j - 1 ] - yA[ j - m_numHubs ];
03009
03010 }
03011
03012 }
03013
03014
03015 }
03016
03017
03018 }
03019
03020
03021 }
03022
03023
03024
03025
03026 int startPnt ;
03027
03028 for(i = 0; i < m_numBmatrixCon; i++){
03029
03030
03031
03032 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
03033
03034
03035
03036 for(k = 0; k < m_numHubs; k++){
03037
03038
03039 for(l = 1; l <= m_upperBoundL[ k]; l++){
03040
03041
03042 startPnt = (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
03043
03044 m_rc[ k][ startPnt + m_Bmatrix[ j] ] -= yB[ i];
03045
03046 }
03047
03048 }
03049
03050
03051 }
03052
03053 }
03054
03055 }
03056
03057
03058 void OSBearcatSolverXkij::createVariableNames( ){
03059
03060 int i;
03061 int j;
03062 int kount;
03063
03064 kount = 0;
03065
03066 for(i = 0; i< m_numNodes; i++){
03067
03068
03069 for(j = 0; j < i; j++){
03070
03071 m_variableNames[ kount] = makeStringFromInt2("x(" , i);
03072 m_variableNames[ kount] += makeStringFromInt2( "," , j);
03073 m_variableNames[ kount] += ")";
03074
03075
03076 kount++;
03077
03078 }
03079
03080 for(j = i + 1; j < m_numNodes; j++){
03081
03082 m_variableNames[ kount] = makeStringFromInt2("x(" , i);
03083 m_variableNames[ kount] += makeStringFromInt2( "," , j);
03084 m_variableNames[ kount] += ")";
03085
03086
03087 kount++;
03088
03089 }
03090
03091
03092 }
03093 }
03094
03095 void OSBearcatSolverXkij::createAmatrix(){
03096
03097
03098
03099
03100
03101
03102
03103 int i;
03104 int j;
03105 int numNonz;
03106
03107
03108 m_pntAmatrix[ 0] = 0;
03109 numNonz = 0;
03110
03111 for(j = m_numHubs; j < m_numNodes; j++){
03112
03113
03114 for(i = 0; i < j; i++){
03115
03116 m_Amatrix[ numNonz++] = i*(m_numNodes - 1) + j - 1 ;
03117
03118 }
03119
03120 for(i = j + 1; i < m_numNodes; i++){
03121
03122 m_Amatrix[ numNonz++] = i*(m_numNodes - 1) + j ;
03123
03124 }
03125
03126 m_pntAmatrix[ j - m_numHubs + 1] = numNonz;
03127
03128 }
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142 }
03143
03144 void OSBearcatSolverXkij::pauHana( std::vector<int> &m_zOptIndexes, int numNodes, int numColsGen){
03145
03146 std::cout << std::endl;
03147 std::cout << " PAU HANA TIME! " << std::endl;
03148 double cost;
03149 cost = 0;
03150 std::vector<int>::iterator vit;
03151 try{
03152 int i;
03153 int j;
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170 for(vit = m_zOptIndexes.begin() ; vit != m_zOptIndexes.end(); vit++){
03171
03172 i = *vit;
03173 std::cout << "x variables for column " << i << std::endl;
03174
03175 cost += m_thetaCost[ i ];
03176
03177 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
03178
03179 std::cout << "INDEX = " << m_thetaIndex[ j] << std::endl;
03180 std::cout << m_variableNames[ m_thetaIndex[ j] ] << " = " << 1 << std::endl;
03181
03182 }
03183
03184 }
03185
03186
03187 std::cout << "cost = " << cost << std::endl << std::endl;
03188
03189 std::cout << std::endl << std::endl;
03190 std::cout << "LOWER BOUND VALUE = " << m_bestLPValue << std::endl;
03191 std::cout << "FINAL BEST IP SOLUTION VALUE = " << m_bestIPValue << std::endl;
03192 std::cout << "NUMBER OF COLUMNS IN FINAL MASTER = " << m_numThetaVar << std::endl;
03193
03194
03195 std::cout << "NUMBER OF GENERATED COLUMNS = " << numColsGen << std::endl;
03196 std::cout << "NUMBER OF GENERATED CUTS = " << m_numBmatrixCon << std::endl;
03197 std::cout << "NUMBER OF NODES = " << numNodes << std::endl;
03198 std::cout << " PAU!!!" << std::endl;
03199
03200 std::cout << std::endl << std::endl;
03201
03202
03203
03204
03205 std::cout << std::endl << std::endl;
03206 }catch (const ErrorClass& eclass) {
03207
03208 throw ErrorClass(eclass.errormsg);
03209
03210 }
03211
03212 }
03213
03214
03215 OSInstance* OSBearcatSolverXkij::getSeparationInstance(){
03216
03217
03218
03219
03220 m_osinstanceSeparation = NULL;
03221
03222
03223
03224
03225 int kountNonz;
03226 int kount;
03227 int startsIdx;
03228
03229 int numYvar = (m_numNodes - m_numHubs)*(m_numNodes - m_numHubs - 1);
03230 int numVvar = m_numNodes - m_numHubs;
03231
03232 int numCon = (m_numNodes - m_numHubs) + (m_numNodes - m_numHubs)*(m_numNodes - m_numHubs - 1)/2 + 1;
03233 double *values = new double[ 2*numYvar + 2*numVvar];
03234 int *indexes = new int[ 2*numYvar + 2*numVvar];
03235 int *starts = new int[ numYvar + numVvar + 1];
03236 starts[ 0] = 0;
03237 startsIdx = 0;
03238 startsIdx++;
03239 kountNonz = 0;
03240 int i;
03241 int j;
03242
03243
03244 std::string separationVarName;
03245 std::string separationConName;
03246
03247 try {
03248
03249 m_osinstanceSeparation = new OSInstance();
03250
03251
03252
03253 m_osinstanceSeparation->setInstanceDescription("The Tour Breaking Separation Problem");
03254
03255
03256
03257 m_osinstanceSeparation->setConstraintNumber( numCon);
03258
03259
03260
03261 for( i = 0; i < m_numNodes - m_numHubs ; i++){
03262
03263 m_osinstanceSeparation->addConstraint(i, makeStringFromInt2("nodeRow_", i+ m_numHubs ) , 0.0, 1.0, 0);
03264
03265 }
03266
03267
03268
03269 int rowKounter;
03270 rowKounter = m_numNodes - m_numHubs;
03271
03272 for(i = m_numHubs; i < m_numNodes; i++){
03273
03274
03275
03276 for(j = i+1; j < m_numNodes; j++){
03277 separationConName = makeStringFromInt2("Row_(", i);
03278 separationConName += makeStringFromInt2(",", j);
03279 separationConName += ")";
03280
03281 m_osinstanceSeparation->addConstraint(rowKounter++, separationConName , 0, 0, 0);
03282 }
03283
03284 }
03285
03286
03287 m_osinstanceSeparation->addConstraint(rowKounter++, "kludgeRow" , 0, m_numNodes, 0);
03288
03289
03290 m_osinstanceSeparation->setVariableNumber( numYvar + numVvar);
03291
03292
03293
03294 std::cout << "NUMBER OF VARIABLES SET = " << numYvar + numVvar << std::endl;
03295
03296 for(i = 0; i < numVvar; i++){
03297
03298 separationVarName = makeStringFromInt2("v", i + m_numHubs);
03299
03300 m_osinstanceSeparation->addVariable(i, separationVarName, 0, 1, 'C');
03301
03302 values[ kountNonz ] = -1.0;
03303 indexes[ kountNonz ] = i;
03304 kountNonz++;
03305
03306 values[ kountNonz ] = 1.0;
03307 indexes[ kountNonz ] = rowKounter - 1;
03308 kountNonz++;
03309
03310
03311
03312 starts[ startsIdx++ ] = kountNonz;
03313
03314
03315 }
03316
03317 kount = numVvar;
03318
03319 int i1;
03320 int j1;
03321 int kountCon;
03322 kountCon = m_numNodes - m_numHubs;
03323
03324 for(i1 = 0; i1 < m_numNodes - m_numHubs; i1++){
03325
03326
03327 i = i1 + m_numHubs;
03328
03329 for(j1 = i1 + 1; j1 < m_numNodes - m_numHubs; j1++){
03330
03331
03332 j = j1 + m_numHubs;
03333
03334 separationVarName = makeStringFromInt2("y(", i);
03335 separationVarName += makeStringFromInt2(",", j);
03336 separationVarName += ")";
03337 m_osinstanceSeparation->addVariable(kount++, separationVarName, 0, 1, 'C');
03338
03339
03340
03341
03342 m_separationIndexMap[ i*(m_numNodes - 1) + (j - 1) ] = kountCon;
03343
03344 values[ kountNonz ] = 1.0;
03345 indexes[ kountNonz ] = i1;
03346 kountNonz++;
03347
03348 values[ kountNonz ] = -1.0;
03349 indexes[ kountNonz ] = kountCon ;
03350 kountNonz++;
03351
03352 starts[ startsIdx++ ] = kountNonz;
03353
03354
03355
03356
03357 separationVarName = makeStringFromInt2("y(", j );
03358 separationVarName += makeStringFromInt2(",", i);
03359 separationVarName += ")";
03360 m_osinstanceSeparation->addVariable(kount++, separationVarName, 0, 1, 'C');
03361
03362 values[ kountNonz ] = 1.0;
03363 indexes[ kountNonz ] = j1;
03364 kountNonz++;
03365
03366
03367 m_separationIndexMap[ j*(m_numNodes - 1) + i ] = kountCon;
03368
03369 values[ kountNonz ] = -1.0;
03370 indexes[ kountNonz ] = kountCon ;
03371 kountNonz++;
03372
03373 starts[ startsIdx++ ] = kountNonz;
03374
03375
03376 kountCon++;
03377
03378
03379 }
03380
03381 }
03382
03383 std::cout << "NUMBER OF VARIABLES ADDED = " << kount << std::endl;
03384
03385
03386 m_osinstanceSeparation->setObjectiveNumber( 1);
03387 SparseVector *objcoeff = new SparseVector( numVvar);
03388
03389
03390 for(i = 0; i < numVvar; i++){
03391
03392 objcoeff->indexes[ i] = i;
03393 objcoeff->values[ i] = 1.0;
03394
03395 }
03396
03397
03398
03399
03400
03401 m_osinstanceSeparation->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
03402
03403
03404 m_osinstanceSeparation->setLinearConstraintCoefficients(kountNonz , true,
03405 values, 0, kountNonz - 1, indexes, 0, kountNonz - 1, starts, 0, startsIdx);
03406
03407
03408
03409
03410
03411 delete objcoeff;
03412
03413
03414
03415
03416
03417
03418 CoinPackedMatrix* matrix;
03419 bool columnMajor = true;
03420 double maxGap = 0;
03421 matrix = new CoinPackedMatrix(
03422 columnMajor,
03423 columnMajor? m_osinstanceSeparation->getConstraintNumber() : m_osinstanceSeparation->getVariableNumber(),
03424 columnMajor? m_osinstanceSeparation->getVariableNumber() : m_osinstanceSeparation->getConstraintNumber(),
03425 m_osinstanceSeparation->getLinearConstraintCoefficientNumber(),
03426 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->values : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->values,
03427 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->indexes : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->indexes,
03428 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->starts : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->starts,
03429 0, 0, maxGap );
03430
03431 ClpNetworkMatrix network( *matrix);
03432
03433 m_separationClpModel = new ClpSimplex();
03434
03435
03436 m_separationClpModel->setOptimizationDirection( 1);
03437 m_separationClpModel->loadProblem( network, m_osinstanceSeparation->getVariableLowerBounds(),
03438 m_osinstanceSeparation->getVariableUpperBounds(),
03439 m_osinstanceSeparation->getDenseObjectiveCoefficients()[0],
03440 m_osinstanceSeparation->getConstraintLowerBounds(), m_osinstanceSeparation->getConstraintUpperBounds()
03441 );
03442
03443 m_separationClpModel->factorization()->maximumPivots(200 + m_separationClpModel->numberRows() / 100);
03444
03445
03446 delete matrix;
03447
03448 }catch (const ErrorClass& eclass) {
03449
03450 throw ErrorClass(eclass.errormsg);
03451
03452 }
03453
03454 return NULL;
03455 }
03456
03457
03458
03459 int OSBearcatSolverXkij::getBranchingVar(const double* theta, const int numThetaVar ) {
03460
03461 int varIdx;
03462 varIdx = -1;
03463 int i;
03464 int j;
03465 int numVar = m_numNodes*m_numNodes - m_numHubs ;
03466
03467 double from1Distance;
03468 double from0Distance;
03469 double fraction;
03470 double minFraction;
03471
03472 double *xvalues;
03473
03474
03475 xvalues = new double[ numVar];
03476 for(i = 0; i < numVar; i++){
03477 xvalues[ i] = 0;
03478 }
03479
03480 try{
03481 if(numThetaVar != m_numThetaVar) throw ErrorClass("inconsistent number of variables in getBranchingVar");
03482
03483 for(i = 0; i < m_numThetaVar; i++){
03484
03485 if( ( theta[ i ] > m_osDecompParam.zeroTol ) && ( theta[ i ] < 1 - m_osDecompParam.zeroTol ) ){
03486
03487 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
03488
03489 xvalues[ m_thetaIndex[ j] ] += theta[ i ] ;
03490
03491 }
03492
03493 }
03494
03495
03496 }
03497
03498
03499 minFraction = 1.0;
03500
03501
03502 for(i = 0; i < m_numHubs; i++){
03503
03504 for( j = 0; j < i; j++){
03505
03506
03507 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
03508 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
03509 fraction = std::max(from1Distance, from0Distance);
03510
03511 if(fraction < minFraction){
03512
03513 minFraction = fraction;
03514 varIdx = i*(m_numNodes - 1) + j;
03515 }
03516
03517 }
03518
03519 for(j = i + 1; j < m_numNodes; j++){
03520
03521
03522
03523 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
03524 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
03525 fraction = std::max(from1Distance, from0Distance);
03526
03527 if(fraction < minFraction) {
03528
03529 minFraction = fraction;
03530 varIdx = i*(m_numNodes - 1) + j - 1;
03531 }
03532
03533
03534 }
03535
03536 }
03537
03538
03539
03540 if(minFraction > 1 - m_osDecompParam.zeroTol){
03541
03542 for(i = m_numHubs; i < m_numNodes; i++){
03543
03544 for( j = 0; j < i; j++){
03545
03546
03547 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
03548 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
03549 fraction = std::max(from1Distance, from0Distance);
03550
03551 if(fraction < minFraction) {
03552
03553 minFraction = fraction;
03554 varIdx = i*(m_numNodes - 1) + j ;
03555 }
03556
03557 }
03558
03559 for(j = i + 1; j < m_numNodes; j++){
03560
03561
03562
03563 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
03564 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
03565 fraction = std::max(from1Distance, from0Distance);
03566
03567 if(fraction < minFraction) {
03568
03569 minFraction = fraction;
03570 varIdx = i*(m_numNodes - 1) + j - 1;
03571 }
03572
03573 }
03574
03575 }
03576
03577 }
03578 std::cout << " HERE IS GAIL 1" << std::endl;
03579
03580
03581
03582 delete[] xvalues;
03583 std::cout << " HERE IS GAIL 2" << std::endl;
03584 xvalues = NULL;
03585
03586 return varIdx;
03587
03588 }catch (const ErrorClass& eclass) {
03589
03590 delete[] xvalues;
03591 xvalues = NULL;
03592
03593 throw ErrorClass(eclass.errormsg);
03594
03595 }
03596
03597
03598 }
03599
03600
03601
03602 int OSBearcatSolverXkij::getBranchingVar(const int* thetaIdx, const double* theta,
03603 const int numThetaVar) {
03604
03605 int varIdx;
03606 varIdx = -1;
03607 int i;
03608 int j;
03609 int numVar = m_numNodes*m_numNodes - m_numHubs ;
03610 double from1Distance;
03611 double from0Distance;
03612 double fraction;
03613 double minFraction;
03614
03615 double *xvalues;
03616
03617
03618 xvalues = new double[ numVar];
03619 for(i = 0; i < numVar; i++){
03620 xvalues[ i] = 0;
03621 }
03622
03623 try{
03624
03625
03626 for(i = 0; i < numThetaVar; i++){
03627
03628 if( ( theta[ i ] > m_osDecompParam.zeroTol ) && ( theta[ i ] < 1 - m_osDecompParam.zeroTol ) ){
03629
03630 for(j = m_thetaPnt[ thetaIdx[ i] ]; j < m_thetaPnt[ thetaIdx[ i] + 1] ; j++){
03631
03632 xvalues[ m_thetaIndex[ j] ] += theta[ i ] ;
03633
03634 }
03635
03636 }
03637
03638
03639 }
03640
03641
03642
03643 minFraction = 1.0;
03644
03645
03646 for(i = 0; i < m_numHubs; i++){
03647
03648 for( j = 0; j < i; j++){
03649
03650
03651 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
03652 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
03653 fraction = std::max(from1Distance, from0Distance);
03654
03655 if(fraction < minFraction){
03656
03657 minFraction = fraction;
03658 varIdx = i*(m_numNodes - 1) + j;
03659 }
03660
03661 }
03662
03663 for(j = i + 1; j < m_numNodes; j++){
03664
03665
03666
03667 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
03668 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
03669 fraction = std::max(from1Distance, from0Distance);
03670
03671 if(fraction < minFraction) {
03672
03673 minFraction = fraction;
03674 varIdx = i*(m_numNodes - 1) + j - 1;
03675 }
03676
03677
03678 }
03679
03680 }
03681
03682
03683
03684 std::cout << "MIN FRACTION = " << minFraction << std::endl;
03685
03686 if(minFraction > 1 - m_osDecompParam.zeroTol){
03687
03688 for(i = m_numHubs; i < m_numNodes; i++){
03689
03690
03691
03692 for( j = 0; j < i; j++){
03693
03694
03695 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j ];
03696 from0Distance = xvalues[ i*(m_numNodes - 1) + j ];
03697 fraction = std::max(from1Distance, from0Distance);
03698
03699 if(fraction < minFraction) {
03700
03701 minFraction = fraction;
03702 varIdx = i*(m_numNodes - 1) + j ;
03703 }
03704
03705 }
03706
03707 for(j = i + 1; j < m_numNodes; j++){
03708
03709
03710
03711 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j - 1 ];
03712 from0Distance = xvalues[ i*(m_numNodes - 1) + j - 1 ];
03713 fraction = std::max(from1Distance, from0Distance);
03714
03715 if(fraction < minFraction) {
03716
03717 minFraction = fraction;
03718 varIdx = i*(m_numNodes - 1) + j - 1;
03719 }
03720
03721 }
03722
03723 }
03724
03725 }
03726
03727
03728
03729 delete[] xvalues;
03730 xvalues = NULL;
03731
03732 return varIdx;
03733
03734 }catch (const ErrorClass& eclass) {
03735
03736 delete[] xvalues;
03737 xvalues = NULL;
03738
03739 throw ErrorClass(eclass.errormsg);
03740
03741 }
03742
03743
03744 }
03745
03746
03747 void OSBearcatSolverXkij::getBranchingCut(const double* thetaVar, const int numThetaVar,
03748 const std::map<int, int> &varConMap, int &varIdx, int &numNonz,
03749 int* &indexes, double* &values) {
03750
03751
03752 int i;
03753 int j;
03754 int kount;
03755 numNonz = 0;
03756
03757
03758
03759 try{
03760
03761 if(numThetaVar != m_numThetaVar) throw ErrorClass("inconsistent number of variables in getBranchingCut");
03762
03763
03764 varIdx = getBranchingVar(thetaVar, numThetaVar );
03765
03766 std::cout << "Branching on Variable: " << m_variableNames[ varIdx] << std::endl;
03767
03768
03769
03770
03771 if( varConMap.find( varIdx) == varConMap.end() ){
03772
03773 for(i = 0; i < m_numThetaVar; i++){
03774
03775 kount = 0;
03776
03777 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
03778
03779 if ( m_thetaIndex[ j] == varIdx) kount++ ;
03780
03781 }
03782
03783
03784
03785 if(kount > 0){
03786
03787 branchCutIndexes[ numNonz] = i;
03788 branchCutValues[ numNonz++] = kount ;
03789
03790 }
03791
03792 }
03793
03794
03795
03796 m_Bmatrix[ m_numBmatrixNonz++] = varIdx;
03797 m_numBmatrixCon++;
03798 m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
03799
03800
03801
03802
03803 m_numThetaVar++;
03804 convexityRowIndex[ m_numThetaVar] = -1;
03805 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
03806
03807
03808
03809
03810 }
03811
03812
03813
03814 indexes = branchCutIndexes;
03815 values = branchCutValues;
03816
03817 return;
03818
03819 }catch (const ErrorClass& eclass) {
03820
03821 throw ErrorClass(eclass.errormsg);
03822
03823 }
03824
03825 }
03826
03827
03828 void OSBearcatSolverXkij::getBranchingCut(const int* thetaIdx, const double* thetaVar,
03829 const int numThetaVar, const std::map<int, int> &varConMap,
03830 int &varIdx, int &numNonz, int* &indexes, double* &values) {
03831
03832
03833 int i;
03834 int j;
03835 int kount;
03836 numNonz = 0;
03837
03838
03839
03840 try{
03841
03842
03843
03844 varIdx = getBranchingVar(thetaIdx, thetaVar, numThetaVar );
03845
03846 std::cout << "Branching on Variable: " << m_variableNames[ varIdx] << std::endl;
03847
03848
03849
03850
03851 if( varConMap.find( varIdx) == varConMap.end() ){
03852
03853
03854
03855
03856
03857
03858 for(i = 0; i < m_numThetaVar; i++){
03859
03860 kount = 0;
03861
03862 for(j = m_thetaPnt[ i]; j < m_thetaPnt[ i + 1] ; j++){
03863
03864 if ( m_thetaIndex[ j] == varIdx) kount++ ;
03865
03866 }
03867
03868
03869
03870 if(kount > 0){
03871
03872 branchCutIndexes[ numNonz] = i;
03873 branchCutValues[ numNonz++] = kount ;
03874
03875 }
03876
03877 }
03878
03879
03880
03881 m_Bmatrix[ m_numBmatrixNonz++] = varIdx;
03882 m_numBmatrixCon++;
03883 m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
03884
03885
03886
03887
03888 m_numThetaVar++;
03889 convexityRowIndex[ m_numThetaVar] = -1;
03890 m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
03891
03892
03893
03894
03895 }
03896
03897
03898
03899 indexes = branchCutIndexes;
03900 values = branchCutValues;
03901
03902 return;
03903
03904 }catch (const ErrorClass& eclass) {
03905
03906 throw ErrorClass(eclass.errormsg);
03907
03908 }
03909
03910 }
03911
03912
03913 void OSBearcatSolverXkij::getInitialSolution(){
03914
03915 try{
03916
03917
03918
03919
03920
03921 if(m_initSolMap.size() == 0) getOptions( m_osoption);
03922
03923
03924
03925
03926
03927
03928
03929 }catch (const ErrorClass& eclass) {
03930
03931 throw ErrorClass(eclass.errormsg);
03932
03933 }
03934
03935
03936 }
03937
03938
03939 void OSBearcatSolverXkij::resetMaster( std::map<int, int> &inVars, OsiSolverInterface *si){
03940
03941 int i;
03942 int j;
03943
03944 int kount;
03945 int numNonz;
03946
03947 std::map<int, int>::iterator mit;
03948
03949 int numVars = inVars.size();
03950 int numVarArt;
03951
03952
03953
03954 numVarArt = m_numNodes + m_numBmatrixCon;
03955
03956
03957 std::vector<double> valuesVec;
03958 double *values = NULL;
03959
03960 std::vector<int> indexesVec;
03961 int *indexes = NULL ;
03962
03963 int *starts = new int[ numVars + 1 + numVarArt];
03964
03965 int startsIdx;
03966
03967
03968
03969
03970 int* thetaPntTmp;
03971 int* thetaIndexTmp;
03972 int* tmpConvexity = new int[ m_numThetaVar];
03973
03974
03975 numNonz = 0;
03976
03977 for(mit = inVars.begin(); mit != inVars.end(); mit++){
03978
03979 numNonz += m_thetaPnt[mit->first + 1 ] - m_thetaPnt[ mit->first ];
03980 }
03981
03982
03983 thetaPntTmp = new int[ numVars + 1];
03984 thetaIndexTmp = new int[ numNonz];
03985
03986
03987
03988 for(mit = inVars.begin(); mit != inVars.end(); mit++){
03989
03990
03991
03992 if( convexityRowIndex[ mit->first] == -1) throw ErrorClass( "we have an artificial variable in reset master");
03993
03994
03995 }
03996
03997
03998 kount = 0;
03999 numNonz = 0;
04000 thetaPntTmp[ kount] = 0;
04001
04002 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04003
04004
04005
04006 kount++;
04007
04008 for(i = m_thetaPnt[ mit->first ]; i < m_thetaPnt[mit->first + 1 ]; i++){
04009
04010 thetaIndexTmp[ numNonz++] = m_thetaIndex[ i];
04011
04012
04013
04014 }
04015
04016 thetaPntTmp[ kount] = numNonz;
04017
04018
04019
04020
04021
04022 inVars[ mit->first] = numVarArt + kount - 1 ;
04023
04024 }
04025
04026
04027
04028
04029
04030
04031
04032 for(i = 0; i < m_numThetaVar; i++) tmpConvexity[ i] = convexityRowIndex[ i];
04033
04034
04035
04036 m_numThetaVar = 0;
04037 m_numThetaNonz = 0;
04038 for(i = 0; i < numVarArt; i++){
04039
04040 convexityRowIndex[ m_numThetaVar] = -1;
04041 m_thetaPnt[ m_numThetaVar++] = 0;
04042
04043
04044 }
04045
04046
04047 intVarSet.clear();
04048 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04049
04050
04051 intVarSet.insert ( std::pair<int,double>(mit->second, 1.0) );
04052
04053
04054
04055
04056 convexityRowIndex[ m_numThetaVar] = tmpConvexity[ mit->first];
04057
04058 m_thetaPnt[ m_numThetaVar++ ] = m_numThetaNonz;
04059
04060 for(j = thetaPntTmp[ mit->second - numVarArt]; j < thetaPntTmp[ mit->second - numVarArt + 1 ]; j++){
04061
04062
04063 m_thetaIndex[ m_numThetaNonz ] = thetaIndexTmp[ m_numThetaNonz] ;
04064 m_numThetaNonz++;
04065
04066 }
04067
04068 }
04069
04070 m_thetaPnt[ m_numThetaVar ] = m_numThetaNonz;
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080 si->writeLp( "gailTest" );
04081
04082
04083
04084
04085
04086 numNonz = 0;
04087 startsIdx = 0;
04088 starts[ startsIdx++] = numNonz;
04089
04090 for(i = 0; i < numVarArt; i++){
04091 numNonz++;
04092 starts[ startsIdx++] = numNonz;
04093 valuesVec.push_back( 1.0);
04094 indexesVec.push_back( i);
04095
04096 }
04097
04098
04099 int rowCount;
04100
04101 int numAmatrixRows;
04102 numAmatrixRows = m_numNodes - m_numHubs;
04103
04104 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04105
04106
04107 valuesVec.push_back( 1.0);
04108 indexesVec.push_back( numAmatrixRows + convexityRowIndex[ mit->second] );
04109
04110 numNonz++;
04111
04112 for(j = m_thetaPnt[ mit->second ]; j < m_thetaPnt[ mit->second + 1 ]; j++){
04113
04114 m_tmpScatterArray[ m_thetaIndex[ j] ]++;
04115
04116
04117
04118 }
04119
04120
04121
04122
04123 for(i = 0; i < numAmatrixRows; i++){
04124
04125 rowCount = 0;
04126
04127 for(j = m_pntAmatrix[ i]; j < m_pntAmatrix[ i + 1]; j++){
04128
04129
04130
04131
04132 rowCount += m_tmpScatterArray[ m_Amatrix[ j] ];
04133
04134
04135 }
04136
04137 if(rowCount > 0){
04138
04139 numNonz++;
04140
04141
04142 valuesVec.push_back( rowCount);
04143 indexesVec.push_back( i);
04144
04145
04146 }
04147
04148
04149 }
04150
04151
04152
04153 for(i = 0; i < m_numBmatrixCon; i++){
04154
04155 rowCount = 0;
04156
04157 for(j = m_pntBmatrix[ i]; j < m_pntBmatrix[ i + 1]; j++){
04158
04159
04160
04161
04162 rowCount += m_tmpScatterArray[ m_Bmatrix[ j] ];
04163
04164
04165 }
04166
04167 if(rowCount > 0){
04168 numNonz++;
04169
04170
04171
04172 valuesVec.push_back( rowCount);
04173 indexesVec.push_back( i + m_numNodes);
04174 }
04175
04176
04177 }
04178
04179
04180
04181
04182 for(j = m_thetaPnt[ mit->second ]; j < m_thetaPnt[ mit->second + 1 ]; j++){
04183
04184 m_tmpScatterArray[ m_thetaIndex[ j] ] = 0;
04185
04186 }
04187
04188 starts[ startsIdx++] = numNonz;
04189
04190 }
04191
04192
04193
04194 values = new double[ numNonz];
04195 indexes = new int[ numNonz];
04196
04197 if(numNonz != valuesVec.size() ) throw ErrorClass("dimension problem in reset");
04198 if(numNonz != indexesVec.size() ) throw ErrorClass("dimension problem in reset");
04199
04200 for(i = 0; i < numNonz; i++){
04201
04202 values[ i] = valuesVec[i];
04203 indexes[ i] = indexesVec[i];
04204
04205 }
04206
04207
04208
04209
04210
04211
04212
04213 delete m_osinstanceMaster;
04214 m_osinstanceMaster = NULL;
04215
04216
04217 m_osinstanceMaster = new OSInstance();
04218 m_osinstanceMaster->setInstanceDescription("The Restricted Master");
04219
04220
04221
04222 m_osinstanceMaster->setVariableNumber( numVars + numVarArt );
04223
04224
04225
04226
04227 SparseVector *objcoeff = new SparseVector( numVars + numVarArt);
04228
04229
04230
04231
04232 m_osinstanceMaster->setConstraintNumber( m_numNodes + m_numBmatrixCon);
04233
04234
04235
04236
04237 int varNumber;
04238 varNumber = 0;
04239
04240
04241
04242 for(i = 0; i < numVarArt; i++){
04243
04244 objcoeff->indexes[ varNumber ] = varNumber ;
04245
04246 objcoeff->values[ varNumber ] = m_osDecompParam.artVarCoeff;
04247
04248 m_thetaCost[ varNumber] = m_osDecompParam.artVarCoeff;
04249
04250 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt2("x", i ) ,
04251 0, 1.0, 'C');
04252
04253
04254 }
04255
04256
04257 kount = 0;
04258 for(mit = inVars.begin(); mit != inVars.end(); mit++){
04259
04260 objcoeff->indexes[ varNumber ] = varNumber ;
04261
04262 objcoeff->values[ varNumber ] = si->getObjCoefficients()[ mit->first] ;
04263
04264 m_thetaCost[ varNumber] = si->getObjCoefficients()[ mit->first];
04265
04266 m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt2("x", kount + numVarArt ) ,
04267 0, 1.0, 'C');
04268
04269 kount++;
04270
04271
04272
04273 }
04274
04275
04276
04277 for(i = 0; i < m_numNodes; i++){
04278
04279 m_osinstanceMaster->addConstraint(i, makeStringFromInt2("con", i),
04280 1.0, 1.0, 0);
04281
04282 }
04283
04284
04285 for(i = m_numNodes; i < m_numBmatrixCon + m_numNodes; i++){
04286
04287 m_osinstanceMaster->addConstraint(i, makeStringFromInt2("con", i),
04288 si->getRowLower()[ i], si->getRowUpper()[ i], 0);
04289
04290
04291 }
04292
04293
04294
04295 m_osinstanceMaster->setObjectiveNumber( 1);
04296 m_osinstanceMaster->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
04297
04298
04299 m_osinstanceMaster->setLinearConstraintCoefficients(numNonz , true,
04300 values, 0, numNonz - 1, indexes, 0, numNonz - 1, starts, 0, startsIdx);
04301
04302
04303
04304
04305
04306 delete[] tmpConvexity;
04307 tmpConvexity = NULL;
04308 delete[] thetaPntTmp;
04309 thetaPntTmp = NULL;
04310 delete[] thetaIndexTmp;
04311 thetaIndexTmp = NULL;
04312 delete objcoeff;
04313 objcoeff = NULL;
04314 }
04315
04316
04317
04318 std::string makeStringFromInt2(std::string theString, int theInt){
04319 ostringstream outStr;
04320 outStr << theString;
04321 outStr << theInt;
04322 return outStr.str();
04323 }
04324
04325
04326
04327
04328