-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathekk.cpp
184 lines (163 loc) · 5.82 KB
/
ekk.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright (C) 2002, International Business Machines
// Corporation and others. All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).
/* This can be used to compare OSL and Clp. The interface functions
below (in ekk_interface.cpp) were written so that calls to osl
in the middle of complex algorithms could easily be swapped
for Clp code. This was to stress test Clp (and Osl :-)).
With the addition of ekk_crash it may be used to see if we need
a crash in Clp. With "both" set it can also be used to see which
gives better behavior after postSolve.
However they may be useful as sample code. Virtuous people would
add return code checking.
This main could just as easily be C code.
*/
#include "ekk_c_api.h"
// These interface functions are needed
// Note - This example wastes memory as it has several copies of matrix
/* As ekk_primalSimplex + postsolve instructions:
presolve - 0 , no presolve, 1 presolve but no primal after postsolve,
2 do primal if any infeasibilities,
3 always do primal.
*/
extern "C" int ekk_primalClp(EKKModel * model, int startup, int presolve);
/* As ekk_dualSimplex + postsolve instructions:
presolve - 0 , no presolve, 1 presolve but no primal after postsolve,
2 do primal if any infeasibilities,
3 always do primal.
*/
extern "C" int ekk_dualClp(EKKModel * model, int presolve);
/* rather like ekk_preSolve (3) plus:
keepIntegers - false to treat as if continuous
pass - do this many passes (0==default(5))
returns 1 if infeasible
*/
extern "C" int ekk_preSolveClp(EKKModel * model, bool keepIntegers,
int pass);
#include "ClpSimplex.hpp"
#include <stdio.h>
#include <stdarg.h>
int main(int argc, const char *argv[])
{
const char * name;
// problem is actually scaled for osl, dynamically for clp (slows clp)
// default is primal, no presolve, minimise and use clp
bool primal = true, presolve = false;
int useosl = 0;
bool freeFormat = false;
bool exportIt = false;
EKKModel * model;
EKKContext * context;
if (argc > 1) {
name = argv[1];
} else {
#if defined(SAMPLEDIR)
name = (SAMPLEDIR "/p0033.mps";
#else
fprintf(stderr, "Do not know where to find sample MPS files.\n");
exit(1);
#endif
}
/* initialize OSL environment */
context = ekk_initializeContext();
model = ekk_newModel(context, "");
int i;
printf("*** Options ");
for (i = 2; i < argc; i++) {
printf("%s ", argv[i]);
}
printf("\n");
// see if free format needed
for (i = 2; i < argc; i++) {
if (!strncmp(argv[i], "free", 4)) {
freeFormat = true;
}
}
// create model from MPS file
if (!freeFormat) {
ekk_importModel(model, name);
} else {
ekk_importModelFree(model, name);
}
// other options
for (i = 2; i < argc; i++) {
if (!strncmp(argv[i], "max", 3)) {
if (!strncmp(argv[i], "max2", 4)) {
// This is for testing - it just reverses signs and maximizes
int i, n = ekk_getInumcols(model);
double * objective = ekk_getObjective(model);
for (i = 0; i < n; i++) {
objective[i] = -objective[i];
}
ekk_setObjective(model, objective);
ekk_setMaximize(model);
} else {
// maximize
ekk_setMaximize(model);
}
}
if (!strncmp(argv[i], "dual", 4)) {
primal = false;
}
if (!strncmp(argv[i], "presol", 6)) {
presolve = true;
}
if (!strncmp(argv[i], "osl", 3)) {
useosl = 1;
}
if (!strncmp(argv[i], "both", 4)) {
useosl = 2;
}
if (!strncmp(argv[i], "export", 6)) {
exportIt = true;
}
}
if (useosl) {
// OSL
if (presolve)
ekk_preSolve(model, 3, NULL);
ekk_scale(model);
if (primal)
ekk_primalSimplex(model, 1);
else
ekk_dualSimplex(model);
if (presolve) {
ekk_postSolve(model, NULL);
ekk_primalSimplex(model, 3);
}
if (useosl == 2)
ekk_allSlackBasis(model); // otherwise it would be easy
}
if ((useosl & 2) == 0) {
// CLP
if (presolve)
ekk_preSolveClp(model, true, 5);
/* 3 is because it is ignored if no presolve, and we
are forcing Clp to re-optimize */
if (primal)
ekk_primalClp(model, 1, 3);
else
ekk_dualClp(model, 3);
}
if (exportIt) {
ClpSimplex * clp = new ClpSimplex();;
int numberRows = ekk_getInumrows(model);
int numberColumns = ekk_getInumcols(model);
clp->loadProblem(numberColumns, numberRows, ekk_blockColumn(model, 0),
ekk_blockRow(model, 0), ekk_blockElement(model, 0),
ekk_collower(model), ekk_colupper(model),
ekk_objective(model),
ekk_rowlower(model), ekk_rowupper(model));
// Do integer stuff
int * which = ekk_listOfIntegers(model);
int numberIntegers = ekk_getInumints(model);
for (int i = 0; i < numberIntegers; i++)
clp->setInteger(which[i]);
ekk_free(which);
clp->writeMps("try1.mps");
delete clp;
}
ekk_deleteModel(model);
ekk_endContext(context);
return 0;
}