4 * Copyright: (c) Universitaet Karlsruhe
5 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
16 #include "lpp_local.h"
19 #include "sp_matrix.h"
20 #include "ilcplex/cplex.h"
22 #define LOGFILE stdout
25 static char cpx_cst_encoding[4] = {'?', 'E', 'L', 'G'};
26 static char cpx_var_encoding[4] = {'?', '?', 'C', 'B'};
28 typedef struct _cpx_t {
36 static INLINE void chk_cpx_err(cpx_t *cpx) {
38 if (CPXgeterrorstring(cpx->env, cpx->status, cpx->buf))
41 printf("Unknown CPLEX error\n");
46 static cpx_t *new_cpx(lpp_t *lpp) {
47 cpx_t *cpx = xcalloc(1, sizeof(*cpx));
49 cpx->env = CPXopenCPLEX(&cpx->status);
51 cpx->prob = CPXcreateprob(cpx->env, &cpx->status, lpp->name);
53 CPXchgobjsen(cpx->env, cpx->prob, (lpp->opt_type == minimize)?1:-1);
55 if (CPXsetlogfile(cpx->env, LOGFILE))
56 assert(0 && "Could not set logfile");
60 static void free_cpx(cpx_t *cpx) {
61 CPXfreeprob(cpx->env, &cpx->prob);
62 CPXcloseCPLEX(&cpx->env);
66 static void cpx_construct(cpx_t *cpx) {
67 const matrix_elem_t *elem;
68 int i, o, sv_cnt, numcols, numrows, numentries, objsen, *matbeg, *matcnt, *matind, *indices;
69 double *obj, *rhs, *matval, *lb, *ub, *startv;
70 char *sense, *vartype, **colname;
71 lpp_t *lpp = cpx->lpp;
73 numcols = lpp->var_next-1;
74 numrows = lpp->cst_next-1;
75 numentries = matrix_get_entries(lpp->m);
76 objsen = lpp->opt_type == minimize ? 1 : -1;
78 obj = alloca(numcols * sizeof(*obj));
79 lb = alloca(numcols * sizeof(*lb));
80 ub = alloca(numcols * sizeof(*ub));
81 colname = alloca(numcols * sizeof(*colname));
82 vartype = alloca(numcols * sizeof(*vartype));
83 indices = alloca(numcols * sizeof(*indices));
84 startv = alloca(numcols * sizeof(*startv));
85 matbeg = alloca(numcols * sizeof(*matbeg));
86 matcnt = alloca(numcols * sizeof(*matcnt));
87 matind = alloca(numentries * sizeof(*matind));
88 matval = alloca(numentries * sizeof(*matval));
89 rhs = alloca(numrows * sizeof(*rhs));
90 sense = alloca(numrows * sizeof(*sense));
94 for(i=0; i<numcols; ++i) {
95 name_t *curr_var = lpp->vars[1+i];
96 obj[i] = matrix_get(lpp->m, 0, 1+i);
99 colname[i] = curr_var->name;
100 vartype[i] = cpx_var_encoding[curr_var->type.var_type];
101 if(curr_var->value_kind == value_start) {
103 startv[sv_cnt++] = curr_var->value;
107 matrix_foreach_in_col(lpp->m, 1+i, elem) {
110 matind[o] = elem->row-1;
111 matval[o] = elem->val;
117 for(i=0; i<numrows; ++i) {
118 rhs[i] = matrix_get(lpp->m, 1+i, 0);
119 sense[i] = cpx_cst_encoding[lpp->csts[1+i]->type.cst_type];
122 cpx->status = CPXcopylpwnames(cpx->env, cpx->prob,
123 numcols, numrows, objsen,
125 matbeg, matcnt, matind, matval,
129 cpx->status = CPXcopyctype(cpx->env, cpx->prob, vartype);
131 cpx->status = CPXcopymipstart(cpx->env, cpx->prob, sv_cnt, indices, startv);
135 static void cpx_solve(cpx_t *cpx) {
136 int i, CPX_state, numcols;
138 struct timeval tvb, tva;
140 lpp_t *lpp = cpx->lpp;
141 numcols = CPXgetnumcols(cpx->env, cpx->prob);
144 /* set performance parameters */
145 CPXsetintparam(cpx->env, CPX_PARAM_MIPSTART, CPX_ON);
146 CPXsetintparam(cpx->env, CPX_PARAM_MIPEMPHASIS, CPX_MIPEMPHASIS_BESTBOUND);
147 CPXsetintparam(cpx->env, CPX_PARAM_VARSEL, CPX_VARSEL_STRONG);
150 gettimeofday(&tvb, NULL);
151 cpx->status = CPXmipopt(cpx->env, cpx->prob);
152 gettimeofday(&tva, NULL);
155 /* get solution status */
156 CPX_state = CPXgetstat(cpx->env, cpx->prob);
158 case CPXMIP_INFEASIBLE:
159 case CPX_STAT_INFEASIBLE: lpp->sol_state = infeasible; break;
160 case CPXMIP_INForUNBD:
161 case CPX_STAT_INForUNBD: lpp->sol_state = inforunb; break;
162 case CPXMIP_UNBOUNDED:
163 case CPX_STAT_UNBOUNDED: lpp->sol_state = unbounded; break;
164 case CPXMIP_ABORT_FEAS:
165 case CPXMIP_FAIL_FEAS:
166 case CPXMIP_MEM_LIM_FEAS:
167 case CPXMIP_NODE_LIM_FEAS:
168 case CPXMIP_TIME_LIM_FEAS: lpp->sol_state = feasible; break;
170 case CPX_STAT_OPTIMAL: lpp->sol_state = optimal; break;
171 default: lpp->sol_state = unknown;
173 assert(lpp->sol_state == optimal);
175 /* get variable solution values */
176 values = alloca(numcols * sizeof(*values));
177 CPXgetmipx(cpx->env, cpx->prob, values, 0, numcols-1);
179 for(i=0; i<numcols; ++i) {
180 lpp->vars[1+i]->value = values[i];
181 lpp->vars[1+i]->value_kind = value_solution;
184 /* get some statistics */
185 lpp->sol_time = tva.tv_sec - tvb.tv_sec;
186 lpp->iterations = CPXgetmipitcnt(cpx->env, cpx->prob);
189 void lpp_solve_local(lpp_t *lpp) {
190 cpx_t *cpx = new_cpx(lpp);
196 void lpp_solve_local(lpp_t *lpp) {
197 fprintf(stderr, "CPLEX not available!\n");