genmodel 0.0.42 → 0.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ string getcplexerror(CPXENVptr env, int status)
10
10
  char errmsg[4096];
11
11
  snprintf(errmsg, 4096, "CPLEX error %d : ", status);
12
12
  string prefix = string(errmsg);
13
- CPXgeterrorstring (env, status, errmsg);
13
+ CPXXgeterrorstring (env, status, errmsg);
14
14
  return prefix+string(errmsg);
15
15
  }
16
16
 
@@ -30,7 +30,7 @@ long GenModelCplex::WriteProblemToLpFile(string filename)
30
30
  throw string("WriteProblemToLpFile() not available : Problem not created yet;");
31
31
 
32
32
  CplexData* d = static_cast<CplexData*>(solverdata);
33
- CPXwriteprob(d->env, d->lp, filename.c_str(), "LP");
33
+ CPXXwriteprob(d->env, d->lp, filename.c_str(), "LP");
34
34
  return 0;
35
35
  }
36
36
 
@@ -40,39 +40,52 @@ long GenModelCplex::WriteSolutionToFile(string filename)
40
40
  throw string("WriteSolutionToFile() not available : Problem not created yet;");
41
41
 
42
42
  CplexData* d = static_cast<CplexData*>(solverdata);
43
- CPXsolwrite (d->env, d->lp, filename.c_str());
43
+ CPXXsolwrite (d->env, d->lp, filename.c_str());
44
44
  return 0;
45
45
  }
46
46
 
47
47
  long GenModelCplex::Solve()
48
48
  {
49
+
49
50
  if(!bcreated)
50
51
  throw string("Solve() not available : Problem not created yet");
52
+ try{
51
53
  CplexData* d = static_cast<CplexData*>(solverdata);
52
54
  int status = 0;
53
55
  if(boolParam.count("mip") > 0 && boolParam["mip"])
54
- status = CPXmipopt(d->env, d->lp);
56
+ status = CPXXmipopt(d->env, d->lp);
55
57
  else if(boolParam.count("qp") > 0 && boolParam["qp"])
56
- status = CPXqpopt(d->env, d->lp);
58
+ status = CPXXqpopt(d->env, d->lp);
57
59
  else if(strParam.count("algo") > 0 && strParam["algo"] == "interior")
58
- status = CPXbaropt(d->env, d->lp);
60
+ status = CPXXbaropt(d->env, d->lp);
59
61
  else if(strParam.count("algo") > 0 && strParam["algo"] == "dual")
60
- status = CPXdualopt(d->env, d->lp);
62
+ status = CPXXdualopt(d->env, d->lp);
61
63
  else if(strParam.count("algo") > 0 && strParam["algo"] == "primal")
62
- status = CPXprimopt(d->env, d->lp);
64
+ status = CPXXprimopt(d->env, d->lp);
63
65
  else if(strParam.count("algo") > 0 && strParam["algo"] == "concurrent")
64
66
  {
65
67
  //printf("choosing concurrent algo\n");
66
- CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_CONCURRENT);
67
- status = CPXlpopt(d->env, d->lp);
68
+ CPXXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_CONCURRENT);
69
+ status = CPXXlpopt(d->env, d->lp);
68
70
  }
69
71
  else if(strParam.count("algo") > 0 && strParam["algo"] == "sifting")
70
72
  {
71
- CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_SIFTING);
72
- status = CPXlpopt(d->env, d->lp);
73
+ CPXXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_SIFTING);
74
+ status = CPXXlpopt(d->env, d->lp);
73
75
  }
74
76
  else
75
- status = CPXlpopt(d->env, d->lp);
77
+ status = CPXXlpopt(d->env, d->lp);
78
+ if(status)
79
+ ThrowError(getcplexerror(d->env, status)+string(". ")+string("Solve() : Solve failed"));
80
+ }
81
+ catch(string str)
82
+ {
83
+ throw string("Solve() error : ")+str;
84
+ }
85
+ catch(...)
86
+ {
87
+ throw ThrowError(string("Solve() : Solve failed with unknown error"));
88
+ }
76
89
 
77
90
  return 0;
78
91
  }
@@ -81,6 +94,7 @@ long GenModelCplex::SetSol()
81
94
  {
82
95
  if(!bcreated)
83
96
  throw string("SetSol() not available : Problem not created yet");
97
+ try {
84
98
  vars.sol.clear();
85
99
  vars.sol.resize(vars.n,0);
86
100
  vars.rc.clear();
@@ -102,16 +116,16 @@ long GenModelCplex::SetSol()
102
116
  d->rcost = new double[nc];
103
117
  d->slack = new double[nr];
104
118
 
105
- int tempstat = CPXgetstat (d->env, d->lp);
119
+ int tempstat = CPXXgetstat (d->env, d->lp);
106
120
  int tempfeas;
107
121
  int tempdualfeas;
108
122
  int temphassol;
109
- int currmeth = CPXgetmethod(d->env, d->lp);
123
+ int currmeth = CPXXgetmethod(d->env, d->lp);
110
124
 
111
125
 
112
- status = CPXsolninfo(d->env, d->lp, &currmeth, &temphassol, &tempfeas, &tempdualfeas);
126
+ status = CPXXsolninfo(d->env, d->lp, &currmeth, &temphassol, &tempfeas, &tempdualfeas);
113
127
  if ( status )
114
- return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXsolninfo)"));
128
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXXsolninfo)"));
115
129
 
116
130
  feasible = static_cast<bool>(tempfeas);
117
131
  dualfeasible = static_cast<bool>(tempdualfeas);
@@ -121,11 +135,11 @@ long GenModelCplex::SetSol()
121
135
  return 0;
122
136
 
123
137
  if(boolParam.count("mip") > 0 && boolParam["mip"])
124
- status = CPXsolution (d->env, d->lp, &solstat, &objval, d->x, NULL, NULL, NULL);
138
+ status = CPXXsolution (d->env, d->lp, &solstat, &objval, d->x, NULL, NULL, NULL);
125
139
  else
126
- status = CPXsolution (d->env, d->lp, &solstat, &objval, d->x, d->dual, d->slack, d->rcost);
140
+ status = CPXXsolution (d->env, d->lp, &solstat, &objval, d->x, d->dual, d->slack, d->rcost);
127
141
  if ( status )
128
- return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXsolution)"));
142
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXXsolution)"));
129
143
 
130
144
  solstat = tempstat;
131
145
 
@@ -143,6 +157,15 @@ long GenModelCplex::SetSol()
143
157
 
144
158
  if(boolParam.count("print_version") > 0 && boolParam["print_version"])
145
159
  printf("*********** Genmodel version = %s ***********\n", version.c_str());
160
+ }
161
+ catch(string str)
162
+ {
163
+ throw string("SetSol() error : ")+str;
164
+ }
165
+ catch(...)
166
+ {
167
+ throw ThrowError(string("SetSol() : Solution retrieval failed with unknown error"));
168
+ }
146
169
 
147
170
  return 0;
148
171
  }
@@ -162,9 +185,9 @@ long GenModelCplex::AddCut(int* cols, double* vals, int nz, double rhs, char sen
162
185
  if(!bcreated)
163
186
  return ThrowError("AddCut() not available : Problem not created yet");
164
187
  CplexData* d = (CplexData*)solverdata;
165
- int rmatbeg = 0;
188
+ int64_t rmatbeg = 0;
166
189
 
167
- CPXaddrows(d->env, d->lp, 0, 1, nz, &rhs, &sense, &rmatbeg, cols, vals, NULL, (char**)(&name));
190
+ CPXXaddrows(d->env, d->lp, 0, 1, nz, &rhs, &sense, &rmatbeg, cols, vals, NULL, (char**)(&name));
168
191
  d->nr++;
169
192
 
170
193
  return 0;
@@ -175,7 +198,7 @@ long GenModelCplex::AddSolverCol(vector<int>& ind, vector<double>& val, double o
175
198
  if(!bcreated)
176
199
  return ThrowError("AddSolverCol() not available : Problem not created yet");
177
200
  AddModelCol(ind, val, obj, lb, ub, name, type);
178
- AddCol(&ind[0], &val[0], int(ind.size()), obj, lb, ub, name.c_str(), type);
201
+ AddCol(&ind[0], &val[0], ind.size(), obj, lb, ub, name.c_str(), type);
179
202
 
180
203
  return 0;
181
204
  }
@@ -185,7 +208,7 @@ long GenModelCplex::AddCol(int* newi, double* newcol, int nz, double obj, double
185
208
  if(!bcreated)
186
209
  return ThrowError("AddCol() not available : Problem not created yet");
187
210
  CplexData* d = (CplexData*)solverdata;
188
- int cmatbeg = 0;
211
+ int64_t cmatbeg = 0;
189
212
 
190
213
  double clb = lb;
191
214
  if(clb == numeric_limits<double>::infinity())
@@ -194,16 +217,16 @@ long GenModelCplex::AddCol(int* newi, double* newcol, int nz, double obj, double
194
217
  clb = -CPX_INFBOUND;
195
218
 
196
219
  double cub = ub;
197
- if(cub == numeric_limits<double>::infinity())
198
- cub = CPX_INFBOUND;
199
- else if(cub == -numeric_limits<double>::infinity())
200
- cub = -CPX_INFBOUND;
220
+ if(cub == numeric_limits<double>::infinity())
221
+ cub = CPX_INFBOUND;
222
+ else if(cub == -numeric_limits<double>::infinity())
223
+ cub = -CPX_INFBOUND;
201
224
 
202
- CPXaddcols(d->env, d->lp, 1, nz, &obj, &cmatbeg, newi, newcol, &clb, &cub, (char**)(&name));
225
+ CPXXaddcols(d->env, d->lp, 1, nz, &obj, &cmatbeg, newi, newcol, &clb, &cub, (char**)(&name));
203
226
  if(type != 'C')
204
227
  {
205
228
  int cind = d->nc;
206
- CPXchgctype(d->env, d->lp, 1, &cind, &type);
229
+ CPXXchgctype(d->env, d->lp, 1, &cind, &type);
207
230
  }
208
231
  d->nc++;
209
232
 
@@ -222,9 +245,9 @@ long GenModelCplex::CreateModel()
222
245
  d->onr = nr;
223
246
 
224
247
  if(boolParam.count("maximize") > 0 && boolParam["maximize"])
225
- CPXchgobjsen (d->env, d->lp, CPX_MAX);
248
+ CPXXchgobjsen (d->env, d->lp, CPX_MAX);
226
249
  else
227
- CPXchgobjsen (d->env, d->lp, CPX_MIN);
250
+ CPXXchgobjsen (d->env, d->lp, CPX_MIN);
228
251
  d->lrhs = new double[nr];
229
252
  d->urhs = new double[nr];
230
253
  d->sense = new char[nr];
@@ -291,12 +314,12 @@ long GenModelCplex::CreateModel()
291
314
 
292
315
  //printf("%ld (%s) -> %f %f %f %c\n", i, vars.name[i].c_str(), d->obj[i], d->lb[i], d->ub[i], d->type[i]);
293
316
  }
294
- status = CPXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname);
317
+ status = CPXXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname);
295
318
  if ( status )
296
319
  {
297
320
  char errmsg[1024];
298
321
  fprintf (stderr, "Could not create new rows.\n");
299
- CPXgeterrorstring (d->env, status, errmsg);
322
+ CPXXgeterrorstring (d->env, status, errmsg);
300
323
  fprintf (stderr, "%s", errmsg);
301
324
  return 1;
302
325
  }
@@ -304,23 +327,23 @@ long GenModelCplex::CreateModel()
304
327
  //printf("Row added!\n");
305
328
 
306
329
  if(boolParam.count("mip") > 0 && boolParam["mip"])
307
- status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname);
330
+ status = CPXXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname);
308
331
  else
309
- status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL);
332
+ status = CPXXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL);
310
333
  if ( status )
311
334
  {
312
335
  char errmsg[1024];
313
336
  fprintf (stderr, "Could not create new cols.\n");
314
- CPXgeterrorstring (d->env, status, errmsg);
337
+ CPXXgeterrorstring (d->env, status, errmsg);
315
338
  fprintf (stderr, "%s", errmsg);
316
339
  return 1;
317
340
  }
318
- //status = CPXnewcols (env, lp, nc, obj, lb, ub, NULL, colname);
341
+ //status = CPXXnewcols (env, lp, nc, obj, lb, ub, NULL, colname);
319
342
  if ( status )
320
343
  return 1;
321
344
  //else
322
345
  //printf("Col added!\n");
323
- status = CPXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v);
346
+ status = CPXXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v);
324
347
  if ( status )
325
348
  return 1;
326
349
 
@@ -330,7 +353,7 @@ long GenModelCplex::CreateModel()
330
353
 
331
354
  vector<vector<pair<int,double> > > qptemp;
332
355
  qptemp.resize(nc);
333
- int* qpbeg = NULL;
356
+ int64_t* qpbeg = NULL;
334
357
  int* qpnum = NULL;
335
358
  int* qpind = NULL;
336
359
  double* qpv = NULL;
@@ -339,7 +362,7 @@ long GenModelCplex::CreateModel()
339
362
  if(!vars.qi.empty())
340
363
  {
341
364
  boolParam["qp"] = true;
342
- qpbeg = new int[nc];
365
+ qpbeg = new int64_t[nc];
343
366
  qpnum = new int[nc];
344
367
  }
345
368
  if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"])
@@ -371,7 +394,7 @@ long GenModelCplex::CreateModel()
371
394
  qpnz++;
372
395
  }
373
396
  }
374
- status = CPXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv);
397
+ status = CPXXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv);
375
398
  delete[] qpbeg;
376
399
  delete[] qpnum;
377
400
  delete[] qpind;
@@ -390,12 +413,12 @@ long GenModelCplex::CreateModel()
390
413
  return 0;
391
414
  }
392
415
 
393
- long AddQuadraticVector(vector<int>& ind, vector<double>& val)
416
+ long AddQuadraticVector(vector<size_t>& ind, vector<double>& val)
394
417
  {
395
418
  return 0;
396
419
  }
397
420
 
398
- long AddQuadraticMatrix(vector<int>& indi, vector<int>& indj, vector<double>& val)
421
+ long AddQuadraticMatrix(vector<size_t>& indi, vector<size_t>& indj, vector<double>& val)
399
422
  {
400
423
  return 0;
401
424
  }
@@ -430,7 +453,7 @@ long GenModelCplex::ChangeBulkBounds(int count, int * ind, char * type, double *
430
453
  }
431
454
  }
432
455
 
433
- CPXchgbds(d->env, d->lp, count, ind, type, vals);
456
+ CPXXchgbds(d->env, d->lp, count, ind, type, vals);
434
457
 
435
458
  return 0;
436
459
  }
@@ -446,7 +469,7 @@ long GenModelCplex::ChangeBulkObjectives(int count, int * ind, double * vals)
446
469
  vars.obj[i] = vals[i];
447
470
  }
448
471
 
449
- CPXchgobj(d->env, d->lp, count, ind, vals);
472
+ CPXXchgobj(d->env, d->lp, count, ind, vals);
450
473
 
451
474
  return 0;
452
475
  }
@@ -473,7 +496,7 @@ long GenModelCplex::ChangeBulkNz(int count, int* rind, int* cind, double * vals)
473
496
  consts[rind[i]].AddNz(cind[i], vals[i]);
474
497
  }
475
498
 
476
- CPXchgcoeflist(d->env, d->lp, count, rind, cind, vals);
499
+ CPXXchgcoeflist(d->env, d->lp, count, rind, cind, vals);
477
500
 
478
501
  return 0;
479
502
  }
@@ -485,9 +508,9 @@ long GenModelCplex::DeleteMipStarts()
485
508
  if(!bcreated)
486
509
  return ThrowError("ChangeBulkNz() not available : Problem not created yet");
487
510
  CplexData* d = (CplexData*)solverdata;
488
- int n = CPXgetnummipstarts(d->env, d->lp);
511
+ int n = CPXXgetnummipstarts(d->env, d->lp);
489
512
  if (n > 0)
490
- CPXdelmipstarts(d->env, d->lp, 0, n - 1);
513
+ CPXXdelmipstarts(d->env, d->lp, 0, n - 1);
491
514
 
492
515
  return 0;
493
516
  }
@@ -498,9 +521,9 @@ double GenModelCplex::GetMIPRelativeGap()
498
521
  return ThrowError("ChangeBulkNz() not available : Problem not created yet");
499
522
  CplexData* d = (CplexData*)solverdata;
500
523
  double gap = 0, bestobjval = 0;
501
- CPXgetbestobjval(d->env, d->lp, &bestobjval);
502
- if (bestobjval > 0) // If the optimal solution is found by the presolve, the CPXgetbestobjval = 0, and the CPXgetmiprelgap ~ 1
503
- CPXgetmiprelgap(d->env, d->lp, &gap);
524
+ CPXXgetbestobjval(d->env, d->lp, &bestobjval);
525
+ if (bestobjval > 0) // If the optimal solution is found by the presolve, the CPXXgetbestobjval = 0, and the CPXXgetmiprelgap ~ 1
526
+ CPXXgetmiprelgap(d->env, d->lp, &gap);
504
527
 
505
528
  return gap;
506
529
  }
@@ -511,7 +534,7 @@ long GenModelCplex::SwitchToMip()
511
534
  return ThrowError("SwitchToMip() not available : Problem not created yet");
512
535
  vector<int> ind;
513
536
  vector<char> type;
514
- for(int i = 0; i < int(vars.type.size()); i++)
537
+ for(size_t i = 0; i < vars.type.size(); i++)
515
538
  {
516
539
  if(vars.type[i] == 'B' || vars.type[i] == 'I' || vars.type[i] == 'S' || vars.type[i] == 'N')
517
540
  {
@@ -520,7 +543,7 @@ long GenModelCplex::SwitchToMip()
520
543
  }
521
544
  }
522
545
  CplexData* d = static_cast<CplexData*>(solverdata);
523
- CPXchgctype(d->env, d->lp, int(ind.size()), &(ind[0]), &(type[0]));
546
+ CPXXchgctype(d->env, d->lp, ind.size(), &(ind[0]), &(type[0]));
524
547
  boolParam["mip"] = true;
525
548
 
526
549
  return 0;
@@ -532,7 +555,7 @@ long GenModelCplex::SwitchToLp()
532
555
  return ThrowError("SwitchToLp() not available : Problem not created yet");
533
556
  vector<int> ind;
534
557
  vector<char> type;
535
- for(int i = 0; i < int(vars.type.size()); i++)
558
+ for(size_t i = 0; i < vars.type.size(); i++)
536
559
  {
537
560
  if(vars.type[i] == 'B' || vars.type[i] == 'I' || vars.type[i] == 'S' || vars.type[i] == 'N')
538
561
  {
@@ -541,12 +564,153 @@ long GenModelCplex::SwitchToLp()
541
564
  }
542
565
  }
543
566
  CplexData* d = static_cast<CplexData*>(solverdata);
544
- CPXchgctype(d->env, d->lp, int(ind.size()), &(ind[0]), &(type[0]));
567
+ CPXXchgctype(d->env, d->lp, ind.size(), &(ind[0]), &(type[0]));
545
568
  boolParam["mip"] = false;
546
569
 
547
570
  return 0;
548
571
  }
549
572
 
573
+ string SolverInfo::inspect() const
574
+ {
575
+ return to_s();
576
+ }
577
+
578
+ string SolverInfo::to_s() const
579
+ {
580
+ char tmp[10000];
581
+ string _cpx_results = cpx_results;
582
+ string _cpx_warning = cpx_warning;
583
+ string _cpx_error = cpx_error;
584
+ string _cpx_log = cpx_log;
585
+ size_t pos = 0;
586
+ while((pos = _cpx_results.find("\n", pos)) != std::string::npos) { _cpx_results.replace(pos, 1, "\\n"); pos += 2; }
587
+ pos = 0;
588
+ while((pos = _cpx_warning.find("\n", pos)) != std::string::npos) { _cpx_warning.replace(pos, 1, "\\n"); pos += 2; }
589
+ pos = 0;
590
+ while((pos = _cpx_error.find("\n", pos)) != std::string::npos) { _cpx_error.replace(pos, 1, "\\n"); pos += 2; }
591
+ pos = 0;
592
+ while((pos = _cpx_log.find("\n", pos)) != std::string::npos) { _cpx_log.replace(pos, 1, "\\n"); pos += 2; }
593
+
594
+ snprintf(tmp, 10000,
595
+ "{\n"
596
+ "\t\"relative_gap\" : \"%f\",\n"
597
+ "\t\"upper_bound\" : \"%f\",\n"
598
+ "\t\"lower_bound\" : \"%f\",\n"
599
+ "\t\"cutoff\" : \"%f\",\n"
600
+ "\t\"nb_node_solved\" : %lu,\n"
601
+ "\t\"nb_node_left\" : %lu,\n"
602
+ "\t\"nb_threads\" : %lu,\n"
603
+ "\t\"nb_iters\" : %lu,\n"
604
+ "\t\"nb_solutions\" : %lu,\n"
605
+ "\t\"nb_clique_cuts\" : %lu,\n"
606
+ "\t\"nb_cover_cuts\" : %lu,\n"
607
+ "\t\"nb_disjcut_cuts\" : %lu,\n"
608
+ "\t\"nb_flow_cover_cuts\" : %lu,\n"
609
+ "\t\"nb_flow_path_cuts\" : %lu,\n"
610
+ "\t\"nb_fractionnal_cuts\" : %lu,\n"
611
+ "\t\"nb_gub_cover_cuts\" : %lu,\n"
612
+ "\t\"nb_implied_bound_cuts\" : %lu,\n"
613
+ "\t\"nb_lift_project_cuts\" : %lu,\n"
614
+ "\t\"nb_flow_mc_flow_cuts\" : %lu,\n"
615
+ "\t\"nb_flow_mir_cuts\" : %lu,\n"
616
+ "\t\"nb_zero_half_cuts\" : %lu,\n"
617
+ "\t\"nb_user_cuts\" : %lu,\n"
618
+ "\t\"nb_lazy_cuts\" : %lu,\n"
619
+ "\t\"nb_soln_pool_cuts\" : %lu,\n"
620
+ "\t\"cpx_results\" : \"%s\",\n"
621
+ "\t\"cpx_warning\" : \"%s\",\n"
622
+ "\t\"cpx_error\" : \"%s\",\n"
623
+ "\t\"cpx_log\" : \"%s\",\n"
624
+ "\t\"status_str\" : \"%s\""
625
+ "}\n",
626
+ relative_gap,upper_bound,lower_bound,cutoff,nb_node_solved,nb_node_left,nb_threads,nb_iters,nb_solutions,nb_clique_cuts,nb_cover_cuts,nb_disjcut_cuts,
627
+ nb_flow_cover_cuts,nb_flow_path_cuts,nb_fractionnal_cuts,nb_gub_cover_cuts,nb_implied_bound_cuts,nb_lift_project_cuts,nb_flow_mc_flow_cuts,nb_flow_mir_cuts,
628
+ nb_zero_half_cuts,nb_user_cuts,nb_lazy_cuts,nb_soln_pool_cuts,_cpx_results.c_str(),_cpx_warning.c_str(),_cpx_error.c_str(),_cpx_log.c_str(), status_str.c_str()
629
+ );
630
+
631
+ return string(tmp);
632
+ }
633
+
634
+ SolverInfo GenModelCplex::GetSolverInfo()
635
+ {
636
+ if(!bcreated)
637
+ {
638
+ ThrowError("GetSolverInfo() not available : Problem not created yet");
639
+ return SolverInfo();
640
+ }
641
+ CplexData* d = static_cast<CplexData*>(solverdata);
642
+ printf("solstat = %ld\n", solstat);
643
+ if(solstat == numeric_limits<int>::infinity())
644
+ d->solver_info.status_str = "No status assigned.";
645
+ else
646
+ {
647
+ char status_str[CPXMESSAGEBUFSIZE];
648
+ char* _status = CPXXgetstatstring(d->env, solstat, status_str);
649
+ if (_status == NULL)
650
+ ThrowError(string("Failure to get the status string"));
651
+ d->solver_info.status_str = status_str;
652
+ printf("GetSolverInfo : status = %s [%s] [%s]\n", _status, status_str, d->solver_info.status_str.c_str());
653
+ }
654
+
655
+ return d->solver_info;
656
+ }
657
+
658
+ int mip_cb(CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle)
659
+ {
660
+ printf("Callback called\n");
661
+ GenModelCplex* pgm = static_cast<GenModelCplex*>(cbhandle);
662
+ CplexData* d = static_cast<CplexData*>(pgm->solverdata);
663
+
664
+ vector<vector<double> > solutions;
665
+ vector<double> solution_objvals;
666
+
667
+ if(pgm->boolParam.count("maximize") > 0 && pgm->boolParam["maximize"])
668
+ {
669
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_INTEGER, &(d->solver_info.lower_bound));
670
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_REMAINING, &(d->solver_info.upper_bound));
671
+ }
672
+ else
673
+ {
674
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_REMAINING, &(d->solver_info.lower_bound));
675
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_INTEGER, &(d->solver_info.upper_bound));
676
+ }
677
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT_LONG, &(d->solver_info.nb_node_solved));
678
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODES_LEFT_LONG, &(d->solver_info.nb_node_left));
679
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_MIP_REL_GAP, &(d->solver_info.relative_gap));
680
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_CUTOFF, &(d->solver_info.cutoff));
681
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_MIP_ITERATIONS_LONG, &(d->solver_info.nb_iters));
682
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_USER_THREADS, &(d->solver_info.nb_threads));
683
+
684
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_CLIQUE_COUNT, &(d->solver_info.nb_clique_cuts));
685
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_COVER_COUNT, &(d->solver_info.nb_cover_cuts));
686
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_DISJCUT_COUNT, &(d->solver_info.nb_disjcut_cuts));
687
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_FLOWCOVER_COUNT, &(d->solver_info.nb_flow_cover_cuts));
688
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_FLOWPATH_COUNT, &(d->solver_info.nb_flow_path_cuts));
689
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_FRACCUT_COUNT, &(d->solver_info.nb_fractionnal_cuts));
690
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_GUBCOVER_COUNT, &(d->solver_info.nb_gub_cover_cuts));
691
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_IMPLBD_COUNT, &(d->solver_info.nb_implied_bound_cuts));
692
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_LANDPCUT_COUNT, &(d->solver_info.nb_lift_project_cuts));
693
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_MCFCUT_COUNT, &(d->solver_info.nb_flow_mc_flow_cuts));
694
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_MIRCUT_COUNT, &(d->solver_info.nb_flow_mir_cuts));
695
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_ZEROHALFCUT_COUNT, &(d->solver_info.nb_zero_half_cuts));
696
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_USERCUT_COUNT, &(d->solver_info.nb_user_cuts));
697
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_TABLECUT_COUNT, &(d->solver_info.nb_lazy_cuts));
698
+ CPXXgetcallbackinfo(d->env, cbdata, wherefrom, CPX_CALLBACK_INFO_SOLNPOOLCUT_COUNT, &(d->solver_info.nb_soln_pool_cuts));
699
+
700
+ if(d->stop_solver)
701
+ return 1;
702
+
703
+ d->solver_info.nb_solutions = CPXXgetsolnpoolnumsolns(d->env, d->lp);
704
+
705
+ return d->original_mip_cb(env, cbdata, wherefrom, d->original_handle);
706
+ }
707
+
708
+ void msg_function(void* cbhandle, const char* msg)
709
+ {
710
+ string* p_str = static_cast<string*>(cbhandle);
711
+ (*p_str) += msg;
712
+ }
713
+
550
714
  long GenModelCplex::Init(string name)
551
715
  {
552
716
 
@@ -579,7 +743,7 @@ long GenModelCplex::Init(string name)
579
743
  CplexData* d = static_cast<CplexData*>(solverdata);
580
744
  int status = 0;
581
745
 
582
- d->env = CPXopenCPLEX (&status);
746
+ d->env = CPXXopenCPLEX (&status);
583
747
 
584
748
  // If an error occurs
585
749
  if ( d->env == NULL )
@@ -591,11 +755,45 @@ long GenModelCplex::Init(string name)
591
755
  // Log file
592
756
  if(strParam.count("log_file") > 0)
593
757
  {
594
- d->cpxfileptr = CPXfopen(strParam["log_file"].c_str(), "w");
595
- status = CPXsetlogfile(d->env, d->cpxfileptr);
596
- if ( status )
758
+ d->cpxfileptr = CPXXfopen(strParam["log_file"].c_str(), "w");
759
+ status = CPXXsetlogfile(d->env, d->cpxfileptr);
760
+ if (status)
597
761
  return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the log file"));
598
762
  }
763
+
764
+ if(boolParam.count("fill_solver_info") > 0)
765
+ {
766
+ printf("solver_info ON\n");
767
+ /*status = CPXXgetmipcallbackfunc(d->env, &(d->original_mip_cb), &(d->original_handle));
768
+ if (status)
769
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to get the default mip callback function"));
770
+
771
+ status = CPXXsetmipcallbackfunc(d->env, mip_cb, this);
772
+ if (status)
773
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the mip callback function"));
774
+ */
775
+
776
+ CPXCHANNELptr cpxresults, cpxwarning, cpxerror, cpxlog;
777
+ status = CPXXgetchannels(d->env, &cpxresults, &cpxwarning, &cpxerror, &cpxlog);
778
+ if (status)
779
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to get the solver channels"));
780
+
781
+ status = CPXXaddfuncdest(d->env, cpxresults, &(d->solver_info.cpx_results), msg_function);
782
+ if (status)
783
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the results channel callback function"));
784
+
785
+ status = CPXXaddfuncdest(d->env, cpxwarning, &(d->solver_info.cpx_warning), msg_function);
786
+ if (status)
787
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the warning channel callback function"));
788
+
789
+ status = CPXXaddfuncdest(d->env, cpxerror, &(d->solver_info.cpx_error), msg_function);
790
+ if (status)
791
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the error channel callback function"));
792
+
793
+ status = CPXXaddfuncdest(d->env, cpxlog, &(d->solver_info.cpx_log), msg_function);
794
+ if (status)
795
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the log channel callback function"));
796
+ }
599
797
 
600
798
  // General settings
601
799
  //boolParam["log_output_stdout"] = true;
@@ -627,6 +825,19 @@ long GenModelCplex::Init(string name)
627
825
  }
628
826
 
629
827
  // Tolerance and limits
828
+
829
+ SetParam("memory_emphasis", CPX_PARAM_MEMORYEMPHASIS, "bool", "Failure to set memory emphasis");
830
+ SetParam("node_file_memory_mode", CPX_PARAM_NODEFILEIND, "long", "Failure to set node file memory mode");
831
+ /*
832
+ 0 No node file
833
+ 1 Node file in memory and compressed; default
834
+ 2 Node file on disk
835
+ 3 Node file on disk and compressed
836
+ */
837
+ SetParam("tree_memory_limit", CPX_PARAM_TRELIM, "dbl", "Failure to set tree memory limit"); // In megabytes
838
+ SetParam("work_memory_limit", CPX_PARAM_WORKMEM, "dbl", "Failure to set work memory limit"); // In megabytes
839
+
840
+
630
841
  SetParam("time_limit", CPX_PARAM_TILIM, "dbl", "Failure to set time limit");
631
842
  SetParam("max_iteration_limit", CPX_PARAM_ITLIM, "long", "Failure to set the maximal number of simplex iterations");
632
843
  SetParam("bounds_feasibility_tolerance", CPX_PARAM_EPRHS, "dbl", "Failure to set bounds feasibility tolerance");
@@ -641,7 +852,7 @@ long GenModelCplex::Init(string name)
641
852
 
642
853
 
643
854
  // Create the problem
644
- d->lp = CPXcreateprob (d->env, &status, name.c_str());
855
+ d->lp = CPXXcreateprob (d->env, &status, name.c_str());
645
856
  if ( d->lp == NULL )
646
857
  return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to create Cplex optimization problem"));
647
858
 
@@ -654,11 +865,11 @@ long GenModelCplex::SetDirectParam(int whichparam, genmodel_param value, string
654
865
  {
655
866
  int status = 0;
656
867
  if(type == "dbl")
657
- status = CPXsetdblparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.dblval);
868
+ status = CPXXsetdblparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.dblval);
658
869
  else if(type == "long")
659
- status = CPXsetintparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.longval);
870
+ status = CPXXsetintparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.longval);
660
871
  else if(type == "str")
661
- status = CPXsetstrparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.strval);
872
+ status = CPXXsetstrparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.strval);
662
873
  if ( status )
663
874
  return ThrowError(getcplexerror(static_cast<CplexData*>(solverdata)->env, status)+string(". ")+message);
664
875
 
@@ -721,7 +932,7 @@ long GenModelCplex::Init(string name) {return cpx_not_implemented();}
721
932
  long GenModelCplex::CreateModel(string filename, int type, string dn) {return cpx_not_implemented();}
722
933
  long GenModelCplex::CreateModel() {return cpx_not_implemented();}
723
934
  long GenModelCplex::AddSolverCol(vector<int>& ind, vector<double>& val, double obj, double lb, double ub, string name, char type) {return cpx_not_implemented();}
724
- long GenModelCplex::AddSolverRow(vector<int>& ind, vector<double>& val, double rhs, char sense, string name) {return cpx_not_implemented();}
935
+ long GenModelCplex::AddSolverRow(vector<size_t>& ind, vector<double>& val, double rhs, char sense, string name) {return cpx_not_implemented();}
725
936
  long GenModelCplex::AddCol(int* newi, double* newcol, int nz, double obj, double lb, double ub, const char* name, char type) {return cpx_not_implemented();}
726
937
  long GenModelCplex::AddCut(int* cols, double* vals, int nz, double rhs, char sense, const char* name) {return cpx_not_implemented();}
727
938
  long GenModelCplex::ChangeBulkBounds(int count, int * ind, char * type, double * vals) {return cpx_not_implemented();}
@@ -761,6 +972,9 @@ long CplexData::Reset()
761
972
  env = NULL;
762
973
  lp = NULL;
763
974
  cpxfileptr = NULL;
975
+ stop_solver = false;
976
+ original_mip_cb = NULL;
977
+ original_handle = NULL;
764
978
 
765
979
  return 0;
766
980
  }
@@ -817,6 +1031,7 @@ long CplexData::ClearStructure()
817
1031
  delete[] rname[i];
818
1032
  delete[] rname;
819
1033
  }
1034
+
820
1035
  Reset();
821
1036
 
822
1037
  return 0;
@@ -827,15 +1042,15 @@ long CplexData::Delete()
827
1042
  #ifdef CPLEX_MODULE
828
1043
  if(lp != NULL)
829
1044
  {
830
- CPXfreeprob(env, &lp);
1045
+ CPXXfreeprob(env, &lp);
831
1046
  }
832
1047
  if(env != NULL)
833
1048
  {
834
- CPXcloseCPLEX(&env);
1049
+ CPXXcloseCPLEX(&env);
835
1050
  }
836
1051
  if(cpxfileptr != NULL)
837
1052
  {
838
- CPXfclose(cpxfileptr);
1053
+ CPXXfclose(cpxfileptr);
839
1054
  }
840
1055
 
841
1056
  ClearStructure();