Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

CglGomoryTest.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
00005 #  pragma warning(disable:4786)
00006 #endif
00007 
00008 #include <cstdio>
00009 
00010 #ifdef NDEBUG
00011 #undef NDEBUG
00012 #endif
00013 
00014 #include <cassert>
00015 
00016 #include "CoinPackedMatrix.hpp"
00017 #include "OsiCuts.hpp"
00018 #include "CoinWarmStartBasis.hpp"
00019 #include "CglGomory.hpp"
00020 
00021 
00022 //--------------------------------------------------------------------------
00023 // ** At present this does not use any solver
00024 void
00025 CglGomoryUnitTest(
00026   const OsiSolverInterface * baseSiP,
00027   const std::string mpsDir )
00028 {
00029   CoinRelFltEq eq(0.000001);
00030 
00031   // Test default constructor
00032   {
00033     CglGomory aGenerator;
00034     assert (aGenerator.getLimit()==50);
00035     assert (aGenerator.getAway()==0.05);
00036   }
00037   
00038   // Test copy & assignment etc
00039   {
00040     CglGomory rhs;
00041     {
00042       CglGomory bGenerator;
00043       bGenerator.setLimit(99);
00044       bGenerator.setAway(0.2);
00045       CglGomory cGenerator(bGenerator);
00046       rhs=bGenerator;
00047       assert (rhs.getLimit()==99);
00048       assert (rhs.getAway()==0.2);
00049     }
00050   }
00051 
00052   // Test explicit form - all integer (pg 125 Wolsey)
00053   if (1) {
00054     OsiCuts osicuts;
00055     CglGomory test1;
00056     int i;
00057     int nOldCuts=0,nRowCuts;
00058  
00059     // matrix data
00060     //deliberate hiccup of 2 between 0 and 1
00061     int start[5]={0,4,7,8,9};
00062     int length[5]={2,3,1,1,1};
00063     int rows[11]={0,2,-1,-1,0,1,2,0,1,2};
00064     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,1,1};
00065     CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length);
00066     
00067     // rim data (objective not used just yet)
00068     double objective[7]={-4.0,1.0,0.0,0.0,0.0,0.0,0.0};
00069     double rowLower[5]={14.0,3.0,3.0,1.0e10,1.0e10};
00070     double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10};
00071     double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0};
00072     double colUpper[7]={100.0,100.0,100.0,100.0,100.0,100.0,100.0};
00073   
00074     // integer
00075     char intVar[7]={2,2,2,2,2,2,2};
00076 
00077     // basis 1
00078     int rowBasis1[3]={-1,-1,-1};
00079     int colBasis1[5]={1,1,-1,-1,1};
00080     CoinWarmStartBasis warm;
00081     warm.setSize(5,3);
00082     for (i=0;i<3;i++) {
00083       if (rowBasis1[i]<0) {
00084         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00085       } else {
00086         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00087       }
00088     }
00089     for (i=0;i<5;i++) {
00090       if (colBasis1[i]<0) {
00091         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00092       } else {
00093         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00094       }
00095     }
00096 
00097     // solution 1
00098     double colsol1[5]={20.0/7.0,3.0,0.0,0.0,23.0/7.0};
00099     test1.generateCuts(NULL, osicuts, matrix,
00100                  objective, colsol1,
00101                  colLower, colUpper,
00102                  rowLower, rowUpper, intVar, &warm);
00103     nRowCuts = osicuts.sizeRowCuts();
00104     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00105     assert (nRowCuts==2);
00106     // cuts always <=
00107     int testCut=0; // test first cut as stronger
00108     double rhs=-6.0;
00109     double testCut1[5]={0.0,0.0,-1.0,-2.0,0.0};
00110     double * cut = testCut1;
00111     double * colsol = colsol1;
00112     for (i=nOldCuts; i<nRowCuts; i++){
00113       OsiRowCut rcut;
00114       CoinPackedVector rpv;
00115       rcut = osicuts.rowCut(i);
00116       rpv = rcut.row();
00117       const int n = rpv.getNumElements();
00118       const int * indices = rpv.getIndices();
00119       double* elements = rpv.getElements();
00120       double sum2=0.0;
00121       int k=0;
00122       double lb=rcut.lb();
00123       double ub=rcut.ub();
00124       for (k=0; k<n; k++){
00125         int column=indices[k];
00126         sum2 += colsol[column]*elements[k];
00127       }
00128       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00129         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00130         for (k=0; k<n; k++){
00131           int column=indices[k];
00132           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00133             colsol[column]<<") ";
00134         }
00135         std::cout <<std::endl;
00136       }
00137       if (i-nOldCuts==testCut) {
00138         assert( eq(rhs,ub));
00139         assert(n==2);
00140         for (k=0; k<n; k++){
00141           int column=indices[k];
00142           assert (eq(cut[column],elements[k]));
00143         }
00144         // add cut
00145         // explicit slack
00146         matrix.setDimensions(-1,6);
00147         rpv.insert(5,1.0*7.0); // to get cut in book
00148         rowLower[3]=ub;
00149         rowUpper[3]=ub;
00150         matrix.appendRow(rpv);
00151       }
00152     }
00153     nOldCuts=nRowCuts;
00154     // basis 2
00155     int rowBasis2[4]={-1,-1,-1,-1};
00156     int colBasis2[6]={1,1,1,1,-1,-1};
00157     warm.setSize(6,4);
00158     for (i=0;i<4;i++) {
00159       if (rowBasis2[i]<0) {
00160         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00161       } else {
00162         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00163       }
00164     }
00165     for (i=0;i<6;i++) {
00166       if (colBasis2[i]<0) {
00167         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00168       } else {
00169         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00170       }
00171     }
00172 
00173     // solution 2
00174     double colsol2[6]={2.0,0.5,1.0,2.5,0.0,0.0};
00175     test1.generateCuts(NULL, osicuts, matrix,
00176                  objective, colsol2,
00177                  colLower, colUpper,
00178                  rowLower, rowUpper, intVar, &warm);
00179     nRowCuts = osicuts.sizeRowCuts();
00180     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00181     assert (nRowCuts-nOldCuts==2);
00182     // cuts always <=
00183     testCut=0; // test first cut as stronger
00184     rhs=-1.0;
00185     double testCut2[6]={0.0,0.0,0.0,0.0,-1.0,0.0};
00186     cut = testCut2;
00187     colsol = colsol2;
00188     for (i=nOldCuts; i<nRowCuts; i++){
00189       OsiRowCut rcut;
00190       CoinPackedVector rpv;
00191       rcut = osicuts.rowCut(i);
00192       rpv = rcut.row();
00193       const int n = rpv.getNumElements();
00194       const int * indices = rpv.getIndices();
00195       double* elements = rpv.getElements();
00196       double sum2=0.0;
00197       int k=0;
00198       double lb=rcut.lb();
00199       double ub=rcut.ub();
00200       for (k=0; k<n; k++){
00201         int column=indices[k];
00202         sum2 += colsol[column]*elements[k];
00203       }
00204       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00205         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00206         for (k=0; k<n; k++){
00207           int column=indices[k];
00208           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00209             colsol[column]<<") ";
00210         }
00211         std::cout <<std::endl;
00212       }
00213       if (i-nOldCuts==testCut) {
00214         assert( eq(rhs,ub));
00215         assert(n==1);
00216         for (k=0; k<n; k++){
00217           int column=indices[k];
00218           assert (eq(cut[column],elements[k]));
00219         }
00220         // add cut
00221         // explicit slack
00222         matrix.setDimensions(-1,7);
00223         rpv.insert(6,1.0);
00224         rowLower[4]=ub;
00225         rowUpper[4]=ub;
00226         matrix.appendRow(rpv);
00227       }
00228     }
00229     nOldCuts=nRowCuts;
00230     // basis 3
00231     int rowBasis3[5]={-1,-1,-1,-1,-1};
00232     int colBasis3[7]={1,1,1,1,1,-1,-1};
00233     warm.setSize(7,5);
00234     for (i=0;i<5;i++) {
00235       if (rowBasis3[i]<0) {
00236         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00237       } else {
00238         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00239       }
00240     }
00241     for (i=0;i<7;i++) {
00242       if (colBasis3[i]<0) {
00243         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00244       } else {
00245         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00246       }
00247     }
00248 
00249     // solution 3
00250     double colsol3[7]={2.0,1.0,2.0,2.0,1.0,0.0,0.0};
00251     test1.generateCuts(NULL, osicuts, matrix,
00252                  objective, colsol3,
00253                  colLower, colUpper,
00254                  rowLower, rowUpper, intVar, &warm);
00255     nRowCuts = osicuts.sizeRowCuts();
00256     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00257     assert (nRowCuts==nOldCuts);
00258     
00259   }
00260   // Test explicit form - this time with x4 flipped
00261   if (1) {
00262     OsiCuts osicuts;
00263     CglGomory test1;
00264     int i;
00265     int nOldCuts=0,nRowCuts;
00266  
00267     // matrix data
00268     //deliberate hiccup of 2 between 0 and 1
00269     int start[5]={0,4,7,8,9};
00270     int length[5]={2,3,1,1,1};
00271     int rows[11]={0,2,-1,-1,0,1,2,0,1,2};
00272     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,-1,1};
00273     CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length);
00274     
00275     // rim data (objective not used just yet)
00276     double objective[7]={-4.0,1.0,0.0,0.0,0.0,0.0,0.0};
00277     double rowLower[5]={14.0,-5.0,3.0,1.0e10,1.0e10};
00278     double rowUpper[5]={14.0,-5.0,3.0,-1.0e10,-1.0e10};
00279     double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0};
00280     double colUpper[7]={100.0,100.0,100.0,8.0,100.0,100.0,100.0};
00281   
00282     // integer
00283     char intVar[7]={2,2,2,2,2,2,2};
00284 
00285     // basis 1
00286     int rowBasis1[3]={-1,-1,-1};
00287     int colBasis1[5]={1,1,-1,-1,1};
00288     CoinWarmStartBasis warm;
00289     warm.setSize(5,3);
00290     for (i=0;i<3;i++) {
00291       if (rowBasis1[i]<0) {
00292         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00293       } else {
00294         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00295       }
00296     }
00297     for (i=0;i<5;i++) {
00298       if (colBasis1[i]<0) {
00299         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00300       } else {
00301         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00302       }
00303     }
00304 
00305     // solution 1
00306     double colsol1[5]={20.0/7.0,3.0,0.0,8.0,23.0/7.0};
00307     test1.generateCuts(NULL, osicuts, matrix,
00308                  objective, colsol1,
00309                  colLower, colUpper,
00310                  rowLower, rowUpper, intVar, &warm);
00311     nRowCuts = osicuts.sizeRowCuts();
00312     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00313     assert (nRowCuts==2);
00314     // cuts always <=
00315     int testCut=0; // test first cut as stronger
00316     double rhs=10.0;
00317     double testCut1[5]={0.0,0.0,-1.0,2.0,0.0};
00318     double * cut = testCut1;
00319     double * colsol = colsol1;
00320     for (i=nOldCuts; i<nRowCuts; i++){
00321       OsiRowCut rcut;
00322       CoinPackedVector rpv;
00323       rcut = osicuts.rowCut(i);
00324       rpv = rcut.row();
00325       const int n = rpv.getNumElements();
00326       const int * indices = rpv.getIndices();
00327       double* elements = rpv.getElements();
00328       double sum2=0.0;
00329       int k=0;
00330       double lb=rcut.lb();
00331       double ub=rcut.ub();
00332       for (k=0; k<n; k++){
00333         int column=indices[k];
00334         sum2 += colsol[column]*elements[k];
00335       }
00336       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00337         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00338         for (k=0; k<n; k++){
00339           int column=indices[k];
00340           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00341             colsol[column]<<") ";
00342         }
00343         std::cout <<std::endl;
00344       }
00345       if (i-nOldCuts==testCut) {
00346         assert( eq(rhs,ub));
00347         assert(n==2);
00348         for (k=0; k<n; k++){
00349           int column=indices[k];
00350           assert (eq(cut[column],elements[k]));
00351         }
00352         // add cut
00353         // explicit slack
00354         matrix.setDimensions(-1,6);
00355         rpv.insert(5,1.0*7.0); // to get cut in book
00356         rowLower[3]=ub;
00357         rowUpper[3]=ub;
00358         matrix.appendRow(rpv);
00359       }
00360     }
00361     nOldCuts=nRowCuts;
00362     // basis 2
00363     int rowBasis2[4]={-1,-1,-1,-1};
00364     int colBasis2[6]={1,1,1,1,-1,-1};
00365     warm.setSize(6,4);
00366     for (i=0;i<4;i++) {
00367       if (rowBasis2[i]<0) {
00368         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00369       } else {
00370         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00371       }
00372     }
00373     for (i=0;i<6;i++) {
00374       if (colBasis2[i]<0) {
00375         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00376       } else {
00377         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00378       }
00379     }
00380 
00381     // solution 2
00382     double colsol2[6]={2.0,0.5,1.0,5.5,0.0,0.0};
00383     test1.generateCuts(NULL, osicuts, matrix,
00384                  objective, colsol2,
00385                  colLower, colUpper,
00386                  rowLower, rowUpper, intVar, &warm);
00387     nRowCuts = osicuts.sizeRowCuts();
00388     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00389     assert (nRowCuts-nOldCuts==2);
00390     // cuts always <=
00391     testCut=0; // test first cut as stronger
00392     rhs=-1.0;
00393     double testCut2[6]={0.0,0.0,0.0,0.0,-1.0,0.0};
00394     cut = testCut2;
00395     colsol = colsol2;
00396     for (i=nOldCuts; i<nRowCuts; i++){
00397       OsiRowCut rcut;
00398       CoinPackedVector rpv;
00399       rcut = osicuts.rowCut(i);
00400       rpv = rcut.row();
00401       const int n = rpv.getNumElements();
00402       const int * indices = rpv.getIndices();
00403       double* elements = rpv.getElements();
00404       double sum2=0.0;
00405       int k=0;
00406       double lb=rcut.lb();
00407       double ub=rcut.ub();
00408       for (k=0; k<n; k++){
00409         int column=indices[k];
00410         sum2 += colsol[column]*elements[k];
00411       }
00412       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00413         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00414         for (k=0; k<n; k++){
00415           int column=indices[k];
00416           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00417             colsol[column]<<") ";
00418         }
00419         std::cout <<std::endl;
00420       }
00421       if (i-nOldCuts==testCut) {
00422         assert( eq(rhs,ub));
00423         assert(n==1);
00424         for (k=0; k<n; k++){
00425           int column=indices[k];
00426           assert (eq(cut[column],elements[k]));
00427         }
00428         // add cut
00429         // explicit slack
00430         matrix.setDimensions(-1,7);
00431         rpv.insert(6,1.0);
00432         rowLower[4]=ub;
00433         rowUpper[4]=ub;
00434         matrix.appendRow(rpv);
00435       }
00436     }
00437     nOldCuts=nRowCuts;
00438     // basis 3
00439     int rowBasis3[5]={-1,-1,-1,-1,-1};
00440     int colBasis3[7]={1,1,1,1,1,-1,-1};
00441     warm.setSize(7,5);
00442     for (i=0;i<5;i++) {
00443       if (rowBasis3[i]<0) {
00444         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00445       } else {
00446         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00447       }
00448     }
00449     for (i=0;i<7;i++) {
00450       if (colBasis3[i]<0) {
00451         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00452       } else {
00453         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00454       }
00455     }
00456 
00457     // solution 3
00458     double colsol3[7]={2.0,1.0,2.0,6.0,1.0,0.0,0.0};
00459     test1.generateCuts(NULL, osicuts, matrix,
00460                  objective, colsol3,
00461                  colLower, colUpper,
00462                  rowLower, rowUpper, intVar, &warm);
00463     nRowCuts = osicuts.sizeRowCuts();
00464     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00465     assert (nRowCuts==nOldCuts);
00466     
00467   }
00468   // Test with slacks 
00469   if (1) {
00470     OsiCuts osicuts;
00471     CglGomory test1;
00472     int i;
00473     int nOldCuts=0,nRowCuts;
00474  
00475     // matrix data
00476     //deliberate hiccup of 2 between 0 and 1
00477     int start[5]={0,4};
00478     int length[5]={2,3};
00479     int rows[11]={0,2,-1,-1,0,1,2};
00480     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0};
00481     CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length);
00482     
00483     // rim data (objective not used just yet)
00484     double objective[2]={-4.0,1.0};
00485     double rowLower[5]={-1.0e10,-1.0e10,-1.0e10,1.0e10,1.0e10};
00486     double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10};
00487     double colLower[2]={0.0,0.0};
00488     double colUpper[2]={100.0,100.0};
00489   
00490     // integer
00491     char intVar[2]={2,2};
00492 
00493     // basis 1
00494     int rowBasis1[3]={-1,-1,1};
00495     int colBasis1[2]={1,1};
00496     CoinWarmStartBasis warm;
00497     warm.setSize(2,3);
00498     for (i=0;i<3;i++) {
00499       if (rowBasis1[i]<0) {
00500         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00501       } else {
00502         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00503       }
00504     }
00505     for (i=0;i<2;i++) {
00506       if (colBasis1[i]<0) {
00507         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00508       } else {
00509         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00510       }
00511     }
00512 
00513     // solution 1
00514     double colsol1[2]={20.0/7.0,3.0};
00515     test1.generateCuts(NULL, osicuts, matrix,
00516                  objective, colsol1,
00517                  colLower, colUpper,
00518                  rowLower, rowUpper, intVar, &warm);
00519     nRowCuts = osicuts.sizeRowCuts();
00520     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00521     assert (nRowCuts==1);
00522     // cuts always <=
00523     int testCut=0; // test first cut as stronger
00524     double rhs=2.0;
00525     double testCut1[2]={1.0,0.0};
00526     double * cut = testCut1;
00527     double * colsol = colsol1;
00528     for (i=nOldCuts; i<nRowCuts; i++){
00529       OsiRowCut rcut;
00530       CoinPackedVector rpv;
00531       rcut = osicuts.rowCut(i);
00532       rpv = rcut.row();
00533       const int n = rpv.getNumElements();
00534       const int * indices = rpv.getIndices();
00535       double* elements = rpv.getElements();
00536       double sum2=0.0;
00537       int k=0;
00538       double lb=rcut.lb();
00539       double ub=rcut.ub();
00540       for (k=0; k<n; k++){
00541         int column=indices[k];
00542         sum2 += colsol[column]*elements[k];
00543       }
00544       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00545         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00546         for (k=0; k<n; k++){
00547           int column=indices[k];
00548           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00549             colsol[column]<<") ";
00550         }
00551         std::cout <<std::endl;
00552       }
00553       if (i-nOldCuts==testCut) {
00554         assert( eq(rhs,ub));
00555         assert(n==1);
00556         for (k=0; k<n; k++){
00557           int column=indices[k];
00558           assert (eq(cut[column],elements[k]));
00559         }
00560         // add cut
00561         rowLower[3]=-1.0e100;
00562         rowUpper[3]=ub;
00563         matrix.appendRow(rpv);
00564       }
00565     }
00566     nOldCuts=nRowCuts;
00567     // basis 2
00568     int rowBasis2[4]={1,1,-1,-1};
00569     int colBasis2[2]={1,1};
00570     warm.setSize(2,4);
00571     for (i=0;i<4;i++) {
00572       if (rowBasis2[i]<0) {
00573         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00574       } else {
00575         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00576       }
00577     }
00578     for (i=0;i<2;i++) {
00579       if (colBasis2[i]<0) {
00580         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00581       } else {
00582         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00583       }
00584     }
00585 
00586     // solution 2
00587     double colsol2[2]={2.0,0.5};
00588     test1.generateCuts(NULL, osicuts, matrix,
00589                  objective, colsol2,
00590                  colLower, colUpper,
00591                  rowLower, rowUpper, intVar, &warm);
00592     nRowCuts = osicuts.sizeRowCuts();
00593     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00594     assert (nRowCuts-nOldCuts==1);
00595     // cuts always <=
00596     testCut=0; // test first cut as stronger
00597     rhs=1.0;
00598     double testCut2[2]={1.0,-1.0};
00599     cut = testCut2;
00600     colsol = colsol2;
00601     for (i=nOldCuts; i<nRowCuts; i++){
00602       OsiRowCut rcut;
00603       CoinPackedVector rpv;
00604       rcut = osicuts.rowCut(i);
00605       rpv = rcut.row();
00606       const int n = rpv.getNumElements();
00607       const int * indices = rpv.getIndices();
00608       double* elements = rpv.getElements();
00609       double sum2=0.0;
00610       int k=0;
00611       double lb=rcut.lb();
00612       double ub=rcut.ub();
00613       for (k=0; k<n; k++){
00614         int column=indices[k];
00615         sum2 += colsol[column]*elements[k];
00616       }
00617       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00618         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00619         for (k=0; k<n; k++){
00620           int column=indices[k];
00621           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00622             colsol[column]<<") ";
00623         }
00624         std::cout <<std::endl;
00625       }
00626       if (i-nOldCuts==testCut) {
00627         assert( eq(rhs,ub));
00628         assert(n==2);
00629         for (k=0; k<n; k++){
00630           int column=indices[k];
00631           assert (eq(cut[column],elements[k]));
00632         }
00633         // add cut
00634         rowLower[4]=-1.0e100;
00635         rowUpper[4]=ub;
00636         matrix.appendRow(rpv);
00637       }
00638     }
00639     nOldCuts=nRowCuts;
00640     // basis 3
00641     int rowBasis3[5]={1,1,1,-1,-1};
00642     int colBasis3[2]={1,1};
00643     warm.setSize(2,5);
00644     for (i=0;i<5;i++) {
00645       if (rowBasis3[i]<0) {
00646         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00647       } else {
00648         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00649       }
00650     }
00651     for (i=0;i<2;i++) {
00652       if (colBasis3[i]<0) {
00653         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00654       } else {
00655         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00656       }
00657     }
00658 
00659     // solution 3
00660     double colsol3[2]={2.0,1.0};
00661     test1.generateCuts(NULL, osicuts, matrix,
00662                  objective, colsol3,
00663                  colLower, colUpper,
00664                  rowLower, rowUpper, intVar, &warm);
00665     nRowCuts = osicuts.sizeRowCuts();
00666     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00667     assert (nRowCuts==nOldCuts);
00668     
00669   }
00670   // swap some rows to G
00671   if (1) {
00672     OsiCuts osicuts;
00673     CglGomory test1;
00674     int i;
00675     int nOldCuts=0,nRowCuts;
00676  
00677     // matrix data
00678     //deliberate hiccup of 2 between 0 and 1
00679     int start[5]={0,4};
00680     int length[5]={2,3};
00681     int rows[11]={0,2,-1,-1,0,1,2};
00682     double elements[11]={-7.0,-2.0,1.0e10,1.0e10,+2.0,1.0,+2.0};
00683     CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length);
00684     
00685     // rim data (objective not used just yet)
00686     double objective[2]={-4.0,1.0};
00687     double rowUpper[5]={1.0e10,3.0,1.0e10,-1.0e10,-1.0e10};
00688     double rowLower[5]={-14.0,-1.0e10,-3.0,1.0e10,1.0e10};
00689     double colLower[2]={0.0,0.0};
00690     double colUpper[2]={100.0,100.0};
00691   
00692     // integer
00693     char intVar[2]={2,2};
00694 
00695     // basis 1
00696     int rowBasis1[3]={-1,-1,1};
00697     int colBasis1[2]={1,1};
00698     CoinWarmStartBasis warm;
00699     warm.setSize(2,3);
00700     for (i=0;i<3;i++) {
00701       if (rowBasis1[i]<0) {
00702         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00703       } else {
00704         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00705       }
00706     }
00707     for (i=0;i<2;i++) {
00708       if (colBasis1[i]<0) {
00709         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00710       } else {
00711         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00712       }
00713     }
00714 
00715     // solution 1
00716     double colsol1[2]={20.0/7.0,3.0};
00717     test1.generateCuts(NULL, osicuts, matrix,
00718                  objective, colsol1,
00719                  colLower, colUpper,
00720                  rowLower, rowUpper, intVar, &warm);
00721     nRowCuts = osicuts.sizeRowCuts();
00722     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00723     assert (nRowCuts==1);
00724     // cuts always <=
00725     int testCut=0; // test first cut as stronger
00726     double rhs=2.0;
00727     double testCut1[2]={1.0,0.0};
00728     double * cut = testCut1;
00729     double * colsol = colsol1;
00730     for (i=nOldCuts; i<nRowCuts; i++){
00731       OsiRowCut rcut;
00732       CoinPackedVector rpv;
00733       rcut = osicuts.rowCut(i);
00734       rpv = rcut.row();
00735       const int n = rpv.getNumElements();
00736       const int * indices = rpv.getIndices();
00737       double* elements = rpv.getElements();
00738       double sum2=0.0;
00739       int k=0;
00740       double lb=rcut.lb();
00741       double ub=rcut.ub();
00742       for (k=0; k<n; k++){
00743         int column=indices[k];
00744         sum2 += colsol[column]*elements[k];
00745       }
00746       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00747         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00748         for (k=0; k<n; k++){
00749           int column=indices[k];
00750           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00751             colsol[column]<<") ";
00752         }
00753         std::cout <<std::endl;
00754       }
00755       if (i-nOldCuts==testCut) {
00756         assert( eq(rhs,ub));
00757         assert(n==1);
00758         for (k=0; k<n; k++){
00759           int column=indices[k];
00760           assert (eq(cut[column],elements[k]));
00761         }
00762         // add cut
00763         rowLower[3]=-1.0e100;
00764         rowUpper[3]=ub;
00765         matrix.appendRow(rpv);
00766       }
00767     }
00768     nOldCuts=nRowCuts;
00769     // basis 2
00770     int rowBasis2[4]={1,1,-1,-1};
00771     int colBasis2[2]={1,1};
00772     warm.setSize(2,4);
00773     for (i=0;i<4;i++) {
00774       if (rowBasis2[i]<0) {
00775         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00776       } else {
00777         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00778       }
00779     }
00780     for (i=0;i<2;i++) {
00781       if (colBasis2[i]<0) {
00782         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00783       } else {
00784         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00785       }
00786     }
00787 
00788     // solution 2
00789     double colsol2[2]={2.0,0.5};
00790     test1.generateCuts(NULL, osicuts, matrix,
00791                  objective, colsol2,
00792                  colLower, colUpper,
00793                  rowLower, rowUpper, intVar, &warm);
00794     nRowCuts = osicuts.sizeRowCuts();
00795     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00796     assert (nRowCuts-nOldCuts==1);
00797     // cuts always <=
00798     testCut=0; // test first cut as stronger
00799     rhs=1.0;
00800     double testCut2[2]={1.0,-1.0};
00801     cut = testCut2;
00802     colsol = colsol2;
00803     for (i=nOldCuts; i<nRowCuts; i++){
00804       OsiRowCut rcut;
00805       CoinPackedVector rpv;
00806       rcut = osicuts.rowCut(i);
00807       rpv = rcut.row();
00808       const int n = rpv.getNumElements();
00809       const int * indices = rpv.getIndices();
00810       double* elements = rpv.getElements();
00811       double sum2=0.0;
00812       int k=0;
00813       double lb=rcut.lb();
00814       double ub=rcut.ub();
00815       for (k=0; k<n; k++){
00816         int column=indices[k];
00817         sum2 += colsol[column]*elements[k];
00818       }
00819       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00820         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00821         for (k=0; k<n; k++){
00822           int column=indices[k];
00823           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00824             colsol[column]<<") ";
00825         }
00826         std::cout <<std::endl;
00827       }
00828       if (i-nOldCuts==testCut) {
00829         assert( eq(rhs,ub));
00830         assert(n==2);
00831         for (k=0; k<n; k++){
00832           int column=indices[k];
00833           assert (eq(cut[column],elements[k]));
00834         }
00835         // add cut
00836         rowLower[4]=-1.0e100;
00837         rowUpper[4]=ub;
00838         matrix.appendRow(rpv);
00839       }
00840     }
00841     nOldCuts=nRowCuts;
00842     // basis 3
00843     int rowBasis3[5]={1,1,1,-1,-1};
00844     int colBasis3[2]={1,1};
00845     warm.setSize(2,5);
00846     for (i=0;i<5;i++) {
00847       if (rowBasis3[i]<0) {
00848         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00849       } else {
00850         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00851       }
00852     }
00853     for (i=0;i<2;i++) {
00854       if (colBasis3[i]<0) {
00855         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00856       } else {
00857         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00858       }
00859     }
00860 
00861     // solution 3
00862     double colsol3[2]={2.0,1.0};
00863     test1.generateCuts(NULL, osicuts, matrix,
00864                  objective, colsol3,
00865                  colLower, colUpper,
00866                  rowLower, rowUpper, intVar, &warm);
00867     nRowCuts = osicuts.sizeRowCuts();
00868     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00869     assert (nRowCuts==nOldCuts);
00870     
00871   }
00872 
00873 
00874   // NOW mixed integer gomory cuts
00875 
00876   // Test explicit form - (pg 130 Wolsey)
00877   // Some arrays left same size as previously although not used in full
00878   if (1) {
00879     OsiCuts osicuts;
00880     CglGomory test1;
00881     int i;
00882     int nOldCuts=0,nRowCuts;
00883  
00884     // matrix data
00885     //deliberate hiccup of 2 between 0 and 1
00886     int start[5]={0,4,7,8,9};
00887     int length[5]={2,3,1,1,1};
00888     int rows[11]={0,2,-1,-1,0,1,2,0,1,2};
00889     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,1,1};
00890     CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length);
00891     
00892     // rim data (objective not used just yet)
00893     double objective[7]={-4.0,1.0,0.0,0.0,0.0,0.0,0.0};
00894     double rowLower[5]={14.0,3.0,3.0,1.0e10,1.0e10};
00895     double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10};
00896     double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0};
00897     double colUpper[7]={100.0,100.0,100.0,100.0,100.0,100.0,100.0};
00898   
00899     // integer
00900     char intVar[7]={2,0,0,0,0,0,0};
00901 
00902     // basis 1
00903     int rowBasis1[3]={-1,-1,-1};
00904     int colBasis1[5]={1,1,-1,-1,1};
00905     CoinWarmStartBasis warm;
00906     warm.setSize(5,3);
00907     for (i=0;i<3;i++) {
00908       if (rowBasis1[i]<0) {
00909         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00910       } else {
00911         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00912       }
00913     }
00914     for (i=0;i<5;i++) {
00915       if (colBasis1[i]<0) {
00916         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00917       } else {
00918         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00919       }
00920     }
00921 
00922     // solution 1
00923     double colsol1[5]={20.0/7.0,3.0,0.0,0.0,23.0/7.0};
00924     test1.generateCuts(NULL, osicuts, matrix,
00925                  objective, colsol1,
00926                  colLower, colUpper,
00927                  rowLower, rowUpper, intVar, &warm);
00928     nRowCuts = osicuts.sizeRowCuts();
00929     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
00930     assert (nRowCuts==1);
00931     // cuts always <=
00932     int testCut=0; // test first cut as stronger
00933     double rhs=-6.0/7.0;
00934     double testCut1[5]={0.0,0.0,-1.0/7.0,-2.0/7.0,0.0};
00935     double * cut = testCut1;
00936     double * colsol = colsol1;
00937     for (i=nOldCuts; i<nRowCuts; i++){
00938       OsiRowCut rcut;
00939       CoinPackedVector rpv;
00940       rcut = osicuts.rowCut(i);
00941       rpv = rcut.row();
00942       const int n = rpv.getNumElements();
00943       const int * indices = rpv.getIndices();
00944       double* elements = rpv.getElements();
00945       double sum2=0.0;
00946       int k=0;
00947       double lb=rcut.lb();
00948       double ub=rcut.ub();
00949       for (k=0; k<n; k++){
00950         int column=indices[k];
00951         sum2 += colsol[column]*elements[k];
00952       }
00953       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
00954         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
00955         for (k=0; k<n; k++){
00956           int column=indices[k];
00957           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
00958             colsol[column]<<") ";
00959         }
00960         std::cout <<std::endl;
00961       }
00962       if (i-nOldCuts==testCut) {
00963         assert( eq(rhs,ub));
00964         assert(n==2);
00965         for (k=0; k<n; k++){
00966           int column=indices[k];
00967           assert (eq(cut[column],elements[k]));
00968         }
00969         // add cut
00970         // explicit slack
00971         matrix.setDimensions(-1,6);
00972         rpv.insert(5,1.0); // to get cut in book
00973         rowLower[3]=ub;
00974         rowUpper[3]=ub;
00975         matrix.appendRow(rpv);
00976       }
00977     }
00978     nOldCuts=nRowCuts;
00979     // basis 2
00980     int rowBasis2[4]={-1,-1,-1,-1};
00981     int colBasis2[6]={1,1,1,1,-1,-1};
00982     warm.setSize(6,4);
00983     for (i=0;i<4;i++) {
00984       if (rowBasis2[i]<0) {
00985         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
00986       } else {
00987         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
00988       }
00989     }
00990     for (i=0;i<6;i++) {
00991       if (colBasis2[i]<0) {
00992         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
00993       } else {
00994         warm.setStructStatus(i,CoinWarmStartBasis::basic);
00995       }
00996     }
00997 
00998     // solution 2
00999     double colsol2[6]={2.0,0.5,1.0,2.5,0.0,0.0};
01000     test1.generateCuts(NULL, osicuts, matrix,
01001                  objective, colsol2,
01002                  colLower, colUpper,
01003                  rowLower, rowUpper, intVar, &warm);
01004     nRowCuts = osicuts.sizeRowCuts();
01005     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01006     assert (nRowCuts==nOldCuts);
01007     
01008   }
01009   // Test explicit form - this time with x4 flipped 
01010   if (1) {
01011     OsiCuts osicuts;
01012     CglGomory test1;
01013     int i;
01014     int nOldCuts=0,nRowCuts;
01015  
01016     // matrix data
01017     //deliberate hiccup of 2 between 0 and 1
01018     int start[5]={0,4,7,8,9};
01019     int length[5]={2,3,1,1,1};
01020     int rows[11]={0,2,-1,-1,0,1,2,0,1,2};
01021     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0,1,-1,1};
01022     CoinPackedMatrix matrix(true,3,5,8,elements,rows,start,length);
01023     
01024     // rim data (objective not used just yet)
01025     double objective[7]={-4.0,1.0,0.0,0.0,0.0,0.0,0.0};
01026     double rowLower[5]={14.0,-5.0,3.0,1.0e10,1.0e10};
01027     double rowUpper[5]={14.0,-5.0,3.0,-1.0e10,-1.0e10};
01028     double colLower[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0};
01029     double colUpper[7]={100.0,100.0,100.0,8.0,100.0,100.0,100.0};
01030   
01031     // integer
01032     char intVar[7]={2,0,0,0,0,0,0};
01033 
01034     // basis 1
01035     int rowBasis1[3]={-1,-1,-1};
01036     int colBasis1[5]={1,1,-1,-1,1};
01037     CoinWarmStartBasis warm;
01038     warm.setSize(5,3);
01039     for (i=0;i<3;i++) {
01040       if (rowBasis1[i]<0) {
01041         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01042       } else {
01043         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01044       }
01045     }
01046     for (i=0;i<5;i++) {
01047       if (colBasis1[i]<0) {
01048         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01049       } else {
01050         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01051       }
01052     }
01053 
01054     // solution 1
01055     double colsol1[5]={20.0/7.0,3.0,0.0,8.0,23.0/7.0};
01056     test1.generateCuts(NULL, osicuts, matrix,
01057                  objective, colsol1,
01058                  colLower, colUpper,
01059                  rowLower, rowUpper, intVar, &warm);
01060     nRowCuts = osicuts.sizeRowCuts();
01061     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01062     assert (nRowCuts==1);
01063     // cuts always <=
01064     int testCut=0; 
01065     double rhs=10.0/7.0;
01066     double testCut1[5]={0.0,0.0,-1.0/7.0,2.0/7.0,0.0};
01067     double * cut = testCut1;
01068     double * colsol = colsol1;
01069     for (i=nOldCuts; i<nRowCuts; i++){
01070       OsiRowCut rcut;
01071       CoinPackedVector rpv;
01072       rcut = osicuts.rowCut(i);
01073       rpv = rcut.row();
01074       const int n = rpv.getNumElements();
01075       const int * indices = rpv.getIndices();
01076       double* elements = rpv.getElements();
01077       double sum2=0.0;
01078       int k=0;
01079       double lb=rcut.lb();
01080       double ub=rcut.ub();
01081       for (k=0; k<n; k++){
01082         int column=indices[k];
01083         sum2 += colsol[column]*elements[k];
01084       }
01085       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
01086         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
01087         for (k=0; k<n; k++){
01088           int column=indices[k];
01089           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
01090             colsol[column]<<") ";
01091         }
01092         std::cout <<std::endl;
01093       }
01094       if (i-nOldCuts==testCut) {
01095         assert( eq(rhs,ub));
01096         assert(n==2);
01097         for (k=0; k<n; k++){
01098           int column=indices[k];
01099           assert (eq(cut[column],elements[k]));
01100         }
01101         // add cut
01102         // explicit slack
01103         matrix.setDimensions(-1,6);
01104         rpv.insert(5,1.0); // to get cut in book
01105         rowLower[3]=ub;
01106         rowUpper[3]=ub;
01107         matrix.appendRow(rpv);
01108       }
01109     }
01110     nOldCuts=nRowCuts;
01111     // basis 2
01112     int rowBasis2[4]={-1,-1,-1,-1};
01113     int colBasis2[6]={1,1,1,1,-1,-1};
01114     warm.setSize(6,4);
01115     for (i=0;i<4;i++) {
01116       if (rowBasis2[i]<0) {
01117         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01118       } else {
01119         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01120       }
01121     }
01122     for (i=0;i<6;i++) {
01123       if (colBasis2[i]<0) {
01124         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01125       } else {
01126         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01127       }
01128     }
01129 
01130     // solution 2
01131     double colsol2[6]={2.0,0.5,1.0,5.5,0.0,0.0};
01132     test1.generateCuts(NULL, osicuts, matrix,
01133                  objective, colsol2,
01134                  colLower, colUpper,
01135                  rowLower, rowUpper, intVar, &warm);
01136     nRowCuts = osicuts.sizeRowCuts();
01137     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01138     assert (nRowCuts==nOldCuts);
01139     
01140   }
01141   // Test with slacks 
01142   if (1) {
01143     OsiCuts osicuts;
01144     CglGomory test1;
01145     int i;
01146     int nOldCuts=0,nRowCuts;
01147  
01148     // matrix data
01149     //deliberate hiccup of 2 between 0 and 1
01150     int start[5]={0,4};
01151     int length[5]={2,3};
01152     int rows[11]={0,2,-1,-1,0,1,2};
01153     double elements[11]={7.0,2.0,1.0e10,1.0e10,-2.0,1.0,-2.0};
01154     CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length);
01155     
01156     // rim data (objective not used just yet)
01157     double objective[2]={-4.0,1.0};
01158     double rowLower[5]={-1.0e10,-1.0e10,-1.0e10,1.0e10,1.0e10};
01159     double rowUpper[5]={14.0,3.0,3.0,-1.0e10,-1.0e10};
01160     double colLower[2]={0.0,0.0};
01161     double colUpper[2]={100.0,100.0};
01162   
01163     // integer
01164     char intVar[2]={2,0};
01165 
01166     // basis 1
01167     int rowBasis1[3]={-1,-1,1};
01168     int colBasis1[2]={1,1};
01169     CoinWarmStartBasis warm;
01170     warm.setSize(2,3);
01171     for (i=0;i<3;i++) {
01172       if (rowBasis1[i]<0) {
01173         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01174       } else {
01175         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01176       }
01177     }
01178     for (i=0;i<2;i++) {
01179       if (colBasis1[i]<0) {
01180         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01181       } else {
01182         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01183       }
01184     }
01185 
01186     // solution 1
01187     double colsol1[2]={20.0/7.0,3.0};
01188     test1.generateCuts(NULL, osicuts, matrix,
01189                  objective, colsol1,
01190                  colLower, colUpper,
01191                  rowLower, rowUpper, intVar, &warm);
01192     nRowCuts = osicuts.sizeRowCuts();
01193     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01194     assert (nRowCuts==1);
01195     // cuts always <=
01196     int testCut=0; // test first cut as stronger
01197     double rhs=2.0;
01198     double testCut1[2]={1.0,0.0};
01199     double * cut = testCut1;
01200     double * colsol = colsol1;
01201     for (i=nOldCuts; i<nRowCuts; i++){
01202       OsiRowCut rcut;
01203       CoinPackedVector rpv;
01204       rcut = osicuts.rowCut(i);
01205       rpv = rcut.row();
01206       const int n = rpv.getNumElements();
01207       const int * indices = rpv.getIndices();
01208       double* elements = rpv.getElements();
01209       double sum2=0.0;
01210       int k=0;
01211       double lb=rcut.lb();
01212       double ub=rcut.ub();
01213       for (k=0; k<n; k++){
01214         int column=indices[k];
01215         sum2 += colsol[column]*elements[k];
01216       }
01217       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
01218         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
01219         for (k=0; k<n; k++){
01220           int column=indices[k];
01221           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
01222             colsol[column]<<") ";
01223         }
01224         std::cout <<std::endl;
01225       }
01226       if (i-nOldCuts==testCut) {
01227         assert( eq(rhs,ub));
01228         assert(n==1);
01229         for (k=0; k<n; k++){
01230           int column=indices[k];
01231           assert (eq(cut[column],elements[k]));
01232         }
01233         // add cut
01234         rowLower[3]=-1.0e100;
01235         rowUpper[3]=ub;
01236         matrix.appendRow(rpv);
01237       }
01238     }
01239     nOldCuts=nRowCuts;
01240     // basis 2
01241     int rowBasis2[4]={1,1,-1,-1};
01242     int colBasis2[2]={1,1};
01243     warm.setSize(2,4);
01244     for (i=0;i<4;i++) {
01245       if (rowBasis2[i]<0) {
01246         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01247       } else {
01248         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01249       }
01250     }
01251     for (i=0;i<2;i++) {
01252       if (colBasis2[i]<0) {
01253         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01254       } else {
01255         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01256       }
01257     }
01258 
01259     // solution 2
01260     double colsol2[2]={2.0,0.5};
01261     test1.generateCuts(NULL, osicuts, matrix,
01262                  objective, colsol2,
01263                  colLower, colUpper,
01264                  rowLower, rowUpper, intVar, &warm);
01265     nRowCuts = osicuts.sizeRowCuts();
01266     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01267     assert (nRowCuts==nOldCuts);
01268     
01269   }
01270   // swap some rows to G
01271   if (1) {
01272     OsiCuts osicuts;
01273     CglGomory test1;
01274     int i;
01275     int nOldCuts=0,nRowCuts;
01276  
01277     // matrix data
01278     //deliberate hiccup of 2 between 0 and 1
01279     int start[5]={0,4};
01280     int length[5]={2,3};
01281     int rows[11]={0,2,-1,-1,0,1,2};
01282     double elements[11]={-7.0,-2.0,1.0e10,1.0e10,+2.0,1.0,+2.0};
01283     CoinPackedMatrix matrix(true,3,2,5,elements,rows,start,length);
01284     
01285     // rim data (objective not used just yet)
01286     double objective[2]={-4.0,1.0};
01287     double rowUpper[5]={1.0e10,3.0,1.0e10,-1.0e10,-1.0e10};
01288     double rowLower[5]={-14.0,-1.0e10,-3.0,1.0e10,1.0e10};
01289     double colLower[2]={0.0,0.0};
01290     double colUpper[2]={100.0,100.0};
01291   
01292     // integer
01293     char intVar[2]={2,0};
01294 
01295     // basis 1
01296     int rowBasis1[3]={-1,-1,1};
01297     int colBasis1[2]={1,1};
01298     CoinWarmStartBasis warm;
01299     warm.setSize(2,3);
01300     for (i=0;i<3;i++) {
01301       if (rowBasis1[i]<0) {
01302         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01303       } else {
01304         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01305       }
01306     }
01307     for (i=0;i<2;i++) {
01308       if (colBasis1[i]<0) {
01309         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01310       } else {
01311         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01312       }
01313     }
01314 
01315     // solution 1
01316     double colsol1[2]={20.0/7.0,3.0};
01317     test1.generateCuts(NULL, osicuts, matrix,
01318                  objective, colsol1,
01319                  colLower, colUpper,
01320                  rowLower, rowUpper, intVar, &warm);
01321     nRowCuts = osicuts.sizeRowCuts();
01322     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01323     assert (nRowCuts==1);
01324     // cuts always <=
01325     int testCut=0; // test first cut as stronger
01326     double rhs=2.0;
01327     double testCut1[2]={1.0,0.0};
01328     double * cut = testCut1;
01329     double * colsol = colsol1;
01330     for (i=nOldCuts; i<nRowCuts; i++){
01331       OsiRowCut rcut;
01332       CoinPackedVector rpv;
01333       rcut = osicuts.rowCut(i);
01334       rpv = rcut.row();
01335       const int n = rpv.getNumElements();
01336       const int * indices = rpv.getIndices();
01337       double* elements = rpv.getElements();
01338       double sum2=0.0;
01339       int k=0;
01340       double lb=rcut.lb();
01341       double ub=rcut.ub();
01342       for (k=0; k<n; k++){
01343         int column=indices[k];
01344         sum2 += colsol[column]*elements[k];
01345       }
01346       if (sum2 >ub + 1.0e-7 ||sum2 < lb - 1.0e-7) {
01347         std::cout<<"Cut "<<i<<" lb "<<lb<<" solution "<<sum2<<" ub "<<ub<<std::endl;
01348         for (k=0; k<n; k++){
01349           int column=indices[k];
01350           std::cout<<"(col="<<column<<",el="<<elements[k]<<",sol="<<
01351             colsol[column]<<") ";
01352         }
01353         std::cout <<std::endl;
01354       }
01355       if (i-nOldCuts==testCut) {
01356         assert( eq(rhs,ub));
01357         assert(n==1);
01358         for (k=0; k<n; k++){
01359           int column=indices[k];
01360           assert (eq(cut[column],elements[k]));
01361         }
01362         // add cut
01363         rowLower[3]=-1.0e100;
01364         rowUpper[3]=ub;
01365         matrix.appendRow(rpv);
01366       }
01367     }
01368     nOldCuts=nRowCuts;
01369     // basis 2
01370     int rowBasis2[4]={1,1,-1,-1};
01371     int colBasis2[2]={1,1};
01372     warm.setSize(2,4);
01373     for (i=0;i<4;i++) {
01374       if (rowBasis2[i]<0) {
01375         warm.setArtifStatus(i,CoinWarmStartBasis::atLowerBound);
01376       } else {
01377         warm.setArtifStatus(i,CoinWarmStartBasis::basic);
01378       }
01379     }
01380     for (i=0;i<2;i++) {
01381       if (colBasis2[i]<0) {
01382         warm.setStructStatus(i,CoinWarmStartBasis::atLowerBound);
01383       } else {
01384         warm.setStructStatus(i,CoinWarmStartBasis::basic);
01385       }
01386     }
01387 
01388     // solution 2
01389     double colsol2[2]={2.0,0.5};
01390     test1.generateCuts(NULL, osicuts, matrix,
01391                  objective, colsol2,
01392                  colLower, colUpper,
01393                  rowLower, rowUpper, intVar, &warm);
01394     nRowCuts = osicuts.sizeRowCuts();
01395     std::cout<<"There are "<<nRowCuts<<" gomory cuts"<<std::endl;
01396     assert (nRowCuts==nOldCuts);
01397     
01398   }
01399 
01400   // Miplib3 problem p0033
01401   if (1) {
01402     // Setup
01403     OsiSolverInterface  * siP = baseSiP->clone();
01404     std::string fn(mpsDir+"p0033");
01405     siP->readMps(fn.c_str(),"mps");
01406     siP->activateRowCutDebugger("p0033");
01407     CglGomory test;
01408 
01409     // Solve the LP relaxation of the model and
01410     // print out ofv for sake of comparison 
01411     siP->initialSolve();
01412     double lpRelaxBefore=siP->getObjValue();
01413     assert( eq(lpRelaxBefore, 2520.5717391304347) );
01414     double mycs[] = {0, 1, 0, 0, -2.0837010502455788e-19, 1, 0, 0, 1,
01415                        0.021739130434782594, 0.35652173913043478, 
01416                        -6.7220534694101275e-18, 5.3125906451789717e-18, 
01417                        1, 0, 1.9298798670241979e-17, 0, 0, 0,
01418                        7.8875708048320448e-18, 0.5, 0, 
01419                        0.85999999999999999, 1, 1, 0.57999999999999996,
01420                        1, 0, 1, 0, 0.25, 0, 0.67500000000000004};
01421     siP->setColSolution(mycs);
01422 #ifdef CGL_DEBUG
01423     printf("\n\nOrig LP min=%f\n",lpRelaxBefore);
01424 #endif
01425     
01426     OsiCuts cuts;    
01427     
01428     // Test generateCuts method
01429     test.generateCuts(*siP,cuts);
01430     OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);
01431     
01432     siP->resolve();
01433     double lpRelaxAfter=siP->getObjValue(); 
01434     //assert( eq(lpRelaxAfter, 2592.1908295194507) );
01435     assert( lpRelaxAfter> 2550.0 );
01436 #ifdef CGL_DEBUG
01437     printf("\n\nOrig LP min=%f\n",lpRelaxBefore);
01438     printf("\n\nFinal LP min=%f\n",lpRelaxAfter);
01439 #endif
01440     assert( lpRelaxBefore < lpRelaxAfter );
01441     
01442     delete siP;
01443   } 
01444   //exit(0);
01445     
01446 }
01447 

Generated on Wed Dec 3 14:34:54 2003 for Cgl by doxygen 1.3.5