lemon/cplex.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 576 745e182d0139
child 1063 1782aa72495a
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
alpar@461
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@461
     2
 *
alpar@461
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@461
     4
 *
deba@551
     5
 * Copyright (C) 2003-2009
alpar@461
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@461
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@461
     8
 *
alpar@461
     9
 * Permission to use, modify and distribute this software is granted
alpar@461
    10
 * provided that this copyright notice appears in all copies. For
alpar@461
    11
 * precise terms see the accompanying LICENSE file.
alpar@461
    12
 *
alpar@461
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@461
    14
 * express or implied, and with no claim as to its suitability for any
alpar@461
    15
 * purpose.
alpar@461
    16
 *
alpar@461
    17
 */
alpar@461
    18
alpar@461
    19
#ifndef LEMON_CPLEX_H
alpar@461
    20
#define LEMON_CPLEX_H
alpar@461
    21
alpar@461
    22
///\file
alpar@461
    23
///\brief Header of the LEMON-CPLEX lp solver interface.
alpar@461
    24
alpar@461
    25
#include <lemon/lp_base.h>
alpar@461
    26
alpar@461
    27
struct cpxenv;
alpar@461
    28
struct cpxlp;
alpar@461
    29
alpar@461
    30
namespace lemon {
alpar@461
    31
alpar@461
    32
  /// \brief Reference counted wrapper around cpxenv pointer
alpar@461
    33
  ///
alpar@461
    34
  /// The cplex uses environment object which is responsible for
alpar@461
    35
  /// checking the proper license usage. This class provides a simple
alpar@461
    36
  /// interface for share the environment object between different
alpar@461
    37
  /// problems.
alpar@461
    38
  class CplexEnv {
alpar@461
    39
    friend class CplexBase;
alpar@461
    40
  private:
alpar@461
    41
    cpxenv* _env;
alpar@461
    42
    mutable int* _cnt;
alpar@461
    43
alpar@461
    44
  public:
alpar@461
    45
alpar@461
    46
    /// \brief This exception is thrown when the license check is not
alpar@461
    47
    /// sufficient
alpar@461
    48
    class LicenseError : public Exception {
alpar@461
    49
      friend class CplexEnv;
alpar@461
    50
    private:
alpar@461
    51
alpar@461
    52
      LicenseError(int status);
alpar@461
    53
      char _message[510];
alpar@461
    54
alpar@461
    55
    public:
alpar@461
    56
alpar@461
    57
      /// The short error message
alpar@461
    58
      virtual const char* what() const throw() {
alpar@461
    59
        return _message;
alpar@461
    60
      }
alpar@461
    61
    };
alpar@461
    62
alpar@461
    63
    /// Constructor
alpar@461
    64
    CplexEnv();
alpar@461
    65
    /// Shallow copy constructor
alpar@461
    66
    CplexEnv(const CplexEnv&);
alpar@461
    67
    /// Shallow assignement
alpar@461
    68
    CplexEnv& operator=(const CplexEnv&);
alpar@461
    69
    /// Destructor
alpar@461
    70
    virtual ~CplexEnv();
alpar@461
    71
alpar@461
    72
  protected:
alpar@461
    73
alpar@461
    74
    cpxenv* cplexEnv() { return _env; }
alpar@461
    75
    const cpxenv* cplexEnv() const { return _env; }
alpar@461
    76
  };
alpar@461
    77
alpar@461
    78
  /// \brief Base interface for the CPLEX LP and MIP solver
alpar@461
    79
  ///
alpar@461
    80
  /// This class implements the common interface of the CPLEX LP and
deba@551
    81
  /// MIP solvers.
alpar@461
    82
  /// \ingroup lp_group
alpar@461
    83
  class CplexBase : virtual public LpBase {
alpar@461
    84
  protected:
alpar@461
    85
alpar@461
    86
    CplexEnv _env;
alpar@461
    87
    cpxlp* _prob;
alpar@461
    88
alpar@461
    89
    CplexBase();
alpar@461
    90
    CplexBase(const CplexEnv&);
alpar@461
    91
    CplexBase(const CplexBase &);
alpar@461
    92
    virtual ~CplexBase();
alpar@461
    93
alpar@461
    94
    virtual int _addCol();
alpar@461
    95
    virtual int _addRow();
deba@746
    96
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
alpar@461
    97
alpar@461
    98
    virtual void _eraseCol(int i);
alpar@461
    99
    virtual void _eraseRow(int i);
alpar@461
   100
alpar@461
   101
    virtual void _eraseColId(int i);
alpar@461
   102
    virtual void _eraseRowId(int i);
alpar@461
   103
alpar@461
   104
    virtual void _getColName(int col, std::string& name) const;
alpar@461
   105
    virtual void _setColName(int col, const std::string& name);
alpar@461
   106
    virtual int _colByName(const std::string& name) const;
alpar@461
   107
alpar@461
   108
    virtual void _getRowName(int row, std::string& name) const;
alpar@461
   109
    virtual void _setRowName(int row, const std::string& name);
alpar@461
   110
    virtual int _rowByName(const std::string& name) const;
alpar@461
   111
alpar@461
   112
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
alpar@461
   113
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
alpar@461
   114
alpar@461
   115
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
alpar@461
   116
    virtual void _getColCoeffs(int i, InsertIterator b) const;
alpar@461
   117
alpar@461
   118
    virtual void _setCoeff(int row, int col, Value value);
alpar@461
   119
    virtual Value _getCoeff(int row, int col) const;
alpar@461
   120
alpar@461
   121
    virtual void _setColLowerBound(int i, Value value);
alpar@461
   122
    virtual Value _getColLowerBound(int i) const;
alpar@461
   123
alpar@461
   124
    virtual void _setColUpperBound(int i, Value value);
alpar@461
   125
    virtual Value _getColUpperBound(int i) const;
alpar@461
   126
alpar@461
   127
  private:
alpar@461
   128
    void _set_row_bounds(int i, Value lb, Value ub);
alpar@461
   129
  protected:
alpar@461
   130
alpar@461
   131
    virtual void _setRowLowerBound(int i, Value value);
alpar@461
   132
    virtual Value _getRowLowerBound(int i) const;
alpar@461
   133
alpar@461
   134
    virtual void _setRowUpperBound(int i, Value value);
alpar@461
   135
    virtual Value _getRowUpperBound(int i) const;
alpar@461
   136
alpar@461
   137
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
alpar@461
   138
    virtual void _getObjCoeffs(InsertIterator b) const;
alpar@461
   139
alpar@461
   140
    virtual void _setObjCoeff(int i, Value obj_coef);
alpar@461
   141
    virtual Value _getObjCoeff(int i) const;
alpar@461
   142
alpar@461
   143
    virtual void _setSense(Sense sense);
alpar@461
   144
    virtual Sense _getSense() const;
alpar@461
   145
alpar@461
   146
    virtual void _clear();
alpar@461
   147
deba@576
   148
    virtual void _messageLevel(MessageLevel level);
deba@576
   149
    void _applyMessageLevel();
deba@576
   150
deba@576
   151
    bool _message_enabled;
deba@576
   152
alpar@461
   153
  public:
alpar@461
   154
alpar@461
   155
    /// Returns the used \c CplexEnv instance
alpar@461
   156
    const CplexEnv& env() const { return _env; }
deba@576
   157
deba@576
   158
    /// \brief Returns the const cpxenv pointer
alpar@461
   159
    ///
deba@576
   160
    /// \note The cpxenv might be destructed with the solver.
alpar@461
   161
    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
alpar@461
   162
deba@576
   163
    /// \brief Returns the const cpxenv pointer
deba@576
   164
    ///
deba@576
   165
    /// \note The cpxenv might be destructed with the solver.
deba@576
   166
    cpxenv* cplexEnv() { return _env.cplexEnv(); }
deba@576
   167
deba@576
   168
    /// Returns the cplex problem object
alpar@461
   169
    cpxlp* cplexLp() { return _prob; }
deba@576
   170
    /// Returns the cplex problem object
alpar@461
   171
    const cpxlp* cplexLp() const { return _prob; }
alpar@461
   172
alpar@461
   173
  };
alpar@461
   174
alpar@461
   175
  /// \brief Interface for the CPLEX LP solver
alpar@461
   176
  ///
alpar@461
   177
  /// This class implements an interface for the CPLEX LP solver.
alpar@461
   178
  ///\ingroup lp_group
alpar@540
   179
  class CplexLp : public LpSolver, public CplexBase {
alpar@461
   180
  public:
alpar@461
   181
    /// \e
alpar@462
   182
    CplexLp();
alpar@461
   183
    /// \e
alpar@462
   184
    CplexLp(const CplexEnv&);
alpar@461
   185
    /// \e
alpar@462
   186
    CplexLp(const CplexLp&);
alpar@461
   187
    /// \e
alpar@462
   188
    virtual ~CplexLp();
alpar@461
   189
alpar@540
   190
    /// \e
alpar@540
   191
    virtual CplexLp* cloneSolver() const;
alpar@540
   192
    /// \e
alpar@540
   193
    virtual CplexLp* newSolver() const;
alpar@540
   194
alpar@461
   195
  private:
alpar@461
   196
alpar@461
   197
    // these values cannot retrieved element by element
alpar@461
   198
    mutable std::vector<int> _col_status;
alpar@461
   199
    mutable std::vector<int> _row_status;
alpar@461
   200
alpar@461
   201
    mutable std::vector<Value> _primal_ray;
alpar@461
   202
    mutable std::vector<Value> _dual_ray;
alpar@461
   203
alpar@461
   204
    void _clear_temporals();
alpar@461
   205
alpar@461
   206
    SolveExitStatus convertStatus(int status);
alpar@461
   207
alpar@461
   208
  protected:
alpar@461
   209
alpar@461
   210
    virtual const char* _solverName() const;
alpar@461
   211
alpar@461
   212
    virtual SolveExitStatus _solve();
alpar@461
   213
    virtual Value _getPrimal(int i) const;
alpar@461
   214
    virtual Value _getDual(int i) const;
alpar@461
   215
    virtual Value _getPrimalValue() const;
alpar@461
   216
alpar@461
   217
    virtual VarStatus _getColStatus(int i) const;
alpar@461
   218
    virtual VarStatus _getRowStatus(int i) const;
alpar@461
   219
alpar@461
   220
    virtual Value _getPrimalRay(int i) const;
alpar@461
   221
    virtual Value _getDualRay(int i) const;
alpar@461
   222
alpar@461
   223
    virtual ProblemType _getPrimalType() const;
alpar@461
   224
    virtual ProblemType _getDualType() const;
alpar@461
   225
alpar@461
   226
  public:
alpar@461
   227
alpar@461
   228
    /// Solve with primal simplex method
alpar@461
   229
    SolveExitStatus solvePrimal();
alpar@461
   230
alpar@461
   231
    /// Solve with dual simplex method
alpar@461
   232
    SolveExitStatus solveDual();
alpar@461
   233
alpar@461
   234
    /// Solve with barrier method
alpar@461
   235
    SolveExitStatus solveBarrier();
alpar@461
   236
alpar@461
   237
  };
alpar@461
   238
alpar@461
   239
  /// \brief Interface for the CPLEX MIP solver
alpar@461
   240
  ///
alpar@461
   241
  /// This class implements an interface for the CPLEX MIP solver.
alpar@461
   242
  ///\ingroup lp_group
alpar@540
   243
  class CplexMip : public MipSolver, public CplexBase {
alpar@461
   244
  public:
alpar@461
   245
    /// \e
alpar@462
   246
    CplexMip();
alpar@461
   247
    /// \e
alpar@462
   248
    CplexMip(const CplexEnv&);
alpar@461
   249
    /// \e
alpar@462
   250
    CplexMip(const CplexMip&);
alpar@461
   251
    /// \e
alpar@462
   252
    virtual ~CplexMip();
alpar@461
   253
deba@551
   254
    /// \e
deba@551
   255
    virtual CplexMip* cloneSolver() const;
deba@551
   256
    /// \e
deba@551
   257
    virtual CplexMip* newSolver() const;
deba@551
   258
alpar@461
   259
  protected:
alpar@461
   260
alpar@461
   261
alpar@461
   262
    virtual const char* _solverName() const;
alpar@461
   263
alpar@461
   264
    virtual ColTypes _getColType(int col) const;
alpar@461
   265
    virtual void _setColType(int col, ColTypes col_type);
alpar@461
   266
alpar@461
   267
    virtual SolveExitStatus _solve();
alpar@461
   268
    virtual ProblemType _getType() const;
alpar@461
   269
    virtual Value _getSol(int i) const;
alpar@461
   270
    virtual Value _getSolValue() const;
alpar@461
   271
alpar@461
   272
  };
alpar@461
   273
alpar@461
   274
} //END OF NAMESPACE LEMON
alpar@461
   275
alpar@461
   276
#endif //LEMON_CPLEX_H
alpar@461
   277