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:
264 //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
265 // 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.
267 // For Simplex, Barrier
269 // Optimal solution found
271 // Problem infeasible
275 // Objective limit exceeded in Phase II
277 // Iteration limit exceeded in Phase II
278 // 6 CPX_IT_LIM_INFEAS
279 // Iteration limit exceeded in Phase I
280 // 7 CPX_TIME_LIM_FEAS
281 // Time limit exceeded in Phase II
282 // 8 CPX_TIME_LIM_INFEAS
283 // Time limit exceeded in Phase I
284 // 9 CPX_NUM_BEST_FEAS
285 // Problem non-optimal, singularities in Phase II
286 // 10 CPX_NUM_BEST_INFEAS
287 // Problem non-optimal, singularities in Phase I
288 // 11 CPX_OPTIMAL_INFEAS
289 // Optimal solution found, unscaled infeasibilities
291 // Aborted in Phase II
292 // 13 CPX_ABORT_INFEAS
293 // Aborted in Phase I
294 // 14 CPX_ABORT_DUAL_INFEAS
295 // Aborted in barrier, dual infeasible
296 // 15 CPX_ABORT_PRIM_INFEAS
297 // Aborted in barrier, primal infeasible
298 // 16 CPX_ABORT_PRIM_DUAL_INFEAS
299 // Aborted in barrier, primal and dual infeasible
300 // 17 CPX_ABORT_PRIM_DUAL_FEAS
301 // Aborted in barrier, primal and dual feasible
302 // 18 CPX_ABORT_CROSSOVER
303 // Aborted in crossover
305 // Infeasible or unbounded
309 // Ezeket hova tegyem:
310 // ??case CPX_ABORT_DUAL_INFEAS
311 // ??case CPX_ABORT_CROSSOVER
312 // ??case CPX_INForUNBD
315 LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
317 int stat = CPXgetstat (env, lp);
320 return UNDEFINED; //Undefined
321 case CPX_OPTIMAL://Optimal
323 case CPX_UNBOUNDED://Unbounded
325 case CPX_INFEASIBLE://Infeasible
326 // case CPX_IT_LIM_INFEAS:
327 // case CPX_TIME_LIM_INFEAS:
328 // case CPX_NUM_BEST_INFEAS:
329 // case CPX_OPTIMAL_INFEAS:
330 // case CPX_ABORT_INFEAS:
331 // case CPX_ABORT_PRIM_INFEAS:
332 // case CPX_ABORT_PRIM_DUAL_INFEAS:
335 // case CPX_IT_LIM_FEAS:
336 // case CPX_TIME_LIM_FEAS:
337 // case CPX_NUM_BEST_FEAS:
338 // case CPX_ABORT_FEAS:
339 // case CPX_ABORT_PRIM_DUAL_FEAS:
342 return UNDEFINED; //Everything else comes here
348 //9.0-as cplex verzio statusai
349 // CPX_STAT_ABORT_DUAL_OBJ_LIM
350 // CPX_STAT_ABORT_IT_LIM
351 // CPX_STAT_ABORT_OBJ_LIM
352 // CPX_STAT_ABORT_PRIM_OBJ_LIM
353 // CPX_STAT_ABORT_TIME_LIM
354 // CPX_STAT_ABORT_USER
355 // CPX_STAT_FEASIBLE_RELAXED
356 // CPX_STAT_INFEASIBLE
357 // CPX_STAT_INForUNBD
360 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
361 // CPX_STAT_OPTIMAL_INFEAS
362 // CPX_STAT_OPTIMAL_RELAXED
363 // CPX_STAT_UNBOUNDED
365 LpCplex::SolutionStatus LpCplex::_getDualStatus()
367 int stat = CPXgetstat (env, lp);
370 return UNDEFINED; //Undefined
371 case CPX_OPTIMAL://Optimal
376 return UNDEFINED; //Everything else comes here
380 LpCplex::Value LpCplex::_getPrimal(int i)
383 CPXgetx (env, lp, &x, i, i);
387 LpCplex::Value LpCplex::_getPrimalValue()
390 //method = CPXgetmethod (env, lp);
391 status = CPXgetobjval (env, lp, &objval);
398 void LpCplex::_setMax()
400 CPXchgobjsen (env, lp, CPX_MAX);
402 void LpCplex::_setMin()
404 CPXchgobjsen (env, lp, CPX_MIN);