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,892 @@
1
+ /*
2
+ * GenModelOsi.cpp
3
+ *
4
+ * Created on: 2012-10-01
5
+ * Author: mbouchard
6
+ */
7
+
8
+ #include "GenModelOsi.h"
9
+ #include "ProblemReaderOsi.h"
10
+ #include "CbcHeuristicFPump.hpp"
11
+ #include "CbcHeuristicRINS.hpp"
12
+ #include "CbcHeuristicLocal.hpp"
13
+ #include "CbcHeuristicDiveCoefficient.hpp"
14
+ #include "CbcHeuristicDiveFractional.hpp"
15
+ #include <limits>
16
+
17
+ using namespace std;
18
+
19
+ long GenModelOsi::WriteProblemToLpFile(string filename)
20
+ {
21
+ if(!bcreated)
22
+ throw string("WriteProblemToLpFile() not available : Problem not created yet;");
23
+
24
+ OsiData* d = static_cast<OsiData*>(solverdata);
25
+ d->model->writeLp(filename.c_str());
26
+ return 0;
27
+ }
28
+
29
+ long GenModelOsi::WriteSolutionToFile(string filename)
30
+ {
31
+ if(!bcreated)
32
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
33
+
34
+ FILE* f = fopen(filename.c_str(), "w");
35
+ for(long i = 0; i < long(vars.n); i++)
36
+ {
37
+ if(fabs(vars.sol[i]) > 0.000001)
38
+ fprintf(f, "%s : %f\n", vars.name[i].c_str(), vars.sol[i]);
39
+ }
40
+
41
+ fclose(f);
42
+ return 0;
43
+ }
44
+
45
+ long GenModelOsi::Solve()
46
+ {
47
+ if(!bcreated)
48
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
49
+ OsiData* d = static_cast<OsiData*>(solverdata);
50
+ d->model->setHintParam(OsiDoReducePrint,true,OsiHintTry);
51
+
52
+
53
+ /*
54
+ if(boolParam.count("mip") > 0 && boolParam["mip"])
55
+ {
56
+ printf("********* OSI Branch and bounds **************\n");
57
+ d->model->branchAndBound();
58
+ }
59
+ else if(boolParam.count("notroot") > 0 && boolParam["notroot"])
60
+ {
61
+ printf("********* OSI Resolve **************\n");
62
+ d->model->resolve();
63
+ }
64
+ else
65
+ {
66
+ printf("********* OSI Initial Solve **************\n");
67
+ d->model->initialSolve();
68
+ }
69
+ */
70
+
71
+ d->model->setHintParam(OsiDoReducePrint,true,OsiHintTry);
72
+
73
+ // Set up some cut generators and defaults
74
+ // Probing first as gets tight bounds on continuous
75
+
76
+ CglProbing generator1;
77
+ // can not use objective
78
+ generator1.setUsingObjective(false);
79
+ generator1.setMaxPass(3);
80
+ generator1.setMaxProbe(100);
81
+ generator1.setMaxLook(50);
82
+ generator1.setRowCuts(3);
83
+
84
+ CglGomory generator2;
85
+ // try larger limit
86
+ generator2.setLimit(30000);
87
+
88
+ CglKnapsackCover generator3;
89
+
90
+ CglOddHole generator4;
91
+ generator4.setMinimumViolation(0.005);
92
+ generator4.setMinimumViolationPer(0.00002);
93
+ // try larger limit
94
+ generator4.setMaximumEntries(50); //(200); //maybe originally 50
95
+
96
+ CglClique generator5;
97
+ generator5.setStarCliqueReport(false);
98
+ generator5.setRowCliqueReport(false);
99
+
100
+ CglMixedIntegerRounding mixedGen;
101
+ CglFlowCover flowGen;
102
+ // Add in generators (just at root)
103
+
104
+ d->mipmodel = new CbcModel(*(d->model));
105
+ // Add in generators
106
+ // Only some generators work (and even then try without first)
107
+
108
+
109
+ d->mipmodel->addCutGenerator(&generator1,1,"Probing");
110
+ // Allow rounding heuristic
111
+
112
+ d->mipmodel->addCutGenerator(&generator1,-99,"Probing",true,false,false,-1);
113
+ d->mipmodel->addCutGenerator(&generator2,-99,"Gomory",true,false,false,-99);
114
+ d->mipmodel->addCutGenerator(&generator3,-99,"Knapsack",true,false,false,-99);
115
+ d->mipmodel->addCutGenerator(&generator4,-99,"OddHole",true,false,false,-99);
116
+ d->mipmodel->addCutGenerator(&generator5,-99,"Clique",true,false,false,-99);
117
+ d->mipmodel->addCutGenerator(&flowGen,-99,"FlowCover",true,false,false,-99);
118
+ d->mipmodel->addCutGenerator(&mixedGen,-99,"MixedIntegerRounding",true,false,false,-100);
119
+
120
+ CbcRounding rounding(*(d->mipmodel));
121
+ rounding.setHeuristicName("Rounding");
122
+ // do not add yet as don't know how to deal with quadratic objective
123
+ d->mipmodel->addHeuristic(&rounding);
124
+ rounding.setHeuristicName("Greedy cover");
125
+ CbcHeuristicGreedyCover greedy(*(d->mipmodel));
126
+ // Use original upper and perturb more
127
+ greedy.setAlgorithm(11);
128
+ greedy.setHeuristicName("Greedy cover");
129
+ d->mipmodel->addHeuristic(&greedy);
130
+
131
+ // Redundant definition of default branching (as Default == User)
132
+ //CbcBranchUserDecision branch;
133
+ //d->mipmodel->setBranchingMethod(&branch);
134
+
135
+ // Definition of node choice
136
+ //CbcCompareUser compare;
137
+ // breadth first
138
+ //compare.setWeight(0.0);
139
+ //d->mipmodel->setNodeComparison(compare);
140
+
141
+
142
+ // Do initial solve to continuous
143
+ d->mipmodel->initialSolve();
144
+
145
+ double objValue = d->mipmodel->getObjValue();
146
+
147
+ CbcHeuristicDiveCoefficient heuristicDC(*(d->mipmodel));
148
+ heuristicDC.setHeuristicName("DiveCoefficient");
149
+ // allow to exit if close enough to optimum
150
+ heuristicDC.setSwitches(1);
151
+ d->mipmodel->addHeuristic(&heuristicDC);
152
+ CbcHeuristicDiveFractional heuristicDF(*(d->mipmodel));
153
+ heuristicDF.setHeuristicName("DiveFractional");
154
+ heuristicDF.setSwitches(1);
155
+ d->mipmodel->addHeuristic(&heuristicDF);
156
+ CbcHeuristicFPump pump(*(d->mipmodel));
157
+ // allow to exit if close enough to optimum
158
+ // plus some dubious options
159
+ pump.setSwitches(1+4+8);
160
+ pump.setMaximumTime(3600);
161
+ pump.setMaximumPasses(50); //100);
162
+ pump.setMaximumRetries(10); //(1);
163
+ pump.setFixOnReducedCosts(1);
164
+ pump.setHeuristicName("Feasibility pump 1");
165
+ pump.setFractionSmall(1.0);
166
+ pump.setWhen(13);
167
+ pump.setFakeCutoff(objValue+0.01*fabs(objValue));
168
+ pump.setReducedCostMultiplier(0.1);
169
+ pump.setFeasibilityPumpOptions(80);
170
+ d->mipmodel->addHeuristic(&pump);
171
+ pump.setHeuristicName("Feasibility pump 2");
172
+ pump.setFakeCutoff(objValue+0.05*fabs(objValue));
173
+ pump.setFeasibilityPumpOptions(80);
174
+ d->mipmodel->addHeuristic(&pump);
175
+ pump.setHeuristicName("Feasibility pump 3");
176
+ pump.setFakeCutoff(objValue+0.01*fabs(objValue));
177
+ pump.setReducedCostMultiplier(0.1);
178
+ pump.setFeasibilityPumpOptions(80);
179
+ d->mipmodel->addHeuristic(&pump);
180
+ pump.setHeuristicName("Feasibility pump 4");
181
+ pump.setFakeCutoff(objValue+0.05*fabs(objValue));
182
+ pump.setReducedCostMultiplier(1.0);
183
+ pump.setFeasibilityPumpOptions(80);
184
+ pump.setMaximumTime(200);
185
+ d->mipmodel->addHeuristic(&pump);
186
+ CbcHeuristicRINS rins(*(d->mipmodel));
187
+ rins.setHeuristicName("RINS");
188
+ rins.setFractionSmall(0.5);
189
+ rins.setDecayFactor(5.0);
190
+ d->mipmodel->addHeuristic(&rins) ;
191
+ CbcHeuristicLocal local(*(d->mipmodel));
192
+ local.setHeuristicName("LOCAL");
193
+ local.setFractionSmall(0.5);
194
+ local.setSearchType(1);
195
+ d->mipmodel->addHeuristic(&local) ;
196
+ if(longParam.count("nb_threads") == 0 && longParam["nb_threads"] >= 1)
197
+ {
198
+ d->mipmodel->setThreadMode(7);
199
+ d->mipmodel->setNumberThreads(longParam["nb_threads"]);
200
+ }
201
+
202
+ // Could tune more
203
+ d->mipmodel->setMinimumDrop(CoinMin(1.0, fabs(d->mipmodel->getMinimizationObjValue())*1.0e-3+1.0e-4));
204
+
205
+ d->mipmodel->setMaximumCutPassesAtRoot(1); // (50);
206
+ d->mipmodel->setMaximumCutPasses(10); //(100);
207
+
208
+ // Switch off strong branching if wanted
209
+ //d->mipmodel->setNumberStrong(5);
210
+
211
+ d->mipmodel->solver()->setIntParam(OsiMaxNumIterationHotStart,10000);
212
+
213
+ // If time is given then stop after that number of minutes
214
+ if (dblParam.count("time_limit") > 0)
215
+ {
216
+ printf("Stopping after %f seconds\n", dblParam["time_limit"]);
217
+ d->mipmodel->setDblParam(CbcModel::CbcMaximumSeconds, dblParam["time_limit"]);
218
+ }
219
+
220
+ // Switch off most output
221
+ if (d->mipmodel->getNumCols()<3000)
222
+ {
223
+ d->mipmodel->messageHandler()->setLogLevel(1);
224
+ //d->model->solver()->messageHandler()->setLogLevel(0);
225
+ }
226
+ else
227
+ {
228
+ d->mipmodel->messageHandler()->setLogLevel(2);
229
+ d->mipmodel->solver()->messageHandler()->setLogLevel(1);
230
+ }
231
+ d->mipmodel->setPrintFrequency(1);//(50);
232
+
233
+ double time1 = CoinCpuTime();
234
+
235
+ // Do complete search
236
+ d->mipmodel->branchAndBound();
237
+
238
+ printf(" took %f seconds, %d nodes with objective %f, %s\n",
239
+ CoinCpuTime()-time1, d->mipmodel->getNodeCount(), d->mipmodel->getObjValue(), (!d->mipmodel->status() ? " Finished" : " Not finished"));
240
+
241
+ // Print more statistics
242
+ printf("Cuts at root node changed objective from %f to %f\n", d->mipmodel->getContinuousObjective(), d->mipmodel->rootObjectiveAfterCuts());
243
+
244
+ int numberGenerators = d->mipmodel->numberCutGenerators();
245
+ for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++)
246
+ {
247
+ CbcCutGenerator * generator = d->mipmodel->cutGenerator(iGenerator);
248
+ printf("%s was tried %d times and created %d cuts of which %d were active after adding rounds of cuts\n", generator->cutGeneratorName(),
249
+ generator->numberTimesEntered(),generator->numberCutsInTotal(), generator->numberCutsActive());
250
+ }
251
+
252
+ hassolution = d->mipmodel->getIntParam(CbcModel::CbcMaxNumSol) > 0;
253
+ objval = d->mult*d->mipmodel->getObjValue();
254
+
255
+ d->model = d->mipmodel->solver();
256
+
257
+ /* CoinData* d = static_cast<CoinData*>(solverdata);
258
+
259
+ if(strParam.count("algo") > 0 && strParam["algo"] == "interior")
260
+ {
261
+ ClpInterior intmod;
262
+ if(boolParam.count("qp") > 0 && boolParam["qp"])
263
+ {
264
+ ClpCholeskyBase * cholesky = new ClpCholeskyBase();
265
+ cholesky->setKKT(true);
266
+ intmod.borrowModel(*(d->model));
267
+ intmod.setCholesky(cholesky);
268
+ intmod.primalDual();
269
+ intmod.returnModel(*(d->model));
270
+ }
271
+ else
272
+ {
273
+ printf("interior\n");
274
+ ClpCholeskyBase * cholesky = new ClpCholeskyBase();
275
+ intmod.borrowModel(*(d->model));
276
+ intmod.setCholesky(cholesky);
277
+ intmod.primalDual();
278
+ intmod.returnModel(*(d->model));
279
+ }
280
+ }
281
+ else if(strParam.count("algo") > 0 && strParam["algo"] == "dual")
282
+ d->model->dual();
283
+ else
284
+ d->model->primal();*/
285
+
286
+ return 0;
287
+ }
288
+
289
+ long GenModelOsi::SetSol()
290
+ {
291
+ if(!bcreated)
292
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
293
+ OsiData* d = static_cast<OsiData*>(solverdata);
294
+
295
+ vars.sol.clear();
296
+ vars.sol.resize(vars.n,0);
297
+ vars.rc.clear();
298
+ vars.rc.resize(vars.n,0);
299
+
300
+ if(!hassolution)
301
+ return 1;
302
+
303
+ const double* sol;
304
+ const double* act;
305
+
306
+ sol = d->model->getColSolution();
307
+ act = d->model->getRowActivity();
308
+
309
+ if(boolParam.count("mip") == 0 || !boolParam["mip"])
310
+ {
311
+ const double* dual = d->model->getRowPrice();
312
+ const double* rc = d->model->getReducedCost();
313
+ for (unsigned int i = 0; i < vars.n; i++)
314
+ vars.rc[i] = rc[i];
315
+ for(long i = 0; i < long(nr); i++)
316
+ consts[i].dual = dual[i];
317
+ }
318
+
319
+ for (unsigned int i = 0; i < vars.n; i++)
320
+ vars.sol[i] = sol[i];
321
+ for(long i = 0; i < long(nr); i++)
322
+ {
323
+ switch (consts[i].sense)
324
+ {
325
+ case 'L': consts[i].slack = consts[i].lrhs-act[i]; break;
326
+ case 'G': consts[i].slack = act[i]-consts[i].lrhs; break;
327
+ default: consts[i].slack = act[i]; break;
328
+ }
329
+ }
330
+
331
+ solstat = d->model->isProvenOptimal();
332
+ if (d->model->isProvenOptimal())
333
+ solstat = 1;
334
+ if (d->model->isProvenPrimalInfeasible())
335
+ solstat = 2;
336
+ if (d->model->isProvenDualInfeasible())
337
+ solstat = 3;
338
+ if (d->model->isIterationLimitReached())
339
+ solstat = 4;
340
+
341
+ if(boolParam.count("print_version") > 0 && boolParam["print_version"])
342
+ printf("*********** Genmodel version = %s ***********\n", version.c_str());
343
+
344
+ //objval = (dynamic_cast<OsiClpSolverInterface*>(d->model))->getModelPtr()->objectiveValue();
345
+
346
+ delete[] sol;
347
+ delete[] act;
348
+
349
+ return 0;
350
+ }
351
+
352
+ long GenModelOsi::CreateModel()
353
+ {
354
+ if(!binit)
355
+ return ThrowError("CreateModel() not available : Problem not initialized yet");
356
+
357
+ OsiData* d = static_cast<OsiData*>(solverdata);
358
+
359
+ d->nc = nc;
360
+ d->nr = nr;
361
+
362
+ d->lrhs = new double[nr];
363
+ d->urhs = new double[nr];
364
+ d->ub = new double[nc];
365
+ d->lb = new double[nc];
366
+ d->obj = new double[nc];
367
+ d->typei = new int[nc];
368
+ d->typec = new int[nc];
369
+ d->mat_r = new int[nz];
370
+ d->mat_beg = new CoinBigIndex[nc+1];
371
+ d->mat_v = new double[nz];
372
+ d->cname = new char*[nc];
373
+ d->rname = new char*[nr];
374
+ d->nq = 0;
375
+ memset(d->mat_beg, 0, (nc+1)*sizeof(CoinBigIndex));
376
+
377
+ d->mult = 1.0;
378
+ if(boolParam.count("maximize") > 0 && boolParam["maximize"])
379
+ d->mult = -1.0;
380
+
381
+ int numint = 0;
382
+ int numcont = 0;
383
+
384
+ vector<vector<pair<int,double> > > tvect;
385
+ tvect.resize(nc);
386
+ for(unsigned long i = 0; i < nr; i++)
387
+ {
388
+ d->rname[i] = new char[consts[i].name.length()+1];
389
+ snprintf(d->rname[i], consts[i].name.length()+1, "%s", consts[i].name.c_str());
390
+ for(unsigned long j = 0; j < consts[i].nz; j++)
391
+ {
392
+ d->mat_beg[consts[i].cols[j]]++;
393
+ tvect[consts[i].cols[j]].push_back(pair<int,double>(i,consts[i].coefs[j]));
394
+ }
395
+
396
+ if(consts[i].lrhs == numeric_limits<double>::infinity())
397
+ d->lrhs[i] = COIN_DBL_MAX;
398
+ else if(consts[i].lrhs == -numeric_limits<double>::infinity())
399
+ d->lrhs[i] = -COIN_DBL_MAX;
400
+ else
401
+ d->lrhs[i] = consts[i].lrhs;
402
+ if(consts[i].urhs == numeric_limits<double>::infinity())
403
+ d->urhs[i] = COIN_DBL_MAX;
404
+ else if(consts[i].urhs == -numeric_limits<double>::infinity())
405
+ d->urhs[i] = -COIN_DBL_MAX;
406
+ else
407
+ d->urhs[i] = consts[i].urhs;
408
+ if(consts[i].sense == 'G')
409
+ {
410
+ //d->lrhs[i] = d->lrhs[i];
411
+ d->urhs[i] = COIN_DBL_MAX;
412
+ }
413
+ else if(consts[i].sense == 'L')
414
+ {
415
+ d->urhs[i] = d->lrhs[i];
416
+ d->lrhs[i] = -COIN_DBL_MAX;
417
+ }
418
+ else if(consts[i].sense == 'E')
419
+ {
420
+ d->urhs[i] = d->lrhs[i];
421
+ //d->lrhs[i] = d->lrhs[i];
422
+ }
423
+ }
424
+ int begcsum = 0;
425
+ long oldnz = nz;
426
+ nz=0;
427
+ for(unsigned long i = 0; i < nc; i++)
428
+ {
429
+ int temp = begcsum;
430
+ begcsum+=d->mat_beg[i];
431
+ d->mat_beg[i]=temp;
432
+
433
+ for(unsigned int k = 0; k < (unsigned int)(tvect[i].size()); k++)
434
+ {
435
+ d->mat_r[nz] = tvect[i][k].first;
436
+ d->mat_v[nz] = tvect[i][k].second;
437
+ nz++;
438
+ }
439
+
440
+ d->cname[i] = new char[vars.name[i].length()+1];
441
+ snprintf(d->cname[i], vars.name[i].length()+1, "%s", vars.name[i].c_str());
442
+ d->obj[i] = d->mult*vars.obj[i];
443
+ if(vars.ub[i] == numeric_limits<double>::infinity())
444
+ d->ub[i] = COIN_DBL_MAX;
445
+ else if(vars.ub[i] == -numeric_limits<double>::infinity())
446
+ d->ub[i] = -COIN_DBL_MAX;
447
+ else
448
+ d->ub[i] = vars.ub[i];
449
+ if(vars.lb[i] == numeric_limits<double>::infinity())
450
+ d->lb[i] = COIN_DBL_MAX;
451
+ else if(vars.lb[i] == -numeric_limits<double>::infinity())
452
+ d->lb[i] = -COIN_DBL_MAX;
453
+ else
454
+ d->lb[i] = vars.lb[i];
455
+ //d->type[i] = vars.type[i];
456
+ if(vars.type[i] == 'B')
457
+ {
458
+ if(d->lb[i] < 0.0)
459
+ d->lb[i] = 0.0;
460
+ if(d->ub[i] > 1.0)
461
+ d->ub[i] = 1.0;
462
+ d->typei[numint] = i;
463
+ numint++;
464
+ }
465
+ else if(vars.type[i] == 'I')
466
+ {
467
+ d->typei[numint] = i;
468
+ numint++;
469
+ }
470
+ else
471
+ {
472
+ d->typec[numcont] = i;
473
+ numcont++;
474
+ }
475
+ }
476
+
477
+ d->mat_beg[nc]=begcsum;
478
+
479
+ d->model->loadProblem(nc,nr,d->mat_beg,d->mat_r,d->mat_v, d->lb,d->ub,d->obj,d->lrhs, d->urhs);
480
+
481
+ d->model->setContinuous(d->typec, numcont);
482
+ d->model->setInteger (d->typei, numint);
483
+
484
+ /*if(boolParam.count("maximize") > 0 && boolParam["maximize"])
485
+ {
486
+ d->model->setObjSense(-1.0);
487
+ d->model->writeMps("tmp/test", "mps", -1.0);
488
+ }
489
+ else
490
+ {*/
491
+ d->model->setObjSense(1.0);
492
+ // d->model->writeMps("tmp/test", "mps", 1.0);
493
+ //}
494
+
495
+ /*d->nq = 0;
496
+ if(boolParam.count("qp_mat") > 0 && boolParam["qp_mat"] && !vars.qi.empty())
497
+ {
498
+ boolParam["qp"] = true;
499
+ vector<long>::iterator iti;
500
+ vector<long>::iterator itj = vars.qj.begin();
501
+ vector<double>::iterator itv = vars.qobj.begin();
502
+ vector<vector<pair<int,double> > > tvect;
503
+ for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++)
504
+ {
505
+ if(*iti )
506
+ tvect[*iti]
507
+ d->Q_beg[i]++;
508
+ d->Q_r[d->nq] = *iti;
509
+ d->Q_v[d->nq] = *itv;
510
+ d->nq++;
511
+ }
512
+ int Qcsum = 0;
513
+ for(unsigned long i = 0; i < nc; i++)
514
+ {
515
+ int temp = Qcsum;
516
+ Qcsum += d->Q_beg[i];
517
+ d->Q_beg[i] = temp;
518
+ }
519
+ d->Q_beg[nc] = Qcsum;
520
+
521
+ printf("Adding quadratic obj\n");
522
+ (dynamic_cast<GenModelOsiInterface*>(d->model))->setQuadraticObjective(d->nc,d->Q_beg,d->Q_r,d->Q_v);
523
+ //(dynamic_cast<OsiClpSolverInterface*>(d->model))->getModelPtr()->loadQuadraticObjective(d->nc,d->Q_beg,d->Q_r,d->Q_v);
524
+ }*/
525
+
526
+ if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"])
527
+ {
528
+ vector<vector<pair<int,double> > > qptemp;
529
+ qptemp.resize(nc);
530
+ int* qpbeg = NULL;
531
+ CoinBigIndex* qpind = NULL;
532
+ double* qpv = NULL;
533
+ int qpnz = 0;
534
+
535
+ vector<long>::iterator iti;
536
+ vector<long>::iterator itj = vars.qj.begin();
537
+ vector<double>::iterator itv = vars.qobj.begin();
538
+
539
+ for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++)
540
+ {
541
+ qptemp[*iti].push_back(pair<int, double>(*itj,*itv));
542
+ qpnz++;
543
+ if(*iti != *itj)
544
+ {
545
+ qptemp[*itj].push_back(pair<int, double>(*iti,*itv));
546
+ qpnz++;
547
+ }
548
+ }
549
+ if(!vars.qi.empty())
550
+ {
551
+ boolParam["qp"] = true;
552
+ qpbeg = new int[nc+1];
553
+
554
+ qpv = new double[qpnz];
555
+ qpind = new CoinBigIndex[qpnz];
556
+
557
+ qpnz=0;
558
+ for(int i = 0; i < int(nc); i++)
559
+ {
560
+ qpbeg[i] = qpnz;
561
+ for(int j = 0; j < int(qptemp[i].size()); j++)
562
+ {
563
+ qpind[qpnz] = qptemp[i][j].first;
564
+ qpv[qpnz] = d->mult*2*qptemp[i][j].second;
565
+ qpnz++;
566
+ }
567
+ }
568
+ qpbeg[nc] = qpnz;
569
+ printf("Adding quadratic obj\n");
570
+ (dynamic_cast<GenModelOsiInterface*>(d->model))->setQuadraticObjective(nc,qpbeg,qpind,qpv);
571
+ //(dynamic_cast<OsiClpSolverInterface*>(d->model))->getModelPtr()->loadQuadraticObjective(nc,qpbeg,qpind,qpv);
572
+ d->nq = qpnz;
573
+
574
+ delete[] qpbeg;
575
+ delete[] qpind;
576
+ delete[] qpv;
577
+ }
578
+ }
579
+ nz = oldnz;
580
+
581
+ bcreated = true;
582
+
583
+ return 0;
584
+ }
585
+
586
+ long GenModelOsi::CreateModel(string filename, int type, string dn)
587
+ {
588
+ OsiData* d = static_cast<OsiData*>(solverdata);
589
+
590
+ switch (type)
591
+ {
592
+ case 0: d->model->readMps(filename.c_str()); break;
593
+ case 1: d->model->readLp(filename.c_str()); break;
594
+ case 2: d->model->readGMPL(filename.c_str(), (dn == "" ? NULL : dn.c_str())); break;
595
+ default: d->model->readMps(filename.c_str()); break;
596
+ }
597
+
598
+ //ReadFromObject(this, d->model);
599
+
600
+ //ReadFromFile(static_cast<GenModel*>(this), filename, type);
601
+ //SetNumbers();
602
+ //CreateModel();
603
+ bcreated = true;
604
+
605
+ return 0;
606
+ }
607
+
608
+ long GenModelOsi::Init(string name) //, int type)
609
+ {
610
+ try {
611
+ int type = 0;
612
+ if(solverdata == NULL)
613
+ solverdata = new OsiData();
614
+ else
615
+ {
616
+ static_cast<OsiData*>(solverdata)->Delete();
617
+ static_cast<OsiData*>(solverdata)->Reset();
618
+ }
619
+
620
+ OsiData* d = static_cast<OsiData*>(solverdata);
621
+
622
+ d->solvertype = type;
623
+ if(type==0)
624
+ {
625
+ if(boolParam.count("qp_mat") > 0 && boolParam["qp_mat"] && !vars.qi.empty())
626
+ d->model = new GenModelOsiInterface();
627
+ else
628
+ d->model = new OsiClpSolverInterface();
629
+ }
630
+ /*else if(type==1)
631
+ d->model = new OsiVolSolverInterface();
632
+ else if(type==2)
633
+ d->model = new OsiGlpkSolverInterface();
634
+ else if(type==3)
635
+ d->model = new OsiSpxSolverInterface();
636
+ else if(type==4)
637
+ d->model = new OsiCpxSolverInterface();
638
+ else if(type==5)
639
+ d->model = new OsiGrbSolverInterface();
640
+ else
641
+ d->model = new OsiClpSolverInterface();*/
642
+
643
+ d->model->setStrParam(OsiProbName, name);
644
+
645
+
646
+ SetParam("log_file", 0, "str", "Failure to set the log file", false);
647
+
648
+ // General settings
649
+ SetParam("log_output_stdout", 0, "bool", "Failure to turn on/off log output to stdout", false);
650
+ SetParam("log_level", 0, "long", "Failure to set log level", false);
651
+ SetParam("use_data_checking", 0, "bool", "Failure to turn on/off data checking", false);
652
+ //SetParam("nb_threads", 0, "long", "Failure to set the number of threads", false);
653
+ SetParam("use_preprocessor", 0, "bool", "Failure to use preprocessor", false);
654
+
655
+ // MIP settings
656
+ SetParam("nb_cut_pass", 0, "long", "Failure to set the number of cut pass", false);
657
+ SetParam("feasibility_pump_level", 0, "long", "Failure to set the feasibility pump level", false);
658
+ SetParam("probing_level", 0, "long", "Failure to set the probing level", false);
659
+ SetParam("mip_emphasis", 0, "long", "Failure to set the MIP emphasis", false);
660
+ SetParam("use_cut_callback", 0, "bool", "Failure to use preprocessor", false);
661
+
662
+ // Tolerance and limits
663
+
664
+ if(longParam.count("max_iteration_limit") == 0) longParam["max_iteration_limit"] = 99999999;
665
+ SetParam("max_iteration_limit", OsiMaxNumIteration, "long", "Failure to set the maximal number of simplex iterations");
666
+ if(dblParam.count("bounds_feasibility_tolerance") == 0) dblParam["bounds_feasibility_tolerance"] = 1e-9;
667
+ SetParam("bounds_feasibility_tolerance", OsiPrimalTolerance, "dbl", "Failure to set bounds feasibility tolerance");
668
+ SetParam("bounds_feasibility_tolerance", OsiDualTolerance, "dbl", "Failure to set bounds feasibility tolerance");
669
+ SetParam("optimality_tolerance", 0, "dbl", "Failure to set optimality tolerance", false);
670
+ SetParam("markowitz_tolerance", 0, "dbl", "Failure to set Markowitz tolerance", false);
671
+ SetParam("absolute_mip_gap_tolerance", 0, "dbl", "Failure to set absolute gap tolerance", false);
672
+ SetParam("relative_mip_gap_tolerance", 0, "dbl", "Failure to set relative gap tolerance", false);
673
+ SetParam("lp_objective_limit", OsiPrimalObjectiveLimit, "dbl", "Failure to set lp objective limit");
674
+ SetParam("lp_objective_limit", OsiDualObjectiveLimit, "dbl", "Failure to set lp objective limit");
675
+
676
+ // int params
677
+ //ClpMaxNumIterationHotStart : The maximum number of iterations Clp can execute in hotstart before terminating
678
+
679
+ // double params
680
+ // ClpDualObjectiveLimit : Set Dual objective limit. This is to be used as a termination criteria in methods where the dual objective monotonically changes (dual simplex)
681
+ // ClpObjOffset : Objective function constant. This the value of the constant term in the objective function
682
+
683
+ // OsiHintParam {
684
+ // OsiDoPresolveInInitial = 0, OsiDoDualInInitial, OsiDoPresolveInResolve, OsiDoDualInResolve,
685
+ // OsiDoScale, OsiDoCrash, OsiDoReducePrint, OsiDoInBranchAndCut,
686
+ // OsiLastHintParam
687
+ //}
688
+ // OsiHintStrength { OsiHintIgnore = 0, OsiHintTry, OsiHintDo, OsiForceDo }
689
+
690
+
691
+ // http://www.coin-or.org/Cbc/cbcuserguide.html
692
+
693
+ } catch (string e) {
694
+ printf("Error : %s\n", e.c_str());
695
+ }
696
+
697
+ binit = true;
698
+
699
+ return 0;
700
+ }
701
+
702
+ long GenModelOsi::SetDirectParam(int whichparam, genmodel_param value, string type, string message)
703
+ {
704
+ bool status = true;
705
+ if(type == "dbl")
706
+ status = (static_cast<OsiData*>(solverdata))->model->setDblParam(OsiDblParam(whichparam), value.dblval);
707
+ else if(type == "long")
708
+ status = (static_cast<OsiData*>(solverdata))->model->setIntParam(OsiIntParam(whichparam), value.longval);
709
+ else if(type == "str")
710
+ status = (static_cast<OsiData*>(solverdata))->model->setStrParam(OsiStrParam(whichparam), value.strval);
711
+ if ( !status )
712
+ return ThrowError(message);
713
+ return 0;
714
+ }
715
+
716
+ long GenModelOsi::SetParam(string param, int whichparam, string type, string message, bool implemented)
717
+ {
718
+ bool notimplmessage = boolParam.count("throw_on_unimplemeted_option") > 0 && boolParam["throw_on_unimplemeted_option"];
719
+
720
+ if(type == "dbl")
721
+ {
722
+ if(dblParam.count(param) > 0 && implemented)
723
+ SetDirectParam(whichparam, dbl2param(dblParam[param]), type, message);
724
+ else if(notimplmessage && !implemented && dblParam.count(param) > 0)
725
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
726
+ }
727
+ else if(type == "long")
728
+ {
729
+ if(longParam.count(param) > 0 && implemented)
730
+ SetDirectParam(whichparam, long2param(longParam[param]), type, message);
731
+ else if(notimplmessage && !implemented && longParam.count(param) > 0)
732
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
733
+ }
734
+ else if(type == "str")
735
+ {
736
+ if(strParam.count(param) > 0 && implemented)
737
+ SetDirectParam(whichparam, str2param(strParam[param]), type, message);
738
+ else if(notimplmessage && !implemented && strParam.count(param) > 0)
739
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
740
+ }
741
+ else if(type == "bool")
742
+ {
743
+ if(boolParam.count(param) > 0 && implemented)
744
+ {
745
+ if(boolParam[param])
746
+ SetDirectParam(whichparam, long2param(0), "long", message);
747
+ else
748
+ SetDirectParam(whichparam, long2param(1), "long", message);
749
+ }
750
+ else if(notimplmessage && !implemented && boolParam.count(param) > 0)
751
+ throw (string("Parameter ")+param+" not implemented in GenModelOsi");
752
+ }
753
+
754
+ return 0;
755
+ }
756
+
757
+ long GenModelOsi::AddSolverRow(vector<int>& ind, vector<double>& val, double rhs, char sense, string name)
758
+ {
759
+ if(!bcreated)
760
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
761
+
762
+ AddModelRow(ind, val, rhs, sense, name);
763
+ AddCut(&ind[0], &val[0], int(ind.size()), rhs, sense, name.c_str());
764
+
765
+ return 0;
766
+ }
767
+
768
+ long GenModelOsi::AddCut(int* cols, double* vals, int nz, double rhs, char sense, const char* name)
769
+ {
770
+ if(!bcreated)
771
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
772
+
773
+ OsiData* d = (OsiData*)solverdata;
774
+
775
+ double lb = rhs;
776
+ double ub = rhs;
777
+
778
+ if(sense == 'L')
779
+ lb = -COIN_DBL_MAX;
780
+ else if(sense == 'G')
781
+ ub = COIN_DBL_MAX;
782
+
783
+ d->model->addRow(nz, cols, vals, lb, ub);
784
+ d->nr++;
785
+
786
+ return 0;
787
+ }
788
+
789
+ long GenModelOsi::AddSolverCol(vector<int>& ind, vector<double>& val, double obj, double lb, double ub, string name, char type)
790
+ {
791
+ if(!bcreated)
792
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
793
+
794
+ AddModelCol(ind, val, obj, lb, ub, name, type);
795
+ AddCol(&ind[0], &val[0], int(ind.size()), obj, lb, ub, name.c_str(), type);
796
+
797
+ return 0;
798
+ }
799
+
800
+
801
+ long GenModelOsi::AddCol(int* newi, double* newcol, int nz, double obj, double lb, double ub, const char* name, char type)
802
+ {
803
+ if(!bcreated)
804
+ throw string("WriteSolutionToFile() not available : Problem not created yet;");
805
+
806
+ OsiData* d = (OsiData*)solverdata;
807
+ d->model->addCol(nz, newi, newcol, lb, ub, obj);
808
+ d->nc++;
809
+
810
+ return 0;
811
+ }
812
+
813
+ long GenModelOsi::Clean()
814
+ {
815
+ if(solverdata != NULL)
816
+ delete static_cast<OsiData*>(solverdata);
817
+
818
+ return 0;
819
+ }
820
+
821
+ long OsiData::Reset()
822
+ {
823
+ model = NULL;
824
+ mipmodel = NULL;
825
+ mat_beg = NULL;
826
+ /*Q_beg = NULL;
827
+ Q_r = NULL;
828
+ Q_v = NULL;*/
829
+ mat_r = NULL;
830
+ mat_v = NULL;
831
+ lrhs = NULL;
832
+ urhs = NULL;
833
+ ub = NULL;
834
+ lb = NULL;
835
+ typei = NULL;
836
+ typec = NULL;
837
+ obj = NULL;
838
+ cname = NULL;
839
+ rname = NULL;
840
+
841
+ return 0;
842
+ }
843
+
844
+ OsiData::OsiData()
845
+ {
846
+ Reset();
847
+ }
848
+
849
+ OsiData::~OsiData()
850
+ {
851
+ Delete();
852
+ }
853
+ long OsiData::Delete()
854
+ {
855
+ //if(model != NULL)
856
+ // delete[] model;
857
+ if(mat_beg != NULL)
858
+ delete[] mat_beg;
859
+ if(mat_r != NULL)
860
+ delete[] mat_r;
861
+ if(mat_v != NULL)
862
+ delete[] mat_v;
863
+ if(lrhs != NULL)
864
+ delete[] lrhs;
865
+ if(obj != NULL)
866
+ delete[] obj;
867
+ if(urhs != NULL)
868
+ delete[] urhs;
869
+ if(ub != NULL)
870
+ delete[] ub;
871
+ if(lb != NULL)
872
+ delete[] lb;
873
+ if(typei != NULL)
874
+ delete[] typei;
875
+ if(typec != NULL)
876
+ delete[] typec;
877
+
878
+ if(cname != NULL)
879
+ {
880
+ for(long i = 0; i < nc; i++)
881
+ delete[] cname[i];
882
+ }
883
+ delete[] cname;
884
+ if(rname != NULL)
885
+ {
886
+ for(long i = 0; i < nr; i++)
887
+ delete[] rname[i];
888
+ }
889
+ delete[] rname;
890
+
891
+ return 0;
892
+ }