00001
00002
00003
00004
00005
00006
00007
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
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
00048
00049
00050 A[0] = 1;
00051 for (int i=0;i<n_;i++) {
00052 A[np*(i+1)] = sol[i];
00053
00054
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
00060
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
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
00134
00135
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:
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
00266
00267
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
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
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
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
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 }
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
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
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
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
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
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
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 }
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 }
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 }
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
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
01357
01358
01359
01360
01361
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
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
01387 int m;
01388
01389 dsyevx_wrapper_only_most_neg (minor_n, minor_A, m, minor_w, minor_z,tracer_);
01390
01391
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 }
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 }
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 }
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 }
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
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
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
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 }
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
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;
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
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;
01756
01757 int has_init_vect = 0;
01758
01759 min_delta = lhs * SPARSIFY_OLD_DELTA;
01760 int start_point = -1;
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
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
01847 }
01848 }
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 }
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 }
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
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 }
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 }
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
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;
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
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;
02025
02026 int has_init_vect = 0;
02027
02028 min_delta = lhs * SPARSIFY_NEW_DELTA;
02029 int start_point = -1;
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
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
02114 }
02115 }
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 }
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 }
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
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 }
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 }
02224
02225