2 * lemon/lp_cplex.cc - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #include<lemon/lp_cplex.h>
20 ///\brief Implementation of the LEMON-CPLEX lp solver interface.
23 LpCplex::LpCplex() : LpSolverBase() {
25 // env = CPXopenCPLEXdevelop(&status);
26 env = CPXopenCPLEX(&status);
27 lp = CPXcreateprob(env, &status, "LP problem");
35 LpSolverBase &LpCplex::_newLp()
37 //The first approach opens a new environment
38 LpCplex* newlp=new LpCplex();
42 LpSolverBase &LpCplex::_copyLp() {
43 //The first approach opens a new environment
44 LpCplex* newlp=new LpCplex();
45 //The routine CPXcloneprob can be used to create a new CPLEX problem
46 //object and copy all the problem data from an existing problem
47 //object to it. Solution and starting information is not copied.
48 newlp->lp = CPXcloneprob(env, lp, &status);
52 int LpCplex::_addCol()
54 int i = CPXgetnumcols(env, lp);
56 lb[0]=-INF;//-CPX_INFBOUND;
57 ub[0]=INF;//CPX_INFBOUND;
58 status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
63 int LpCplex::_addRow()
65 //We want a row that is not constrained
67 sense[0]='L';//<= constraint
70 int i = CPXgetnumrows(env, lp);
71 status = CPXnewrows(env, lp, 1, rhs, sense, NULL, NULL);
76 void LpCplex::_eraseCol(int i) {
77 CPXdelcols(env, lp, i, i);
80 void LpCplex::_eraseRow(int i) {
81 CPXdelrows(env, lp, i, i);
85 ///\warning Data at index 0 is ignored in the arrays.
86 void LpCplex::_setRowCoeffs(int i,
89 Value const * values )
91 int rowlist[length+1];
93 for (int k=1;k<=length;++k){
96 status = CPXchgcoeflist(env, lp,
99 const_cast<int * >(indices+1),
100 const_cast<Value * >(values+1));
103 void LpCplex::_setColCoeffs(int i,
106 Value const * values)
108 int collist[length+1];
110 for (int k=1;k<=length;++k){
113 status = CPXchgcoeflist(env, lp,
115 const_cast<int * >(indices+1),
117 const_cast<Value * >(values+1));
120 void LpCplex::_setCoeff(int row, int col, Value value)
122 CPXchgcoef(env, lp, row, col, value);
125 void LpCplex::_setColLowerBound(int i, Value value)
133 status = CPXchgbds(env, lp, 1, indices, lu, bd);
137 void LpCplex::_setColUpperBound(int i, Value value)
145 status = CPXchgbds(env, lp, 1, indices, lu, bd);
148 //This will be easier to implement
149 void LpCplex::_setRowBounds(int i, Value lb, Value ub)
152 if (lb==INF || ub==-INF) {
163 CPXchgsense(env, lp, cnt, indices, sense);
164 CPXchgcoef(env, lp, i, -1, ub);
170 CPXchgsense(env, lp, cnt, indices, sense);
171 CPXchgcoef(env, lp, i, -1, lb);
176 CPXchgsense(env, lp, cnt, indices, sense);
177 CPXchgcoef(env, lp, i, -1, lb);
181 CPXchgsense(env, lp, cnt, indices, sense);
182 CPXchgcoef(env, lp, i, -1, lb);
183 CPXchgcoef(env, lp, i, -2, ub-lb);
189 // void LpCplex::_setRowLowerBound(int i, Value value)
191 // //Not implemented, obsolete
194 // void LpCplex::_setRowUpperBound(int i, Value value)
196 // //Not implemented, obsolete
197 // // //TODO Ezt kell meg megirni
198 // // //type of the problem
200 // // status = CPXgetsense(env, lp, sense, i, i);
202 // // status = CPXgetrhs(env, lp, rhs, i, i);
204 // // switch (sense[0]) {
205 // // case 'L'://<= constraint
207 // // case 'E'://= constraint
209 // // case 'G'://>= constraint
211 // // case 'R'://ranged constraint
217 // // status = CPXchgcoef(env, lp, i, -2, value_rng);
220 void LpCplex::_setObjCoeff(int i, Value obj_coef)
222 CPXchgcoef(env, lp, -1, i, obj_coef);
225 void LpCplex::_clearObj()
227 for (int i=0;i< CPXgetnumcols(env, lp);++i){
228 CPXchgcoef(env, lp, -1, i, 0);
232 // The routine returns zero unless an error occurred during the
233 // optimization. Examples of errors include exhausting available
234 // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
235 // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
236 // user-specified CPLEX limit, or proving the model infeasible or
237 // unbounded, are not considered errors. Note that a zero return
238 // value does not necessarily mean that a solution exists. Use query
239 // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
240 // further information about the status of the optimization.
241 LpCplex::SolveExitStatus LpCplex::_solve()
244 status = CPXlpopt(env, lp);
246 //We want to exclude some cases
247 switch (CPXgetstat(env, lp)){
249 case CPX_IT_LIM_FEAS:
250 case CPX_IT_LIM_INFEAS:
251 case CPX_TIME_LIM_FEAS:
252 case CPX_TIME_LIM_INFEAS:
263 LpCplex::Value LpCplex::_getPrimal(int i)
266 CPXgetx(env, lp, &x, i, i);
270 LpCplex::Value LpCplex::_getPrimalValue()
273 //method = CPXgetmethod (env, lp);
274 //printf("CPXgetprobtype %d \n",CPXgetprobtype(env,lp));
275 status = CPXgetobjval(env, lp, &objval);
276 //printf("Objective value: %g \n",objval);
281 //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
282 // This table lists the statuses, returned by the CPXgetstat() routine, for solutions to LP problems or mixed integer problems. If no solution exists, the return value is zero.
284 // For Simplex, Barrier
286 // Optimal solution found
288 // Problem infeasible
292 // Objective limit exceeded in Phase II
294 // Iteration limit exceeded in Phase II
295 // 6 CPX_IT_LIM_INFEAS
296 // Iteration limit exceeded in Phase I
297 // 7 CPX_TIME_LIM_FEAS
298 // Time limit exceeded in Phase II
299 // 8 CPX_TIME_LIM_INFEAS
300 // Time limit exceeded in Phase I
301 // 9 CPX_NUM_BEST_FEAS
302 // Problem non-optimal, singularities in Phase II
303 // 10 CPX_NUM_BEST_INFEAS
304 // Problem non-optimal, singularities in Phase I
305 // 11 CPX_OPTIMAL_INFEAS
306 // Optimal solution found, unscaled infeasibilities
308 // Aborted in Phase II
309 // 13 CPX_ABORT_INFEAS
310 // Aborted in Phase I
311 // 14 CPX_ABORT_DUAL_INFEAS
312 // Aborted in barrier, dual infeasible
313 // 15 CPX_ABORT_PRIM_INFEAS
314 // Aborted in barrier, primal infeasible
315 // 16 CPX_ABORT_PRIM_DUAL_INFEAS
316 // Aborted in barrier, primal and dual infeasible
317 // 17 CPX_ABORT_PRIM_DUAL_FEAS
318 // Aborted in barrier, primal and dual feasible
319 // 18 CPX_ABORT_CROSSOVER
320 // Aborted in crossover
322 // Infeasible or unbounded
326 // Ezeket hova tegyem:
327 // ??case CPX_ABORT_DUAL_INFEAS
328 // ??case CPX_ABORT_CROSSOVER
329 // ??case CPX_INForUNBD
332 LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
334 int stat = CPXgetstat(env, lp);
335 //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
338 return UNDEFINED; //Undefined
339 case CPX_OPTIMAL://Optimal
341 case CPX_UNBOUNDED://Unbounded
343 case CPX_INFEASIBLE://Infeasible
344 // case CPX_IT_LIM_INFEAS:
345 // case CPX_TIME_LIM_INFEAS:
346 // case CPX_NUM_BEST_INFEAS:
347 // case CPX_OPTIMAL_INFEAS:
348 // case CPX_ABORT_INFEAS:
349 // case CPX_ABORT_PRIM_INFEAS:
350 // case CPX_ABORT_PRIM_DUAL_INFEAS:
353 // case CPX_IT_LIM_FEAS:
354 // case CPX_TIME_LIM_FEAS:
355 // case CPX_NUM_BEST_FEAS:
356 // case CPX_ABORT_FEAS:
357 // case CPX_ABORT_PRIM_DUAL_FEAS:
360 return UNDEFINED; //Everything else comes here
366 //9.0-as cplex verzio statusai
367 // CPX_STAT_ABORT_DUAL_OBJ_LIM
368 // CPX_STAT_ABORT_IT_LIM
369 // CPX_STAT_ABORT_OBJ_LIM
370 // CPX_STAT_ABORT_PRIM_OBJ_LIM
371 // CPX_STAT_ABORT_TIME_LIM
372 // CPX_STAT_ABORT_USER
373 // CPX_STAT_FEASIBLE_RELAXED
374 // CPX_STAT_INFEASIBLE
375 // CPX_STAT_INForUNBD
378 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
379 // CPX_STAT_OPTIMAL_INFEAS
380 // CPX_STAT_OPTIMAL_RELAXED
381 // CPX_STAT_UNBOUNDED
383 LpCplex::SolutionStatus LpCplex::_getDualStatus()
385 int stat = CPXgetstat(env, lp);
388 return UNDEFINED; //Undefined
389 case CPX_OPTIMAL://Optimal
394 return UNDEFINED; //Everything else comes here
399 LpCplex::ProblemTypes LpCplex::_getProblemType()
401 int stat = CPXgetstat(env, lp);
403 case CPX_OPTIMAL://Optimal
404 return PRIMAL_DUAL_FEASIBLE;
406 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
407 // return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
408 // return PRIMAL_DUAL_INFEASIBLE;
410 //Seems to be that this is all we can say for sure
418 void LpCplex::_setMax()
420 CPXchgobjsen(env, lp, CPX_MAX);
422 void LpCplex::_setMin()
424 CPXchgobjsen(env, lp, CPX_MIN);