/home/coin/SVN-release/OS-2.4.1/OS/applications/columnGen/code/OSBearcatSolverXkij.cpp

Go to the documentation of this file.
00001 /* $Id: OSBearcatSolverXkij.cpp 3038 2009-11-07 11:43:44Z kmartin $ */
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 }//end default OSBearcatSolverXkij constructor
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 }//end OSBearcatSolverXkijDestructor
00103 
00104 void OSBearcatSolverXkij::initializeDataStructures(){
00105         
00106         int k;
00107         int i;
00108         int l;
00109         
00110         try{
00111                 
00112 
00113                 //get all the parameter values
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                         //set m_upperBoundL cannot exceed total demand
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                 //m_varIdx = new int[ m_numNodes];
00132                 // I think we can make this the max of  m_upperBoundL
00133                 // over the k
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                         //kipp we can use the biggest possible m_upperBoundL
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                 //outer dynamic programming arrays
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                         //allocate memory for the reduced cost vector. 
00194                         //assume order is k, l, i, j
00195                         //assume order is l, i, j
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                 //these are constraints that say we must be incident to each
00208                 //non-hub node -- there are  m_numNodes - m_numHubs of these
00209                 m_pntAmatrix = new int[ m_numNodes - m_numHubs + 1];
00210                 //the variables -- the variable space we are in is x_{ij} NOT
00211                 // x_{ijk} -- a bit tricky
00212                 //m_Amatrix[ j] is a variable index -- this logic works
00213                 //since the Amatrix coefficient is 1 -- we don't need a value
00214                 //it indexes variable that points into the node
00215                 m_Amatrix = new  int[ (m_numNodes - m_numHubs)*(m_numNodes - 1) ];
00216                 createAmatrix();
00217                 
00218                 //this has size of the number of x variables
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                 //New column arrays
00228                 m_newColumnNonz = new int[ m_numHubs] ; //at most one column per Hub
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                         //size of arrray is maximum number of constraints
00235                         // 1) coupling + 2) tour breaking + 3) branching
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                 //New row arrays
00244                 m_newRowNonz = new int[ m_numHubs] ; //at most one cut per Hub
00245                 m_newRowColumnIdx = new int*[ m_numHubs] ; //at most one cut per Hub
00246                 m_newRowColumnValue = new double*[ m_numHubs] ; //at most one cut per Hub
00247                 m_newRowUB = new double[ m_numHubs]; //at most one cut per Hub
00248                 m_newRowLB = new double[ m_numHubs]; //at most one cut per Hub
00249                 
00250 
00251                 //for now, the number of columns will be m_maxMasterColumns     
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                 //new array for keeping track of convexity rows
00260                 convexityRowIndex = new int[ m_maxMasterColumns];
00261                 //new arrays for branches
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                 //the number of cuts will be at most nubmer of tour 
00278                 // breaking constraints + braching variable cuts
00279                 // branching variable constraints = m_numNodes*(m_numNodes - 1)
00280                 m_pntBmatrix = new int[ m_maxBmatrixCon];
00281                 // number of nonzeros in the Bmatrix
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                 //kipp -- move this later
00302                 getSeparationInstance();
00303         } catch (const ErrorClass& eclass) {
00304 
00305                 throw ErrorClass(eclass.errormsg);
00306 
00307         }       
00308         
00309         
00310 }//end initializeDataStructures
00311 
00312 
00313 OSBearcatSolverXkij::~OSBearcatSolverXkij(){
00314         
00315         std::cout << "INSIDE ~OSBearcatSolverXkij DESTRUCTOR" << std::endl;
00316 
00317 
00318         
00319         //delete data structures for arrays used in calculating minimum reduced cost
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                 //std::cout << "I AM DELETING m_demand" << std::endl;
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         //getCut arrays
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         //garbage collection on row arrays
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 }//end ~OSBearcatSolverXkij
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 void OSBearcatSolverXkij::getOptL( double** c) {
00505         
00506         //initialize the first HUB
00507         
00508         int k;
00509         int d;
00510         int d1;
00511         int kountVar;
00512         double testVal;
00513         int l;
00514         //int startPntInc;
00515         double trueMin;
00516         
00517         bool isFeasible;
00518         isFeasible = false;
00519         
00520         kountVar = 0;
00521         //startPntInc = m_upperBoundL*(m_numNodes*m_numNodes - m_numNodes);
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         //initialize up to last hub
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         //now loop over the other HUBS
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                 //kipp make d the min demand for the previous routes
00549                 for(d = dlower; d <= m_totalDemand; d++){
00550                         
00551                         m_vv[ k][ d] = OSDBL_MAX;
00552                         
00553                         //d1 is the state variable at stage k -1
00554                         for(d1 = 0; d1 <= m_totalDemand; d1++){
00555                         
00556                                 l = d - d1;
00557                                 //kipp make m_upperBoundL the route capapcity
00558                                 if( (m_vv[ k - 1][ d1] < OSDBL_MAX) &&  (l <= m_upperBoundL[ k  - 1]) && (l >= m_lowerBoundL[ k - 1]) ){
00559                                 
00560                                         
00561                                         // l was the decision at state d1 in stage k-1
00562                                         // l + d1 brings us to state d at stage k
00563                                         // d is the total carried on routes 0 -- k-1
00564                                 
00565                                         testVal = qrouteCost(k - 1,  l,  c[ k - 1],  &kountVar);
00566                                         
00567                                         //std::cout << "L = " << l << std::endl;
00568                                         //std::cout << "testVal " << testVal << std::endl;
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                                                 //now point to the best way to get to d
00574                                                 m_vvpnt[ k][ d]  = d1;
00575                                                 
00576                                         }
00577                                         
00578                                         
00579                                 }
00580                                 
00581                         }
00582                         
00583                 }
00584                 
00585                 //c+=  startPntInc ;    
00586                 
00587         }//  end for on k
00588         
00589         trueMin = OSDBL_MAX;
00590         //we now enter the last stage through the other hubs
00591         // have satisfied total demand d
00592 
00593 
00594         //if (m_numHubs > 1) dlower = 1;
00595         
00596         for(d = dlower; d < m_totalDemand; d++){
00597                 
00598                 //std::cout << "m_vv[ m_numHubs - 1 ][ d]  " << m_vv[ m_numHubs - 1 ][ d]  << std::endl;
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                         //must execute this loop at least once
00604                         
00605                         //std::cout << "LL = " <<  l  << std::endl;
00606                         
00607                         isFeasible = true;
00608                         
00609                         
00610                         testVal = qrouteCost(m_numHubs -1 ,  l,  c[ m_numHubs -1],  &kountVar);
00611                         
00612                         //std::cout << "l = " << l << std::endl;
00613                         //std::cout << "testVal = " << testVal << std::endl;
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         //std::cout << "TRUE MIN = " <<  trueMin << std::endl;
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                 //std::cout << "k = " <<  k << std::endl;
00644                 //std::cout << "m_optD[  k  ]  = " <<  m_optD[  k  ] << std::endl;
00645                 //std::cout << "m_optD[  k -1 ] " << m_optD[  k - 1 ]  << std::endl;
00646                 
00647                 k--;
00648                 
00649                 
00650         }
00651         
00652 }//end getOptL
00653 
00654 
00655 
00656 
00657 
00658 
00659 double OSBearcatSolverXkij::qrouteCost(const int& k, const int& l, const double* c, int* kountVar){
00660         
00661         //critical -- nodes 0, ..., m_numNodes - 1 are the hub nodes
00662         // we are doing the calculation for hub k, k <= m_numNodes - 1
00663         //l  should be the total demand on the network -- we are NOT using 0 based counting
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         //start of the cost vector for hub k plus move to start of l demands
00684         // now move the pointer up
00685         //int startPnt = m_upperBoundL[ k]*(m_numNodes*m_numNodes - m_numNodes) + (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
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         //initialize
00695         bestLastNode = OSINT_MAX;
00696         int i;
00697         int j;
00698         int l1;
00699         int l2;
00700         //for(i = 0; i < 20; i++){
00701         //      std::cout << "i =  " << i  <<  " c[i] = " << *(c + i) << std::endl ;
00702         //}
00703 
00704 
00705 
00706         // l  is the total demand on this network
00707         //address of node (j, i) is j*(m_numNodes-1) + i when i < j
00708         //address of node (j, i) is j*(m_numNodes-1) + i - 1 when i > j
00709         
00710         //
00711         // initialize
00712         
00713         
00714         
00715         for(i = m_numHubs; i < m_numNodes; i++){
00716                 
00717                 
00718                 for(l1 = m_minDemand; l1 <= l; l1++){  //l-1  is total demand on network
00719                         
00720                         m_u[i][l1] = OSDBL_MAX;
00721                         m_v[i][l1] = OSDBL_MAX;
00722                         m_px[i][l1] = -1; //a node we don't have
00723                         if(l1 == *(m_demand + i) ){
00724                                 
00725                                 m_px[i][l1] = k;
00726                                 // want the cost for arc (k, i)
00727                                 // note: k < i so use that formula
00728                                 m_u[i][l1] = *(c + k*(m_numNodes - 1) + i - 1);  // put in correct cost
00729                                 
00730 
00731                 
00732                         }
00733                 }       
00734         }
00735         //end initialize
00736 
00737         //
00738         
00739         //if l = minDemand we visit only one node, let's get the reduced cost in this case
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                                 //std::cout << " m_u[i][l2] = "  << m_u[i][l2] << std::endl;
00750                                 
00751                                 //std::cout << " *(c + i*(m_numNodes-1) + k ) = "  << *(c + i*(m_numNodes-1) + k ) << std::endl;
00752                                 //push node back
00753                                 bestLastNode = i;
00754                         }
00755                         
00756                 }
00757                 
00758                 //go from node bestLastNode to node k           
00759                 //node bestLastNode is a higher number than k
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         }//end if on l == minDemand
00767         
00768 
00769 // now calculate values for demand 2 or greater         
00770         //address of node (j, i) is j*(m_numNodes-1) + i when i < j
00771         //address of node (j, i) is j*(m_numNodes-1) + i - 1 when i > j
00772         // we start l2 at 2 since demand must be at least 1
00773         // change to min demand + 1
00774         int lowerVal = m_minDemand + 1;
00775         for(l2 = lowerVal; l2 <= l; l2++){// loop over possible demand values assuming we have already gone to at least one node
00776                         
00777                 for(i = m_numHubs; i < m_numNodes; i++) { //we are finding least cost to node i
00778                         
00779                         
00780                         if( *(m_demand + i) < l2 ){ // kipp < OR <= ????
00781                                         
00782                                 for(j = m_numHubs; j < i; j++){ //we are coming from node j
00783                                         
00784 
00785                                                 
00786                                         //calculate g  -- l2 - d[ i]  is the demand trough and including node j
00787                                         l1 = l2 - *(m_demand + i);
00788                                         
00789                                         if( m_px[j][ l1 ] != i ){//check to make sure we did not come into j from 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                                         // update u and the pointer for p
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                                 }//end of first for loop on j, j < i
00817                                 
00818                                 
00819                                 for(j = i + 1; j < m_numNodes; j++){ //we are coming from node j
00820                                         
00821                 
00822                                         //calculate g  -- l2 - d[ i]  is the demand trough and including node j
00823                                         l1 = l2 - *(m_demand + i);
00824                                         
00825                                         if( m_px[j][ l1 ] != i ){//check to make sure we did not come into j from 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                                         // update u and the pointer for p
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                                 }//end of second for loop on j, j > i                           
00848                                 
00849                                 
00850                                 //now calculate the second best solution and point
00851                                 //right now m_px[i][l2] points to the best j node
00852                                 
00853                                 for(j =m_numHubs; j < m_numNodes; j++){ //we are coming from node j
00854                                         
00855                                         if(j != i){
00856                                                 
00857                                                 if( (m_g[j][i] < m_v[i][l2] ) && (m_px[i][l2] != j)  ){ // kipp the && gives the second best
00858                                                         
00859                                                 //if( m_g[j][i] < m_v[i][l2] )  {       
00860                                                         
00861                                                         m_v[i][l2] = m_g[j][i];
00862                                                         m_tx[i][l2] = j;        
00863                                                         
00864                                                         
00865                                                 }
00866                                                 
00867                                         }
00868                                         
00869                                         
00870                                 }//end second best calculation, another for loop on j
00871                                 
00872                                 //now if l2 = l  we are done
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                         }//end if on demand less than l2
00886                         
00887                         
00888                 }//i loop
00889                 
00890                 
00891         }//l2 loop
00892 
00893         
00894         //std::cout << "best Last Node = "  << bestLastNode << std::endl;
00895         
00896         // now get the path that gives the reduced cost
00897 
00898         
00899         int currentNode;
00900         int successorNode;
00901         int lvalue;
00902         
00903         //initialize
00904         // we work backwords from bestLastNode
00905         //in our recursion we recurse on the currentNode and assume
00906         //it is in the optimal path
00907         
00908         //node bestLastNode is a higher number than k
00909         *(m_varIdx + (*kountVar)++) = startPnt + bestLastNode*(m_numNodes - 1)  +  k ;
00910         
00911         
00912         //if we are here we should have a value for bestLastNode
00913         //if not return infinity
00914         if( bestLastNode == OSINT_MAX) return OSDBL_MAX;
00915 
00916         //by successor, I mean node after current node in the path
00917         successorNode = k;
00918         currentNode = bestLastNode;
00919         //the lvalue is the demand through the currentNode
00920         lvalue = l ;
00921 
00922 
00923         while(currentNode != k){
00924                 //std::cout << "currentNode = " << currentNode << "   " <<  "lvalue " <<  lvalue << std::endl;
00925                 if( m_px[ currentNode][ lvalue ] != successorNode){
00926                         
00927 
00928                         
00929                         //update nodes
00930                         successorNode = currentNode;
00931                         currentNode = m_px[ currentNode][ lvalue ];
00932                         
00933                         
00934                         if(currentNode - successorNode > 0){
00935                                  //below diagonal
00936 
00937                                 *(m_varIdx  + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1)  +  successorNode;
00938 
00939                                 
00940                         }else{
00941                                  //above diagonal
00942 
00943                                 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1)  +  successorNode  - 1 ;
00944 
00945                         }
00946 
00947                         
00948                 }else{ //take second best
00949                         
00950                         
00951                         //update nodes
00952                         successorNode = currentNode;
00953                         currentNode = m_tx[ currentNode][ lvalue ];
00954                         
00955                         if(currentNode - successorNode > 0){
00956                                  //below diagonal
00957                                 *(m_varIdx  + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1)  +  successorNode;
00958                                 
00959                         }else{
00960                                  //above diagonal
00961                                 *(m_varIdx + (*kountVar)++) = startPnt + currentNode*(m_numNodes - 1)  +  successorNode  - 1 ;
00962                                 
00963                         }
00964                         
00965                 }
00966                 
00967                 //update lvalue
00968                 lvalue = lvalue - *(m_demand + successorNode);
00969         
00970                 
00971 
00972         }//end while
00973 
00974         
00975         //go from node k to bestLastNode -- already done in loop above
00976         //*(m_varIdx + (*kountVar)++) = startPnt + k*(m_numNodes - 1)  +  currentNode - 1;
00977         
00978 
00979         return rcost;
00980         
00981 }//end qroute
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 //first strip of the phi dual values and then the convexity row costs
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                 //get the reduced costs 
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                         //startPntInc  = k*m_upperBoundL*(m_numNodes*m_numNodes - m_numNodes) + (m_optL[ k] - 1)*(m_numNodes*m_numNodes - m_numNodes);
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                         //loop over the rows, scatter each row and figure
01051                         //out the column coefficients in this row
01052                         //first scatter the sparse array m_varIdx[ j]
01053                         
01054                         m_costVec[ k] = 0.0;
01055                         
01056                         for(j = 0; j < kountVar; j++){
01057                                 
01058                                 
01059                                 //we are counting the NUMBER of times the variable used
01060                                 //the same variable can appear more than once in m_varIdx
01061                                 m_tmpScatterArray[ m_varIdx[ j] - startPntInc  ] += 1;
01062                                 
01063                                 // is variable m_varIdx[ j] - startPntInc in this row   
01064                                 
01065                                 m_costVec[ k] += m_cost[k][  m_varIdx[ j] - startPntInc  ];
01066                                 
01067                         }
01068                         
01069                         
01070                         
01071                         numNonz = 0;
01072                         //multiply the sparse array by each A matrix constraint
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                                         //m_Amatrix[ j] is a variable index -- this logic works
01080                                         //since the Amatrix coefficient is 1 -- we don't need a value
01081                                         //it indexes variable that points into the node
01082                                         rowCount += m_tmpScatterArray[  m_Amatrix[ j] ];
01083                                         
01084 
01085                                 }
01086                                 
01087                                 if(rowCount > 0){
01088                                         
01089                                         //std::cout << "GAIL NODE " << i + m_numHubs <<  " COUNT = " << rowCount << std::endl;
01090                                         m_newColumnRowIdx[ k][ numNonz] = i;
01091                                         m_newColumnRowValue[ k][ numNonz] = rowCount;
01092                                         numNonz++;
01093                                 }
01094                                         
01095                                         
01096                         }//end loop on coupling constraints
01097                         
01098                         //add a 1 in the convexity row
01099                         m_newColumnRowIdx[ k][ numNonz] = m_numNodes - m_numHubs + k;
01100                         m_newColumnRowValue[ k][ numNonz++] = 1.0;
01101                         
01102                         
01103                         
01104                         //now multiply the sparse array by each B-matrix constraint
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                                         //m_Bmatrix[ j] is a variable index -- this logic works
01113                                         //since the Bmatrix coefficient is 1 -- we don't need a value
01114                                         //it indexes variable that points into the node
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                         //zero out the scatter vector and store the generated column
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                                 // is variable m_varIdx[ j] - startPntInc in this row   
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                         //stuff for debugging
01158                         //*****************************//
01191                         //**************************//
01192                         //end debugging stuff
01193         
01194                         
01195                 }//end of loop on hubs
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         //set method parameters
01226         numNewColumns = m_numHubs;
01227         lowerBound =  m_lowerBnd;
01228         
01229         std::cout << "LEAVING GET COLUMNS" << std::endl;
01230         return;
01231         
01232 }//end getColumns
01233 
01234 
01235 
01529 OSInstance* OSBearcatSolverXkij::getInitialRestrictedMaster( ){
01530 
01531         
01532         std::cout << "Executing OSBearcatSolverXkij::getInitialRestrictedMaster2( )" << std::endl;
01533         
01534         //this master will have m_numNodes artificial variables
01535         int numVarArt;
01536         //numVarArt = 2*m_numNodes;
01537         numVarArt = m_numNodes;
01538         
01539         //numVarArt = 0;
01540         
01541         // define the classes
01542         FileUtil *fileUtil = NULL;
01543         OSiLReader *osilreader = NULL;
01544         CoinSolver *solver  = NULL;
01545         OSInstance *osinstance = NULL;
01546         // end classes    
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         //std::vector< int> indexes;
01559         fileUtil = new FileUtil();
01560         
01561         m_osinstanceMaster = NULL;
01562         
01563         //add linear constraint coefficients
01564         //number of values will nodes.size() the coefficients in the node constraints
01565         //plus coefficients in convexity constraints which is the number of varaibles
01566         int kountNonz;
01567         int kount;
01568         m_numberOfSolutions = 1;
01569         int numThetaVar = m_numberOfSolutions*m_numHubs;
01570         //the extra  is for the artificial variables
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         //stuff for cut generation
01590         //
01591         double* xVar;
01592         int numXVar;
01593         numXVar = m_numNodes*(m_numNodes - 1);
01594         xVar = new double[ numXVar];
01595         //zero this array out
01596         for(i = 0; i < numXVar; i++){
01597                 
01598                 xVar[ i] = 0;
01599                 
01600         }
01601         //getRows function call return parameters
01602         int numNewRows;
01603         int* numRowNonz = NULL;
01604         int** colIdx = NULL; 
01605         double** rowValues = NULL ; 
01606         double* rowLB;
01607         double* rowUB;
01608         //end of getRows function call return parameters        
01609         //
01610         //end of cut generation stuff
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                         //turn on or off fixing the variables
01625                 
01627                         //set kount to the start of the z variables
01628                         //go past the x variables
01629                         //here is where we fix the z variables
01630                         kount  =  2*m_numHubs + m_numHubs*(m_numNodes*m_numNodes - m_numNodes);
01631                         //if we are using SK's heuristic fix the assignment of nodes to hubs
01632                         if(m_use1OPTstart == true){
01633                                 osinstance->bVariablesModified = true;
01634                                 //get the first solution
01635                                 mit = m_initSolMap.find( 0);
01636                                 for ( mit2 = mit->second.begin() ; mit2 != mit->second.end(); mit2++ ){ //we are looping over routes in solution mit
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                 //fill in the cost vector first
01655                 //the x vector starts at 2*m_numHubs
01656                 
01657                 int idx1;
01658                 int idx2;
01659                 idx2 = 0;  //zRouteDemand have 0 coefficients in obj
01660                 //fill in m_cost from the cost coefficient in osil
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                 //get variable names for checking purposes
01683                 std::string* varNames;
01684                 varNames =  osinstance->getVariableNames();
01685 
01686                 
01687                 //start building the restricted master here
01688                 m_osinstanceMaster = new OSInstance();
01689                 m_osinstanceMaster->setInstanceDescription("The Initial Restricted Master");
01690                 
01691                 // first the variables
01692                 // we have numVarArt] artificial variables 
01693                 m_osinstanceMaster->setVariableNumber( m_numberOfSolutions*m_numHubs + numVarArt);   
01694                 
01695                 // now add the objective function
01696                 m_osinstanceMaster->setObjectiveNumber( 1);
01697                 //add m_numNodes artificial variables
01698                 SparseVector *objcoeff = new SparseVector( m_numberOfSolutions*m_numHubs + numVarArt);   
01699 
01700                 
01701                 // now the constraints
01702                 m_osinstanceMaster->setConstraintNumber( m_numNodes);   
01703                 
01704                 
01705                 
01706                 //add the artificial variables -- they must be first in the model
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                         //if obj too large we get the following error
01718                         //Assertion failed: (fabs(obj[i]) < 1.0e25), function createRim, 
01719                         //file ../../../Clp/src/ClpSimplex.cpp, l
01720                         
01721                         //objcoeff->values[ varNumber ] = OSDBL_MAX;
01722                         
01723                         //objcoeff->values[ varNumber ] = 1.0e24;
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                 for(i = 0; i < m_numNodes; i++){
01741                         
01742                         
01743                         objcoeff->indexes[ varNumber ] = varNumber ;
01744                         
01745                         //if obj too large we get the following error
01746                         //Assertion failed: (fabs(obj[i]) < 1.0e25), function createRim, 
01747                         //file ../../../Clp/src/ClpSimplex.cpp, l
01748                         //objcoeff->values[ varNumber ] = 1.0e24;
01749                         //kipp -- change this number -- even 1.0e24 drives
01750                         //clp crazy and gives infeasible when actually feasible
01751                         objcoeff->values[ varNumber ] =m_osDecompParam.artVarCoeff;
01752                         
01753                         
01754                         
01755                         m_osinstanceMaster->addVariable(varNumber++, makeStringFromInt2("AN", i ) , 
01756                                         0, OSDBL_MAX, 'C');
01757                         
01758                         
01759                         values[ kountNonz] = -1;
01760                         indexes[ kountNonz++] = i ;
01761                         starts[ startsIdx++] = kountNonz;
01762                         
01763                         
01764                         
01765                 }
01766                  */
01767                 
01768                 
01769                 //
01770                 // now get the primal solution
01771                 //solve the model for solution in the osoption object
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                 //get the solver solution status
01785                 
01786                 std::cout << "Solution Status =  " << solver->osresult->getSolutionStatusType( 0 ) << std::endl;
01787                 
01788                 
01789 
01790                 
01791         
01792                 
01793                 //get the optimal objective function value
01794                 
01795                 primalValPair = solver->osresult->getOptimalPrimalVariableValues( 0);
01796 
01797                 //loop over routes again to create master objective coefficients
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                                 //lets get the x variables
01808                                 //the variables for this route should be from 2*numHubs + k*(numNodes - 1*)*(numNodes - 1)
01809                                 idx1 = 2*m_numHubs + k*m_numNodes*(m_numNodes - 1);
01810                                 idx2 = idx1 + m_numNodes*(m_numNodes - 1);
01811                                 //end of x variables
01812                         
01813                                 std::cout << "HUB " <<  k  << " VARIABLES" << std::endl;
01814                                 
01815                                 //generate a cut
01816                                 //need to do index mapping
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                                                 //m_thetaIndex[ m_numThetaNonz++ ] = primalValPair[ i]->idx  -  k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs;
01825                                                 
01826                                                 //scatter operation
01827                                                 xVar[ primalValPair[ i]->idx  -  k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs   ] = primalValPair[ i]->value;
01828                                                 
01829                                                 
01830                                         }       
01831                                 }
01832                                 
01833                                 //get a cut
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                                                 //set the variable indexes to the correct values
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                                 //zero out the vector again
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                                 //std::cout <<  osinstance->getVariableNames()[ k ] << std::endl;
01887                                 //std::cout <<  osinstance->getVariableNames()[ k + m_numHubs ] << std::endl;
01888                                 std::cout << "Optimal Objective Value = " << primalValPair[ k]->value*primalValPair[ k + m_numHubs]->value << std::endl;
01889                                 
01890                                 
01891         
01892                         }//end for on k -- hubs
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                 }//end while -- we have an integer solution with no subtours
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                         //lets get the x variables
01919                         //the variables for this route should be from 2*numHubs + k*(numNodes - 1*)*(numNodes - 1)
01920                         idx1 = 2*m_numHubs + k*m_numNodes*(m_numNodes - 1);
01921                         idx2 = idx1 + m_numNodes*(m_numNodes - 1);
01922                         
01923                         //for(i = idx1; i < idx2; i++){
01924                                 
01925                         //      if(  primalValPair[ i]->value > .1 ){
01926                                         //std::cout <<  osinstance->getVariableNames()[  primalValPair[ i]->idx  ] << std::endl;
01927                                         //std::cout <<  m_variableNames[  primalValPair[ i]->idx  -  k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs  ] << std::endl;
01928                                         //m_thetaIndex[ m_numThetaNonz++ ] = primalValPair[ i]->idx  -  k*(m_numNodes - 1)*m_numNodes - 2*m_numHubs;
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                                         //std::cout <<  osinstance->getVariableNames()[ primalValPair[ idx1 ]->idx]  << " " << primalValPair[ idx1 ]->value  << " " << i1 << " " << j1 << std::endl;
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                                                 // a positive variable pointing into node j1
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                                 }//end of for on j1
01959                                 
01960                                 
01961                                 for(j1 = i1 + 1; j1 < m_numNodes; j1++){
01962                                         
01963                                         //std::cout <<  osinstance->getVariableNames()[ primalValPair[ idx1 ]->idx]  << " " << primalValPair[ idx1 ]->value  << " " << i1 << " " << j1 << std::endl;
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                                                 // a positive variable pointing into node j1
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                                 }//end of for on j1
01984                                 
01985                         }//end of for on i1
01986                         
01987                         
01988                         //now for convexity row  k
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                 }//end of index on k
02017                 
02018                 //add the constraints
02019                 //add the row saying we must visit each node
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                 //add the convexity row
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                 //add the linear constraints coefficients
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                 //exit( 1);
02052                 //delete[] values;
02053                 //values = NULL;
02054                 //delete[] starts;
02055                 //starts = NULL;
02056                 //delete[] indexes;
02057                 //indexes = NULL;
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                 //  Problem with the parser
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 }//end generateInitialRestrictedMaster2
02084 
02085 
02086 
02087 void OSBearcatSolverXkij::getOptions(OSOption *osoption) {
02088         
02089         
02090         std::cout << "Executing getOptions(OSOption *osoption)" << std::endl;
02091         //get any options relevant to OSColGenApp
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                 //iterate over the vector
02108                 
02109                 int tmpVal;
02110                 
02111                 std::string routeString; //variable for parsing a category option
02112                 std::string solutionString; //variable for parsing a category option
02113                 string::size_type pos1; //variable for parsing a category option
02114                 string::size_type pos2; //variable for parsing a category option
02115                 string::size_type pos3; //variable for parsing a category option
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                         //std::cout << (*vit)->name << std::endl;
02128                         
02129                         //(*vit)->name.compare("initialCol") == 0
02130                         //if(rowNames[ i3].find("routeCapacity(1)") == string::npos )
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                                                         //std::cout << "m_minDemand = " << tmpVal <<  std::endl;
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                                                                 //std::cout << "demand = " << tmpVal <<  std::endl;
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                                                                         //std::cout << "m_routeCapacity = " << tmpVal <<  std::endl;
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                                                                                         //std::istringstream buffer( (*vit)->value);
02193                                                                                         //buffer >> m_numberOfSolutions;
02194         
02195                                                                                         //get the block number and solution number
02196                                                                                         //first get routeString and soluionString
02197                                                                                         //parse the category string base on :
02198                                                                                         pos1 = (*vit)->category.find( ":");
02199                                                                                         if(pos1 == std::string::npos ) throw ErrorClass("OSoL category attribute not properly defined");
02200                                                                                         
02201                                                                                         //solutionString = (*vit)->category.substr( pos1 + 1, pos2 - pos1 - 1);
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                                                                                         //std::cout << "solution number = " << solutionNumber  << std::endl;
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                                                                                         //std::cout << "route number = " <<  routeNumber << std::endl;
02218                                                                                         std::istringstream nodeBuffer( (*vit)->value);
02219                                                                                         nodeBuffer >> tmpVal;
02220                                                                                         
02221                                                                                         mit = m_initSolMap.find(  solutionNumber  );
02222                                                                                         
02223                                                                                         if( mit  != m_initSolMap.end() ){
02224                                                                                                 // we have solution from before
02225                                                                                                 // do we have a new route?
02226                                                                                                 
02227                                                                                                 mit2 = mit->second.find( routeNumber);
02228                                                                                                 
02229                                                                                                 if(mit2 != mit->second.end() ){
02230                                                                                                 // we have a route from before and solution from before
02231         
02232                                                                                                         
02233                                                                                                         mit2->second.push_back( tmpVal);
02234                                                                                                         
02235                                                                                                         
02236                                                                                                 }else{
02237                                                                                                         
02238                                                                                                         //we have a new route, but old solution
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                                                                                                 // we have a new solution
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                                                                                 }//if on restricted master solution
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                         }//end if on solver options
02306                         
02307                 }//end for loop on options
02308                 
02309                 
02310                 //now fill in route capacities
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                 //now fill in route min pickups
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                 //now fill in demand            
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                 //kipp -- fill in numberOfRestricedMasterSolutions from map size
02348                  m_numberOfSolutions = m_initSolMap.size();
02349                 
02350         
02351         } catch (const ErrorClass& eclass) {
02352 
02353                 throw ErrorClass(eclass.errormsg);
02354 
02355         }               
02356         
02357 }//end getOptions
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         //critical -- the variables that come in the theta variables
02365         //not the x variables, we must convert to x, find a cut in x-space
02366         //and then convert back to theta
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                 //m_numNodes is the number of artificial variables
02388                 if(numTheta != m_numThetaVar ) throw 
02389                                 ErrorClass("number of master varibles in OSBearcatSolverXkij::getCuts inconsistent");
02390                 
02391                 //for(i = 0; i < numTheta; i++){
02392                 
02393                 //std::cout << "numTheta = " << numTheta << std::endl;
02394                 //std::cout << "m_numThetaVar = " << m_numThetaVar - 1 << std::endl;
02395                 
02396                 //exit( 1);
02397                 
02398                 for(i = 0; i < numTheta; i++){
02399                         
02400                         //get a postive theta
02401                         if(theta[ i] > m_osDecompParam.zeroTol){
02402                                 
02403                                 //get the xij indexes associated with this variable
02404                                 for(j = m_thetaPnt[ i ]; j <  m_thetaPnt[ i + 1 ]; j++ ){
02405                                         
02406                                         //get the xij index 
02407                                         
02408                                         
02409 
02410                                         rowKount = m_separationIndexMap[  m_thetaIndex[ j] ];
02411                                         
02412                                         //std::cout << "rowKount = " << rowKount  <<std::endl;
02413                                         
02414                                         if(rowKount < OSINT_MAX ){
02415                                                 
02416                                                 tmpRhs[ rowKount] -= theta[ i];
02417                                                 
02418                                         }
02419                                         
02420                                 }
02421                         }
02422                 }
02423                 
02424                 
02425                 // don't adjust the kludge row
02426                 
02427                 for(i = indexAdjust; i < numSepRows - 1; i++){
02428                         
02429                         if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
02430                                 // quick and dirty does x_{ij} + x_{ji} <= 1 cut off anything
02431                                 //std::cout << " tmpRhs[ i] =  " << tmpRhs[ i]  << std::endl;
02432                                 //which variable is this 
02433                                 //kipp this an inefficient way of finding i and j -- improve this
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                                                         //std::cout << "i = " << i1 << std::endl;
02444                                                         //std::cout << "j = " << j1 << std::endl;
02445                                                         //okay generate a cut that says
02446                                                         // x(i1,j1) + x(j1, i1) << 1
02447                                                         //get index for i1,j1
02448                                                         m_Bmatrix[   m_numBmatrixNonz++ ] = i1*(m_numNodes - 1) + j1 - 1 ;
02449                                                         //get index for j1,i1
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                                                         //now we have to get the theta column indexes
02461                                                         //scatter the constraint in the x - variables
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                                                                 //get the xij indexes in this column 
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 ){ //count number of xij for theta_i
02485                                                                                 
02486                                                                                 std::cout << " Variable  " << m_variableNames[ m_thetaIndex[ j]  ]  << std::endl;
02487                                                                                 
02488                                                                                 tmpKount++;
02489                                                                                 
02490                                                                         }
02491                                                                         
02492                                                                 }//end loop on j
02493                                                                 
02494                                                                 if(tmpKount > 0){
02495                                                                         //theta_i has a nonzero coefficient in this row
02496                                                                         
02497                                                                         m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = k ;
02498                                                                         //m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02499                                                                         m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02500                                                                          
02501                                                                         
02502                                                                 }
02503                                                                 
02504                                                         }//end loop on k
02505                                                         
02506                                                         
02507                                                         //zero out the scatter array again
02508                                                         
02509                                                         //::cout << " m_numBmatrixCon  - 1  " << m_numBmatrixCon  - 1  << std::endl;
02510                                                         //std::cout << " m_pntBmatrix[  m_numBmatrixCon  - 1] "  << m_pntBmatrix[  m_numBmatrixCon  - 1] <<  std::endl ;
02511                                                         //std::cout << " m_pntBmatrix[  m_numBmatrixCon  ] "  << m_pntBmatrix[  m_numBmatrixCon  ] <<  std::endl ;
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                                                         //we found a row, add the corresponding artificial variables
02529                                                         //to the transformation matrix
02530                                                         m_numThetaVar++;
02531                                                         convexityRowIndex[ m_numThetaVar] = -1;
02532                                                         m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02533                                                         //m_thetaPnt[ m_numThetaVar++] = m_numThetaNonz;
02534                                                         //m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
02535                                                         
02536                                                         return;                                         
02537                                                         
02538                                                 } //end loop on if tmpKount
02539                                                 
02540                                                 tmpKount++;
02541                                         
02542                                         }//loop on j1
02543                                         
02544                                 }//loop  on i1
02545                         
02546                         
02547                         }//end if on tmpRHS
02548                         
02549                         m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
02550                         m_separationClpModel->setRowLower(i, tmpRhs[ i] );              
02551 
02552                 }//end loop on i
02553                 
02554                 
02555                 //std::cout << m_osinstanceSeparation->printModel() << std::endl;
02556         
02557 
02558                 std::vector<int> dualIdx;
02559                 std::vector<int>::iterator vit1;
02560                 std::vector<int>::iterator vit2;
02561                 
02562                 //if the objective function value is greater than zero we have a cut
02563                 //the cut is based on the nodes with dual value - 1
02564                 
02565                 for(k = 0; k < indexAdjust; k++){
02566                         //std::cout <<   std::endl << std::endl;
02567                         
02568                         
02569                         m_separationClpModel->setRowUpper(k, 0.0);
02570                         //we don't need output
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                                         //std::cout <<   m_osinstanceSeparation->getConstraintNames()[ i]   << " = " << m_separationClpModel->getRowPrice()[ i] << std::endl;
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                                         }//end for on vit2
02612                                 }//end for on vit1
02613                                 
02614                                 //add the tour-breaking cut
02615                                 m_numBmatrixCon++;
02616                                 m_pntBmatrix[ m_numBmatrixCon ] =  m_numBmatrixNonz;
02617         
02618                                 // multiply the transformation matrix times this cut to get the cut in theta space
02619                                 // do the usual trick and scatter m_Bmatrix into a dense vector
02620 
02621                                 //reset
02622                                 // don't adjust the kludge row
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                                 //now we have to get the theata column indexes
02642                                 //scatter the constraint in the x - variables
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                                         //get the xij indexes in this column 
02657                                         tmpKount = 0;
02658                                         for(j = m_thetaPnt[i]; j < m_thetaPnt[i + 1] ;  j++){
02659                                                 
02660                                                 if(m_tmpScatterArray[ m_thetaIndex[ j] ] > 0 ){ //count number of xij for theta_i
02661                                                         
02662                                                         tmpKount++;
02663                                                         
02664                                                 }
02665                                                 
02666                                         }//end loop on j
02667                                         
02668                                         if(tmpKount > 0){
02669                                                 //theta_i has a nonzero coefficient in this row
02670                                                 
02671                                                 m_newRowColumnIdx[0][ m_newRowNonz[ 0] ] = i ;
02672                                                 
02673                                                 m_newRowColumnValue[0][ m_newRowNonz[ 0]++ ] = tmpKount;
02674                                                  
02675                                                 
02676                                         }
02677                                         
02678                                 }//end loop on i
02679                                 
02680                         
02681                                 //zero out the scatter array again
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                                 //m_thetaPnt[ m_numThetaVar++] = m_numThetaNonz; //first artificial variable
02701                                 //m_thetaPnt[ m_numThetaVar] = m_numThetaNonz; //second artificial varaible
02702                         
02703                                 return;
02704                                 
02705                         
02706                                 
02707                         }//end if on obj value          
02708                         m_separationClpModel->setRowUpper(k, 1.0);
02709                         dualIdx.clear();
02710                         
02711                 }//end loop on k
02712                 
02713                 //if we are here there was no cut
02714                 //reset
02715                 // don't adjust the kludge row
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 }//end getCutsTheta
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         //critical -- we are assuming that the size of x is going to be 
02747         // m_numNodes*(m_numNodes - 1)
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                         //get a postive theta
02773                         if(x[ i] > m_osDecompParam.zeroTol){
02774                                 
02775                                 //the row index for x_{ij}
02776                                 rowKount = m_separationIndexMap[ i ];
02777                                 
02778                                 if(rowKount < OSINT_MAX ){
02779                                         
02780                                         tmpRhs[ rowKount] -= x[ i];
02781                                         
02782                                 }
02783                                 
02784                         }
02785                 }// end i loop
02786                 
02787                 for(i = indexAdjust; i < numSepRows - 1; i++){
02788                         
02789                         if(-tmpRhs[ i] > 1 + m_osDecompParam.zeroTol ){
02790                         
02791                                 // quick and dirty does x_{ij} + x_{ji} <= 1 cut off anything
02792                                 //std::cout << " tmpRhs[ i] =  " << tmpRhs[ i]  << std::endl;
02793                                 //which variable is this 
02794                                 //kipp this an inefficient way of finding i and j -- improve this
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                                         }// end loop on j1
02830                                         
02831                                 }//end loop on i1
02832                         
02833                         
02834                         }//end if on tmpRHS
02835                         
02836                         m_separationClpModel->setRowUpper(i, tmpRhs[ i] );
02837                         m_separationClpModel->setRowLower(i, tmpRhs[ i] );              
02838 
02839                 }//end loop on i
02840                 
02841                 
02842                 //std::cout << m_osinstanceSeparation->printModel() << std::endl;
02843         
02844 
02845                 std::vector<int> dualIdx;
02846                 std::vector<int>::iterator vit1;
02847                 std::vector<int>::iterator vit2;
02848                 
02849                 //if the objective function value is greater than zero we have a cut
02850                 //the cut is based on the nodes with dual value - 1
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                                         //std::cout <<   m_osinstanceSeparation->getConstraintNames()[ i]   << " = " << m_separationClpModel->getRowPrice()[ i] << std::endl;
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                                         }//end for on vit2
02901                                 }//end for on vit1
02902                                 
02903 
02904                                 m_newRowUB[ 0] =  dualIdx.size()  - 1;
02905                                 
02906                                 dualIdx.clear();
02907                                 //reset
02908                                 // don't adjust the kludge row
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                         }//end if on obj value          
02932                         m_separationClpModel->setRowUpper(k, 1.0);
02933                         dualIdx.clear();
02934                         
02935                 }//end loop on k
02936                 
02937                 //if we are here there was no cut
02938                 //reset
02939                 // don't adjust the kludge row
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 }//end getCutsX
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                 }//end l loop
03019                 
03020                 
03021         }//end hub loop
03022         
03023         //now adjust for tour breaking constraints
03024 
03025         
03026         int startPnt ;
03027         
03028         for(i = 0; i < m_numBmatrixCon; i++){
03029                 
03030                 //get the xij
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                                         //startPnt = k*m_upperBoundL*(m_numNodes*m_numNodes - m_numNodes) + (l - 1)*(m_numNodes*m_numNodes - m_numNodes);
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 }//end calcReducedCost
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                 //if we have (i, j) where j is hub then do not subtract off phi[ j]
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                         //std::cout << "GAIL VARIABLE NAME " << m_variableNames[ kount] << std::endl;
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                         //std::cout << "GAIL VARIABLE NAME " << m_variableNames[ kount] << std::endl;
03087                         kount++;
03088                         
03089                 }
03090                 
03091                 
03092         }       
03093 }//end createVariableNames
03094 
03095 void OSBearcatSolverXkij::createAmatrix(){
03096         
03097         //arrays for the coupling constraint matrix
03098         //this is in the x variable space, not theta
03099         //int* m_pntAmatrix;
03100         //int* m_Amatrix;
03101         
03102         
03103         int i;
03104         int j;
03105         int numNonz;
03106         
03107         //loop over nodes 
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         for(i = 0; i < m_numNodes - m_numHubs; i++){
03132                 
03133                 for(j = m_pntAmatrix[ i]; j <  m_pntAmatrix[ i + 1]; j++){
03134                         
03135                         std::cout << m_variableNames[  m_Amatrix[ j ] ] << std::endl;
03136                         
03137                 }
03138 
03139         }
03140         */
03141         
03142 }//end createAmatrix
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                 //we better NOT have any artifical variables positive
03157                 //for(i = 0; i < numVarArt  ; i++){
03158                 //      
03159                 //      if(theta[ i] > m_osDecompParam.zeroTol) throw ErrorClass("we have a positive artificial variable");
03160                 //}
03161                 
03162                 //for(i = 0; i < m_numThetaVar    ; i++){
03163                 
03164                         //cost += theta[ i]*m_thetaCost[ i ];
03165                         //std::cout << "COLUMN VALUE = " << theta[ i] << std::endl;
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                 //std::cout << "NUMBER OF GENERATED COLUMNS = " << m_numThetaVar - 2*m_numNodes - 2*m_numBmatrixCon << std::endl;
03194                 //the original master has m_numHubs + m_numNodes columns
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 }//end pauHana -- no pun intended
03213 
03214 
03215 OSInstance* OSBearcatSolverXkij::getSeparationInstance(){
03216         
03217 
03218         
03219         
03220         m_osinstanceSeparation = NULL;
03221         
03222         //add linear constraint coefficients
03223         //number of values will nodes.size() the coefficients in the node constraints
03224         //plus coefficients in convexity constraints which is the number of varaibles
03225         int kountNonz;
03226         int kount;
03227         int startsIdx;
03228         //we build these on nodes that do not include the hubs
03229         int numYvar = (m_numNodes - m_numHubs)*(m_numNodes - m_numHubs - 1);
03230         int numVvar = m_numNodes - m_numHubs;
03231         //the plus 1 is for the kludge row
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                 //start building the separation instance
03252 
03253                 m_osinstanceSeparation->setInstanceDescription("The Tour Breaking Separation Problem");
03254 
03255                 
03256                 // now the constraints
03257                 m_osinstanceSeparation->setConstraintNumber( numCon); 
03258                 
03259                 
03260                 //add the node rows
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                 //add the variable rows rows
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                 // the klude row so we have +/-1 in every column
03287                 m_osinstanceSeparation->addConstraint(rowKounter++,  "kludgeRow" , 0, m_numNodes, 0);
03288                 
03289                 //  the variables
03290                 m_osinstanceSeparation->setVariableNumber(  numYvar + numVvar);   
03291                 
03292                 
03293                 
03294                 std::cout << "NUMBER OF VARIABLES SET = " << numYvar + numVvar << std::endl;
03295                 //add the v variables
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                 //add the y variables
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                                 //map the variable to row kountCon
03340                                 
03341                                 // i < j case
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                                 // i < j case
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                 // now add the objective function
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                 //now for the nonzeros
03403                 //add the linear constraints coefficients
03404                 m_osinstanceSeparation->setLinearConstraintCoefficients(kountNonz , true, 
03405                                 values, 0, kountNonz - 1,  indexes, 0, kountNonz - 1, starts, 0, startsIdx);
03406         
03407                 
03408                 
03409                 //std::cout << m_osinstanceSeparation->printModel(  ) << std::endl;     
03410                 //
03411                 delete objcoeff;
03412                 
03413                 
03414                 // now create the Clp model
03415                 
03416                 
03417                 //below is temporty see if we can setup as a Clp network problem
03418             CoinPackedMatrix* matrix;
03419             bool columnMajor = true;
03420             double maxGap = 0;
03421                 matrix = new CoinPackedMatrix(
03422                 columnMajor, //Column or Row Major
03423                 columnMajor? m_osinstanceSeparation->getConstraintNumber() : m_osinstanceSeparation->getVariableNumber(), //Minor Dimension
03424                 columnMajor? m_osinstanceSeparation->getVariableNumber() : m_osinstanceSeparation->getConstraintNumber(), //Major Dimension
03425                 m_osinstanceSeparation->getLinearConstraintCoefficientNumber(), //Number of nonzeroes
03426                 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->values : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->values, //Pointer to matrix nonzeroes
03427                 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->indexes : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->indexes, //Pointer to start of minor dimension indexes -- change to allow for row storage
03428                 columnMajor? m_osinstanceSeparation->getLinearConstraintCoefficientsInColumnMajor()->starts : m_osinstanceSeparation->getLinearConstraintCoefficientsInRowMajor()->starts, //Pointers to start of columns.
03429                 0,   0, maxGap ); 
03430                 
03431                 ClpNetworkMatrix network( *matrix);
03432                 
03433                 m_separationClpModel = new ClpSimplex();
03434                 
03435                 //if( m_osinstanceSeparation->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
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 }//end getSeparationInstance
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                 //loop over the fractional thetas
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                 //let's branch on a variable in and out of hub first
03499                 minFraction = 1.0;
03500                 //ideally we find minFraction very close to .5
03501                 
03502                 for(i = 0; i < m_numHubs; i++){
03503                         
03504                         for( j = 0;  j < i;  j++){
03505                                 
03506                                 //j < i so the index is i*(m_numNodes - 1) + j
03507                                 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j  ];
03508                                 from0Distance = xvalues[ i*(m_numNodes - 1) + j  ];
03509                                 fraction = std::max(from1Distance, from0Distance);
03510                                 //try to find fractional variable that is the closest to .5
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                                 //j < i so the index is i*(m_numNodes - 1) + j - 1
03522                                 //j < i so the index is i*(m_numNodes - 1) + j
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                                 //try to find fractional variable that is the closest to .5
03527                                 if(fraction < minFraction) {
03528                                         
03529                                         minFraction = fraction;
03530                                         varIdx = i*(m_numNodes - 1) + j - 1;
03531                                 }
03532                                 
03533                                 
03534                         }
03535                         
03536                 }
03537                 
03538                 //if we have a candidate among arcs in/out of hubs, take it
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                                         //j < i so the index is i*(m_numNodes - 1) + j
03547                                         from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j  ];
03548                                         from0Distance = xvalues[ i*(m_numNodes - 1) + j  ];
03549                                         fraction = std::max(from1Distance, from0Distance);
03550                                         //try to find fractional variable that is the closest to .5
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                                         //j < i so the index is i*(m_numNodes - 1) + j - 1
03562                                         //j < i so the index is i*(m_numNodes - 1) + j
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                                         //try to find fractional variable that is the closest to .5
03567                                         if(fraction < minFraction) {
03568                                                 
03569                                                 minFraction = fraction;
03570                                                 varIdx = i*(m_numNodes - 1) + j - 1;
03571                                         }
03572                                         
03573                                 }
03574                                 
03575                         }
03576                 
03577                 }//end of if on minFraction
03578                 std::cout << " HERE IS GAIL 1" << std::endl;
03579                 
03580                 //zero out the scatter array
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 }//end getBranchingVar Dense
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                 //loop over the fractional thetas
03625                 //working with a sparse matrix
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                 //let's branch on a variable in and out of hub first
03643                 minFraction = 1.0;
03644                 //ideally we find minFraction very close to .5
03645                 
03646                 for(i = 0; i < m_numHubs; i++){
03647                         
03648                         for( j = 0;  j < i;  j++){
03649                                 
03650                                 //j < i so the index is i*(m_numNodes - 1) + j
03651                                 from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j  ];
03652                                 from0Distance = xvalues[ i*(m_numNodes - 1) + j  ];
03653                                 fraction = std::max(from1Distance, from0Distance);
03654                                 //try to find fractional variable that is the closest to .5
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                                 //j < i so the index is i*(m_numNodes - 1) + j - 1
03666                                 //j < i so the index is i*(m_numNodes - 1) + j
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                                 //try to find fractional variable that is the closest to .5
03671                                 if(fraction < minFraction) {
03672                                         
03673                                         minFraction = fraction;
03674                                         varIdx = i*(m_numNodes - 1) + j - 1;
03675                                 }
03676                                 
03677                                 
03678                         }
03679                         
03680                 }
03681                 
03682                 //if we have a candidate among arcs in/out of hubs, take it
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                                         //j < i so the index is i*(m_numNodes - 1) + j
03695                                         from1Distance = 1 - xvalues[ i*(m_numNodes - 1) + j  ];
03696                                         from0Distance = xvalues[ i*(m_numNodes - 1) + j  ];
03697                                         fraction = std::max(from1Distance, from0Distance);
03698                                         //try to find fractional variable that is the closest to .5
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                                         //j < i so the index is i*(m_numNodes - 1) + j - 1
03710                                         //j < i so the index is i*(m_numNodes - 1) + j
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                                         //try to find fractional variable that is the closest to .5
03715                                         if(fraction < minFraction) {
03716                                                 
03717                                                 minFraction = fraction;
03718                                                 varIdx = i*(m_numNodes - 1) + j - 1;
03719                                         }
03720                                         
03721                                 }
03722                                 
03723                         }
03724                 
03725                 }//end of if on minFraction
03726                 
03727                 //zero out the scatter array
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 }//end getBranchingVar Sparse
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         //get a branching variable
03752         int i;
03753         int j;
03754         int kount;
03755         numNonz = 0;
03756         //keep numNonz at zero if there is no cut
03757         //there will be no cut if the xij is in conVarMap
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                 //if this variable is in the map, then we just return with the index, 
03769                 //if this variable is NOT in the map then we add a cut
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                                 //count is the number times variable i appears in the constraint
03784                                 
03785                                 if(kount > 0){
03786                                         
03787                                         branchCutIndexes[ numNonz] = i;
03788                                         branchCutValues[ numNonz++] = kount ;
03789                                         
03790                                 }
03791                                 
03792                         }
03793                         
03794                         
03795                         //add varIdx cut to B matrix
03796                         m_Bmatrix[ m_numBmatrixNonz++] = varIdx;
03797                         m_numBmatrixCon++;
03798                         m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
03799                         
03800                         //make sure to add artificial variables
03801                         //of course they have no nonzero elements in 
03802                         //the transformation matrix
03803                         m_numThetaVar++;
03804                         convexityRowIndex[ m_numThetaVar] = -1;
03805                         m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
03806                         //m_thetaPnt[ m_numThetaVar++] = m_numThetaNonz; //first artificial variable
03807                         //m_thetaPnt[ m_numThetaVar] = m_numThetaNonz; //second artificial variable
03808                 
03809                 
03810                 }//end of if on checking for map membership
03811                 
03812                 //set return arguments
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 }//end getBranchingCut dense
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         //get a branching variable
03833         int i;
03834         int j;
03835         int kount;
03836         numNonz = 0;
03837         //keep numNonz at zero if there is no cut
03838         //there will be no cut if the xij is in conVarMap
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                 //if this variable is in the map, then we just return with the index, 
03849                 //if this variable is NOT in the map then we add a cut
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                                 //count is the number times variable i appears in the constraint
03869                                 
03870                                 if(kount > 0){
03871                                         
03872                                         branchCutIndexes[ numNonz] = i;
03873                                         branchCutValues[ numNonz++] = kount ;
03874                                         
03875                                 }
03876                                 
03877                         }
03878                         
03879                         
03880                         //add varIdx cut to B matrix
03881                         m_Bmatrix[ m_numBmatrixNonz++] = varIdx;
03882                         m_numBmatrixCon++;
03883                         m_pntBmatrix[ m_numBmatrixCon] = m_numBmatrixNonz;
03884                         
03885                         //make sure to add artificial variables
03886                         //of course they have no nonzero elements in 
03887                         //the transformation matrix
03888                         m_numThetaVar++;
03889                         convexityRowIndex[ m_numThetaVar] = -1;
03890                         m_thetaPnt[ m_numThetaVar] = m_numThetaNonz;
03891                         //m_thetaPnt[ m_numThetaVar++] = m_numThetaNonz; //first artificial variable
03892                         //m_thetaPnt[ m_numThetaVar] = m_numThetaNonz; // second artificial variable
03893                 
03894                 
03895                 }//end of if on checking for map membership
03896                 
03897                 //set return arguments
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 }//end getBranchingCut sparse
03911 
03912 
03913 void OSBearcatSolverXkij::getInitialSolution(){
03914         
03915         try{    
03916                 //kipp -- stil not done we depend on SKs solution
03917                 //let's get the initial assignment of nodes to hubs
03918                 //this is in m_initSolMap which is calculated when we
03919                 //call  getOptions( OSOption *osoption);
03920                 
03921                 if(m_initSolMap.size() == 0) getOptions( m_osoption);
03922                 
03923                 //get cost vector
03924                 
03925                 //get demand vector
03926                 
03927                 //now improve on m_initSolMap
03928                 
03929         }catch (const ErrorClass& eclass) {
03930         
03931                 throw ErrorClass(eclass.errormsg);
03932         
03933         }       
03934         
03935         
03936 }//end getInitialSolution
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         //temporarily create memory for the columns we keep
03949         int numVars = inVars.size();
03950         int numVarArt;
03951         //there 2*m_numNodes in the A matrix
03952         //there are  m_numBmatrixCon B matrix constraints
03953         //numVarArt = 2*m_numNodes +  2*m_numBmatrixCon;
03954         numVarArt = m_numNodes +  m_numBmatrixCon;
03955         
03956         //arrays for the new osinstance
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         //temporay holders
03970         int* thetaPntTmp;
03971         int* thetaIndexTmp;
03972         int*  tmpConvexity = new int[  m_numThetaVar];
03973         
03974         //get the number of nonzeros that we need
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         //allocate the memory
03983         thetaPntTmp = new int[ numVars + 1];
03984         thetaIndexTmp = new int[ numNonz];
03985         
03986         
03987         //error check
03988         for(mit = inVars.begin();  mit != inVars.end(); mit++){
03989                 
03990                 
03991                 //std::cout << "VARIABLE INDEX =  " <<  mit->first  << " OBJ COEF = " <<  si->getObjCoefficients()[ mit->first ] << std::endl;
03992                 if( convexityRowIndex[ mit->first] == -1) throw ErrorClass( "we have an artificial variable in reset master");
03993                 
03994                 
03995         }
03996         
03997         //fill in the temporary arrays
03998         kount = 0;
03999         numNonz = 0;
04000         thetaPntTmp[ kount] = 0;
04001         
04002         for(mit = inVars.begin();  mit != inVars.end(); mit++){
04003                 
04004                 //std::cout << "mit->first " <<   mit->first << "  mit->second   " << mit->second   << std::endl;
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                         //std::cout << "Column = " <<   mit->first << "  Variable   " <<   m_variableNames[ m_thetaIndex[ i] ]   << std::endl;
04013                         
04014                 }
04015                 
04016                 thetaPntTmp[ kount] = numNonz;
04017                 
04018                 //std::cout << "kount =  " << kount << "  thetaPntTmp[ kount] = " << thetaPntTmp[ kount] << std::endl;
04019                 //readjust numbering to take into account artificial variables
04020                 //mit->second += numVarArt;
04021                 //kipp -- double check calculation below
04022                 inVars[ mit->first] = numVarArt + kount - 1 ;
04023                 
04024         }
04025         
04026         //std::cout << "kount = " <<  kount  << std::endl;
04027         //std::cout << "numVars = " << numVars  << std::endl;
04028         
04029 
04030         
04031         //copy old values of convexityRowIndex
04032         for(i = 0; i < m_numThetaVar; i++) tmpConvexity[ i] = convexityRowIndex[ i];
04033         
04034         //reset the theta pointers
04035         //first the artificial variables
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         //now fill in the other pointers from the temp arrarys
04046         //std::cout << "Number of artificial variables =  " << numVarArt   << std::endl;
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                 //std::cout << " m_numThetaVar =  "  << m_numThetaVar << "  m_numThetaNonz =  " <<  m_numThetaNonz  << std::endl;
04054                 //std::cout << "Variable number " << mit->first << "  OBJ coefficient = " <<   si->getObjCoefficients()[  mit->first] << std::endl;
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         //std::cout << " number of art vars = " <<  numVarArt  << std::endl;
04072         //std::cout << " m_numThetaVar = " <<  m_numThetaVar  << std::endl;
04073         //std::cout << " m_numThetaNonz = " <<  m_numThetaNonz  << std::endl;
04074         //done with the transformation matrix
04075         
04076 
04077         
04078         //
04079         //write old master --- just for testing
04080         si->writeLp( "gailTest" );
04081         
04082         //now create the formulation
04083         
04084         //first get each column of the new master
04085         //first take care of the artificial variables
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                 //std::cout << "CONVEXITY ROW = " << convexityRowIndex[ mit->second]  << std::endl;
04107                 valuesVec.push_back( 1.0);
04108                 indexesVec.push_back( numAmatrixRows + convexityRowIndex[ mit->second] );
04109                 //increment numNonz by 1 for the convexity row
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                         //std::cout << "Column = " <<  mit->second << "  Variable   " <<   m_variableNames[ m_thetaIndex[ j] ]   << std::endl;
04117                         
04118                 }
04119                 
04120 
04121         
04122                 //multiply the sparse array by each A matrix constraint
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                                 //m_Amatrix[ j] is a variable index -- this logic works
04130                                 //since the Amatrix coefficient is 1 -- we don't need a value
04131                                 //it indexes variable that points into the node
04132                                 rowCount += m_tmpScatterArray[  m_Amatrix[ j] ];
04133                                 
04134 
04135                         }
04136                         
04137                         if(rowCount > 0){
04138                                 
04139                                 numNonz++;
04140                                 
04141                                 //std::cout << "Column = " <<  mit->second << "  Nonzero in A marix row  " << i  <<  " Value = " << rowCount << std::endl;
04142                                 valuesVec.push_back( rowCount);
04143                                 indexesVec.push_back( i);
04144 
04145                                 
04146                         }
04147                                 
04148                                 
04149                 }//end loop on coupling constraints
04150                 
04151                 
04152                 //multiply the sparse array by each B matrix constraint
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                                 //m_Amatrix[ j] is a variable index -- this logic works
04160                                 //since the Amatrix coefficient is 1 -- we don't need a value
04161                                 //it indexes variable that points into the node
04162                                 rowCount += m_tmpScatterArray[  m_Bmatrix[ j] ];
04163                                 
04164 
04165                         }
04166                         
04167                         if(rowCount > 0){
04168                                 numNonz++;
04169                                 
04170                                 //std::cout << "Column = " <<  mit->first << "  Nonzero in B matrix row  " << i  + m_numNodes<<  " Value = " << rowCount << std::endl;
04171 
04172                                 valuesVec.push_back( rowCount);
04173                                 indexesVec.push_back( i + m_numNodes);
04174                         }
04175                                 
04176                                 
04177                 }//end loop on B matrix constraints
04178                 
04179                 
04180                 //zero out the scatter array
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         //for(i = 0; i < startsIdx; i++) std::cout << "starts[ i] = " << starts[ i] << std::endl;
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         //construct the new master
04210         //create an OSInstance from the tmp arrays
04211         // delete the old  m_osinstanceMaster
04212         
04213         delete m_osinstanceMaster;
04214         m_osinstanceMaster = NULL;
04215         
04216         //start building the restricted master here
04217         m_osinstanceMaster = new OSInstance();
04218         m_osinstanceMaster->setInstanceDescription("The Restricted Master");
04219         
04220         // first the variables
04221         // we have numVarArt] artificial variables 
04222         m_osinstanceMaster->setVariableNumber( numVars + numVarArt );   
04223         
04224         // now add the objective function
04225         //m_osinstanceMaster->setObjectiveNumber( 1);
04226         //add m_numNodes artificial variables
04227         SparseVector *objcoeff = new SparseVector( numVars + numVarArt);   
04228         
04229 
04230 
04231         // now the constraints
04232         m_osinstanceMaster->setConstraintNumber( m_numNodes  + m_numBmatrixCon); 
04233         
04234         
04235         //add the artificial variables first
04236         
04237         int varNumber;
04238         varNumber = 0;
04239         
04240 
04241         //define the artificial variables
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         // now the theta variables
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         // now add the objective function
04295         m_osinstanceMaster->setObjectiveNumber( 1);
04296         m_osinstanceMaster->addObjective(-1, "objfunction", "min", 0.0, 1.0, objcoeff);
04297         
04298         //add the linear constraints coefficients
04299         m_osinstanceMaster->setLinearConstraintCoefficients(numNonz , true, 
04300                         values, 0, numNonz - 1,  indexes, 0, numNonz - 1, starts, 0, startsIdx);
04301         
04302         
04303         //std::cout << m_osinstanceMaster->printModel( ) << std::endl;  
04304         
04305         //garbage collection
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 }//end resetMaster
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 }//end makeStringFromInt
04324 
04325 
04326 
04327 
04328 

Generated on Thu Nov 10 03:05:47 2011 by  doxygen 1.4.7