genmodel 0.0.20 → 0.0.21

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.
@@ -0,0 +1,814 @@
1
+ #include "GenModelCplex.h"
2
+ #ifdef OSI_MODULE
3
+ #include "ProblemReaderOsi.h"
4
+ #endif
5
+ #include <limits>
6
+
7
+ string getcplexerror(CPXENVptr env, int status)
8
+ {
9
+ char errmsg[4096];
10
+ snprintf(errmsg, 4096, "CPLEX error %d : ", status);
11
+ string prefix = string(errmsg);
12
+ CPXgeterrorstring (env, status, errmsg);
13
+ return prefix+string(errmsg);
14
+ }
15
+
16
+ GenModelCplex::~GenModelCplex()
17
+ {
18
+ if (solverdata != NULL) delete static_cast<CplexData*>(solverdata);
19
+ }
20
+
21
+ GenModelCplex::GenModelCplex() {
22
+
23
+ }
24
+
25
+ long GenModelCplex::WriteProblemToLpFile(string filename)
26
+ {
27
+ if(!bcreated)
28
+ throw string("WriteProblemToLpFile() not available : Problem not created yet;");
29
+
30
+ CplexData* d = static_cast<CplexData*>(solverdata);
31
+ CPXwriteprob(d->env, d->lp, filename.c_str(), "LP");
32
+ return 0;
33
+ }
34
+
35
+ long GenModelCplex::WriteSolutionToFile(string filename)
36
+ {
37
+ if(!bcreated)
38
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
39
+
40
+ CplexData* d = static_cast<CplexData*>(solverdata);
41
+ CPXsolwrite (d->env, d->lp, filename.c_str());
42
+ return 0;
43
+ }
44
+
45
+ long GenModelCplex::Solve()
46
+ {
47
+ if(!bcreated)
48
+ throw string("Solve() not available : Problem not created yet");
49
+ CplexData* d = static_cast<CplexData*>(solverdata);
50
+ int status = 0;
51
+ if(boolParam.count("mip") > 0 && boolParam["mip"])
52
+ status = CPXmipopt(d->env, d->lp);
53
+ else if(boolParam.count("qp") > 0 && boolParam["qp"])
54
+ status = CPXqpopt(d->env, d->lp);
55
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "interior")
56
+ status = CPXbaropt(d->env, d->lp);
57
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "dual")
58
+ status = CPXdualopt(d->env, d->lp);
59
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "primal")
60
+ status = CPXprimopt(d->env, d->lp);
61
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "concurrent")
62
+ {
63
+ //printf("choosing concurrent algo\n");
64
+ CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_CONCURRENT);
65
+ status = CPXlpopt(d->env, d->lp);
66
+ }
67
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "sifting")
68
+ {
69
+ CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_SIFTING);
70
+ status = CPXlpopt(d->env, d->lp);
71
+ }
72
+ else
73
+ status = CPXlpopt(d->env, d->lp);
74
+
75
+ return 0;
76
+ }
77
+
78
+ long GenModelCplex::SetSol()
79
+ {
80
+ if(!bcreated)
81
+ throw string("SetSol() not available : Problem not created yet");
82
+ vars.sol.clear();
83
+ vars.sol.resize(vars.n,0);
84
+ vars.rc.clear();
85
+ vars.rc.resize(vars.n,0);
86
+ CplexData* d = (CplexData*)solverdata;
87
+ int status = 0;
88
+
89
+ if(d->x != NULL)
90
+ delete[] d->x;
91
+ if(d->dual != NULL)
92
+ delete[] d->dual;
93
+ if(d->rcost != NULL)
94
+ delete[] d->rcost;
95
+ if(d->slack != NULL)
96
+ delete[] d->slack;
97
+
98
+ d->x = new double[nc];
99
+ d->dual = new double[nr];
100
+ d->rcost = new double[nc];
101
+ d->slack = new double[nr];
102
+
103
+ int tempstat = CPXgetstat (d->env, d->lp);
104
+ int tempfeas;
105
+ int tempdualfeas;
106
+ int temphassol;
107
+ int currmeth = CPXgetmethod(d->env, d->lp);
108
+
109
+
110
+ status = CPXsolninfo(d->env, d->lp, &currmeth, &temphassol, &tempfeas, &tempdualfeas);
111
+ if ( status )
112
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXsolninfo)"));
113
+
114
+ feasible = static_cast<bool>(tempfeas);
115
+ dualfeasible = static_cast<bool>(tempdualfeas);
116
+ hassolution= static_cast<bool>(temphassol);
117
+
118
+ if(!hassolution)
119
+ return 0;
120
+
121
+ if(boolParam.count("mip") > 0 && boolParam["mip"])
122
+ status = CPXsolution (d->env, d->lp, &solstat, &objval, d->x, NULL, NULL, NULL);
123
+ else
124
+ status = CPXsolution (d->env, d->lp, &solstat, &objval, d->x, d->dual, d->slack, d->rcost);
125
+ if ( status )
126
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set set solution (CPXsolution)"));
127
+
128
+ solstat = tempstat;
129
+
130
+ for(long i = 0; i < long(nc); i++)
131
+ {
132
+ vars.sol[i] = d->x[i];
133
+ vars.rc[i] = d->rcost[i];
134
+ }
135
+
136
+ for(long i = 0; i < long(nr); i++)
137
+ {
138
+ consts[i].dual = d->dual[i];
139
+ consts[i].slack = d->slack[i];
140
+ }
141
+
142
+ if(boolParam.count("print_version") > 0 && boolParam["print_version"])
143
+ printf("*********** Genmodel version = %s ***********\n", version.c_str());
144
+
145
+ return 0;
146
+ }
147
+
148
+ long GenModelCplex::AddSolverRow(vector<int>& ind, vector<double>& val, double rhs, char sense, string name)
149
+ {
150
+ if(!bcreated)
151
+ return ThrowError("AddSolverRow() not available : Problem not created yet");
152
+ AddModelRow(ind, val, rhs, sense, name);
153
+ AddCut(&ind[0], &val[0], int(ind.size()), rhs, sense, name.c_str());
154
+
155
+ return 0;
156
+ }
157
+
158
+ long GenModelCplex::AddCut(int* cols, double* vals, int nz, double rhs, char sense, const char* name)
159
+ {
160
+ if(!bcreated)
161
+ return ThrowError("AddCut() not available : Problem not created yet");
162
+ CplexData* d = (CplexData*)solverdata;
163
+ int rmatbeg = 0;
164
+
165
+ CPXaddrows(d->env, d->lp, 0, 1, nz, &rhs, &sense, &rmatbeg, cols, vals, NULL, (char**)(&name));
166
+ d->nr++;
167
+
168
+ return 0;
169
+ }
170
+
171
+ long GenModelCplex::AddSolverCol(vector<int>& ind, vector<double>& val, double obj, double lb, double ub, string name, char type)
172
+ {
173
+ if(!bcreated)
174
+ return ThrowError("AddSolverCol() not available : Problem not created yet");
175
+ AddModelCol(ind, val, obj, lb, ub, name, type);
176
+ AddCol(&ind[0], &val[0], int(ind.size()), obj, lb, ub, name.c_str(), type);
177
+
178
+ return 0;
179
+ }
180
+
181
+ long GenModelCplex::AddCol(int* newi, double* newcol, int nz, double obj, double lb, double ub, const char* name, char type)
182
+ {
183
+ if(!bcreated)
184
+ return ThrowError("AddCol() not available : Problem not created yet");
185
+ CplexData* d = (CplexData*)solverdata;
186
+ int cmatbeg = 0;
187
+
188
+ double clb = lb;
189
+ if(clb == numeric_limits<double>::infinity())
190
+ clb = CPX_INFBOUND;
191
+ else if(clb == -numeric_limits<double>::infinity())
192
+ clb = -CPX_INFBOUND;
193
+
194
+ double cub = ub;
195
+ if(cub == numeric_limits<double>::infinity())
196
+ cub = CPX_INFBOUND;
197
+ else if(cub == -numeric_limits<double>::infinity())
198
+ cub = -CPX_INFBOUND;
199
+
200
+ CPXaddcols(d->env, d->lp, 1, nz, &obj, &cmatbeg, newi, newcol, &clb, &cub, (char**)(&name));
201
+ if(type != 'C')
202
+ {
203
+ int cind = d->nc;
204
+ CPXchgctype(d->env, d->lp, 1, &cind, &type);
205
+ }
206
+ d->nc++;
207
+
208
+ return 0;
209
+ }
210
+
211
+ long GenModelCplex::CreateModel()
212
+ {
213
+ if(!binit)
214
+ return ThrowError("CreateModel() not available : Problem not initialized yet");
215
+ CplexData* d = (CplexData*)solverdata;
216
+ int status = 0;
217
+ d->nc = nc;
218
+ d->nc = nc;
219
+ d->onc = nc;
220
+ d->onr = nr;
221
+
222
+ if(boolParam.count("maximize") > 0 && boolParam["maximize"])
223
+ CPXchgobjsen (d->env, d->lp, CPX_MAX);
224
+ else
225
+ CPXchgobjsen (d->env, d->lp, CPX_MIN);
226
+ d->lrhs = new double[nr];
227
+ d->urhs = new double[nr];
228
+ d->sense = new char[nr];
229
+ d->ub = new double[nc];
230
+ d->lb = new double[nc];
231
+ d->obj = new double[nc];
232
+ d->type = new char[nc];
233
+ d->mat_r = new int[nz];
234
+ d->mat_c = new int[nz];
235
+ d->mat_v = new double[nz];
236
+ d->cname = new char*[nc];
237
+ d->rname = new char*[nr];
238
+
239
+
240
+ nz=0;
241
+ for(unsigned long i = 0; i < nr; i++)
242
+ {
243
+ d->rname[i] = new char[consts[i].name.length()+1];
244
+ snprintf(d->rname[i], consts[i].name.length()+1, "%s", consts[i].name.c_str());
245
+ //printf("%ld %s: ", i, consts[i].name.c_str());
246
+ for(unsigned long j = 0; j < consts[i].nz; j++)
247
+ {
248
+ d->mat_r[nz] = i;
249
+ d->mat_c[nz] = consts[i].cols[j];
250
+ d->mat_v[nz] = consts[i].coefs[j];
251
+ //if(i >= 198)
252
+ //printf("(%ld,%ld(%s),%f) ", d->mat_r[nz], d->mat_c[nz], vars.name[d->mat_c[nz]].c_str(), d->mat_v[nz]);
253
+ nz++;
254
+ }
255
+
256
+ if(consts[i].lrhs == numeric_limits<double>::infinity())
257
+ d->lrhs[i] = CPX_INFBOUND;
258
+ else if(consts[i].lrhs == -numeric_limits<double>::infinity())
259
+ d->lrhs[i] = -CPX_INFBOUND;
260
+ else
261
+ d->lrhs[i] = consts[i].lrhs;
262
+ if(consts[i].urhs == numeric_limits<double>::infinity())
263
+ d->urhs[i] = CPX_INFBOUND;
264
+ else if(consts[i].urhs == -numeric_limits<double>::infinity())
265
+ d->urhs[i] = -CPX_INFBOUND;
266
+ else
267
+ d->urhs[i] = consts[i].urhs-consts[i].lrhs;
268
+ d->sense[i] = consts[i].sense;
269
+ // printf("%ld/%ld -> %c\n", i, nr, d->sense[i]);
270
+ }
271
+ for(unsigned long i = 0; i < nc; i++)
272
+ {
273
+ d->cname[i] = new char[vars.name[i].length()+1];
274
+ snprintf(d->cname[i], vars.name[i].length()+1, "%s", vars.name[i].c_str());
275
+ d->obj[i] = vars.obj[i];
276
+ if(vars.ub[i] == numeric_limits<double>::infinity())
277
+ d->ub[i] = CPX_INFBOUND;
278
+ else if(vars.ub[i] == -numeric_limits<double>::infinity())
279
+ d->ub[i] = -CPX_INFBOUND;
280
+ else
281
+ d->ub[i] = vars.ub[i];
282
+ if(vars.lb[i] == numeric_limits<double>::infinity())
283
+ d->lb[i] = CPX_INFBOUND;
284
+ else if(vars.lb[i] == -numeric_limits<double>::infinity())
285
+ d->lb[i] = -CPX_INFBOUND;
286
+ else
287
+ d->lb[i] = vars.lb[i];
288
+ d->type[i] = vars.type[i];
289
+
290
+ //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]);
291
+ }
292
+ status = CPXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname);
293
+ if ( status )
294
+ {
295
+ char errmsg[1024];
296
+ fprintf (stderr, "Could not create new rows.\n");
297
+ CPXgeterrorstring (d->env, status, errmsg);
298
+ fprintf (stderr, "%s", errmsg);
299
+ return 1;
300
+ }
301
+ //else
302
+ //printf("Row added!\n");
303
+
304
+ if(boolParam.count("mip") > 0 && boolParam["mip"])
305
+ status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname);
306
+ else
307
+ status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL);
308
+ if ( status )
309
+ {
310
+ char errmsg[1024];
311
+ fprintf (stderr, "Could not create new cols.\n");
312
+ CPXgeterrorstring (d->env, status, errmsg);
313
+ fprintf (stderr, "%s", errmsg);
314
+ return 1;
315
+ }
316
+ //status = CPXnewcols (env, lp, nc, obj, lb, ub, NULL, colname);
317
+ if ( status )
318
+ return 1;
319
+ //else
320
+ //printf("Col added!\n");
321
+ status = CPXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v);
322
+ if ( status )
323
+ return 1;
324
+
325
+ vector<long>::iterator iti;
326
+ vector<long>::iterator itj = vars.qj.begin();
327
+ vector<double>::iterator itv = vars.qobj.begin();
328
+
329
+ vector<vector<pair<int,double> > > qptemp;
330
+ qptemp.resize(nc);
331
+ int* qpbeg = NULL;
332
+ int* qpnum = NULL;
333
+ int* qpind = NULL;
334
+ double* qpv = NULL;
335
+ int qpnz = 0;
336
+
337
+ if(!vars.qi.empty())
338
+ {
339
+ boolParam["qp"] = true;
340
+ qpbeg = new int[nc];
341
+ qpnum = new int[nc];
342
+ }
343
+ if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"])
344
+ {
345
+ for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++)
346
+ {
347
+ qptemp[*iti].push_back(pair<int, double>(*itj,*itv));
348
+ qpnz++;
349
+ if(*iti != *itj)
350
+ {
351
+ qptemp[*itj].push_back(pair<int, double>(*iti,*itv));
352
+ qpnz++;
353
+ }
354
+ }
355
+ if(!vars.qi.empty())
356
+ {
357
+ qpv = new double[qpnz];
358
+ qpind = new int[qpnz];
359
+
360
+ qpnz=0;
361
+ for(int i = 0; i < int(nc); i++)
362
+ {
363
+ qpbeg[i] = qpnz;
364
+ qpnum[i] = int(qptemp[i].size());
365
+ for(int j = 0; j < int(qptemp[i].size()); j++)
366
+ {
367
+ qpind[qpnz] = qptemp[i][j].first;
368
+ qpv[qpnz] = 2.0*qptemp[i][j].second;
369
+ qpnz++;
370
+ }
371
+ }
372
+ status = CPXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv);
373
+ delete[] qpbeg;
374
+ delete[] qpnum;
375
+ delete[] qpind;
376
+ delete[] qpv;
377
+ }
378
+ if ( status )
379
+ {
380
+ printf("QP problem!\n");
381
+ return 1;
382
+ }
383
+ }
384
+ //else
385
+ //printf("Coefs added!\n");
386
+ bcreated = true;
387
+
388
+ return 0;
389
+ }
390
+
391
+ long AddQuadraticVector(vector<int>& ind, vector<double>& val)
392
+ {
393
+ return 0;
394
+ }
395
+
396
+ long AddQuadraticMatrix(vector<int>& indi, vector<int>& indj, vector<double>& val)
397
+ {
398
+ return 0;
399
+ }
400
+
401
+ long GenModelCplex::CreateModel(string filename, int type, string dn)
402
+ {
403
+ #ifdef OSI_MODULE
404
+ ReadFromFile(static_cast<GenModel*>(this), filename, type);
405
+ SetNumbers();
406
+ CreateModel();
407
+ #else
408
+ return ThrowError("Cannot use CreateModel(filenamem, type, dn) : Osi Module not present");
409
+ #endif
410
+ return 0;
411
+ }
412
+
413
+ long GenModelCplex::ChangeBulkBounds(int count, int * ind, char * type, double * vals)
414
+ {
415
+ if(!bcreated)
416
+ return ThrowError("ChangeBulkBounds not available : Problem not created yet");
417
+ CplexData* d = (CplexData*)solverdata;
418
+
419
+ for(long i = 0; i < count; i++)
420
+ {
421
+ if (type[i] == 'L' || type[i] == 'B')
422
+ {
423
+ vars.lb[i] = vals[i];
424
+ }
425
+ if (type[i] == 'U' || type[i] == 'B')
426
+ {
427
+ vars.ub[i] = vals[i];
428
+ }
429
+ }
430
+
431
+ CPXchgbds(d->env, d->lp, count, ind, type, vals);
432
+
433
+ return 0;
434
+ }
435
+
436
+ long GenModelCplex::ChangeBulkObjectives(int count, int * ind, double * vals)
437
+ {
438
+ if(!bcreated)
439
+ return ThrowError("ChangeBulkObjectives() not available : Problem not created yet");
440
+ CplexData* d = (CplexData*)solverdata;
441
+
442
+ for(long i = 0; i < count; i++)
443
+ {
444
+ vars.obj[i] = vals[i];
445
+ }
446
+
447
+ CPXchgobj(d->env, d->lp, count, ind, vals);
448
+
449
+ return 0;
450
+ }
451
+
452
+ long GenModelCplex::ChangeBulkNz(int count, int* rind, int* cind, double * vals)
453
+ {
454
+ if(!bcreated)
455
+ return ThrowError("ChangeBulkNz() not available : Problem not created yet");
456
+ CplexData* d = (CplexData*)solverdata;
457
+
458
+ for(long i = 0; i < count; i++)
459
+ {
460
+ bool found = false;
461
+ for(long j = 0; j < int(consts[rind[i]].cols.size()); j++)
462
+ {
463
+ if(consts[rind[i]].cols[j] == cind[i])
464
+ {
465
+ consts[rind[i]].coefs[j] = vals[i];
466
+ found = true;
467
+ break;
468
+ }
469
+ }
470
+ if(!found)
471
+ consts[rind[i]].AddNz(cind[i], vals[i]);
472
+ }
473
+
474
+ CPXchgcoeflist(d->env, d->lp, count, rind, cind, vals);
475
+
476
+ return 0;
477
+ }
478
+
479
+
480
+
481
+ long GenModelCplex::DeleteMipStarts()
482
+ {
483
+ if(!bcreated)
484
+ return ThrowError("ChangeBulkNz() not available : Problem not created yet");
485
+ CplexData* d = (CplexData*)solverdata;
486
+ int n = CPXgetnummipstarts(d->env, d->lp);
487
+ if (n > 0)
488
+ CPXdelmipstarts(d->env, d->lp, 0, n - 1);
489
+
490
+ return 0;
491
+ }
492
+
493
+ double GenModelCplex::GetMIPRelativeGap()
494
+ {
495
+ if(!bcreated)
496
+ return ThrowError("ChangeBulkNz() not available : Problem not created yet");
497
+ CplexData* d = (CplexData*)solverdata;
498
+ double gap = 0, bestobjval = 0;
499
+ CPXgetbestobjval(d->env, d->lp, &bestobjval);
500
+ if (bestobjval > 0) // If the optimal solution is found by the presolve, the CPXgetbestobjval = 0, and the CPXgetmiprelgap ~ 1
501
+ CPXgetmiprelgap(d->env, d->lp, &gap);
502
+
503
+ return gap;
504
+ }
505
+
506
+ long GenModelCplex::SwitchToMip()
507
+ {
508
+ if(!bcreated)
509
+ return ThrowError("SwitchToMip() not available : Problem not created yet");
510
+ vector<int> ind;
511
+ vector<char> type;
512
+ for(int i = 0; i < int(vars.type.size()); i++)
513
+ {
514
+ if(vars.type[i] == 'B' || vars.type[i] == 'I' || vars.type[i] == 'S' || vars.type[i] == 'N')
515
+ {
516
+ ind.push_back(i);
517
+ type.push_back(vars.type[i]);
518
+ }
519
+ }
520
+ CplexData* d = static_cast<CplexData*>(solverdata);
521
+ CPXchgctype(d->env, d->lp, int(ind.size()), &(ind[0]), &(type[0]));
522
+ boolParam["mip"] = true;
523
+
524
+ return 0;
525
+ }
526
+
527
+ long GenModelCplex::SwitchToLp()
528
+ {
529
+ if(!bcreated)
530
+ return ThrowError("SwitchToLp() not available : Problem not created yet");
531
+ vector<int> ind;
532
+ vector<char> type;
533
+ for(int i = 0; i < int(vars.type.size()); i++)
534
+ {
535
+ if(vars.type[i] == 'B' || vars.type[i] == 'I' || vars.type[i] == 'S' || vars.type[i] == 'N')
536
+ {
537
+ ind.push_back(i);
538
+ type.push_back('C');
539
+ }
540
+ }
541
+ CplexData* d = static_cast<CplexData*>(solverdata);
542
+ CPXchgctype(d->env, d->lp, int(ind.size()), &(ind[0]), &(type[0]));
543
+ boolParam["mip"] = false;
544
+
545
+ return 0;
546
+ }
547
+
548
+ long GenModelCplex::Init(string name)
549
+ {
550
+
551
+ //strParam.count("log_file")
552
+ //dblParam.count("relative_mip_gap_tolerance")
553
+ //dblParam.count("absolute_mip_gap_tolerance")
554
+ //dblParam.count("time_limit")
555
+ //dblParam.count("bounds_feasibility_tolerance")
556
+ //dblParam.count("optimality_tolerance")
557
+ //dblParam.count("markowitz_tolerance"))
558
+ //longParam.count("threads")
559
+ //longParam.count("cutpass")
560
+ //longParam.count("pumplevel")
561
+ //longParam.count("mipemphasis")
562
+ //longParam.count("probinglevel")
563
+ //longParam.count("max_iteration_limit");
564
+ //boolParam.count("preprocoff") : turn on/off preprocessing
565
+ //boolParam.count("datacheckoff")
566
+ //boolParam.count("screen_output")
567
+ //boolParam.count("usecutcb")
568
+
569
+ if(solverdata == NULL)
570
+ solverdata = new CplexData();
571
+ else
572
+ {
573
+ static_cast<CplexData*>(solverdata)->Delete();
574
+ static_cast<CplexData*>(solverdata)->Reset();
575
+ }
576
+
577
+ CplexData* d = static_cast<CplexData*>(solverdata);
578
+ int status = 0;
579
+
580
+ d->env = CPXopenCPLEX (&status);
581
+
582
+ // If an error occurs
583
+ if ( d->env == NULL )
584
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Could not open CPLEX environment"));
585
+
586
+
587
+ hassolution = false;
588
+
589
+ // Log file
590
+ if(strParam.count("log_file") > 0)
591
+ {
592
+ d->cpxfileptr = CPXfopen(strParam["log_file"].c_str(), "w");
593
+ status = CPXsetlogfile(d->env, d->cpxfileptr);
594
+ if ( status )
595
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to set the log file"));
596
+ }
597
+
598
+ // General settings
599
+ boolParam["log_output_stdout"] = true;
600
+ SetParam("log_output_stdout", CPX_PARAM_SCRIND, "bool", "Failure to turn on/off log output to stdout");
601
+ SetParam("log_level", 0, "long", "Failure to set log level", false);
602
+ SetParam("use_data_checking", CPX_PARAM_DATACHECK, "bool", "Failure to turn on/off data checking");
603
+ SetParam("nb_threads", CPX_PARAM_THREADS, "long", "Failure to set the number of threads");
604
+ if(boolParam.count("use_preprocessor") > 0 && !boolParam["use_preprocessor"])
605
+ {
606
+ SetDirectParam(CPX_PARAM_AGGFILL, long2param(0), "long", "Failure to use preprocessor (CPX_PARAM_AGGFILL)");
607
+ SetDirectParam(CPX_PARAM_PREPASS, long2param(0), "long", "Failure to use preprocessor (CPX_PARAM_PREPASS)");
608
+ SetDirectParam(CPX_PARAM_AGGIND, long2param(CPX_OFF), "long", "Failure to use preprocessor (CPX_PARAM_AGGIND)");
609
+ SetDirectParam(CPX_PARAM_DEPIND, long2param(0), "long", "Failure to use preprocessor (CPX_PARAM_DEPIND)");
610
+ SetDirectParam(CPX_PARAM_PRELINEAR, long2param(0), "long", "Failure to use preprocessor (CPX_PARAM_PRELINEAR)");
611
+ SetDirectParam(CPX_PARAM_PREDUAL, long2param(-1), "long", "Failure to use preprocessor (CPX_PARAM_PREDUAL)");
612
+ SetDirectParam(CPX_PARAM_REDUCE, long2param(0), "long", "Failure to use preprocessor (CPX_PARAM_REDUCE)");
613
+ SetDirectParam(CPX_PARAM_PREIND, long2param(CPX_OFF), "long", "Failure to use preprocessor (CPX_PARAM_PREIND)");
614
+ }
615
+
616
+ // MIP settings
617
+ SetParam("nb_cut_pass", CPX_PARAM_CUTPASS, "long", "Failure to set the number of cut pass");
618
+ SetParam("feasibility_pump_level", CPX_PARAM_FPHEUR, "long", "Failure to set the feasibility pump level");
619
+ SetParam("probing_level", CPX_PARAM_PROBE, "long", "Failure to set the probing level");
620
+ SetParam("mip_emphasis", CPX_PARAM_MIPEMPHASIS, "long", "Failure to set the MIP emphasis");
621
+ if(boolParam.count("use_cut_callback") > 0 && boolParam["use_cut_callback"])
622
+ {
623
+ SetDirectParam(CPX_PARAM_PRELINEAR, long2param(0), "long", "Failure to use cut callback (CPX_PARAM_PRELINEAR)");
624
+ SetDirectParam(CPX_PARAM_MIPCBREDLP, long2param(0), "long", "Failure to use cut callback (CPX_PARAM_MIPCBREDLP)");
625
+ }
626
+
627
+ // Tolerance and limits
628
+ SetParam("time_limit", CPX_PARAM_TILIM, "dbl", "Failure to set time limit");
629
+ SetParam("max_iteration_limit", CPX_PARAM_ITLIM, "long", "Failure to set the maximal number of simplex iterations");
630
+ SetParam("bounds_feasibility_tolerance", CPX_PARAM_EPRHS, "dbl", "Failure to set bounds feasibility tolerance");
631
+ SetParam("optimality_tolerance", CPX_PARAM_EPOPT, "dbl", "Failure to set optimality tolerance");
632
+ SetParam("markowitz_tolerance", CPX_PARAM_EPMRK, "dbl", "Failure to set Markowitz tolerance");
633
+ SetParam("absolute_mip_gap_tolerance", CPX_PARAM_EPAGAP, "dbl", "Failure to set absolute gap tolerance");
634
+ SetParam("relative_mip_gap_tolerance", CPX_PARAM_EPGAP, "dbl", "Failure to set relative gap tolerance");
635
+ if(boolParam.count("maximize") > 0 && boolParam["maximize"])
636
+ SetParam("lp_objective_limit", CPX_PARAM_OBJULIM, "dbl", "Failure to set lp objective limit");
637
+ else
638
+ SetParam("lp_objective_limit", CPX_PARAM_OBJLLIM, "dbl", "Failure to set lp objective limit");
639
+
640
+
641
+ // Create the problem
642
+ d->lp = CPXcreateprob (d->env, &status, name.c_str());
643
+ if ( d->lp == NULL )
644
+ return ThrowError(getcplexerror(d->env, status)+string(". ")+string("Failure to create Cplex optimization problem"));
645
+
646
+ binit = true;
647
+
648
+ return 0;
649
+ }
650
+
651
+ long GenModelCplex::SetDirectParam(int whichparam, genmodel_param value, string type, string message)
652
+ {
653
+ int status = 0;
654
+ if(type == "dbl")
655
+ status = CPXsetdblparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.dblval);
656
+ else if(type == "long")
657
+ status = CPXsetintparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.longval);
658
+ else if(type == "str")
659
+ status = CPXsetstrparam (static_cast<CplexData*>(solverdata)->env, whichparam, value.strval);
660
+ if ( status )
661
+ return ThrowError(getcplexerror(static_cast<CplexData*>(solverdata)->env, status)+string(". ")+message);
662
+
663
+ return 0;
664
+ }
665
+
666
+ long GenModelCplex::SetParam(string param, int whichparam, string type, string message, bool implemented)
667
+ {
668
+ bool notimplmessage = boolParam.count("throw_on_unimplemeted_option") > 0 && boolParam["throw_on_unimplemeted_option"];
669
+
670
+ if(type == "dbl")
671
+ {
672
+ if(dblParam.count(param) > 0 && implemented)
673
+ SetDirectParam(whichparam, dbl2param(dblParam[param]), type, message);
674
+ else if(notimplmessage && !implemented && dblParam.count(param) > 0)
675
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
676
+ }
677
+ else if(type == "long")
678
+ {
679
+ if(longParam.count(param) > 0 && implemented)
680
+ SetDirectParam(whichparam, long2param(longParam[param]), type, message);
681
+ else if(notimplmessage && !implemented && longParam.count(param) > 0)
682
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
683
+ }
684
+ else if(type == "str")
685
+ {
686
+ if(strParam.count(param) > 0 && implemented)
687
+ SetDirectParam(whichparam, str2param(strParam[param]), type, message);
688
+ else if(notimplmessage && !implemented && strParam.count(param) > 0)
689
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
690
+ }
691
+ else if(type == "bool")
692
+ {
693
+ if(boolParam.count(param) > 0 && implemented)
694
+ {
695
+ if(boolParam[param])
696
+ SetDirectParam(whichparam, long2param(CPX_ON), "long", message);
697
+ else
698
+ SetDirectParam(whichparam, long2param(CPX_OFF), "long", message);
699
+ }
700
+ else if(notimplmessage && !implemented && boolParam.count(param) > 0)
701
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
702
+ }
703
+ return 0;
704
+ }
705
+
706
+ long GenModelCplex::Clean()
707
+ {
708
+ if(solverdata != NULL)
709
+ delete static_cast<CplexData*>(solverdata);
710
+
711
+ return 0;
712
+ }
713
+
714
+ long CplexData::Reset()
715
+ {
716
+ mat_c = NULL;
717
+ mat_r = NULL;
718
+ mat_v = NULL;
719
+ lrhs = NULL;
720
+ urhs = NULL;
721
+ sense = NULL;
722
+ ub = NULL;
723
+ lb = NULL;
724
+ type = NULL;
725
+ obj = NULL;
726
+ x = NULL;
727
+ dual = NULL;;
728
+ rcost = NULL;
729
+ slack = NULL;
730
+ cname = NULL;
731
+ rname = NULL;
732
+ env = NULL;
733
+ lp = NULL;
734
+ cpxfileptr = NULL;
735
+
736
+ return 0;
737
+ }
738
+
739
+ CplexData::CplexData()
740
+ {
741
+ Reset();
742
+ }
743
+
744
+ CplexData::~CplexData()
745
+ {
746
+ Delete();
747
+ }
748
+
749
+ long CplexData::ClearStructure()
750
+ {
751
+ if(mat_c != NULL)
752
+ delete[] mat_c;
753
+ if(mat_r != NULL)
754
+ delete[] mat_r;
755
+ if(mat_v != NULL)
756
+ delete[] mat_v;
757
+ if(lrhs != NULL)
758
+ delete[] lrhs;
759
+ if(obj != NULL)
760
+ delete[] obj;
761
+ if(urhs != NULL)
762
+ delete[] urhs;
763
+ if(sense != NULL)
764
+ delete[] sense;
765
+ if(ub != NULL)
766
+ delete[] ub;
767
+ if(lb != NULL)
768
+ delete[] lb;
769
+ if(type != NULL)
770
+ delete[] type;
771
+ if(x != 0)
772
+ delete[] x;
773
+ if(dual != NULL)
774
+ delete[] dual;
775
+ if(rcost != NULL)
776
+ delete[] rcost;
777
+ if(slack != NULL)
778
+ delete[] slack;
779
+ if(cname != NULL)
780
+ {
781
+ for(long i = 0; i < onc; i++)
782
+ delete[] cname[i];
783
+ delete[] cname;
784
+ }
785
+ if(rname != NULL)
786
+ {
787
+ for(long i = 0; i < onr; i++)
788
+ delete[] rname[i];
789
+ delete[] rname;
790
+ }
791
+ Reset();
792
+
793
+ return 0;
794
+ }
795
+
796
+ long CplexData::Delete()
797
+ {
798
+ if(lp != NULL)
799
+ {
800
+ CPXfreeprob(env, &lp);
801
+ }
802
+ if(env != NULL)
803
+ {
804
+ CPXcloseCPLEX(&env);
805
+ }
806
+ if(cpxfileptr != NULL)
807
+ {
808
+ CPXfclose(cpxfileptr);
809
+ }
810
+
811
+ ClearStructure();
812
+
813
+ return 0;
814
+ }