Some bug fix.
Added: Concept check for maps and IdReader/Writer classes
Some runtime check
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 status = CPXgetobjval (env, lp, &objval);
279 //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
280 // 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.
282 // For Simplex, Barrier
284 // Optimal solution found
286 // Problem infeasible
290 // Objective limit exceeded in Phase II
292 // Iteration limit exceeded in Phase II
293 // 6 CPX_IT_LIM_INFEAS
294 // Iteration limit exceeded in Phase I
295 // 7 CPX_TIME_LIM_FEAS
296 // Time limit exceeded in Phase II
297 // 8 CPX_TIME_LIM_INFEAS
298 // Time limit exceeded in Phase I
299 // 9 CPX_NUM_BEST_FEAS
300 // Problem non-optimal, singularities in Phase II
301 // 10 CPX_NUM_BEST_INFEAS
302 // Problem non-optimal, singularities in Phase I
303 // 11 CPX_OPTIMAL_INFEAS
304 // Optimal solution found, unscaled infeasibilities
306 // Aborted in Phase II
307 // 13 CPX_ABORT_INFEAS
308 // Aborted in Phase I
309 // 14 CPX_ABORT_DUAL_INFEAS
310 // Aborted in barrier, dual infeasible
311 // 15 CPX_ABORT_PRIM_INFEAS
312 // Aborted in barrier, primal infeasible
313 // 16 CPX_ABORT_PRIM_DUAL_INFEAS
314 // Aborted in barrier, primal and dual infeasible
315 // 17 CPX_ABORT_PRIM_DUAL_FEAS
316 // Aborted in barrier, primal and dual feasible
317 // 18 CPX_ABORT_CROSSOVER
318 // Aborted in crossover
320 // Infeasible or unbounded
324 // Ezeket hova tegyem:
325 // ??case CPX_ABORT_DUAL_INFEAS
326 // ??case CPX_ABORT_CROSSOVER
327 // ??case CPX_INForUNBD
330 LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
332 int stat = CPXgetstat (env, lp);
335 return UNDEFINED; //Undefined
336 case CPX_OPTIMAL://Optimal
338 case CPX_UNBOUNDED://Unbounded
340 case CPX_INFEASIBLE://Infeasible
341 // case CPX_IT_LIM_INFEAS:
342 // case CPX_TIME_LIM_INFEAS:
343 // case CPX_NUM_BEST_INFEAS:
344 // case CPX_OPTIMAL_INFEAS:
345 // case CPX_ABORT_INFEAS:
346 // case CPX_ABORT_PRIM_INFEAS:
347 // case CPX_ABORT_PRIM_DUAL_INFEAS:
350 // case CPX_IT_LIM_FEAS:
351 // case CPX_TIME_LIM_FEAS:
352 // case CPX_NUM_BEST_FEAS:
353 // case CPX_ABORT_FEAS:
354 // case CPX_ABORT_PRIM_DUAL_FEAS:
357 return UNDEFINED; //Everything else comes here
363 //9.0-as cplex verzio statusai
364 // CPX_STAT_ABORT_DUAL_OBJ_LIM
365 // CPX_STAT_ABORT_IT_LIM
366 // CPX_STAT_ABORT_OBJ_LIM
367 // CPX_STAT_ABORT_PRIM_OBJ_LIM
368 // CPX_STAT_ABORT_TIME_LIM
369 // CPX_STAT_ABORT_USER
370 // CPX_STAT_FEASIBLE_RELAXED
371 // CPX_STAT_INFEASIBLE
372 // CPX_STAT_INForUNBD
375 // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
376 // CPX_STAT_OPTIMAL_INFEAS
377 // CPX_STAT_OPTIMAL_RELAXED
378 // CPX_STAT_UNBOUNDED
380 LpCplex::SolutionStatus LpCplex::_getDualStatus()
382 int stat = CPXgetstat (env, lp);
385 return UNDEFINED; //Undefined
386 case CPX_OPTIMAL://Optimal
391 return UNDEFINED; //Everything else comes here
396 LpCplex::ProblemTypes LpCplex::_getProblemType()
398 int stat = CPXgetstat (env, lp);
400 case CPX_OPTIMAL://Optimal
401 return PRIMAL_DUAL_FEASIBLE;
403 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
404 // return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
405 // return PRIMAL_DUAL_INFEASIBLE;
407 //Seems to be that this is all we can say for sure
415 void LpCplex::_setMax()
417 CPXchgobjsen (env, lp, CPX_MAX);
419 void LpCplex::_setMin()
421 CPXchgobjsen (env, lp, CPX_MIN);