lemon/mip_glpk.cc
author kpeter
Fri, 29 Feb 2008 15:55:13 +0000
changeset 2586 37fb2c384c78
parent 2458 93b4132ac1e8
permissions -rw-r--r--
Reimplemented Suurballe class.

- The new version is the specialized version of CapacityScaling.
- It is about 10-20 times faster than the former Suurballe algorithm
and about 20-50 percent faster than CapacityScaling.
- Doc improvements.
- The test file is also replaced.
athos@2144
     1
/* -*- C++ -*-
athos@2144
     2
 *
athos@2144
     3
 * This file is a part of LEMON, a generic C++ optimization library
athos@2144
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
athos@2144
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
athos@2144
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
athos@2144
     8
 *
athos@2144
     9
 * Permission to use, modify and distribute this software is granted
athos@2144
    10
 * provided that this copyright notice appears in all copies. For
athos@2144
    11
 * precise terms see the accompanying LICENSE file.
athos@2144
    12
 *
athos@2144
    13
 * This software is provided "AS IS" with no warranty of any kind,
athos@2144
    14
 * express or implied, and with no claim as to its suitability for any
athos@2144
    15
 * purpose.
athos@2144
    16
 *
athos@2144
    17
 */
athos@2144
    18
athos@2144
    19
///\file
athos@2218
    20
///\brief Implementation of the LEMON-GLPK mip solver interface.
athos@2144
    21
athos@2144
    22
#include <lemon/mip_glpk.h>
athos@2144
    23
deba@2441
    24
#if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15)
deba@2441
    25
#define LEMON_glp(func) (glp_##func)
deba@2441
    26
#define LEMON_lpx(func) (lpx_##func)
deba@2441
    27
deba@2441
    28
#define LEMON_GLP(def) (GLP_##def)
deba@2441
    29
#define LEMON_LPX(def) (LPX_##def)
deba@2441
    30
deba@2441
    31
#else
deba@2441
    32
deba@2441
    33
#define LEMON_glp(func) (lpx_##func)
deba@2441
    34
#define LEMON_lpx(func) (lpx_##func)
deba@2441
    35
deba@2441
    36
#define LEMON_GLP(def) (LPX_##def)
deba@2441
    37
#define LEMON_LPX(def) (LPX_##def)
deba@2441
    38
deba@2441
    39
#endif
deba@2441
    40
athos@2144
    41
namespace lemon {
athos@2144
    42
  
athos@2144
    43
  MipGlpk::MipGlpk() {
deba@2441
    44
#if !(GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15))
deba@2441
    45
    LEMON_lpx(set_class)(lp,LEMON_GLP(MIP));
deba@2441
    46
#endif
athos@2144
    47
  }
athos@2148
    48
athos@2149
    49
  void MipGlpk::_colType(int i, MipGlpk::ColTypes col_type){
athos@2148
    50
    switch (col_type){
athos@2267
    51
      case INT:
deba@2441
    52
	LEMON_glp(set_col_kind)(lp,i,LEMON_GLP(IV));
athos@2148
    53
	break;
athos@2148
    54
      case REAL:
deba@2441
    55
	LEMON_glp(set_col_kind)(lp,i,LEMON_GLP(CV));
athos@2148
    56
	break;
athos@2149
    57
    default:;
athos@2148
    58
        //FIXME problem
athos@2144
    59
    }
athos@2144
    60
  }
athos@2144
    61
  
deba@2366
    62
  MipGlpk::ColTypes MipGlpk::_colType(int i) const {
deba@2441
    63
    switch (LEMON_glp(get_col_kind)(lp,i)){
deba@2441
    64
    case LEMON_GLP(IV):
athos@2267
    65
      return INT;//Or binary
deba@2441
    66
    case LEMON_GLP(CV):
athos@2148
    67
      return REAL;
athos@2148
    68
    default:
athos@2148
    69
      return REAL;//Error!
athos@2144
    70
    }
athos@2148
    71
    
athos@2144
    72
  }
athos@2144
    73
  
deba@2366
    74
  LpGlpk::SolveExitStatus MipGlpk::_solve() {
deba@2441
    75
    int result = LEMON_lpx(simplex)(lp);
deba@2441
    76
deba@2441
    77
    // hack: mip does not contain integer variable 
deba@2458
    78
#if GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION == 16
deba@2441
    79
    int tmp = -1;
deba@2441
    80
    if (LEMON_glp(get_num_int(lp)) == 0) {
deba@2441
    81
      tmp = LEMON_lpx(add_cols)(lp, 1);
deba@2441
    82
      LEMON_glp(set_col_bnds)(lp, tmp, LEMON_GLP(FX), 0.0, 0.0);
deba@2441
    83
      LEMON_glp(set_col_kind)(lp, tmp, LEMON_GLP(IV));
deba@2441
    84
    }
deba@2441
    85
#endif
deba@2441
    86
deba@2441
    87
    if (LEMON_lpx(get_status)(lp)==LEMON_LPX(OPT)) {
athos@2213
    88
      //Maybe we could try the routine lpx_intopt(lp), a revised
athos@2213
    89
      //version of lpx_integer
deba@2441
    90
deba@2441
    91
      result = LEMON_lpx(integer)(lp);
athos@2213
    92
      switch (result){
deba@2441
    93
      case LEMON_LPX(E_OK):
deba@2441
    94
	solved = true;
deba@2442
    95
	break;
athos@2144
    96
      default:
deba@2441
    97
	solved = false;
deba@2441
    98
      }  
deba@2441
    99
    } else {
deba@2441
   100
      solved = false;
athos@2144
   101
    }
deba@2458
   102
#if GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION == 16
deba@2441
   103
    if (tmp != -1) {
deba@2441
   104
      int tmpa[2];
deba@2441
   105
      tmpa[1] = tmp;
deba@2441
   106
      LEMON_lpx(del_cols)(lp, 1, tmpa);
deba@2441
   107
    }
deba@2441
   108
#endif
deba@2441
   109
    return solved ? SOLVED : UNSOLVED;
athos@2144
   110
  }
athos@2185
   111
athos@2185
   112
deba@2366
   113
  LpGlpk::SolutionStatus MipGlpk::_getMipStatus() const {
athos@2185
   114
deba@2441
   115
    if (LEMON_lpx(get_status)(lp)==LEMON_LPX(OPT)){
athos@2213
   116
      //Meg kell nezni: ha az LP is infinite, akkor ez is, ha az is
athos@2213
   117
      //infeasible, akkor ez is, de ez lehet maskepp is infeasible.
deba@2441
   118
      int stat= LEMON_lpx(mip_status)(lp);
athos@2213
   119
      
athos@2213
   120
      switch (stat) {
deba@2441
   121
      case LEMON_LPX(I_UNDEF)://Undefined (no solve has been run yet)
athos@2213
   122
	return UNDEFINED;
deba@2441
   123
      case LEMON_LPX(I_NOFEAS)://There is no feasible integral solution
athos@2213
   124
	return INFEASIBLE;
deba@2441
   125
	//     case LEMON_LPX(UNBND)://Unbounded
athos@2213
   126
	//       return INFINITE;
deba@2441
   127
      case LEMON_LPX(I_FEAS)://Feasible
athos@2213
   128
	return FEASIBLE;
deba@2441
   129
      case LEMON_LPX(I_OPT)://Feasible
athos@2213
   130
	return OPTIMAL;
athos@2213
   131
      default:
deba@2441
   132
	return UNDEFINED; //to avoid gcc warning
athos@2185
   133
      //FIXME error
athos@2213
   134
      }
athos@2185
   135
    }
athos@2213
   136
    else 
athos@2213
   137
      return UNDEFINED; //Maybe we could refine this: what does the LP
athos@2213
   138
			//relaxation look like
athos@2213
   139
      
athos@2185
   140
  }  
athos@2185
   141
deba@2366
   142
  MipGlpk::Value MipGlpk::_getPrimal(int i) const {
deba@2441
   143
    return LEMON_glp(mip_col_val)(lp,i);
athos@2144
   144
  }
athos@2144
   145
  
deba@2366
   146
  MipGlpk::Value MipGlpk::_getPrimalValue() const {
deba@2441
   147
    return LEMON_glp(mip_obj_val)(lp);
athos@2144
   148
  }
athos@2218
   149
} //END OF NAMESPACE LEMON