/home/coin/SVN-release/OS-2.4.1/Couenne/src/cut/sdpcuts/sdpsol.cpp

Go to the documentation of this file.
00001 /* $Id: sdpsol.cpp 508 2011-02-15 21:52:44Z pbelotti $
00002  *
00003  * Name:    sdpsol.cpp
00004  * Author:  Andrea Qualizza
00005  * Purpose: 
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 
00013 #include <misc_util.hpp>
00014 #include <OsiXxxSolverInterface.hpp>
00015 #include <populate.hpp>
00016 
00017 #include <CoinPackedVector.hpp>
00018 
00019 
00020 
00021 //#define DEBUG_SDPSOL
00022 #define ADD_LB
00023 #define ADD_UB
00024 #define ADD_RLT
00025 
00026 double getCoinPackedVectorElementAt(const CoinPackedVector vector, int index){
00027         int size = vector.getNumElements();
00028         const int *indices = vector.getIndices();
00029         const double *elements = vector.getElements();
00030         for (int i=0;i<size;i++)
00031                 if (indices[i] == index)
00032                         return elements[i];
00033         return 0.0;
00034 }
00035 
00036 void removeCoinPackedVectorColumn(CoinPackedVector &vector, int index) {
00037         int size = vector.getNumElements();
00038         const int *indices = vector.getIndices();
00039         const double *elements = vector.getElements();
00040 
00041         int *newIndices = new int[size];
00042         double *newElements = new double[size];
00043         int newSize = 0;
00044         for (int i=0;i<size;i++) {
00045                 if (indices[i] < index) {
00046                         newElements[newSize] = elements[i];
00047                         newIndices[newSize] = indices[i];
00048                         newSize++;
00049                 } else if (indices[i] > index) {
00050                         newElements[newSize] = elements[i];
00051                         newIndices[newSize] = indices[i]-1;
00052                         newSize++;
00053                 }
00054         }
00055         
00056         vector.clear();
00057         vector.setVector(newSize,newIndices,newElements);
00058         delete [] newIndices;
00059         delete [] newElements;
00060 }
00061 
00062 
00063 void print(CoinPackedVector r) {
00064         const int *indices = r.getIndices();
00065         const double *elements = r.getElements();
00066         int size = r.getNumElements();
00067         for(int i=0;i<size;i++) {
00068                 printf("r[%d]=%.1f  ",indices[i],elements[i]);
00069         }
00070         printf("\n");
00071 }
00072 
00073 #if 0
00074 int main (int argc, const char **argv) {
00075         if (argc < 2) {
00076                 printf("Missing argument [mps file] <[matlab file]>\n");
00077                 return 1;
00078         }
00079 
00080         FILE *matlabout;
00081         if (argc >= 3)
00082                 matlabout = fopen(argv[2],"w");
00083         else
00084                 matlabout = stdout;
00085 
00086         // determine problem name
00087         char name[256];
00088         char *name_pos = strrchr(const_cast <char *> (argv[1]), '/');
00089         if(name_pos != NULL)
00090                 strcpy(name, &(name_pos[1]));
00091         else
00092                 strcpy(name, argv[1]);
00093         char *last_dot_pos = strrchr(name, '.');
00094         if(last_dot_pos !=NULL)
00095                 last_dot_pos[0] = '\0';
00096 
00097         OsiXxxSolverInterface si;
00098 
00099         Timer globaltimer;
00100         globaltimer.start();
00101 
00102         int n;                  // number of x_i variables
00103         int t;                  // number of y_i variables
00104         int origCons_tmp;               // number of original constraints
00105         double *b_tmp;          // obj coefficients for the x_i variables
00106         double *c_tmp;          // obj coefficients for the y_i variables
00107         double **Q_tmp;         // obj coefficients for the x_i_j variables
00108         double constant;        // obj function additive constant
00109         double **origMat_tmp;   // original problem matrix
00110         double *origRhs_tmp;    // original constraints' RHS
00111         char *origSense_tmp;    // original constraints' sense
00112         double *xlb_tmp;        // lower bounds on x_i vars
00113         double *xub_tmp;        // upper bounds on x_i vars
00114         double *ylb_tmp;        // lower bounds on y_i vars
00115         double *yub_tmp;        // upper bounds on y_i vars
00116 
00117 
00118         int status;
00119 
00120         // read problem file
00121         status = populateProblem (argv[1],&n, &t, &origCons_tmp, &b_tmp, &c_tmp, 
00122                 &Q_tmp, &constant, &origMat_tmp, &origRhs_tmp, &origSense_tmp, 
00123                 &xlb_tmp, &xub_tmp, &ylb_tmp, &yub_tmp,&si);
00124 
00125         if (status) {
00126                 printf("ERROR! _\n");
00127                 exit(1);
00128         }
00129 
00130 
00131         printf("Problem    : %s\n",argv[1]);
00132         printf("n (x vars) : %d\n",n);
00133         printf("t (y vars) : %d\n",t);
00134         printf("orig. cons : %d\n",origCons_tmp);
00135         printf("tot.  cons : %d\n",si.getNumRows());
00136 
00137 
00138 
00139         // ext vars indices
00140         int *extvar_i = new int[si.getNumCols()];
00141         int *extvar_j = new int[si.getNumCols()];
00142         for(int i=0;i<si.getNumCols();i++) {
00143                 extvar_i[i] = -1;
00144                 extvar_j[i] = -1;
00145         }
00146         int tmpcnt = n;
00147         for (int i=0;i<n;i++)
00148                 for(int j=i;j<n;j++) {
00149                         extvar_i[tmpcnt]  = i;
00150                         extvar_j[tmpcnt]  = j;
00151                         //printf("i=%d j=%d n=%d indexQ(i,j,n)=%d tmpcnt = %d\n"
00152                         //      ,i,j,n,indexQ(i,j,n),tmpcnt);
00153                         assert(indexQ(i,j,n) == tmpcnt);
00154                         tmpcnt++;
00155                 }
00156 
00157         // determining slack variables
00158         int slackvars_cnt = 0;
00159         
00160         // determine slack variables for lb ub
00161         int slacklb_cnt = 0;
00162         int slackub_cnt = 0;
00163         const double *si_lb = si.getColLower();
00164         const double *si_ub = si.getColUpper();
00165         int *lb_origidx = new int[si.getNumCols()];
00166         int *ub_origidx = new int[si.getNumCols()];
00167         int *lb_slackvaridx = new int[si.getNumCols()];
00168         int *ub_slackvaridx = new int[si.getNumCols()];
00169         double *lb_value = new double[si.getNumCols()];
00170         double *ub_value = new double[si.getNumCols()];
00171 
00172         for (int i=0;i<si.getNumCols();i++) {
00173 #ifdef ADD_LB
00174                 lb_origidx[slacklb_cnt] = i;
00175                 lb_value[slacklb_cnt] = si_lb[i];
00176                 lb_slackvaridx[slacklb_cnt] = slackvars_cnt++;
00177                 slacklb_cnt++;
00178 #endif
00179 #ifdef ADD_UB
00180                 ub_origidx[slackub_cnt] = i;
00181                 ub_value[slackub_cnt] = si_ub[i];
00182                 ub_slackvaridx[slackub_cnt] = slackvars_cnt++;
00183                 slackub_cnt++;
00184 #endif
00185         }
00186 
00187         
00188         // determine slack variables for constraints
00189         int slackcons_cnt = 0;
00190         const char *si_sense = si.getRowSense();
00191         int *slackcons_varidx = new int[si.getNumRows()];
00192 
00193         for (int i=0;i<si.getNumRows();i++) {
00194                 slackcons_varidx[i] = -1;
00195                 if (si_sense[i] != 'E') {
00196 #ifndef ADD_RLT
00197                 if (i >= origCons_tmp )
00198 #endif
00199                         {
00200                                 slackcons_varidx[i] = slackvars_cnt++;
00201                                 slackcons_cnt++;
00202                         }
00203                 }
00204         }
00205 
00206         int yvars_first = slackvars_cnt;
00207         int sdpvars_first = yvars_first + t;
00208         
00209         int cons = 0;
00210 
00211 
00212 #ifdef DEBUG_SDPSOL
00213 printf("n = %d     t = %d\n",n,t);
00214 printf("\n");
00215 printf("slackvars_cnt = %d\n",slackvars_cnt);
00216 printf("\n");
00217 printf("slackcons_cnt = %d\n",slackcons_cnt);
00218 printf("slacklb_cnt = %d\n",slacklb_cnt);
00219 printf("slackub_cnt = %d\n",slackub_cnt);
00220 printf("\n");
00221 printf("yvars_first = %d\n",yvars_first);
00222 printf("sdpvars_first = %d\n",sdpvars_first);
00223 
00224 printf("\n");
00225 printf("lb_origidx:     ");
00226 for (int i=0;i<slacklb_cnt;i++) {
00227 printf("[%d]:%d  ",i,lb_origidx[i]);
00228 }
00229 printf("\n");
00230 printf("lb_slackvaridx: ");
00231 for (int i=0;i<slacklb_cnt;i++) {
00232 printf("[%d]:%d  ",i,lb_slackvaridx[i]);
00233 }
00234 printf("\n");
00235 printf("ub_origidx:     ");
00236 for (int i=0;i<slackub_cnt;i++) {
00237 printf("[%d]:%d  ",i,ub_origidx[i]);
00238 }
00239 printf("\n");
00240 printf("ub_slackvaridx: ");
00241 for (int i=0;i<slackub_cnt;i++) {
00242 printf("[%d]:%d  ",i,ub_slackvaridx[i]);
00243 }
00244 printf("\n");
00245 printf("\n");
00246 #endif
00247 
00248         // variable correspondance
00249         int *varmap = new int[si.getNumCols()];
00250         int *varmapsym = new int[si.getNumCols()];
00251         for(int i=0;i<si.getNumCols();i++) {
00252                 varmap[i] = -1;
00253                 varmapsym[i] = -1;
00254         }
00255         for(int i=0;i<n;i++) {
00256                 varmap[i] = sdpvars_first + i+1;
00257                 varmapsym[i] = sdpvars_first + (i+1) * (n+1); 
00258         }
00259         for(int i=0;i<n;i++)
00260                 for(int j=i;j<n;j++) {
00261                         varmap[indexQ(i,j,n)] = sdpvars_first + (n+2) + (n+1)*j + i;
00262                         varmapsym[indexQ(i,j,n)] = sdpvars_first + (n+2) + (n+1)*i + j;
00263                 }
00264         for(int i=0;i<t;i++) {
00265                 varmap[(n*(n+1)/2) + i] = yvars_first + i;
00266                 varmapsym[(n*(n+1)/2) + i] = yvars_first + i;
00267         }
00268 
00269 #ifdef DEBUG_SDPSOL
00270 printf("varmap:    ");
00271 for (int i=0;i<si.getNumCols();i++)
00272 printf("[%d]>%d ",i,varmap[i]);
00273 printf("\n");
00274 printf("varmapsym: ");
00275 for (int i=0;i<si.getNumCols();i++)
00276 printf("[%d]>%d ",i,varmapsym[i]);
00277 printf("\n");
00278 #endif
00279 
00280         CoinPackedMatrix *A = new CoinPackedMatrix();
00281         CoinPackedVector b(0,(double*)NULL,(int*)NULL);
00282         CoinPackedVector c(0,(double*)NULL,(int*)NULL);
00283 
00284         int origcons = origCons_tmp; //original constraints (not the RLT)
00285 #ifdef ADD_RLT
00286         origcons = si.getNumRows(); //original constraints + RLT constraints
00287 #endif
00288         int A_rows = slacklb_cnt + slackub_cnt + origcons + 1;
00289         int A_cols = slacklb_cnt + slackub_cnt + slackcons_cnt + t + (n+1)*(n+1);
00290         
00291         A->setDimensions(A_rows,A_cols);
00292 
00293 #ifdef DEBUG_SDPSOL
00294 printf("A_rows = %d\n",A_rows);
00295 printf("A_cols = %d\n",A_cols);
00296 #endif
00297 
00298         // add lb ub constraints
00299         for (int i=0;i<slacklb_cnt;i++){
00300                 A->modifyCoefficient(cons,varmap[lb_origidx[i]],1.0);
00301                 A->modifyCoefficient(cons,lb_slackvaridx[i],-1.0);
00302                 b.insert(cons,lb_value[i]);
00303                 cons++;
00304         }
00305         for (int i=0;i<slackub_cnt;i++){
00306                 A->modifyCoefficient(cons,varmap[ub_origidx[i]],1.0);
00307                 A->modifyCoefficient(cons,ub_slackvaridx[i],1.0);
00308                 b.insert(cons,ub_value[i]);
00309                 cons++;
00310         }
00311         
00312         // add constraints that set first element to 1
00313         A->modifyCoefficient(cons,sdpvars_first,1.0);
00314         b.insert(cons,1.0);
00315         cons++;
00316         
00317         // add constraints from si
00318         const double *rhs = si.getRightHandSide();
00319         const CoinPackedMatrix *matrixByRow = si.getMatrixByRow();
00320 
00321         for (int i=0;i<si.getNumRows();i++) {
00322                 if (si_sense[i] == 'G') {
00323                         A->modifyCoefficient(cons,slackcons_varidx[i],-1.0);
00324                 }
00325                 if (si_sense[i] == 'L') {
00326                         A->modifyCoefficient(cons,slackcons_varidx[i],1.0);
00327                 }
00328                 const CoinShallowPackedVector row = matrixByRow->getVector(i);
00329                 const int *indices = row.getIndices();
00330                 const double *elements = row.getElements();
00331                 for(int j=0;j<row.getNumElements();j++) {
00332                         // assuming that populate returns a model with the following order of vars
00333                         // x X y
00334                         A->modifyCoefficient(cons,varmap[indices[j]],elements[j]);
00335                 }
00336                 b.insert(cons,rhs[i]);
00337                 cons++;
00338         }
00339 
00340         //objective function
00341         const double *coeff = si.getObjCoefficients();
00342         double *newCoeff = new double[A_cols];
00343         for(int i=0;i<A_cols;i++)
00344                 newCoeff[i] = 0.0;
00345         for (int i=0;i<si.getNumCols();i++) {
00346                 newCoeff[varmap[i]] += -0.5 * coeff[i];
00347                 newCoeff[varmapsym[i]] += -0.5 * coeff[i];
00348         }
00349         for(int i=0;i<A_cols;i++)
00350                 if (newCoeff[i] != 0.0)
00351                         c.insert(i,newCoeff[i]);
00352 
00353 #ifdef DEBUG_SDPSOL
00354 printf("c ");
00355 print(c);
00356 printf("b ");
00357 print(b);
00358 for(int i=0;i<A_rows;i++){
00359 printf("row=%d ",i);
00360 for(int j=0;j<A_cols;j++){
00361 printf("%.2f ",A->getCoefficient(i,j));
00362 }
00363 printf("\n");
00364 }
00365 #endif
00366         
00367         //check redundancy in the constraints (discards added slacks, check only slack sign and rhs)
00369         
00370         
00371         
00372         //output mat file
00373         fprintf(matlabout,"c = [ ");
00374         
00375         for (int i=0;i<A_cols;i++){
00376                 fprintf(matlabout,"%.8f ",getCoinPackedVectorElementAt(c,i));
00377                 if (i!=A_cols-1) {
00378                         fprintf(matlabout,", ");
00379                 }
00380         }
00381         fprintf(matlabout,"];\n");
00382 
00383         fprintf(matlabout,"b = [ ");
00384         for (int i=0;i<A_rows;i++){
00385                 fprintf(matlabout,"%.8f ",getCoinPackedVectorElementAt(b,i));
00386                 if (i!=A_rows-1) {
00387                         fprintf(matlabout,"; ");
00388                 }
00389         }
00390         fprintf(matlabout,"];\n");
00391 
00392         // matrix A input in sparse format
00393         fprintf(matlabout,"A=[];\n");
00394         fprintf(matlabout,"A=sparse(A);\n");
00395         for (int i=0;i<A_rows;i++) {
00396                 for (int j=0;j<A_cols;j++) {
00397                         if (A->getCoefficient(i,j) != 0.0)
00398                                 fprintf(matlabout,"A(%d,%d)=%.8f;\n",i+1,j+1,A->getCoefficient(i,j));
00399                 }
00400         }
00401 
00402         fprintf(matlabout,"K.l=%d;\n",slacklb_cnt + slackub_cnt + slackcons_cnt + t);
00403         fprintf(matlabout,"K.s=%d;\n",n+1);
00404         fprintf(matlabout,"sedumi(A,b,c,K);\n");
00405         
00406         printf("ADD_LB: ");
00407 #ifdef ADD_LB
00408         printf(" added\n");
00409 #else
00410         printf(" NOT added\n");
00411 #endif
00412         printf("ADD_UB: ");
00413 #ifdef ADD_UB
00414         printf(" added\n");
00415 #else
00416         printf(" NOT added\n");
00417 #endif
00418         printf("ADD_RLT: ");
00419 #ifdef ADD_RLT
00420         printf(" added\n");
00421 #else
00422         printf(" NOT added\n");
00423 #endif
00424 
00425         delete [] extvar_i;
00426         delete [] extvar_j;
00427         delete [] slackcons_varidx;
00428         delete [] lb_origidx;
00429         delete [] ub_origidx;
00430         delete [] lb_slackvaridx;
00431         delete [] ub_slackvaridx;
00432         delete [] lb_value;
00433         delete [] ub_value;
00434 
00435         delete [] varmap;
00436         delete [] varmapsym;
00437         delete A;
00438 
00439         return 0;
00440 }
00441 
00442 
00443 
00444 
00445 
00446 #endif

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