COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_cplex.cc @ 1528:1aa71600000c

Last change on this file since 1528:1aa71600000c was 1508:389a94a1d9eb, checked in by athos, 19 years ago

cplex test included

File size: 10.9 KB
Line 
1/* -*- C++ -*-
2 * lemon/lp_cplex.cc - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
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.
10 *
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
13 * purpose.
14 *
15 */
16#include <iostream>
17#include<lemon/lp_cplex.h>
18
19///\file
20///\brief Implementation of the LEMON-CPLEX lp solver interface.
21namespace lemon {
22 
23  LpCplex::LpCplex() : LpSolverBase() {
24
25    //    env = CPXopenCPLEXdevelop(&status);     
26    env = CPXopenCPLEX(&status);     
27    lp = CPXcreateprob(env, &status, "LP problem");
28  }
29 
30  LpCplex::~LpCplex() {
31    CPXfreeprob(env,&lp);
32    CPXcloseCPLEX(&env);
33  }
34 
35  LpSolverBase &LpCplex::_newLp()
36  {
37    //The first approach opens a new environment
38    LpCplex* newlp=new LpCplex();
39    return *newlp;
40  }
41
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);
49    return *newlp;
50  }
51
52  int LpCplex::_addCol()
53  {
54    int i = CPXgetnumcols(env, lp);
55    Value lb[1],ub[1];
56    lb[0]=-INF;//-CPX_INFBOUND;
57    ub[0]=INF;//CPX_INFBOUND;
58    status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
59    return i;
60  }
61
62 
63  int LpCplex::_addRow()
64  {
65    //We want a row that is not constrained
66    char sense[1];
67    sense[0]='L';//<= constraint
68    Value rhs[1];
69    rhs[0]=INF;
70    int i = CPXgetnumrows(env, lp);
71    status = CPXnewrows(env, lp, 1, rhs, sense, NULL, NULL);
72    return i;
73  }
74
75
76  void LpCplex::_eraseCol(int i) {
77    CPXdelcols(env, lp, i, i);
78  }
79 
80  void LpCplex::_eraseRow(int i) {
81    CPXdelrows(env, lp, i, i);
82  }
83
84 
85  ///\warning Data at index 0 is ignored in the arrays.
86  void LpCplex::_setRowCoeffs(int i,
87                              int length,
88                              int  const * indices,
89                              Value  const * values )
90  {
91    int rowlist[length+1];
92    int* p=rowlist;
93    for (int k=1;k<=length;++k){
94      rowlist[k]=i;
95    }
96    status = CPXchgcoeflist(env, lp,
97                            length,
98                            p+1,
99                            const_cast<int * >(indices+1),
100                            const_cast<Value * >(values+1));
101  }
102 
103  void LpCplex::_setColCoeffs(int i,
104                              int length,
105                              int  const * indices,
106                              Value  const * values)
107  {
108    int collist[length+1];
109    int* p=collist;
110    for (int k=1;k<=length;++k){
111      collist[k]=i;
112    }
113    status = CPXchgcoeflist(env, lp,
114                            length,
115                            const_cast<int * >(indices+1),
116                            p+1,
117                            const_cast<Value * >(values+1));
118  }
119 
120  void LpCplex::_setCoeff(int row, int col, Value value)
121  {
122    CPXchgcoef(env, lp, row, col, value);
123  }
124
125  void LpCplex::_setColLowerBound(int i, Value value)
126  {
127    int indices[1];
128    indices[0]=i;
129    char lu[1];
130    lu[0]='L';
131    Value bd[1];
132    bd[0]=value;
133    status = CPXchgbds(env, lp, 1, indices, lu, bd);
134 
135  }
136 
137  void LpCplex::_setColUpperBound(int i, Value value)
138  {
139    int indices[1];
140    indices[0]=i;
141    char lu[1];
142    lu[0]='U';
143    Value bd[1];
144    bd[0]=value;
145    status = CPXchgbds(env, lp, 1, indices, lu, bd);
146  }
147
148  //This will be easier to implement
149  void LpCplex::_setRowBounds(int i, Value lb, Value ub)
150  {
151    //Bad parameter
152    if (lb==INF || ub==-INF) {
153      //FIXME error
154    }
155   
156    int cnt=1;
157    int indices[1];
158    indices[0]=i;
159    char sense[1];
160
161    if (lb==-INF){
162      sense[0]='L';
163      CPXchgsense(env, lp, cnt, indices, sense);
164      CPXchgcoef(env, lp, i, -1, ub);
165     
166    }
167    else{
168      if (ub==INF){
169        sense[0]='G';
170        CPXchgsense(env, lp, cnt, indices, sense);
171        CPXchgcoef(env, lp, i, -1, lb);
172      }
173      else{
174        if (lb == ub){
175          sense[0]='E';
176          CPXchgsense(env, lp, cnt, indices, sense);
177          CPXchgcoef(env, lp, i, -1, lb);
178        }
179        else{
180          sense[0]='R';
181          CPXchgsense(env, lp, cnt, indices, sense);
182          CPXchgcoef(env, lp, i, -1, lb);
183          CPXchgcoef(env, lp, i, -2, ub-lb);     
184        }
185      }
186    }
187  }
188
189//   void LpCplex::_setRowLowerBound(int i, Value value)
190//   {
191//     //Not implemented, obsolete
192//   }
193 
194//   void LpCplex::_setRowUpperBound(int i, Value value)
195//   {
196//     //Not implemented, obsolete
197// //     //TODO Ezt kell meg megirni
198// //     //type of the problem
199// //     char sense[1];
200// //     status = CPXgetsense(env, lp, sense, i, i);
201// //     Value rhs[1];
202// //     status = CPXgetrhs(env, lp, rhs, i, i);
203
204// //     switch (sense[0]) {
205// //     case 'L'://<= constraint
206// //       break;
207// //     case 'E'://= constraint
208// //       break;
209// //     case 'G'://>= constraint
210// //       break;
211// //     case 'R'://ranged constraint
212// //       break;
213// //     default: ;
214// //       //FIXME error
215// //     }
216
217// //     status = CPXchgcoef(env, lp, i, -2, value_rng);
218//   }
219 
220  void LpCplex::_setObjCoeff(int i, Value obj_coef)
221  {
222    CPXchgcoef(env, lp, -1, i, obj_coef);
223  }
224
225  void LpCplex::_clearObj()
226  {
227    for (int i=0;i< CPXgetnumcols(env, lp);++i){
228      CPXchgcoef(env, lp, -1, i, 0);
229    }
230   
231  }
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()
242  {
243    //CPX_PARAM_LPMETHOD
244    status = CPXlpopt(env, lp);
245    if (status == 0){
246      //We want to exclude some cases
247      switch (CPXgetstat(env, lp)){
248      case CPX_OBJ_LIM:
249      case CPX_IT_LIM_FEAS:
250      case CPX_IT_LIM_INFEAS:               
251      case CPX_TIME_LIM_FEAS:
252      case CPX_TIME_LIM_INFEAS:
253        return UNSOLVED;
254      default:
255        return SOLVED;
256      }
257    }
258    else{
259      return UNSOLVED;
260    }
261  }
262
263  LpCplex::Value LpCplex::_getPrimal(int i)
264  {
265    Value x;
266    CPXgetx(env, lp, &x, i, i);
267    return x;
268  }
269 
270  LpCplex::Value LpCplex::_getPrimalValue()
271  {
272    Value objval;
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);
277    return objval;
278  }
279 
280
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.
283
284// For Simplex, Barrier 
285// 1    CPX_OPTIMAL 
286//       Optimal solution found 
287// 2    CPX_INFEASIBLE 
288//       Problem infeasible 
289// 3    CPX_UNBOUNDED 
290//       Problem unbounded 
291// 4    CPX_OBJ_LIM 
292//       Objective limit exceeded in Phase II 
293// 5    CPX_IT_LIM_FEAS 
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 
307// 12   CPX_ABORT_FEAS 
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 
321// 19   CPX_INForUNBD 
322//       Infeasible or unbounded 
323// 20   CPX_PIVOT
324//       User pivot used
325//
326//     Ezeket hova tegyem:
327// ??case CPX_ABORT_DUAL_INFEAS           
328// ??case CPX_ABORT_CROSSOVER             
329// ??case CPX_INForUNBD                   
330// ??case CPX_PIVOT                       
331
332  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
333  {
334    int stat = CPXgetstat(env, lp);
335    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
336    switch (stat) {
337    case 0:
338      return UNDEFINED; //Undefined
339    case CPX_OPTIMAL://Optimal
340      return OPTIMAL;
341    case CPX_UNBOUNDED://Unbounded
342      return INFINITE;
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:     
351      return INFEASIBLE;
352//     case CPX_OBJ_LIM:                   
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:       
358//       return FEASIBLE;
359    default:
360      return UNDEFINED; //Everything else comes here
361      //FIXME error
362    }
363
364  }
365
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
376// CPX_STAT_NUM_BEST
377// CPX_STAT_OPTIMAL
378// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
379// CPX_STAT_OPTIMAL_INFEAS
380// CPX_STAT_OPTIMAL_RELAXED
381// CPX_STAT_UNBOUNDED
382
383  LpCplex::SolutionStatus LpCplex::_getDualStatus()
384  {
385    int stat = CPXgetstat(env, lp);
386    switch (stat) {
387    case 0:
388      return UNDEFINED; //Undefined
389    case CPX_OPTIMAL://Optimal
390      return OPTIMAL;
391    case CPX_UNBOUNDED:
392     return INFEASIBLE;
393    default:
394      return UNDEFINED; //Everything else comes here
395      //FIXME error
396    }
397  }
398
399  LpCplex::ProblemTypes LpCplex::_getProblemType()
400  {
401    int stat = CPXgetstat(env, lp);
402    switch (stat) {
403    case CPX_OPTIMAL://Optimal
404        return PRIMAL_DUAL_FEASIBLE;
405    case CPX_UNBOUNDED:
406        return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
407//      return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
408//      return PRIMAL_DUAL_INFEASIBLE;
409
410//Seems to be that this is all we can say for sure
411    default:
412        //In all other cases
413        return UNKNOWN;
414      //FIXME error
415    }
416  }
417
418  void LpCplex::_setMax()
419  {
420    CPXchgobjsen(env, lp, CPX_MAX);
421   }
422  void LpCplex::_setMin()
423  {
424    CPXchgobjsen(env, lp, CPX_MIN);
425   }
426 
427} //namespace lemon
428
Note: See TracBrowser for help on using the repository browser.