/home/coin/SVN-release/OS-2.4.2/Couenne/src/cut/sdpcuts/CutGen.cpp

Go to the documentation of this file.
00001 /* $Id: CutGen.cpp 509 2011-02-15 22:14:33Z stefan $
00002  *
00003  * Name:    CutGen.cpp
00004  * Author:  Andrea Qualizza
00005  * Purpose: Generation of all cust
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include "stdlib.h"
00011 #include "stdio.h"
00012 #include "math.h"
00013 #include "CoinTime.hpp"
00014 
00015 #include "CutGen.hpp"
00016 #include "misc_util.hpp"
00017 #include "dsyevx_wrapper.hpp"
00018 #include "orthocut.hpp"
00019 #include "disjunctive_cuts.hpp"
00020 #include "linquad_cuts.hpp"
00021 #include "rlt_cuts.hpp"
00022 
00023 static int decomposition_counter;
00024 
00025 /************************************************************************/
00026 // sdpcut separator
00027 void CutGen::generateCuts (const OsiSolverInterface &si, OsiCuts &cs, 
00028                               const CglTreeInfo info) const {
00029 #ifdef TRACE_CUT_TIME
00030         Timer cut_timer;
00031         cut_timer.start();
00032 #endif
00033 
00034         int np = n_ + 1;
00035         int ncuts = cs.sizeRowCuts ();
00036         const double *sol  = si.getColSolution ();
00037         double *A = new double[np*np];
00038 
00039         int origsdpcuts_card = 0;
00040         int duplicate_cuts = 0;
00041 
00042         Timer origsdpcuts_timer;
00043         Timer sparsify_timer;
00044 
00045         origsdpcuts_timer.start();
00046         /*
00047            A =  /1 x^T\
00048                 \x  X /
00049         */
00050         A[0] = 1;
00051         for (int i=0;i<n_;i++) {
00052                 A[np*(i+1)] = sol[i];
00053                 //A[1+i] = sol[i];
00054                 // we need only the upper triangular part, so we can comment out the previous line
00055         }
00056         for (int i=0;i<n_;i++) {
00057                 for (int j=i;j<n_;j++) {
00058                         A[(j+1)*np+(i+1)] = sol[indexQ (i, j, n_)];
00059                         //A[(i+1)*np+(j+1)] = sol[indexQ (i, j, n_)]; 
00060                         // we need only the upper triangular part, so we can comment out the previous line
00061                 }
00062         }
00063 
00064         double *Acopy = new double[np*np];
00065         for (int i=0;i<np*np;i++)
00066                 Acopy[i] = A[i];
00067 
00068         double *w = NULL, *z = NULL;
00069         int m;
00070         dsyevx_wrapper_only_negative (np, A, m, w, z,tracer_);
00071         //remember that A gets destroyed
00072 
00073         double **work_ev = new double*[m];
00074         for (int i=0;i<m;i++) {
00075                 work_ev[i] = new double[np];
00076         
00077                 double *curr_ev ;
00078                 curr_ev = z + (i*np);
00079 #ifdef SCALE_EIGENV
00080                 double scaling_factor = sqrt(np);
00081                 for (int j=0;j<np;j++)
00082                         work_ev[i][j] = curr_ev[j] * scaling_factor;
00083 #else
00084                 for (int j=0;j<np;j++)
00085                         work_ev[i][j] = curr_ev[j];
00086 #endif // SCALE_EIGENV
00087         }
00088 
00089         for (int i=0;i<m;i++) {
00090 #ifdef INCL_ORIG
00091 #ifdef ONLY_NEG_EIGENV
00092                 if(w [i] > 0)
00093                         break;
00094 #endif
00095 
00096 #ifdef ONLY_MOST_NEG
00097                 if(i > 0)
00098                         break;
00099 #endif
00100                 genSDPcut(si,cs,work_ev[i],work_ev[i],removeduplicates_,&duplicate_cuts);
00101                 origsdpcuts_card++;
00102 #endif //INCL_ORIG
00103         }
00104         origsdpcuts_timer.pause();
00105 
00106         tracer_->setSDPNumNegativeEV(m);
00107         if (m >= 1) 
00108                 tracer_->setSDPMostNegativeEV(w[0]);
00109 
00110 #if (defined TRACE_ALL)||(defined TRACE_EIGENVALUES)
00111         printf("Eigenvalues: ");
00112         for(int i=0;i<m;i++)
00113                 printf("%.5f ",w[i]);
00114         printf("\n");
00115 #endif
00116 
00117 #ifdef RLT_SEPARATION
00118         rltCutsGen(sol, n_, cs, xlb_, xub_, m, tracer_);
00119 #endif
00120 
00121 #ifdef ORTHOCUT
00122         orthoCutGen(sol, n_, cs, z, w, m, tracer_);
00123 #endif
00124 
00125 #ifdef DISJUNCTIVE_CUTS
00126         disjunctiveCutGen(si, cs, sol, n_, tracer_);
00127 #endif
00128 
00129 #ifdef LINQUAD_CUTS
00130         linQuadCutGen(si.getColSolution(),n_,cs,tracer_);
00131 #endif
00132 
00133 //FILE *fsparsifycmp = fopen("sparsifycmp.txt","a");
00134 //compareSparsify(si,n_,m,sol,z,w,fsparsifycmp); 
00135 //fclose(fsparsifycmp);
00136 
00137         int ncuts_beforesparsify = cs.sizeRowCuts ();
00138         int wise_evdec_num = 0;
00139 
00140         sparsify_timer.start();
00141 #if (defined SPARSIFY) || (defined SPARSIFY2) || (defined WISE_SPARSIFY)
00142         int card_sparse_v_mat = 0;
00143         double **sparse_v_mat = new double*[SPARSIFY_MAX_CARD];
00144         for (int i=0; i<SPARSIFY_MAX_CARD; i++)
00145                 sparse_v_mat[i] = new double[np];
00146 #endif
00147 
00148 #ifdef SPARSIFY2
00149         int min_nz;
00150         
00151         min_nz = ceil(np*0.70);
00152         card_sparse_v_mat = 0;
00153 
00154         sparsify2(n_,sol,sparse_v_mat,&card_sparse_v_mat,min_nz,&wise_evdec_num);
00155         for(int k=0; k<card_sparse_v_mat; k++) {
00156                 genSDPcut (si, cs, sparse_v_mat[k], sparse_v_mat[k],removeduplicates_,&duplicate_cuts);
00157         }
00158 #endif // SPARSIFY2
00159 
00160         double *v;
00161         for (int i=0;i<m;i++) {
00162                 v = work_ev[i];
00163 #ifdef ONLY_NEG_EIGENV
00164                 if(w [i] > 0)
00165                         break;
00166 #endif
00167 
00168 #ifdef ONLY_MOST_NEG
00169                 if(i > 0)
00170                         break;
00171 #endif
00172 
00173 #if (defined TRACE_ALL) || (defined TRACE_USED_EIGENVECTORS)
00174                 printf("Used Eigenvector idx:%d - (Corresp. to Eigenvalue = %.5f)\n",i,w[i]);
00175                 for(int j=0;j<np;j++)
00176                         printf("%.5f ",v[j]);
00177                 printf("\n");
00178 #endif
00179 
00180 #if  (defined SPARSIFY) || (defined WISE_SPARSIFY)
00181                 card_sparse_v_mat = 0;
00182                 double *work = new double[np];
00183 #if (defined WISE_SPARSIFY)
00184                 sparsify_new(i,w[i], v, n_, sol, sparse_v_mat, &card_sparse_v_mat,work,
00185                         true,&wise_evdec_num);
00186 #else
00187                 sparsify(i,w[i], v, n_, sol, sparse_v_mat, &card_sparse_v_mat,work,
00188                         false,&wise_evdec_num);
00189 #endif // (defined WISE_SPARSIFY)
00190                 delete [] work;
00191 
00192                 for(int k=0; k<card_sparse_v_mat; k++) {
00193 
00194 #ifdef  ADD_RAND_PERC_SPARSIFY_CUTS
00195                         if ( cpp_genalea(seed_) <= ADD_RAND_PERC_SPARSIFY_CUTS)
00196 #endif
00197                         genSDPcut (si, cs, sparse_v_mat[k], sparse_v_mat[k],removeduplicates_,
00198                                         &duplicate_cuts);
00199 
00200 
00201 #ifdef SPARSIFY_MINOR_SDP_CUTS
00202                         additionalSDPcuts(si,cs, np, Acopy, sparse_v_mat[k],
00203                                         &duplicate_cuts);
00204 #endif
00205 
00206 #ifdef TRACE_ALL
00207                         print_mat_from_vvT(stdout, "generated cut", sparse_v_mat[k], n);
00208 #endif
00209                 }
00210 #endif // (defined SPARSIFY) || (defined WISE_SPARSIFY)
00211 
00212 #ifdef TRACE_SPARSIFY_CUT_DEPTH
00213                 sparsify_timer.pause();
00214                 for(int k=0; k<card_sparse_v_mat; k++) {
00215                         double violation = sparse_v_mat[k][0]*sparse_v_mat[k][0];
00216                         for (int p=0;p<n_;p++) {
00217                                 violation += 2*sparse_v_mat[k][0]*sparse_v_mat[k][p+1]*sol[p];
00218                                 violation += sparse_v_mat[k][p+1]*sparse_v_mat[k][p+1]*sol[indexQ(p,p,n_)];
00219                                 for (int q=p+1;q<n_;q++)
00220                                         violation += 2*sparse_v_mat[k][p+1]*sparse_v_mat[k][q+1]*sol[indexQ(p,q,n_)];
00221                         }
00222                         printf("violation = %.8f\n",violation);
00223                 }
00224                 sparsify_timer.restore();
00225 #endif
00226         }
00227 
00228 
00229 #if (defined SPARSIFY) || (defined SPARSIFY2) || (defined WISE_SPARSIFY)
00230         for(int i=0;i<SPARSIFY_MAX_CARD;i++)
00231                 delete [] sparse_v_mat[i];
00232         delete [] sparse_v_mat;
00233 #endif
00234 
00235 
00236 #if (defined ADD_ONLY_PERC_DEEPEST_SPARSIFY_CUTS)  ||  (defined TRACE_SPARSIFY_CUT_DEPTH)
00237         int card_cuts = cs.sizeRowCuts();
00238         double *cuts_violations = new double[card_cuts - ncuts_beforesparsify];
00239         int *cuts_indices = new int[card_cuts - ncuts_beforesparsify];
00240         for (int i=ncuts_beforesparsify;i<card_cuts;i++)
00241                 cuts_indices[i-ncuts_beforesparsify] = i;
00242         for (int i=ncuts_beforesparsify;i<card_cuts;i++) {
00243                 const OsiRowCut *curr_cut = cs.rowCutPtr(i);
00244                 const double *curr_cut_elem = curr_cut->row().getElements();
00245                 const int *curr_cut_ind = curr_cut->row().getIndices();
00246                 
00247                 const double rhs = curr_cut->rhs();
00248                 double lhs = 0.0;
00249                 for(int j=0;j<curr_cut->row().getNumElements();j++) {
00250                         lhs += curr_cut_elem[j] * sol[curr_cut_ind[j]];
00251                 }
00252                 switch(curr_cut->sense()) {
00253                         case 'L': 
00254                                 cuts_violations[i-ncuts_beforesparsify] = lhs - rhs;
00255                                 break;
00256                         case 'G': 
00257                                 cuts_violations[i-ncuts_beforesparsify] = - lhs + rhs;
00258                                 break;
00259                         default: //'E' 
00260                                 cuts_violations[i-ncuts_beforesparsify] = max((lhs - rhs),(- lhs + rhs));
00261                 }
00262         }
00263         cpp_quicksort_dec(0,card_cuts - ncuts_beforesparsify, cuts_indices, cuts_violations);
00264 
00265 //printf("card_cuts=%d ",card_cuts);
00266 //printf(" ncuts_beforesparsify=%d ",ncuts_beforesparsify);
00267 //printf(" card_cuts-ncuts_beforesparsify=%d\n",card_cuts-ncuts_beforesparsify);
00268 
00269 #ifdef  ADD_ONLY_PERC_DEEPEST_SPARSIFY_CUTS
00270         int card_to_be_removed = (int) floor((card_cuts - ncuts_beforesparsify) *
00271                                                 (1-ADD_ONLY_PERC_DEEPEST_SPARSIFY_CUTS));
00272         if (card_to_be_removed > 0 ) {
00273                 int *cuts_indices_to_be_removed = new int[card_to_be_removed];
00274                 for (int i=0;i<card_to_be_removed;i++) {
00275                         cuts_indices_to_be_removed[i] = cuts_indices[i];
00276                 }
00277                 int *unuseful_vector = new int[card_to_be_removed];
00278                 cpp_quicksortINT_dec(0,card_to_be_removed,unuseful_vector,cuts_indices_to_be_removed);
00279                 //remove cuts from the last one !
00280                 for (int i=0;i<card_to_be_removed;i++)
00281                         cs.eraseRowCut(cuts_indices_to_be_removed[i]);
00282                 delete [] cuts_indices_to_be_removed;
00283                 delete [] unuseful_vector;
00284         }
00285 #endif // ADD_ONLY_PERC_DEEPEST_SPARSIFY_CUTS
00286 
00287 #ifdef TRACE_SPARSIFY_CUT_DEPTH
00288         for (int i=0;i<card_cuts- ncuts_beforesparsify;i++)
00289                 printf("sparse_cut[%4d]_violation=%.8f\n",i,cuts_violations[i]);
00290 #endif
00291         delete [] cuts_violations;
00292         delete [] cuts_indices;
00293 #endif // (defined TRACE_SPARSIFY_CUT_DEPTH) || (defined ADD_ONLY_PERC_DEEPEST_SPARSIFY_CUTS)
00294 
00295 
00296         delete [] z;
00297         delete [] w;
00298         delete [] A;
00299         delete [] Acopy;
00300         for (int i=0;i<m;i++)
00301                 delete [] work_ev[i];
00302         delete [] work_ev;
00303 
00304 #ifdef TRACE_CUT_TIME
00305         double time = cut_timer.time();
00306         double timepercut = time / (cs.sizeRowCuts() - ncuts);
00307         printf("tot_cutgen_time=%.6f time_per_cut=%.6f\n",time,timepercut);
00308 #endif
00309 
00310         tracer_->setSDPCutsTime(origsdpcuts_timer.time());
00311         tracer_->setSDPCutsTotalCuts(origsdpcuts_card);
00312 
00313 #if (defined SPARSIFY) || (defined SPARSIFY2) || (defined WISE_SPARSIFY)
00314         globaltimer_->pause();
00315         tracer_->setSparsifyTime(sparsify_timer.time());
00316         tracer_->setSparsifyTotalCuts(cs.sizeRowCuts() - ncuts_beforesparsify);
00317         tracer_->setSparsifyDuplicatedCuts(duplicate_cuts);
00318         tracer_->setSparsifyWiseDecompositions(wise_evdec_num);
00319 
00320         double *violation = new double[cs.sizeRowCuts()-ncuts_beforesparsify];
00321         int *notused = new int[cs.sizeRowCuts()-ncuts_beforesparsify];
00322         int *cols_sparsity = new int[np];
00323         for (int i=0;i<np;i++)
00324                 cols_sparsity[i] = 0;
00325         int **pair_sparsity = new int*[np];
00326         for (int i=0;i<np;i++) {
00327                 pair_sparsity[i] = new int[np];
00328                 for (int j=0;j<np;j++)
00329                         pair_sparsity[i][j] = 0;
00330         }
00331         double *sparse_vector = new double[np];
00332         for (int i=0;i<cs.sizeRowCuts()-ncuts_beforesparsify;i++) {
00333                 const OsiRowCut *cut = cs.rowCutPtr(i+ncuts_beforesparsify);
00334                 tracer_->addSparsifyNz(cut->row().getNumElements());
00335                 violation[i] = cut->violated(sol);
00336                 const double *elements = cut->row().getElements();
00337                 const int *indices = cut->row().getIndices();
00338                 int numelements = cut->row().getNumElements();
00339                 for (int k=0;k<np;k++)
00340                         sparse_vector[k] = 0.0;
00341                 sparse_vector[0] = sqrt(cut->rhs());
00342                 for (int k=0;k<n_;k++) {
00343                         int idx = indexQ(k,k,n_);
00344                         for (int j=0;j<numelements;j++)
00345                                 if ((indices[j] == idx) && (elements[j] != 0.0))
00346                                         sparse_vector[k+1] = sqrt(elements[j]);
00347                 }
00348                 for (int k=0;k<np;k++) {
00349                         if (sparse_vector[k] != 0.0) {
00350                                 cols_sparsity[k]++;
00351                                 for (int p=k+1;p<np;p++)
00352                                         if (sparse_vector[p] != 0.0)
00353                                                 pair_sparsity[k][p]++;
00354                         }
00355                 }
00356         }
00357         cpp_quicksort_dec(0,cs.sizeRowCuts()-ncuts_beforesparsify, notused,violation);
00358         for (int i=0;i<ceil((cs.sizeRowCuts()-ncuts_beforesparsify)*0.20);i++)
00359                 tracer_->addSparsifyTop20PercCutsViolation(violation[i]);
00360         for (int j=0;j<np;j++) {
00361                 tracer_->addSparsifySingleColumnSparsity(cols_sparsity[j]);
00362                 for (int p=j+1;p<np;p++)
00363                         tracer_->addSparsifyColumnPairSparsity(pair_sparsity[j][p]);
00364         }
00365 
00366         delete [] cols_sparsity;
00367         for (int i=0;i<np;i++)
00368                 delete [] pair_sparsity[i];
00369         delete [] pair_sparsity;
00370         delete [] violation;
00371         delete [] notused;
00372         delete [] sparse_vector;
00373         globaltimer_->restore();
00374 #endif
00375 
00376 }
00377 
00378 
00379 
00380 
00381 double violation_from_v(int n, double *v1, double *v2, const double *sol) {
00382         double violation = (v1[0]*v2[0]);
00383         for (int i=0;i<n;i++) {
00384                 violation += v1[0] * v2[i+1] * sol[i];
00385                 violation += v2[0] * v1[i+1] * sol[i];
00386                 violation += v1[i+1] * v2[i+1] * sol[indexQ(i,i,n)];
00387                 for (int j=i+1;j<n;j++) {
00388                         violation += v1[i+1] * v2[j+1] * sol[indexQ(i,j,n)];
00389                         violation += v2[i+1] * v1[j+1] * sol[indexQ(i,j,n)];
00390                 }
00391         }
00392         return violation;
00393 }
00394 
00395 void CutGen::compareSparsify(const OsiSolverInterface &si,int n, int m, const double *sol, double *z, double *w,FILE *out) const {
00396 
00397 
00398         static int iter;
00399         iter++;
00400         
00401         int duplicate_cuts1 = 0;
00402         int duplicate_cuts2 = 0;
00403         
00404         int np = n+1;
00405         int card_sparse_v_mat1 = 0;
00406         double **sparse_v_mat1 = new double*[SPARSIFY_MAX_CARD];
00407         for (int i=0; i<SPARSIFY_MAX_CARD; i++)
00408                 sparse_v_mat1[i] = new double[np];
00409         int card_sparse_v_mat2 = 0;
00410         double **sparse_v_mat2 = new double*[SPARSIFY_MAX_CARD];
00411         for (int i=0; i<SPARSIFY_MAX_CARD; i++)
00412                 sparse_v_mat2[i] = new double[np];
00413 
00414         OsiSolverInterface *sirlt = si.clone(true);
00415         sirlt->unmarkHotStart();
00416         Timer timer_rlt;
00417         timer_rlt.start();      
00418         sirlt->initialSolve();
00419         double time_rlt = timer_rlt.time();
00420 
00421 
00422         OsiCuts cs_origev;
00423         for(int i=0;i<m;i++) {
00424                 double *curr_ev ;
00425                 curr_ev = z + (i*np);
00426                 genSDPcut (si, cs_origev, curr_ev, curr_ev,false,&duplicate_cuts1);
00427         }
00428 
00429 
00430 
00431 
00432 //first sparsify
00433         decomposition_counter = 0;
00434         int evdec_num1 = 0;
00435         int *sparsify_cols1 = new int[np];
00436         for (int i=0;i<np;i++)
00437                 sparsify_cols1[i] = 0;
00438         int **pair_sparsity1 = new int*[np];
00439         for (int i=0;i<np;i++) {
00440                 pair_sparsity1[i] = new int[np];
00441                 for (int j=0;j<np;j++)
00442                         pair_sparsity1[i][j] = 0;
00443         }
00444         double time1 = 0,starttime1 = 0;
00445 
00446         starttime1 = CoinCpuTime ();
00447 
00448 
00449         int gencuts1 = 0;
00450         OsiCuts cs1;
00451         double *workevs1 = new double[m];
00452         for(int i=0;i<m;i++) {
00453                 double *curr_ev ;
00454                 curr_ev = z + (i*np);
00455                 double *work_ev = new double[np];
00456                 sparsify(i,w[i], curr_ev, n, sol, sparse_v_mat1, &card_sparse_v_mat1,work_ev,false,&evdec_num1);
00457                 workevs1[i] = violation_from_v(n_,work_ev,work_ev,sol);
00458                 gencuts1 += card_sparse_v_mat1;
00459                 for (int k=0;k<card_sparse_v_mat1;k++) {
00460                         genSDPcut (si, cs1, sparse_v_mat1[k], sparse_v_mat1[k],true,&duplicate_cuts1);
00461                         for (int j=0;j<np;j++)
00462                                 if (sparse_v_mat1[k][j] != 0.0) {
00463                                         sparsify_cols1[j]++;
00464                                         for (int p=j+1;p<np;p++) {
00465                                                 if (sparse_v_mat1[k][p] != 0.0)
00466                                                         pair_sparsity1[j][p]++;
00467                                         }
00468                                 }
00469                 }
00470         }
00471 
00472         int decomposition_counter1 = decomposition_counter;
00473 
00474         time1 = CoinCpuTime () - starttime1;
00475         double time_per_cut1 = time1 / gencuts1;
00476         int dupcuts1 = gencuts1 - cs1.sizeRowCuts();
00477         double dupcuts_perc1 = (100.0 * ((double) dupcuts1)) / ((double)gencuts1);
00478 
00479         OsiSolverInterface *si1_lp = si.clone(true);
00480         double starttime1_lp = CoinCpuTime ();
00481         si1_lp->applyCuts (cs1);
00482         si1_lp->resolve();
00483         double time1_lp = CoinCpuTime () - starttime1_lp;
00484         double obj1 = si1_lp->getObjValue() + objConst_;
00485 
00486         OsiSolverInterface *si1_lporigcuts = si.clone(true);
00487         double starttime1_lporigcuts = CoinCpuTime ();
00488         si1_lporigcuts->applyCuts(cs_origev);
00489         si1_lporigcuts->applyCuts(cs1);
00490         si1_lporigcuts->resolve();
00491         double time1_lporigcuts = CoinCpuTime () - starttime1_lporigcuts;
00492         double obj1_withorigev = si1_lporigcuts->getObjValue() + objConst_;
00493 
00494 
00495         double nz_mean1 = 0.0;
00496         int nz_min1 = 10000000;
00497         int nz_max1 = 0;
00498         for (int i=0;i<cs1.sizeRowCuts();i++) {
00499                 const OsiRowCut *cut = cs1.rowCutPtr(i);
00500                 nz_mean1 += (double) cut->row().getNumElements();
00501                 if (cut->row().getNumElements() > nz_max1)
00502                         nz_max1 = cut->row().getNumElements();
00503                 if (cut->row().getNumElements() < nz_min1)
00504                         nz_min1 = cut->row().getNumElements();
00505         }
00506         nz_mean1 /= cs1.sizeRowCuts();
00507         double nz_std_dev1 = 0.0;
00508         for (int i=0;i<cs1.sizeRowCuts();i++) {
00509                 const OsiRowCut *cut = cs1.rowCutPtr(i);
00510                 nz_std_dev1 += (((double) cut->row().getNumElements()) - nz_mean1)
00511                                 *(((double) cut->row().getNumElements()) - nz_mean1);
00512         }
00513         nz_std_dev1 /= cs1.sizeRowCuts();
00514         nz_std_dev1 = sqrt(nz_std_dev1);
00515 
00516 //second sparsify procedure
00517         decomposition_counter = 0;
00518         int evdec_num2 = 0;
00519         int *sparsify_cols2 = new int[np];
00520         for (int i=0;i<np;i++)
00521                 sparsify_cols2[i] = 0;
00522         int **pair_sparsity2 = new int*[np];
00523         for (int i=0;i<np;i++) {
00524                 pair_sparsity2[i] = new int[np];
00525                 for (int j=0;j<np;j++)
00526                         pair_sparsity2[i][j] = 0;
00527         }
00528         double time2 = 0,starttime2 = 0;
00529 
00530         starttime2 = CoinCpuTime ();
00531         int gencuts2 = 0;
00532         OsiCuts cs2;
00533         double *workevs2 = new double[m];
00534         for(int i=0;i<m;i++) {
00535                 double *curr_ev ;
00536                 curr_ev = z + (i*np);
00537                 double *work_ev = new double[np];
00538                 sparsify_new(i,w[i], curr_ev, n, sol, sparse_v_mat2, &card_sparse_v_mat2,work_ev,true,&evdec_num2);
00539                 workevs2[i] = violation_from_v(n_,work_ev,work_ev,sol);
00540                 gencuts2 += card_sparse_v_mat2;
00541                 for (int k=0;k<card_sparse_v_mat2;k++) {
00542                         genSDPcut (si, cs2, sparse_v_mat2[k], sparse_v_mat2[k],true,&duplicate_cuts2);
00543                         for (int j=0;j<np;j++)
00544                                 if (sparse_v_mat2[k][j] != 0.0) {
00545                                         sparsify_cols2[j]++;
00546                                         for (int p=j+1;p<np;p++) {
00547                                                 if (sparse_v_mat2[k][p] != 0.0)
00548                                                         pair_sparsity2[j][p]++;
00549                                         }
00550                                 }
00551                 }
00552         }
00553 
00554         int decomposition_counter2 = decomposition_counter;
00555 
00556         time2 = CoinCpuTime () - starttime2;
00557         double time_per_cut2 = time2 / gencuts2;
00558         int dupcuts2 = gencuts2 - cs2.sizeRowCuts();
00559         double dupcuts_perc2 = (100.0 * ((double) dupcuts2)) / ((double)gencuts2);
00560         OsiSolverInterface *si2_lp = si.clone(true);
00561         double starttime2_lp = CoinCpuTime ();
00562         si2_lp->applyCuts (cs2);
00563         si2_lp->resolve();
00564         double time2_lp = CoinCpuTime () - starttime2_lp;
00565         double obj2 = si2_lp->getObjValue() + objConst_;
00566         OsiSolverInterface *si2_lporigcuts = si.clone(true);
00567         double starttime2_lporigcuts = CoinCpuTime ();
00568         si2_lporigcuts->applyCuts(cs_origev);
00569         si2_lporigcuts->applyCuts (cs2);
00570         si2_lporigcuts->resolve();
00571         double time2_lporigcuts = CoinCpuTime () - starttime2_lporigcuts;
00572         double obj2_withorigev = si2_lporigcuts->getObjValue() + objConst_;
00573 
00574         double nz_mean2 = 0.0;
00575         int nz_min2 = 10000000;
00576         int nz_max2 = 0;
00577         for (int i=0;i<cs2.sizeRowCuts();i++) {
00578                 const OsiRowCut *cut = cs2.rowCutPtr(i);
00579                 nz_mean2 += (double) cut->row().getNumElements();
00580                 if (cut->row().getNumElements() > nz_max2)
00581                         nz_max2 = cut->row().getNumElements();
00582                 if (cut->row().getNumElements() < nz_min2)
00583                         nz_min2 = cut->row().getNumElements();
00584         }
00585         nz_mean2 /= cs2.sizeRowCuts();
00586         double nz_std_dev2 = 0.0;
00587         for (int i=0;i<cs2.sizeRowCuts();i++) {
00588                 const OsiRowCut *cut = cs2.rowCutPtr(i);
00589                 nz_std_dev2 += (((double) cut->row().getNumElements()) - nz_mean2)
00590                                 *(((double) cut->row().getNumElements()) - nz_mean2);
00591         }
00592         nz_std_dev2 /= cs2.sizeRowCuts();
00593         nz_std_dev2 = sqrt(nz_std_dev2);
00594 
00595 
00596         fprintf(out,"     Cuts Dup Dup%%  TotTime    TimePerCut NZmean NZSD Bound     Bound(+origev)\n");
00597         fprintf(out,"%2d S1 %3d %3d %2.2f%% %.8f %.8f %5.2f %5.2f %.4f %.4f\n",
00598                 iter,gencuts1,dupcuts1,dupcuts_perc1,time1,time_per_cut1,nz_mean1,nz_std_dev1,obj1,obj1_withorigev);
00599         fprintf(out,"%2d S2 %3d %3d %2.2f%% %.8f %.8f %5.2f %5.2f %.4f %.4f\n",
00600                 iter,gencuts2,dupcuts2,dupcuts_perc2,time2,time_per_cut2,nz_mean2,nz_std_dev2,obj2,obj2_withorigev);
00601         fprintf(out,"\n");
00602         fprintf(out,"      Bound(onlysp)  Time            Bound(+origev) Time       Decomp\n");
00603         fprintf(out,"%2d S1 %.4f      %.8f      %.4f      %.8f %d\n",
00604                 iter,obj1,time1_lp,obj1_withorigev,time1_lporigcuts,decomposition_counter1);
00605         fprintf(out,"%2d S2 %.4f      %.8f      %.4f      %.8f %d\n",
00606                 iter,obj2,time2_lp,obj2_withorigev,time2_lporigcuts,decomposition_counter2);
00607 
00608         fprintf(out,"\n");
00609 
00610 
00611 #ifdef DETAILED_SPARSIFY_COMPARISON
00612         fprintf(out,"   orig_ev     S1_work     S2_work\n");
00613         for (int i=0;i<m;i++) {
00614                 fprintf(out,"%2d %2.8f %2.8f %2.8f\n",iter,w[i],workevs1[i],workevs2[i]);
00615         }
00616         fprintf(out,"\n");
00617 #endif
00618         fprintf(out,"sparsity statistics\n");
00619 #ifdef DETAILED_SPARSIFY_COMPARISON
00620         fprintf(out,"idx: ");
00621         for (int i=0;i<np;i++) {
00622                 fprintf(out,"%2d ",i);
00623         }
00624         fprintf(out,"\n");
00625         fprintf(out,"S1 : ");
00626         for (int i=0;i<np;i++) {
00627                 fprintf(out,"%2d ",sparsify_cols1[i]);
00628         }
00629         fprintf(out,"\n");
00630         fprintf(out,"S2 : ");
00631         for (int i=0;i<np;i++) {
00632                 fprintf(out,"%2d ",sparsify_cols2[i]);
00633         }
00634         fprintf(out,"\n");
00635 #endif
00636         double mean_cols1 = 0.0;
00637         double mean_cols2 = 0.0;
00638         int max_cols1 = 0;
00639         int max_cols2 = 0;
00640         int min_cols1 = 1000000000;
00641         int min_cols2 = 1000000000;
00642         for (int i=0;i<np;i++) {
00643                 mean_cols1 += sparsify_cols1[i];
00644                 mean_cols2 += sparsify_cols2[i];
00645                 if (sparsify_cols1[i] > max_cols1)
00646                         max_cols1 = sparsify_cols1[i];
00647                 if (sparsify_cols2[i] > max_cols2)
00648                         max_cols2 = sparsify_cols2[i];
00649                 if (sparsify_cols1[i] < min_cols1)
00650                         min_cols1 = sparsify_cols1[i];
00651                 if (sparsify_cols2[i] < min_cols2)
00652                         min_cols2 = sparsify_cols2[i];
00653         }
00654         mean_cols1 /= np;
00655         mean_cols2 /= np;
00656         double stddev_cols1 = 0.0;
00657         double stddev_cols2 = 0.0;
00658         for (int i=0;i<np;i++) {
00659                 stddev_cols1 += ((sparsify_cols1[i]-mean_cols1)*(sparsify_cols1[i]-mean_cols1));
00660                 stddev_cols2 += ((sparsify_cols2[i]-mean_cols2)*(sparsify_cols2[i]-mean_cols2));
00661         }
00662         stddev_cols1 /= np;
00663         stddev_cols1 = sqrt(stddev_cols1);
00664         stddev_cols2 /= np;
00665         stddev_cols2 = sqrt(stddev_cols2);
00666 
00667         fprintf(out,"single column sparsity:\n");
00668 #ifdef DETAILED_SPARSIFY_COMPARISON
00669         fprintf(out,"     idx  S1  S2\n");
00670         for (int i=0;i<np;i++) {
00671                 fprintf(out,"%2d   %3d %3d %3d\n",iter,i,sparsify_cols1[i],sparsify_cols2[i]);
00672         }
00673 #endif
00674         fprintf(out,"S1 mean = %.2f  stddev = %.2f  max = %d  min = %d\n"
00675                 ,mean_cols1,stddev_cols1,max_cols1,min_cols1);
00676         fprintf(out,"S2 mean = %.2f  stddev = %.2f  max = %d  min = %d\n"
00677                 ,mean_cols2,stddev_cols2,max_cols2,min_cols2);
00678         //column pair sparsity
00679         double mean_pair_sparsity1 = 0.0;
00680         double mean_pair_sparsity2 = 0.0;
00681         int max_pair_sparsity1 = 0;
00682         int max_pair_sparsity2 = 0;
00683         int min_pair_sparsity1 = 1000000000;
00684         int min_pair_sparsity2 = 1000000000;
00685         for (int i=0;i<np;i++)
00686                 for (int j=i+1;j<np;j++) {
00687                         mean_pair_sparsity1 += pair_sparsity1[i][j];
00688                         mean_pair_sparsity2 += pair_sparsity2[i][j];
00689                         if (pair_sparsity1[i][j] > max_pair_sparsity1)
00690                                 max_pair_sparsity1 = pair_sparsity1[i][j];
00691                         if (pair_sparsity2[i][j] > max_pair_sparsity2)
00692                                 max_pair_sparsity2 = pair_sparsity2[i][j];
00693                         if (pair_sparsity1[i][j] < min_pair_sparsity1)
00694                                 min_pair_sparsity1 = pair_sparsity1[i][j];
00695                         if (pair_sparsity2[i][j] < min_pair_sparsity2)
00696                                 min_pair_sparsity2 = pair_sparsity2[i][j];
00697                 }
00698         mean_pair_sparsity1 /= (np*(np-1))/2;
00699         mean_pair_sparsity2 /= (np*(np-1))/2;
00700         double stddev_pair_sparsity1 = 0.0;
00701         double stddev_pair_sparsity2 = 0.0;
00702         for (int i=0;i<np;i++)
00703                 for (int j=i+1;j<np;j++) {
00704                         stddev_pair_sparsity1 += (pair_sparsity1[i][j]-mean_pair_sparsity1) *
00705                                                  (pair_sparsity1[i][j]-mean_pair_sparsity1);
00706                         stddev_pair_sparsity2 += (pair_sparsity2[i][j]-mean_pair_sparsity2) *
00707                                                  (pair_sparsity2[i][j]-mean_pair_sparsity2);
00708                 }
00709         stddev_pair_sparsity1 /= (np*(np-1))/2;
00710         stddev_pair_sparsity2 /= (np*(np-1))/2;
00711         stddev_pair_sparsity1 = sqrt(stddev_pair_sparsity1);
00712         stddev_pair_sparsity2 = sqrt(stddev_pair_sparsity2);
00713         fprintf(out,"column pair sparsity:\n");
00714 #ifdef DETAILED_SPARSIFY_COMPARISON
00715         fprintf(out,"column pair sparsity:\n");
00716         fprintf(out,"     idx1 idx2  S1  S2\n");
00717         for (int i=0;i<np;i++)
00718                 for (int j=i+1;j<np;j++) {
00719                         fprintf(out,"%2d   %3d  %3d  %3d  %3d\n"
00720                                 ,iter,i,j,pair_sparsity1[i][j],pair_sparsity2[i][j]);
00721                 }
00722 #endif
00723         fprintf(out,"S1 mean = %.2f  stddev = %.2f  max = %d min = %d\n",mean_pair_sparsity1,stddev_pair_sparsity1,max_pair_sparsity1,min_pair_sparsity1);
00724         fprintf(out,"S2 mean = %.2f  stddev = %.2f  max = %d  min = %d\n",mean_pair_sparsity2,stddev_pair_sparsity2,max_pair_sparsity2,min_pair_sparsity1);
00725         fprintf(out,"\n");
00726 
00727 
00728 
00729         double *violations1 = new double[cs1.sizeRowCuts()];
00730         int *nz1 = new int[cs1.sizeRowCuts()];
00731         for (int i=0;i<cs1.sizeRowCuts();i++) {
00732                 const OsiRowCut *cut = cs1.rowCutPtr(i);
00733                 violations1[i] = cut->violated(sol);
00734                 nz1[i] = cut->row().getNumElements();
00735         }
00736         cpp_quicksort_dec(0,cs1.sizeRowCuts(), nz1,violations1);
00737 
00738         double *violations2 = new double[cs2.sizeRowCuts()];
00739         int *nz2 = new int[cs2.sizeRowCuts()];
00740         for (int i=0;i<cs2.sizeRowCuts();i++) {
00741                 const OsiRowCut *cut = cs2.rowCutPtr(i);
00742                 violations2[i] = cut->violated(sol);
00743                 nz2[i] = cut->row().getNumElements();
00744         }
00745         cpp_quicksort_dec(0,cs2.sizeRowCuts(), nz2,violations2);
00746         int max_card = CoinMax(cs1.sizeRowCuts(),cs2.sizeRowCuts());
00747 
00748         int min_card = CoinMin(cs1.sizeRowCuts(),cs2.sizeRowCuts());
00749         int top_card = (int) (ceil(min_card * 0.20));
00750         fprintf(out,"Top 20%% cuts statistics (cardinality=%d)\n",top_card);
00751         double mean_viol1 = 0.0;
00752         double mean_viol2 = 0.0;
00753         for(int i=0;i<top_card;i++) {
00754                 mean_viol1 += violations1[i];
00755                 mean_viol2 += violations2[i];
00756         }
00757 printf("--->%.18f %.18f %d %.18f %.18f\n",mean_viol1,mean_viol2,top_card,mean_viol1/top_card,mean_viol2/top_card);
00758         mean_viol1 /= top_card;
00759         mean_viol2 /= top_card;
00760         double stddev_viol1 = 0.0;
00761         double stddev_viol2 = 0.0;
00762         for(int i=0;i<top_card;i++) {
00763                 stddev_viol1 += (violations1[i] - mean_viol1)*(violations1[i] - mean_viol1);
00764                 stddev_viol2 += (violations2[i] - mean_viol2)*(violations2[i] - mean_viol2);
00765         }
00766         stddev_viol1 /= top_card;
00767         stddev_viol2 /= top_card;
00768         stddev_viol1 = sqrt(stddev_viol1);
00769         stddev_viol2 = sqrt(stddev_viol2);
00770         fprintf(out,"S1 mean violation = %.4f  stddev = %.4f\n",mean_viol1,stddev_viol1);
00771         fprintf(out,"S2 mean violation = %.4f  stddev = %.4f\n",mean_viol2,stddev_viol2);
00772 #ifdef DETAILED_SPARSIFY_COMPARISON
00773         fprintf(out,"   S1                  S2               [sparsified cuts only]\n");
00774         fprintf(out,"   violation    cutNZ        violation    cutNZ  \n");
00775         for (int i=0;i<max_card;i++) {
00776                 fprintf(out,"%2d ",iter);
00777                 if (i+1<= cs1.sizeRowCuts())
00778                         fprintf(out,"%.8f    %4d",violations1[i],nz1[i]);
00779                 else
00780                         fprintf(out,"    N/A           ");
00781                 fprintf(out,"       ");
00782                 if (i+1<= cs2.sizeRowCuts())
00783                         fprintf(out," %.8f    %4d",violations2[i],nz2[i]);
00784                 else
00785                         fprintf(out,"         N/A      ");
00786                 fprintf(out,"\n");
00787         }
00788 #endif
00789 
00790         fprintf(out,"\n-------------------------------------------\n\n");
00791 
00792 
00793 
00794         spartrace.generated_cuts1[iter-1] = gencuts1;
00795         spartrace.generated_cuts2[iter-1] = gencuts2;
00796         spartrace.duplicate1[iter-1] = dupcuts1;
00797         spartrace.duplicate2[iter-1] = dupcuts2;
00798         spartrace.sparsifytime1[iter-1] = time1;
00799         spartrace.sparsifytime2[iter-1] = time2;
00800         spartrace.boundtime1[iter-1] = time1_lporigcuts;
00801         spartrace.boundtime2[iter-1] = time2_lporigcuts;
00802 
00803         spartrace.nzmean1[iter-1] = nz_mean1;
00804         spartrace.nzmean2[iter-1] = nz_mean2;
00805         spartrace.nzmin1[iter-1] = nz_min1;
00806         spartrace.nzmin2[iter-1] = nz_min2;
00807         spartrace.nzmax1[iter-1] = nz_max1;
00808         spartrace.nzmax2[iter-1] = nz_max2;
00809         spartrace.decomp1[iter-1] = decomposition_counter1;
00810         spartrace.decomp2[iter-1] = decomposition_counter2;
00811         spartrace.single_column_sparsity_mean1[iter-1] = mean_cols1;
00812         spartrace.single_column_sparsity_mean2[iter-1] = mean_cols2;
00813         spartrace.single_column_sparsity_max1[iter-1] = max_cols1;
00814         spartrace.single_column_sparsity_max2[iter-1] = max_cols2;
00815         spartrace.single_column_sparsity_min1[iter-1] = min_cols1;
00816         spartrace.single_column_sparsity_min2[iter-1] = min_cols2;
00817         spartrace.column_pair_sparsity_mean1[iter-1] = mean_pair_sparsity1;
00818         spartrace.column_pair_sparsity_mean2[iter-1] = mean_pair_sparsity2;
00819         spartrace.column_pair_sparsity_max1[iter-1] = max_pair_sparsity1;
00820         spartrace.column_pair_sparsity_max2[iter-1] = max_pair_sparsity2;
00821         spartrace.column_pair_sparsity_min1[iter-1] = min_pair_sparsity1;
00822         spartrace.column_pair_sparsity_min2[iter-1] = min_pair_sparsity2;
00823         spartrace.top_cuts_mean_violation1[iter-1] = mean_viol1;
00824         spartrace.top_cuts_mean_violation2[iter-1] = mean_viol2;
00825         spartrace.bounds1[iter-1] = obj1_withorigev;
00826         spartrace.bounds2[iter-1] = obj2_withorigev;
00827         if (iter == 1)
00828                 spartrace.times1[iter-1] = time_rlt + time1_lporigcuts;
00829         else
00830                 spartrace.times1[iter-1] = spartrace.times1[iter-2] + time1_lporigcuts;
00831         if (iter == 1)
00832                 spartrace.times2[iter-1] = time_rlt + time2_lporigcuts;
00833         else
00834                 spartrace.times2[iter-1] = spartrace.times2[iter-2] + time2_lporigcuts;
00835         *spartrace.iterations = iter;
00836 
00837         for(int i=0;i<SPARSIFY_MAX_CARD;i++)
00838                 delete [] sparse_v_mat1[i];
00839         delete [] sparse_v_mat1;
00840         for(int i=0;i<SPARSIFY_MAX_CARD;i++)
00841                 delete [] sparse_v_mat2[i];
00842         delete [] sparse_v_mat2;
00843 
00844         delete [] violations1;
00845         delete [] violations2;
00846         delete [] nz1;
00847         delete [] nz2;
00848         delete [] sparsify_cols1; 
00849         delete [] sparsify_cols2;
00850 } //compareSparsify()
00851 
00852 /************************************************************************/
00853 void CutGen::genSDPcut (const OsiSolverInterface &si,
00854                            OsiCuts &cs, double *v1, double *v2, bool checkduplicates, int *duplicate_cuts) const {
00855         
00856         int nterms = 0;
00857         int np     = n_+1;
00858         
00859         OsiRowCut *cut   = new OsiRowCut;
00860         double    *coeff = new double [N_];
00861         int       *ind   = new int    [N_];
00862         
00863         // coefficients for X_ij
00864         for (int i=1; i<np; i++)
00865                 for (int j=i; j<np; j++) {
00866                         double coeff0 = v1 [i] * v2 [j] + v1 [j] * v2 [i];
00867                         if (coeff0 != 0.0) {
00868                                 coeff [nterms] = (i==j) ? (0.5 * coeff0) : (coeff0);
00869                                 ind   [nterms++] = indexQ (i-1, j-1, n_);
00870                         }
00871                 }
00872 
00873         // coefficients for x_i
00874         for (int i=1; i<np; i++) {
00875                 double coeff0 = v1 [i] * v2 [0] + v1 [0] * v2 [i];
00876                 if (coeff0 != 0.0) {
00877                         coeff [nterms]   = coeff0;
00878                         ind   [nterms++] = i-1;
00879                 }
00880         }
00881         
00882         cut -> setRow (nterms, ind, coeff);
00883         cut -> setLb (- *v1 * *v2);
00884 
00885 
00886 
00887         if(nterms > 0) {
00888 #ifdef RAND_CUT_ADD
00889                 if ( cpp_genalea(seed_) <= RAND_CUT_ADD)
00890 #endif
00891                 {
00892 
00893                 if (!(checkduplicates)) {
00894                         globaltimer_->pause();
00895                 }
00896                 CoinAbsFltEq treatAsSame = CoinAbsFltEq(1.0e-8);
00897                 int initial = cs.sizeRowCuts();
00898                 cs.insertIfNotDuplicate (*cut, treatAsSame);
00899                 int final = cs.sizeRowCuts();
00900                 if (initial == final) {
00901                         (*duplicate_cuts) ++;
00902                         // if flag was false, we still add the duplicate cut
00903                         if (!(checkduplicates))
00904                                 cs.insert (cut);
00905                 }
00906                 if (!(checkduplicates)) {
00907                         globaltimer_->restore();
00908                 }
00909 
00910                 }
00911         }
00912 
00913 
00914 
00915         delete cut;
00916         delete [] ind;
00917         delete [] coeff;
00918 }
00919 
00920 
00921 /************************************************************************/
00922 void CutGen::updateSol() {
00923         heuristics_->run();
00924 }
00925 
00926 /************************************************************************/
00927 // constructor
00928 CutGen::CutGen (const int n, 
00929                         const int t,
00930                         const int cons,
00931                         const double objConst,
00932                         const double *b,
00933                         const double *c,
00934                         const double **Q,
00935                         const double **origMat,
00936                         const double *origRhs,
00937                         const char *origSense,
00938                         const double *xlb,
00939                         const double *xub,
00940                         const double *ylb,
00941                         const double *yub,
00942                         OsiSolverInterface *si,
00943                         Timer *globaltimer,
00944                         Tracer *tracer
00945                         ):
00946 
00947         n_ (n),
00948         t_ (t),
00949         cons_ (cons),
00950         objConst_ (objConst),
00951         si_ (si),
00952         globaltimer_ (globaltimer),
00953         tracer_ (tracer) {
00954 
00955         N_ = n*(n+3)/2;
00956 
00957         heuristics_ = new
00958                         Heuristics(n,t,cons,objConst,b,c,Q,origMat,origRhs,origSense,xlb,xub,ylb,yub,si,tracer);
00959 
00960         b_ = new double[n];
00961         c_ = new double[t];
00962         Q_ = new double*[n];
00963         for (int i=0; i<n;i++)
00964                 Q_[i] = new double[n];
00965 
00966         for (int i=0; i<n;i++) {
00967                 b_ [i] = b [i];
00968                 for (int j=0; j<n;j++) 
00969                         Q_ [i] [j] = Q [i] [j];
00970         }
00971 
00972         for (int i=0; i<t ;i++) {
00973                 c_[i] = c[i];
00974         }
00975 
00976         origRhs_ = new double[cons];
00977         origSense_ = new char[cons];
00978         origMat_ = new double*[cons];
00979         for (int i=0; i<cons;i++)
00980                 origMat_[i] = new double[N_+t];
00981         for (int i=0; i<cons;i++) {
00982                 for(int j=0;j<N_+t;j++)
00983                         origMat_[i][j] = origMat[i][j];
00984                 origRhs_[i] = origRhs[i];
00985                 origSense_[i] = origSense[i];
00986         }
00987 
00988         xlb_ = new double[n];
00989         xub_ = new double[n];
00990         ylb_ = new double[t];
00991         yub_ = new double[t];
00992 
00993         for (int i=0; i<n;i++) {
00994                 xlb_[i] = xlb[i];
00995                 xub_[i] = xub[i];
00996         }
00997         for (int i=0; i<t;i++) {
00998                 ylb_[i] = ylb[i];
00999                 yub_[i] = yub[i];
01000         }
01001         
01002         seed_ = new int[0];
01003         *seed_ = time(0);
01004 
01005         max_nb_cuts = 100000;
01006 
01007 #ifdef SPARSIFY_REMOVE_DUPLICATES
01008         removeduplicates_ = true;
01009 #else
01010         removeduplicates_ = false;
01011 #endif
01012 
01013 
01014 
01015 #if 0
01016         spartrace.generated_cuts1 = new int[EXIT_ON_ITER];
01017         spartrace.generated_cuts2 = new int[EXIT_ON_ITER];
01018         spartrace.duplicate1 = new int[EXIT_ON_ITER];
01019         spartrace.duplicate2 = new int[EXIT_ON_ITER];
01020         spartrace.sparsifytime1 = new double[EXIT_ON_ITER];
01021         spartrace.sparsifytime2 = new double[EXIT_ON_ITER];
01022         spartrace.boundtime1 = new double[EXIT_ON_ITER];
01023         spartrace.boundtime2 = new double[EXIT_ON_ITER];
01024         spartrace.nzmean1 = new double[EXIT_ON_ITER];
01025         spartrace.nzmean2 = new double[EXIT_ON_ITER];
01026         spartrace.nzmin1 = new double[EXIT_ON_ITER];
01027         spartrace.nzmin2 = new double[EXIT_ON_ITER];
01028         spartrace.nzmax1 = new double[EXIT_ON_ITER];
01029         spartrace.nzmax2 = new double[EXIT_ON_ITER];
01030         spartrace.decomp1 = new int[EXIT_ON_ITER];
01031         spartrace.decomp2 = new int[EXIT_ON_ITER];
01032         spartrace.single_column_sparsity_mean1 = new double[EXIT_ON_ITER];
01033         spartrace.single_column_sparsity_mean2 = new double[EXIT_ON_ITER];
01034         spartrace.single_column_sparsity_max1 = new int[EXIT_ON_ITER];
01035         spartrace.single_column_sparsity_max2 = new int[EXIT_ON_ITER];
01036         spartrace.single_column_sparsity_min1 = new int[EXIT_ON_ITER];
01037         spartrace.single_column_sparsity_min2 = new int[EXIT_ON_ITER];
01038         spartrace.column_pair_sparsity_mean1 = new double[EXIT_ON_ITER];
01039         spartrace.column_pair_sparsity_mean2 = new double[EXIT_ON_ITER];
01040         spartrace.column_pair_sparsity_max1 = new int[EXIT_ON_ITER];
01041         spartrace.column_pair_sparsity_max2 = new int[EXIT_ON_ITER];
01042         spartrace.column_pair_sparsity_min1 = new int[EXIT_ON_ITER];
01043         spartrace.column_pair_sparsity_min2 = new int[EXIT_ON_ITER];
01044         spartrace.top_cuts_mean_violation1 = new double[EXIT_ON_ITER];
01045         spartrace.top_cuts_mean_violation2 = new double[EXIT_ON_ITER];
01046         spartrace.bounds1 = new double[EXIT_ON_ITER];
01047         spartrace.times1 = new double[EXIT_ON_ITER];
01048         spartrace.bounds2 = new double[EXIT_ON_ITER];
01049         spartrace.times2 = new double[EXIT_ON_ITER];
01050         spartrace.iterations = new int[1];
01051 #endif
01052 
01053 }
01054 /************************************************************************/
01055 // destructor
01056 CutGen::~CutGen () {
01057         delete seed_;
01058 
01059         delete heuristics_;
01060 
01061         delete [] b_;
01062         delete [] c_;
01063         for(int i=0;i<n_;i++)
01064                 delete [] Q_[i];
01065         delete [] Q_;
01066         for (int i=0;i<cons_;i++)
01067                 delete [] origMat_[i];
01068         delete [] origMat_;
01069         delete [] origRhs_;
01070         delete [] origSense_;
01071         delete [] xlb_;
01072         delete [] xub_;
01073         delete [] ylb_;
01074         delete [] yub_;
01075 
01076 
01077         delete [] spartrace.generated_cuts1;
01078         delete [] spartrace.generated_cuts2;
01079         delete [] spartrace.duplicate1;
01080         delete [] spartrace.duplicate2;
01081         delete [] spartrace.sparsifytime1;
01082         delete [] spartrace.sparsifytime2;
01083         delete [] spartrace.boundtime1;
01084         delete [] spartrace.boundtime2;
01085         delete [] spartrace.nzmean1;
01086         delete [] spartrace.nzmean2;
01087         delete [] spartrace.nzmin1;
01088         delete [] spartrace.nzmin2;
01089         delete [] spartrace.nzmax1;
01090         delete [] spartrace.nzmax2;
01091         delete [] spartrace.decomp1;
01092         delete [] spartrace.decomp2;
01093         delete [] spartrace.single_column_sparsity_mean1;
01094         delete [] spartrace.single_column_sparsity_mean2;
01095         delete [] spartrace.single_column_sparsity_max1;
01096         delete [] spartrace.single_column_sparsity_max2;
01097         delete [] spartrace.single_column_sparsity_min1;
01098         delete [] spartrace.single_column_sparsity_min2;
01099         delete [] spartrace.column_pair_sparsity_mean1;
01100         delete [] spartrace.column_pair_sparsity_mean2;
01101         delete [] spartrace.column_pair_sparsity_max1;
01102         delete [] spartrace.column_pair_sparsity_max2;
01103         delete [] spartrace.column_pair_sparsity_min1;
01104         delete [] spartrace.column_pair_sparsity_min2;
01105         delete [] spartrace.top_cuts_mean_violation1;
01106         delete [] spartrace.top_cuts_mean_violation2;
01107         delete [] spartrace.bounds1;
01108         delete [] spartrace.times1;
01109         delete [] spartrace.bounds2;
01110         delete [] spartrace.times2;
01111         delete [] spartrace.iterations;
01112 }
01113 
01114 /***********************************************************************/
01115 void CutGen::myremoveBestOneRowCol(double *matrix, int n, int running_n, int min_nz,bool *del_idx, double **sparse_v_mat, int *card_v_mat, int *evdec_num) const {
01116         
01117         double best_val=1;
01118         int best_idx=-1;
01119 
01120         if(running_n==1) 
01121                 return;
01122 
01123         double *matrixCopy = new double[(running_n)*(running_n)];
01124         for (int i=0;i<(running_n)*(running_n);i++)
01125                 matrixCopy[i] = matrix[i];
01126 
01127         double *T = new double[(running_n-1)*(running_n-1)];
01128         double *Tcopy = new double[(running_n - 1)*(running_n - 1)];
01129         double *Tbest = new double[(running_n - 1)*(running_n - 1)];
01130         double *zbest = new double[(running_n - 1)*(running_n - 1)];
01131         double *wbest = new double[running_n - 1];
01132         double *w,*z;
01133         int card_ev_best;
01134 
01135         for(int k=0;k<running_n;k++) {
01136                 int ii,jj;
01137                 ii=0;
01138                 for(int i=0;i<running_n;i++) {
01139                         if(i==k) continue;
01140                         jj=0;
01141                         for(int j=0;j<running_n;j++) {
01142                                 if(j==k) continue;
01143                                 T[(running_n-1)*ii+jj]=matrixCopy[running_n*i+j];
01144                                 Tcopy[(running_n-1)*ii+jj]=matrixCopy[running_n*i+j];
01145                                 jj++;
01146                         }
01147                         ii++;
01148                 }
01149                 int card_ev;
01150                 w=NULL;
01151                 z=NULL;
01152 
01153                 (*evdec_num)++;
01154                 if (running_n-1 == min_nz)
01155                         dsyevx_wrapper_only_negative(running_n - 1,T,card_ev,w,z,tracer_);
01156                 else
01157                         dsyevx_wrapper_only_most_neg(running_n - 1,T,card_ev,w,z,tracer_);
01158 
01159                 double val=w[0];
01160 
01161                 if(val<0 && val<best_val) {
01162                         best_val=val;
01163                         best_idx=k;
01164                         for(int i=0;i<(running_n-1)*(running_n-1);i++) {
01165                                 Tbest[i] = Tcopy[i];
01166                                 zbest[i] = z[i];
01167                         }
01168                         for(int i=0;i<(running_n-1);i++) {
01169                                 wbest[i] = w[i];
01170                         }
01171                         card_ev_best = card_ev;
01172                 }
01173                 delete [] z;
01174                 delete [] w;
01175         }
01176         delete [] T;
01177         delete [] Tcopy;
01178         delete [] matrixCopy;
01179 
01180 
01181         if(best_idx>=0) {
01182                 
01183                 if (del_idx == NULL) {
01184                         del_idx = new bool[n];
01185                         for (int i=0;i<n;i++)
01186                                 del_idx[i]=false;
01187                 }
01188                 int cnt_idx_orig = 0;
01189                 int cnt_idx_minor = 0;
01190                 while (cnt_idx_minor < running_n) {
01191                         if (del_idx[cnt_idx_orig] == false) {
01192                                 if (cnt_idx_minor == best_idx) {
01193                                         del_idx[cnt_idx_orig] = true;
01194                                         break;
01195                                 }
01196                                 else 
01197                                         cnt_idx_minor++;
01198                         }
01199                         cnt_idx_orig++;
01200                 }
01201 
01202                 if (running_n-1 == min_nz) {
01203                         for(int i=0;i<card_ev_best;i++) {
01204                                 if (wbest[i] < 0) {
01205                                         double *curr_ev = zbest + (i*(running_n-1));
01206                                         
01207                                         for(int j=0;j<n;j++)
01208                                                 sparse_v_mat[i][j]=0.0;
01209                                         
01210                                         int idx_orig = 0;
01211                                         int idx_minor = 0;
01212 
01213                                         while (idx_orig < n) {
01214                                                 if (!(del_idx[idx_orig])) {
01215                                                         sparse_v_mat[i][idx_orig] = curr_ev[idx_minor];
01216                                                         idx_minor++;
01217                                                 }
01218                                                 idx_orig++;
01219                                         }
01220 
01221                                         (*card_v_mat)++;
01222                                 }
01223                                 else //no more negative eigenvalues
01224                                         break;
01225                         }
01226                         delete [] del_idx;
01227                 }
01228                 else {
01229                         myremoveBestOneRowCol(Tbest, n, running_n-1,min_nz,del_idx,sparse_v_mat,card_v_mat,evdec_num);
01230                 }
01231         }
01232         
01233         delete [] Tbest;
01234         delete [] zbest;
01235         delete [] wbest;
01236 
01237 }// myremoveBestOneRowCol()
01238 /************************************************************************/
01239 void CutGen::sparsify2(const int n,
01240                          const double *sol, double **sparse_v_mat,
01241                          int *card_v_mat, int min_nz, int *evdec_num) const {
01242         
01243         int np = n+1;
01244         double *matrix = new double[np*np];
01245 
01246         matrix[0] = 1;
01247         for (int i=0;i<n;i++)
01248                 matrix[np*(i+1)] = sol[i];
01249         for (int i=0;i<n;i++) {
01250                 for (int j=i;j<n;j++)
01251                         matrix[(j+1)*np+(i+1)] = sol[indexQ (i, j, n)];
01252         }
01253 
01254         myremoveBestOneRowCol(matrix, np, np,min_nz,NULL,sparse_v_mat,card_v_mat,evdec_num);
01255 
01256         delete [] matrix;
01257 }// sparsify2()
01258 /************************************************************************/
01259 void CutGen::additionalSDPcuts(const OsiSolverInterface &si,OsiCuts &cs, int np, const double *A, const double *vector, int *duplicate_cuts) const{
01260 
01261         int *indices;
01262         indices = new int[np];
01263         int cnt = 0;
01264         for(int i=0;i<np;i++) {
01265                 if (vector[i] != 0.0)
01266                         indices[i] = cnt++;
01267                 else
01268                         indices[i] = -1;
01269         }
01270         
01271         double *subA = new double[cnt*cnt];
01272 
01273         for (register int i=0; i<np; i++) {
01274                 if (indices[i] >= 0) {
01275                         for (register int j=0; j<np; j++) {
01276                                 if (indices[j] >= 0)
01277                                         subA[cnt*indices[j]+indices[i]] = A[np*j+i];
01278                         }
01279                 }
01280         }
01281 
01282         double *w = NULL, *z = NULL;
01283         int m;
01284         dsyevx_wrapper_only_negative (cnt, subA, m, w, z,tracer_);
01285 
01286         double *v = new double[np];
01287         double *newv = new double[np];
01288 
01289 
01290         for (int k=0; k<m; k++) {
01291         
01292 #ifdef ONLY_NEG_EIGENV
01293                 if(w [k] > 0) {
01294                         break;
01295                 }
01296 #endif
01297 
01298                 double *zbase = z + k * cnt;
01299                 for (int j=0; j<cnt; j++) {
01300                         v [j] = *zbase++;
01301                 }
01302 
01303                 for(int j=0;j<np;j++) {
01304                         if (indices[j] >= 0)
01305                                 newv[j] = v[indices[j]];
01306                         else
01307                                 newv[j] = 0;
01308                 }
01309 
01310                 genSDPcut (si, cs, newv, newv,removeduplicates_,duplicate_cuts);
01311         }
01312 
01313         delete [] v;
01314         delete [] newv;
01315 
01316         delete [] w;
01317         delete [] z;
01318 
01319         delete [] subA;
01320         delete [] indices;
01321 } // additionalSDPcuts
01322 
01323 
01324 
01325 
01326 
01327 
01328 
01329 /************************************************************************/
01330 void CutGen::update_sparsify_structures(const int np, const double *sol, double *v,double* margin, double** mat, double *lhs, const int *zeroed, int evidx, bool decompose, int *evdec_num) const {
01331 
01332         // copy sol[] in mat[][]
01333         mat[0][0] = 1;
01334         for(int i=1; i<np; i++) {
01335                 mat[0][i] = sol[i-1];
01336                 mat[i][0] = sol[i-1];
01337         }
01338         for(int i=1; i<np; i++) {
01339                 for(int j=i; j<np; j++) {
01340                         int ind = indexQ(i-1, j-1, np-1);
01341                         mat[i][j] = sol[ind];
01342                         mat[j][i] = sol[ind];
01343                 }
01344         }
01345 
01346         int minor_n = np;
01347         if (zeroed != NULL) {
01348                 for(int i=0;i<np;i++)
01349                         if (zeroed[i] == 0)
01350                                 minor_n--;
01351         }
01352 
01353         if ((decompose)  && (minor_n > 2)) {
01354 
01355 /*
01356         if (minor_n < np) {
01357                         add_v_cut(np, loc_selected, loc_card_selected, locv, 
01358                                 init_card_selected, &has_init_vect,
01359                                 selected, &card_selected, &new_selected, 
01360                                 trace_bin, trace_bin_size,
01361                                 sparse_v_mat, card_v_mat);
01362         }
01363 */
01364                 decomposition_counter++;
01365                 (*evdec_num)++;
01366                 double *minor_A = new double[np*np];
01367                 double *minor_w = new double[np];
01368                 double *minor_z = new double[np*np];
01369 
01370                 //prepare active submatrix (induced by zeroed vector)
01371 
01372                 int ii = 0;
01373                 int jj = 0;
01374                 for (int i=0;i<np;i++) {
01375                         if (zeroed[i] == 0)
01376                                 continue;
01377                         jj = 0;
01378                         for (int j=0;j<np;j++) {
01379                                 if (zeroed[j] == 0)
01380                                         continue;
01381                                 minor_A[(minor_n*ii) + jj] = mat[i][j];
01382                                 jj++;
01383                         }
01384                         ii++;
01385                 }
01386                 //eigendecomposition
01387                 int m;
01388 //              dsyevx_wrapper_first_p (minor_n, minor_A, m, minor_w, minor_z,evidx+1,tracer_);
01389                 dsyevx_wrapper_only_most_neg (minor_n, minor_A, m, minor_w, minor_z,tracer_);
01390 
01391                 //update v (reindex the evidx-th eigenvector entries)
01392                 ii = 0;
01393                 for (int i=0;i<np;i++) {
01394                         v[i] = 0;
01395                         if (zeroed[i] == 0)
01396                                 continue;
01397                         v[i] = minor_z[ii];
01398                         ii++;
01399                 }
01400                 delete [] minor_A;
01401                 delete [] minor_w;
01402                 delete [] minor_z;
01403         }
01404 
01405         for(int i=0; i<np; i++) {
01406                 for(int j=0; j<np; j++) {
01407                         mat[i][j] *= v[i] * v[j];
01408                         if ((zeroed != NULL) && (zeroed[j] == 0)) {
01409                                 mat[i][j] = 0;
01410                                 mat[j][i] = 0;
01411                         }
01412                 }
01413         }
01414 
01415         (*lhs) = 0;
01416         for(int i=0; i<np; i++) {
01417                 margin[i] = 0;
01418                 for(int j=0; j<np; j++) {
01419                         margin[i] += mat[i][j]; 
01420                 }
01421                 (*lhs) += margin[i];
01422         }
01423 }
01424 /************************************************************************/
01425 void CutGen::zero_comp(const int ind_i, const double delta,
01426                           const int np, const int *selected,
01427                           int *loc_selected, 
01428                           int *ploc_card_selected, int *ploc_card_new_selected, 
01429                           double *ploc_lhs, 
01430                           double *locmargin, double **locmat, 
01431                           const double *sol, double *locv, 
01432                           const int evidx, bool wise, int *evdec_num, double *recomp_gap, double *threshold) const {
01433 
01434 double  curr_lhs = (*ploc_lhs);
01435 static int zerocount;
01436 bool local_wise = false;
01437 if ((wise) && ((*ploc_lhs)-delta > (*threshold))) {
01438         (*threshold) = (*ploc_lhs)-delta + (*recomp_gap);
01439         local_wise = true;
01440 }
01441 
01442 
01443 zerocount++;
01444 
01445 
01446   loc_selected[ind_i] = 0;
01447   (*ploc_card_selected)--;
01448   
01449   if(selected[ind_i] != 1) {
01450     (*ploc_card_new_selected)--;
01451   }
01452   (*ploc_lhs) -= delta;
01453 
01454   update_sparsify_structures(np,sol,locv,locmargin,locmat,ploc_lhs, loc_selected, evidx, local_wise, evdec_num);
01455 
01456 } /* zero_comp */
01457 
01458 /************************************************************************/
01459 void CutGen::zero_valid_delta(const int np, const int *order,
01460                                  const int * selected,
01461                                  const int min_card_new_selected,
01462                                  const double min_delta, const int start_point, 
01463                                  const int curr_i, 
01464                                  int *loc_selected, 
01465                                  int *ploc_card_selected, 
01466                                  int *ploc_card_new_selected, 
01467                                  double *ploc_lhs, 
01468                                  double *locmargin, double **locmat, 
01469                                  int *pnchanged, 
01470                                  const double *sol, double *locv, 
01471                                  const int evidx, bool wise,double *recomp_gap, double *threshold,
01472                                  int *pcard_selected,
01473                                  int *pnew_selected,
01474                                  int *trace_bin, const int trace_bin_size,
01475                                  double **sparse_v_mat,
01476                                  int *pcard_v_mat,
01477                                  const int init_card_selected, int *has_init_vect,
01478                                  int *evdec_num) const {
01479 
01480   int curr_ind = curr_i;
01481 
01482   (*pnchanged = 0);
01483   for(int i=0; i<np; i++) {
01484     
01485     curr_ind++;
01486     if(curr_ind == np) {
01487       curr_ind = 0;
01488     }
01489     
01490     int ind_i = order[curr_ind];
01491     int skip = 0;
01492 
01493     if((selected[ind_i] == 0) && 
01494        (min_card_new_selected >= *ploc_card_new_selected)) {
01495       skip = 1;
01496     }
01497 
01498     if((skip) || (curr_ind == start_point) || (loc_selected[ind_i] == 0)) {
01499       continue;
01500     }
01501     
01502     double delta = 2 * locmargin[ind_i] - locmat[ind_i][ind_i];
01503     if(*ploc_lhs - delta < min_delta) {
01504 
01505       zero_comp(ind_i, delta, np, selected, loc_selected, 
01506                 ploc_card_selected, ploc_card_new_selected, 
01507                 ploc_lhs, locmargin, locmat, sol, locv, evidx, wise, evdec_num , recomp_gap,threshold);
01508       (*pnchanged)++;
01509 
01510     }
01511   }
01512 } /* zero_valid_delta */
01513 
01514 /************************************************************************/
01515 void CutGen::zero_selected(const int np, const int *order,
01516                               const int *selected,
01517                               const int min_card_new_selected,
01518                               const double min_delta, const int start_point,
01519                               const int curr_i, 
01520                               int *loc_selected, int *ploc_card_selected, 
01521                               int *ploc_card_new_selected, 
01522                               double *ploc_lhs, 
01523                               double *locmargin, double **locmat, 
01524                               int *pnchanged, 
01525                               const double *sol, double *locv, 
01526                               const int evidx, bool wise,double *recomp_gap, double *threshold,
01527                               int *pcard_selected,
01528                               int *pnew_selected,
01529                               int *trace_bin, const int trace_bin_size,
01530                               double **sparse_v_mat,
01531                               int *pcard_v_mat,
01532                               const int init_card_selected, int *has_init_vect,
01533                               int *evdec_num) const {
01534 
01535   int curr_ind = curr_i;
01536 
01537   (*pnchanged = 0);
01538   for(int i=0; i<np; i++) {
01539     
01540     curr_ind++;
01541     if(curr_ind == np) {
01542       curr_ind = 0;
01543     }
01544     
01545     int ind_i = order[curr_ind];
01546 
01547     if((selected[ind_i] == 0) || (loc_selected[ind_i] == 0)) {
01548       continue;
01549     }
01550     
01551     double delta = 2 * locmargin[ind_i] - locmat[ind_i][ind_i];
01552     if(*ploc_lhs - delta < min_delta) {
01553 
01554       zero_comp(ind_i, delta, np, selected, loc_selected, 
01555                 ploc_card_selected, ploc_card_new_selected, 
01556                 ploc_lhs, locmargin, locmat, sol, locv, evidx,wise,evdec_num,recomp_gap,threshold);
01557       (*pnchanged)++;
01558     } 
01559   }
01560 } /* zero_selected */
01561 
01562 /************************************************************************/
01563 void CutGen::zero_pos_delta(const int np, const int *order,
01564                                const int *selected,
01565                                const int min_card_new_selected,
01566                                const int start_point, const int curr_i, 
01567                                int *loc_selected, int *ploc_card_selected, 
01568                                int *ploc_card_new_selected, 
01569                                double *ploc_lhs, 
01570                                double *locmargin, double **locmat, 
01571                                int *pnchanged, 
01572                                const double *sol, double *locv, 
01573                                const int evidx, bool wise, double *recomp_gap, double *threshold,
01574                                int *pcard_selected,
01575                                int *pnew_selected,
01576                                int *trace_bin, const int trace_bin_size,
01577                                double **sparse_v_mat,
01578                                int *pcard_v_mat,
01579                                const int init_card_selected, int *has_init_vect,
01580                                int *evdec_num) const {
01581 
01582   int curr_ind = curr_i;
01583 
01584   (*pnchanged) = 0;
01585   for(int i=0; i<np; i++) {
01586     
01587     curr_ind++;
01588     if(curr_ind == np) {
01589       curr_ind = 0;
01590     }
01591     
01592     int ind_i = order[curr_ind];
01593     
01594     int skip = 0;
01595 
01596     if((selected[ind_i] == 0) && 
01597        (min_card_new_selected >= *ploc_card_new_selected)) {
01598       skip = 1;
01599     }
01600 
01601     if((skip) || (curr_ind == start_point) || (loc_selected[ind_i] == 0)) {
01602       continue;
01603     }
01604     
01605     double delta = 2 * locmargin[ind_i] - locmat[ind_i][ind_i];
01606     if(delta > 0) {
01607 
01608       zero_comp(ind_i, delta, np, selected, loc_selected, 
01609                 ploc_card_selected, ploc_card_new_selected, 
01610                 ploc_lhs, locmargin, locmat, sol, locv, evidx,wise,evdec_num,recomp_gap,threshold);
01611       (*pnchanged)++;
01612 
01613     } 
01614   }
01615 } /* zero_pos_delta */
01616 
01617 /************************************************************************/
01618 void CutGen::add_v_cut(const int np,
01619                           const int *loc_selected, 
01620                           const int loc_card_selected,
01621                           const double *locv,
01622                           const int init_card_selected, int *has_init_vect,
01623                           int *selected, int *pcard_selected,
01624                           int *pnew_selected,
01625                           int *trace_bin, const int trace_bin_size,
01626                           double **sparse_v_mat,
01627                           int *pcard_v_mat) const {
01628 
01629   (*pnew_selected) = 0;
01630 
01631   for(int i=0; i<np; i++) {
01632     if(loc_selected[i]) {
01633       sparse_v_mat[*pcard_v_mat][i] = locv[i];
01634       if(selected[i] == 0) {
01635         selected[i] = 1;
01636         (*pcard_selected)++;
01637         (*pnew_selected)++;
01638       }
01639     }
01640     else {
01641       sparse_v_mat[*pcard_v_mat][i] = 0;
01642     }
01643   }
01644 
01645 
01646 #ifdef NORMALIZE_SPARSE_CUTS
01647 //normalization (setting vector norm to 1)
01648 double curr_norm = 0.0;
01649 for (int i=0;i<np;i++) {
01650         curr_norm += fabs(sparse_v_mat[*pcard_v_mat][i]);
01651 }
01652 for (int i=0;i<np;i++) {
01653         if (sparse_v_mat[*pcard_v_mat][i] != 0.0)
01654                 sparse_v_mat[*pcard_v_mat][i] = sparse_v_mat[*pcard_v_mat][i]/curr_norm;
01655 }
01656 #endif
01657 
01658 /*
01659   if(loc_card_selected + init_card_selected == np) {
01660     if(*has_init_vect == 1) {
01661 
01662 #ifdef TRACE_ALL
01663       printf("SdpCutGen::add_v_cut(): repeat of original cut skipped\n");
01664 #endif
01665 
01666       return;
01667     }
01668     else {
01669       (*has_init_vect) = 1;
01670     }
01671   }
01672 */
01673         
01674 #ifdef TRACE_ALL
01675   printf("SdpCutGen::add_v_cut(): loc_card_selected: %d  new_selected: %d\n", 
01676          loc_card_selected, *pnew_selected);
01677 #endif
01678         
01679   (*pcard_v_mat)++;
01680   
01681 #ifdef TRACE_ALL
01682   trace_bin[loc_card_selected / trace_bin_size] += 1;
01683 #endif
01684   
01685 #ifdef TRACE_ALL
01686   cpp_printvecDBL("SdpCutGen::add_v_cut(): sparse vector", 
01687                   sparse_v_mat[(*pcard_v_mat) - 1], np);
01688 #endif
01689 } /* add_v_cut */
01690 
01691 /************************************************************************/
01692 void CutGen::sparsify(const int evidx, const double eigen_val, 
01693                          const double *v, const int n,
01694                          const double *sol, double **sparse_v_mat,
01695                          int *card_v_mat, double *work_ev,bool wise,int *evdec_num) const {
01696 
01697         int i, j, np = n+1, nchanged = 0;
01698         double sq_np = sqrt((double)np);
01699 
01700         double min_delta;
01701         double is_zero = 1/(10 * sq_np);
01702         int min_number_new_per_cut = 1;
01703         
01704         int *selected = new int[np], card_selected = 0;
01705         int *loc_selected = new int[np], loc_card_selected = 0;
01706         int loc_card_new_selected = 0;
01707         
01708         double lhs = 0, loc_lhs = 0;
01709         double *margin = new double[np];
01710         double *locv = new double[np];
01711         double *locv_orig = new double[np];
01712         double *locmargin = new double[np];
01713         double **mat = new double*[np];
01714         double **locmat = new double*[np];
01715         
01716         int seed = 225535;
01717         int *order = new int[np];
01718         double *rand_val = new double[np];
01719 
01720         *card_v_mat = 0;
01721         
01722         for (i=0; i<np; i++) {
01723                 selected[i] = 0;
01724                 mat[i] = new double[np];
01725                 locmat[i] = new double[np];
01726                 order[i] = i;
01727                 rand_val[i] = cpp_genalea(&seed);
01728                 
01729                 
01730                 // zero small components in v
01731                 if(fabs(v[i]) < is_zero) {
01732 
01733 #ifdef TRACE_ALL
01734                         printf("zero: ind: %d  value: %8.6f\n", i, v[i]);
01735 #endif
01736 
01737                         locv_orig[i] = 0;
01738                         selected[i] = -1; // -1: ind will be set to 0 in loc_selected
01739                         card_selected++;
01740                 } else {
01741                         locv_orig[i] = v[i];
01742                 }
01743         }
01744 
01745 
01746         for (int i=0;i<np;i++)
01747                 work_ev[i] = locv_orig[i];
01748 
01749         // get random ordering
01750         cpp_quicksort_dec(0, np, order, rand_val);
01751         
01752 
01753         update_sparsify_structures(np,sol,locv_orig,margin,mat,&lhs, NULL, evidx, false,evdec_num);
01754 
01755         int init_card_selected = card_selected; // to recognize if cut from original
01756                                                 // vector is generated
01757         int has_init_vect = 0;
01758         
01759         min_delta = lhs * SPARSIFY_OLD_DELTA; // do not weaken the cut too much
01760         int start_point = -1; // order[start_point]: index that should not be removed
01761         
01762         int trace_bin_size = 0;
01763         int *trace_bin = NULL;
01764 
01765 #ifdef TRACE_ALL
01766         trace_bin_size = 5;
01767         int card_trace_bin = np / trace_bin_size + 1;
01768         trace_bin = new int[card_trace_bin];
01769         for(i=0; i<card_trace_bin; i++) {
01770                 trace_bin[i] = 0;
01771         }
01772 #endif
01773 
01774 
01775         while(card_selected < np) {
01776                 for(i=0; i<np; i++) {
01777                         if(selected[order[i]] == 0) {
01778                                 start_point = i;
01779                                 break;
01780                         }
01781                 }
01782     
01783                 loc_card_selected = np;
01784                 loc_card_new_selected = np;
01785                 loc_lhs = lhs;
01786                 double recomp_gap = fabs(lhs*WISE_SPARSIFY_GAP);
01787                 double threshold = lhs + recomp_gap;
01788 
01789                 // restore locv (might have been changed by WISE_SPARSIFY during the generation of the last sparse cut)
01790                 for(i=0;i<np;i++)
01791                         locv[i] = locv_orig[i];
01792 
01793                 for(i=0; i<np; i++) {
01794                         if(selected[i] == -1) {
01795                                 loc_selected[i] = 0;
01796                                 loc_card_selected--;
01797                                 loc_card_new_selected--;
01798                         } else {
01799                                 loc_selected[i] = 1;
01800                                 
01801                                 if(selected[i] == 1) {
01802                                         loc_card_new_selected--;
01803                                 }
01804                         }
01805                         locmargin[i] = margin[i];
01806                         for(j=0; j<np; j++) {
01807                                 locmat[i][j] = mat[i][j];
01808                         }
01809                 }
01810 
01811                 if(loc_lhs < min_delta) {
01812 
01813                         int changed = 1;
01814                         
01815                         while(changed) {
01816 
01817 #ifdef TRACE_ALL
01818                                 printf("SdpCutGen::sparsify(): loc_lhs: %8.6f\n", loc_lhs);
01819                                 cpp_printmatDBL("locmat", locmat, np, np);
01820                                 cpp_printvecDBL("locmargin", locmargin, np);
01821                                 cpp_printvecINT("loc_selected", loc_selected, np);
01822 #endif
01823 
01824 
01825                                 int curr_i = start_point;
01826                                 
01827                                 changed = 0;
01828                                 
01829                                 int sel_nchanged = -1; 
01830 
01831                                 while(sel_nchanged != 0) {
01832                                         int new_selected = 0;
01833                                         zero_selected(np, order, selected, min_number_new_per_cut,
01834                                                 min_delta, start_point,
01835                                                 curr_i, loc_selected, 
01836                                                 &loc_card_selected, &loc_card_new_selected, 
01837                                                 &loc_lhs, locmargin, locmat, 
01838                                                 &sel_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
01839                                                 &card_selected, &new_selected, 
01840                                                 trace_bin, trace_bin_size,
01841                                                 sparse_v_mat, card_v_mat,
01842                                                 init_card_selected, &has_init_vect,evdec_num);
01843                                         
01844                                         if(sel_nchanged) {
01845                                                 nchanged += sel_nchanged;
01846                                         //          changed = 1;
01847                                         }
01848                                 } // while(sel_nchanged != 0) 
01849 
01850                                 int pos_nchanged = -1;
01851         
01852                                 while(pos_nchanged != 0) {
01853                                         int new_selected = 0;
01854                                         zero_pos_delta(np, order, selected, min_number_new_per_cut,
01855                                                         start_point, start_point, loc_selected, 
01856                                                         &loc_card_selected, &loc_card_new_selected, 
01857                                                         &loc_lhs, locmargin, locmat, 
01858                                                         &pos_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
01859                                                         &card_selected, &new_selected, 
01860                                                         trace_bin, trace_bin_size,
01861                                                         sparse_v_mat, card_v_mat,
01862                                                         init_card_selected, &has_init_vect,evdec_num);
01863                                 
01864                                         if(pos_nchanged) {
01865                                                 nchanged += pos_nchanged;
01866                                                 changed = 1;
01867                                         }
01868                                 } /* while(pos_nchanged != 0) */
01869 
01870                                 if(changed) {
01871                                         continue;
01872                                 }
01873                                 
01874 
01875                                 curr_i = start_point;
01876                                 
01877                                 int val_nchanged = -1;
01878 
01879                                 if(val_nchanged) {
01880                                         int new_selected = 0;
01881                                         zero_valid_delta(np, order, selected, min_number_new_per_cut,
01882                                                         min_delta, start_point,
01883                                                         curr_i, loc_selected, 
01884                                                         &loc_card_selected, &loc_card_new_selected, 
01885                                                         &loc_lhs, locmargin, locmat, 
01886                                                         &val_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
01887                                                         &card_selected, &new_selected, 
01888                                                         trace_bin, trace_bin_size,
01889                                                         sparse_v_mat, card_v_mat,
01890                                                         init_card_selected, &has_init_vect,evdec_num);
01891                                         
01892                                         if(val_nchanged) {
01893                                         nchanged += val_nchanged;
01894                                         changed = 1;
01895                                         }
01896                                 }
01897 
01898 
01899                         } /* while(changed) */
01900 
01901                         if((loc_card_selected < np * SPARSIFY_OLD_NZ_THRESHOLD) || (*card_v_mat == 0)) {
01902                                 
01903                                 int new_selected = 0;
01904                                 
01905                                 add_v_cut(np, loc_selected, loc_card_selected, locv, 
01906                                         init_card_selected, &has_init_vect,
01907                                         selected, &card_selected, &new_selected, 
01908                                         trace_bin, trace_bin_size,
01909                                         sparse_v_mat, card_v_mat);
01910                         } else {
01911                                 selected[order[start_point]] = 1;
01912                                 card_selected++;
01913                         }
01914                 } else {
01915                 // loc_lhs >= min_delta  use vector as is
01916 
01917                         card_selected = np;
01918 
01919 #ifdef TRACE_ALL
01920                         printf("SdpCutGen::sparsify(): lhs: %8.6f  too large. No sparsification\n", lhs);
01921 #endif
01922 
01923 #ifndef ONLY_NEG_EIGENV
01924                         int new_selected = 0;
01925                         
01926                         add_v_cut(np, loc_selected, loc_card_selected, locv, 
01927                                         init_card_selected, &has_init_vect,
01928                                         selected, &card_selected, &new_selected, 
01929                                         trace_bin, trace_bin_size,
01930                                         sparse_v_mat, card_v_mat);
01931 #endif
01932 
01933                 }
01934         } /* while(card_selected < np) */
01935 
01936 
01937 #ifdef TRACE_ALL
01938         printf("SdpCutGen::sparsify(): bin size: %d\n", trace_bin_size);
01939         cpp_printvecINT("trace_bin", trace_bin, card_trace_bin);
01940         delete[] trace_bin;
01941 #endif
01942 
01943         delete[] order;
01944         delete[] rand_val;
01945         
01946         for (i=0; i<np; i++) {
01947                 delete [] mat[i];
01948                 delete [] locmat[i];
01949         }
01950         delete [] mat;
01951         delete [] locmat;
01952 
01953         delete[] locv;
01954         delete[] locv_orig;
01955         delete[] margin;
01956         delete[] locmargin;
01957         
01958         delete[] selected;
01959         delete[] loc_selected;
01960 } // sparsify
01961 /************************************************************************/
01962 void CutGen::sparsify_new(const int evidx, const double eigen_val, 
01963                          const double *v, const int n,
01964                          const double *sol, double **sparse_v_mat,
01965                          int *card_v_mat, double *work_ev, bool wise, int *evdec_num) const {
01966 
01967         int i, j, np = n+1, nchanged = 0;
01968         double sq_np = sqrt((double)np);
01969 
01970         double min_delta;
01971         double is_zero = 1/(10 * sq_np);
01972         int min_number_new_per_cut = 1;
01973         
01974         int *selected = new int[np], card_selected = 0;
01975         int *loc_selected = new int[np], loc_card_selected = 0;
01976         int loc_card_new_selected = 0;
01977         
01978         double lhs = 0, loc_lhs = 0;
01979         double *margin = new double[np];
01980         double *locv = new double[np];
01981         double *locv_orig = new double[np];
01982         double *locmargin = new double[np];
01983         double **mat = new double*[np];
01984         double **locmat = new double*[np];
01985         
01986         int seed = 225535;
01987         int *order = new int[np];
01988         double *rand_val = new double[np];
01989 
01990         *card_v_mat = 0;
01991         
01992         for (i=0; i<np; i++) {
01993                 selected[i] = 0;
01994                 mat[i] = new double[np];
01995                 locmat[i] = new double[np];
01996                 order[i] = i;
01997                 rand_val[i] = cpp_genalea(&seed);
01998                 
01999                 
02000                 // zero small components in v
02001                 if(fabs(v[i]) < is_zero) {
02002 
02003 #ifdef TRACE_ALL
02004                         printf("zero: ind: %d  value: %8.6f\n", i, v[i]);
02005 #endif
02006 
02007                         locv_orig[i] = 0;
02008                         selected[i] = -1; // -1: ind will be set to 0 in loc_selected
02009                         card_selected++;
02010                 } else {
02011                         locv_orig[i] = v[i];
02012                 }
02013         }
02014 
02015 
02016         for (int i=0;i<np;i++)
02017                 work_ev[i] = locv_orig[i];
02018 
02019         // get random ordering
02020         cpp_quicksort_dec(0, np, order, rand_val);
02021         
02022         update_sparsify_structures(np,sol,locv_orig,margin,mat,&lhs, NULL, evidx, false, evdec_num);
02023 
02024         int init_card_selected = card_selected; // to recognize if cut from original
02025                                                 // vector is generated
02026         int has_init_vect = 0;
02027         
02028 min_delta = lhs * SPARSIFY_NEW_DELTA; // do not weaken the cut too much
02029         int start_point = -1; // order[start_point]: index that should not be removed
02030         
02031         int trace_bin_size = 0;
02032         int *trace_bin = NULL;
02033 
02034 #ifdef TRACE_ALL
02035         trace_bin_size = 5;
02036         int card_trace_bin = np / trace_bin_size + 1;
02037         trace_bin = new int[card_trace_bin];
02038         for(i=0; i<card_trace_bin; i++) {
02039                 trace_bin[i] = 0;
02040         }
02041 #endif
02042 
02043 
02044         while(card_selected < np) {
02045                 for(i=0; i<np; i++) {
02046                         if(selected[order[i]] == 0) {
02047                                 start_point = i;
02048                                 break;
02049                         }
02050                 }
02051     
02052                 loc_card_selected = np;
02053                 loc_card_new_selected = np;
02054                 loc_lhs = lhs;
02055                 double recomp_gap = fabs(lhs*WISE_SPARSIFY_GAP);
02056                 double threshold = lhs + recomp_gap;
02057 
02058                 // restore locv (might have been changed by WISE_SPARSIFY during the generation of the last sparse cut)
02059                 for(i=0;i<np;i++)
02060                         locv[i] = locv_orig[i];
02061 
02062                 for(i=0; i<np; i++) {
02063                         if(selected[i] == -1) {
02064                                 loc_selected[i] = 0;
02065                                 loc_card_selected--;
02066                                 loc_card_new_selected--;
02067                         } else {
02068                                 loc_selected[i] = 1;
02069                                 
02070                                 if(selected[i] == 1) {
02071                                         loc_card_new_selected--;
02072                                 }
02073                         }
02074                         locmargin[i] = margin[i];
02075                         for(j=0; j<np; j++) {
02076                                 locmat[i][j] = mat[i][j];
02077                         }
02078                 }
02079 
02080                 if(loc_lhs < min_delta) {
02081 
02082                         int changed = 1;
02083                         while(changed) {
02084 
02085 #ifdef TRACE_ALL
02086                                 printf("SdpCutGen::sparsify(): loc_lhs: %8.6f\n", loc_lhs);
02087                                 cpp_printmatDBL("locmat", locmat, np, np);
02088                                 cpp_printvecDBL("locmargin", locmargin, np);
02089                                 cpp_printvecINT("loc_selected", loc_selected, np);
02090 #endif
02091         
02092                                 int curr_i = start_point;
02093                                 
02094                                 changed = 0;
02095                                 
02096                                 int sel_nchanged = -1; 
02097 
02098                                 while(sel_nchanged != 0) {
02099                                         int new_selected = 0;
02100                                         zero_selected(np, order, selected, min_number_new_per_cut,
02101                                                 min_delta, start_point,
02102                                                 curr_i, loc_selected, 
02103                                                 &loc_card_selected, &loc_card_new_selected, 
02104                                                 &loc_lhs, locmargin, locmat, 
02105                                                 &sel_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
02106                                                 &card_selected, &new_selected, 
02107                                                 trace_bin, trace_bin_size,
02108                                                 sparse_v_mat, card_v_mat,
02109                                                 init_card_selected, &has_init_vect,evdec_num);
02110                                         
02111                                         if(sel_nchanged) {
02112                                                 nchanged += sel_nchanged;
02113                                         //          changed = 1;
02114                                         }
02115                                 } // while(sel_nchanged != 0) 
02116 
02117                                 int pos_nchanged = -1;
02118         
02119                                 while(pos_nchanged != 0) {
02120                                         int new_selected = 0;
02121                                         zero_pos_delta(np, order, selected, min_number_new_per_cut,
02122                                                         start_point, start_point, loc_selected, 
02123                                                         &loc_card_selected, &loc_card_new_selected, 
02124                                                         &loc_lhs, locmargin, locmat, 
02125                                                         &pos_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
02126                                                         &card_selected, &new_selected, 
02127                                                         trace_bin, trace_bin_size,
02128                                                         sparse_v_mat, card_v_mat,
02129                                                         init_card_selected, &has_init_vect,evdec_num);
02130                                 
02131                                         if(pos_nchanged) {
02132                                                 nchanged += pos_nchanged;
02133                                                 changed = 1;
02134                                         }
02135                                 } /* while(pos_nchanged != 0) */
02136         
02137                                 if(changed) {
02138                                         continue;
02139                                 }
02140 
02141                                 curr_i = start_point;
02142                                 
02143                                 int val_nchanged = -1;
02144 
02145                                 if(val_nchanged) {
02146                                         int new_selected = 0;
02147                                         zero_valid_delta(np, order, selected, min_number_new_per_cut,
02148                                                         min_delta, start_point,
02149                                                         curr_i, loc_selected, 
02150                                                         &loc_card_selected, &loc_card_new_selected, 
02151                                                         &loc_lhs, locmargin, locmat, 
02152                                                         &val_nchanged,sol,locv,evidx,wise,&recomp_gap,&threshold,
02153                                                         &card_selected, &new_selected, 
02154                                                         trace_bin, trace_bin_size,
02155                                                         sparse_v_mat, card_v_mat,
02156                                                         init_card_selected, &has_init_vect,evdec_num);
02157                                         
02158                                         if(val_nchanged) {
02159                                         nchanged += val_nchanged;
02160                                         changed = 1;
02161                                         }
02162                                 }
02163                         } /* while(changed) */
02164 
02165                         if((loc_card_selected < np * SPARSIFY_NEW_NZ_THRESHOLD) || (*card_v_mat == 0)) {
02166                                 
02167                                 int new_selected = 0;
02168                                 
02169                                 add_v_cut(np, loc_selected, loc_card_selected, locv, 
02170                                         init_card_selected, &has_init_vect,
02171                                         selected, &card_selected, &new_selected, 
02172                                         trace_bin, trace_bin_size,
02173                                         sparse_v_mat, card_v_mat);
02174                         } else {
02175                                 selected[order[start_point]] = 1;
02176                                 card_selected++;
02177                         }
02178                 } else {
02179                 // loc_lhs >= min_delta  use vector as is
02180                         card_selected = np;
02181 
02182 #ifdef TRACE_ALL
02183                         printf("SdpCutGen::sparsify(): lhs: %8.6f  too large. No sparsification\n", lhs);
02184 #endif
02185 
02186 #ifndef ONLY_NEG_EIGENV
02187                         int new_selected = 0;
02188                         
02189                         add_v_cut(np, loc_selected, loc_card_selected, locv, 
02190                                         init_card_selected, &has_init_vect,
02191                                         selected, &card_selected, &new_selected, 
02192                                         trace_bin, trace_bin_size,
02193                                         sparse_v_mat, card_v_mat);
02194 #endif
02195 
02196                 }
02197         } /* while(card_selected < np) */
02198 
02199 
02200 #ifdef TRACE_ALL
02201         printf("SdpCutGen::sparsify(): bin size: %d\n", trace_bin_size);
02202         cpp_printvecINT("trace_bin", trace_bin, card_trace_bin);
02203         delete[] trace_bin;
02204 #endif
02205 
02206         delete[] order;
02207         delete[] rand_val;
02208         
02209         for (i=0; i<np; i++) {
02210                 delete [] mat[i];
02211                 delete [] locmat[i];
02212         }
02213         delete [] mat;
02214         delete [] locmat;
02215 
02216         delete[] locv;
02217         delete[] locv_orig;
02218         delete[] margin;
02219         delete[] locmargin;
02220         
02221         delete[] selected;
02222         delete[] loc_selected;
02223 } // sparsify_new
02224 
02225 

Generated on Wed Nov 30 03:03:59 2011 by  doxygen 1.4.7