/home/coin/SVN-release/OS-2.4.0/Couenne/src/cut/sdpcuts/disjunctive_cuts.cpp

Go to the documentation of this file.
00001 /* $Id: disjunctive_cuts.cpp 508 2011-02-15 21:52:44Z pbelotti $
00002  *
00003  * Name:    disjunctive_cuts.cpp
00004  * Author:  Andrea Qualizza
00005  * Purpose: 
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <disjunctive_cuts.hpp>
00011 
00012 #include <CoinPackedVector.hpp>
00013 #include <CglCutGenerator.hpp>
00014 #include <OsiSolverInterface.hpp>
00015 #include <AsxBmqsTest.hpp>
00016 #include <AsxBmqsUtil.hpp>
00017 #include <AsxUtil.hpp>
00018 #include <AsxBpTest.hpp>
00019 #include <AsxBpFracData.hpp>
00020 #include <AsxUtil.hpp>
00021 #include <OsiClpSolverInterface.hpp>
00022 #include <AsxBpDisjunction.hpp>
00023 #include <AsxBpCGLP.hpp>
00024 #include <cplex.h>
00025 #include <dsyevx_wrapper.hpp>
00026 #include <OsiXxxSolverInterface.hpp>
00027 #include <sdpcuts.hpp>
00028 #include <tracer.hpp>
00029 #include <misc_util.hpp>
00030 
00031 
00032 void disjunctiveCutGen(const OsiSolverInterface &si, OsiCuts &cs, const double *sol, int n, Tracer *tracer) {
00033         Timer disjcuts_timer;
00034         disjcuts_timer.start();
00035         int origcuts = cs.sizeCuts();
00036 
00037         //prepare matrix X-xxT for eigendecomposition
00038         double *A = new double[n*n];
00039         double *z = new double[n*n];
00040         double *w = new double[n];
00041         for (int i=0;i<n;i++) {
00042                 for (int j=i;j<n;j++) {
00043                         A[(i*n) + j] = sol[indexQ(i,j,n)] - (sol[i] * sol[j]);
00044                         A[(j*n) + i] = sol[indexQ(i,j,n)] - (sol[i] * sol[j]);
00045                 }
00046         }
00047 
00048         double *coeff = new double[n];
00049         int *ind = new int[n];
00050         // create indices Xind
00051         int **Xind = new int*[n];
00052         for (int i=0;i<n;i++) {
00053                 Xind[i] = new int[n];
00054         }
00055         for (int i=0;i<n;i++) {
00056                 for (int j=i;j<n;j++) {
00057                         Xind[i][j] = indexQ(i,j,n);
00058                         Xind[j][i] = indexQ(i,j,n);
00059                 }
00060         }
00061 
00062         int m;
00063         dsyevx_wrapper_only_positive(n,A,m,w,z,tracer);
00064 
00065 #ifdef TRACE_DISJUNCTIVE_CUTS
00066         si.writeMps("outerappr.mps");
00067         
00068         printf("X-xxT positive ev: ");
00069         for (int i=0;i<m;i++) {
00070         printf("%.5f ",w[i]);
00071         }
00072         printf("\n");
00073 #endif
00074 
00075         // Cplex environment for AsxBp
00076         CPXENVptr asxenv;
00077         util_open_cpxenv(asxenv);
00078 
00079         // TODO:probably is more efficient if we copy the current solution and the current objective function and we use the same solver iterface to generate min and max, and then we restore current solution and obj functions for warm restart
00080 
00081         // clone the current outer-approximation
00082         OsiSolverInterface *sifull = si.clone(true);
00083         //reset current objective function
00084         for (int i=0;i<sifull->getNumCols();i++) {
00085                 sifull->setObjCoeff(i,0.0);
00086         }
00087 
00088 
00089         // for each positive eigenvector we try to generate a disjunctive cut
00090         for (int k=0;k<m;k++) {
00091 if (w[k] < 10e-8)
00092 continue;
00093                 double *curr_ev = z + k *n;
00094                 for (int i=0;i<n;i++) {
00095                         sifull->setObjCoeff(i,curr_ev[i]);
00096                 }
00097                 // compute lb
00098                 sifull->setObjSense(1.0); // 1.0 sets min, -1.0 sets max
00099                 sifull->resolve();
00100                 solver_status(sifull);
00101                 double lb = sifull->getObjValue();
00102                 //compute ub
00103                 sifull->setObjSense(-1.0); // 1.0 sets min, -1.0 sets max
00104                 sifull->resolve();
00105                 solver_status(sifull);
00106                 double ub = sifull->getObjValue();
00107                 
00108                 
00109                 // create CoinPackedVector
00110                 int cnt = 0;
00111                 for(int i=0;i<n;i++) {
00112                         if(curr_ev[i] != 0.0) {
00113                                 coeff[cnt] = curr_ev[i];
00114                                 ind[cnt++] = i;
00115                         }
00116                 }
00117                 CoinPackedVector *curr_ev_cpv = new CoinPackedVector(cnt, ind,coeff, false);
00118 
00119 #ifdef TRACE_DISJUNCTIVE_CUTS
00120                 printf("ev[%d]=%.5f   lb=%.5f   ub=%.5f\n",k,w[k],lb,ub);
00121 #endif
00122 
00123                 //call to the disjunctive cut generator function
00124                 AsxBpDisjunction* dsj=
00125                         AsxBmqs_compute_disjunction(curr_ev_cpv,lb,ub,Xind,sol,si.getNumCols());
00126 
00127 #ifdef TRACE_DISJUNCTIVE_CUTS
00128                 dsj->fprint("dsj.txt");
00129 #endif
00130 
00131                 // generate disjunctive cut
00132                 AsxBpFracData* fdata=AsxBpFracData::instance(&si,sol);
00133                 AsxBpCGLP* cglp=AsxBpCGLP::instance(fdata, fdata, dsj, asxenv);
00134 
00135                 cglp->generate_cuts(&cs, false);
00136                 
00137                 delete curr_ev_cpv;
00138                 delete cglp;
00139                 delete fdata;
00140                 delete dsj;
00141         }
00142 
00143         delete sifull;
00144 
00145         delete [] coeff;
00146         delete [] ind;  
00147 
00148         for (int i=0;i<n;i++)
00149                 delete [] Xind[i];
00150         delete [] Xind;
00151 
00152         delete [] A;
00153         delete [] z;
00154         delete [] w;
00155 
00156         tracer->setDisjunctiveCutsTime(disjcuts_timer.time());
00157         tracer->setDisjunctiveCutsTotalCuts(cs.sizeCuts() - origcuts);
00158 }
00159 
00160 
00161 

Generated on Thu Sep 22 03:05:56 2011 by  doxygen 1.4.7