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 185
|
/* $Id: ekk.cpp 1662 2011-01-04 17:52:40Z lou $ */
// 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;
}
|