COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/lp_cplex.cc @ 1459:2ee881cf30a8

Last change on this file since 1459:2ee881cf30a8 was 1458:7a483c1d38b5, checked in by athos, 19 years ago

Not ready, but I commit it for simplicity.

File size: 10.4 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
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.
266
267// For Simplex, Barrier 
268// 1    CPX_OPTIMAL 
269//       Optimal solution found 
270// 2    CPX_INFEASIBLE 
271//       Problem infeasible 
272// 3    CPX_UNBOUNDED 
273//       Problem unbounded 
274// 4    CPX_OBJ_LIM 
275//       Objective limit exceeded in Phase II 
276// 5    CPX_IT_LIM_FEAS 
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 
290// 12   CPX_ABORT_FEAS 
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 
304// 19   CPX_INForUNBD 
305//       Infeasible or unbounded 
306// 20   CPX_PIVOT
307//       User pivot used
308//
309//     Ezeket hova tegyem:
310// ??case CPX_ABORT_DUAL_INFEAS           
311// ??case CPX_ABORT_CROSSOVER             
312// ??case CPX_INForUNBD                   
313// ??case CPX_PIVOT                       
314
315  LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
316  {
317    int stat = CPXgetstat (env, lp);
318    switch (stat) {
319    case 0:
320      return UNDEFINED; //Undefined
321    case CPX_OPTIMAL://Optimal
322      return OPTIMAL;
323    case CPX_UNBOUNDED://Unbounded
324      return INFINITE;
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:     
333      return INFEASIBLE;
334//     case CPX_OBJ_LIM:                   
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:       
340//       return FEASIBLE;
341    default:
342      return UNDEFINED; //Everything else comes here
343      //FIXME error
344    }
345
346  }
347
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
358// CPX_STAT_NUM_BEST
359// CPX_STAT_OPTIMAL
360// CPX_STAT_OPTIMAL_FACE_UNBOUNDED
361// CPX_STAT_OPTIMAL_INFEAS
362// CPX_STAT_OPTIMAL_RELAXED
363// CPX_STAT_UNBOUNDED
364
365  LpCplex::SolutionStatus LpCplex::_getDualStatus()
366  {
367    int stat = CPXgetstat (env, lp);
368    switch (stat) {
369    case 0:
370      return UNDEFINED; //Undefined
371    case CPX_OPTIMAL://Optimal
372      return OPTIMAL;
373    case CPX_UNBOUNDED:
374     return INFEASIBLE;
375    default:
376      return UNDEFINED; //Everything else comes here
377      //FIXME error
378    }
379
380  LpCplex::Value LpCplex::_getPrimal(int i)
381  {
382    Value x;
383    CPXgetx (env, lp, &x, i, i);
384    return x;
385  }
386 
387  LpCplex::Value LpCplex::_getPrimalValue()
388  {
389    Value objval;
390    //method = CPXgetmethod (env, lp);
391    status = CPXgetobjval (env, lp, &objval);
392    return objval;
393  }
394 
395 
396
397
398  void LpCplex::_setMax()
399  {
400    CPXchgobjsen (env, lp, CPX_MAX);
401   }
402  void LpCplex::_setMin()
403  {
404    CPXchgobjsen (env, lp, CPX_MIN);
405   }
406 
407} //namespace lemon
408
Note: See TracBrowser for help on using the repository browser.