1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/mip_glpk.cc Tue Dec 02 21:40:33 2008 +0100
1.3 @@ -0,0 +1,154 @@
1.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library.
1.7 + *
1.8 + * Copyright (C) 2003-2008
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +///\file
1.23 +///\brief Implementation of the LEMON-GLPK mip solver interface.
1.24 +
1.25 +#include <lemon/mip_glpk.h>
1.26 +
1.27 +extern "C" {
1.28 +#include <glpk.h>
1.29 +}
1.30 +
1.31 +#if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15)
1.32 +#define LEMON_glp(func) (glp_##func)
1.33 +#define LEMON_lpx(func) (lpx_##func)
1.34 +
1.35 +#define LEMON_GLP(def) (GLP_##def)
1.36 +#define LEMON_LPX(def) (LPX_##def)
1.37 +
1.38 +#else
1.39 +
1.40 +#define LEMON_glp(func) (lpx_##func)
1.41 +#define LEMON_lpx(func) (lpx_##func)
1.42 +
1.43 +#define LEMON_GLP(def) (LPX_##def)
1.44 +#define LEMON_LPX(def) (LPX_##def)
1.45 +
1.46 +#endif
1.47 +
1.48 +namespace lemon {
1.49 +
1.50 + MipGlpk::MipGlpk() {
1.51 +#if !(GLP_MAJOR_VERSION > 4 || \
1.52 + (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15))
1.53 + LEMON_lpx(set_class)(lp,LEMON_GLP(MIP));
1.54 +#endif
1.55 + }
1.56 +
1.57 + void MipGlpk::_colType(int i, MipGlpk::ColTypes col_type){
1.58 + switch (col_type){
1.59 + case INT:
1.60 + LEMON_glp(set_col_kind)(lp,i,LEMON_GLP(IV));
1.61 + break;
1.62 + case REAL:
1.63 + LEMON_glp(set_col_kind)(lp,i,LEMON_GLP(CV));
1.64 + break;
1.65 + default:;
1.66 + //FIXME problem
1.67 + }
1.68 + }
1.69 +
1.70 + MipGlpk::ColTypes MipGlpk::_colType(int i) const {
1.71 + switch (LEMON_glp(get_col_kind)(lp,i)){
1.72 + case LEMON_GLP(IV):
1.73 + return INT;//Or binary
1.74 + case LEMON_GLP(CV):
1.75 + return REAL;
1.76 + default:
1.77 + return REAL;//Error!
1.78 + }
1.79 +
1.80 + }
1.81 +
1.82 + LpGlpk::SolveExitStatus MipGlpk::_solve() {
1.83 + int result = LEMON_lpx(simplex)(lp);
1.84 +
1.85 + // hack: mip does not contain integer variable
1.86 +#if GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION == 16
1.87 + int tmp = -1;
1.88 + if (LEMON_glp(get_num_int(lp)) == 0) {
1.89 + tmp = LEMON_lpx(add_cols)(lp, 1);
1.90 + LEMON_glp(set_col_bnds)(lp, tmp, LEMON_GLP(FX), 0.0, 0.0);
1.91 + LEMON_glp(set_col_kind)(lp, tmp, LEMON_GLP(IV));
1.92 + }
1.93 +#endif
1.94 +
1.95 + if (LEMON_lpx(get_status)(lp)==LEMON_LPX(OPT)) {
1.96 + //Maybe we could try the routine lpx_intopt(lp), a revised
1.97 + //version of lpx_integer
1.98 +
1.99 + result = LEMON_lpx(integer)(lp);
1.100 + switch (result){
1.101 + case LEMON_LPX(E_OK):
1.102 + solved = true;
1.103 + break;
1.104 + default:
1.105 + solved = false;
1.106 + }
1.107 + } else {
1.108 + solved = false;
1.109 + }
1.110 +#if GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION == 16
1.111 + if (tmp != -1) {
1.112 + int tmpa[2];
1.113 + tmpa[1] = tmp;
1.114 + LEMON_lpx(del_cols)(lp, 1, tmpa);
1.115 + }
1.116 +#endif
1.117 + return solved ? SOLVED : UNSOLVED;
1.118 + }
1.119 +
1.120 +
1.121 + LpGlpk::SolutionStatus MipGlpk::_getMipStatus() const {
1.122 +
1.123 + if (LEMON_lpx(get_status)(lp)==LEMON_LPX(OPT)){
1.124 + //Meg kell nezni: ha az LP is infinite, akkor ez is, ha az is
1.125 + //infeasible, akkor ez is, de ez lehet maskepp is infeasible.
1.126 + int stat= LEMON_lpx(mip_status)(lp);
1.127 +
1.128 + switch (stat) {
1.129 + case LEMON_LPX(I_UNDEF)://Undefined (no solve has been run yet)
1.130 + return UNDEFINED;
1.131 + case LEMON_LPX(I_NOFEAS)://There is no feasible integral solution
1.132 + return INFEASIBLE;
1.133 + // case LEMON_LPX(UNBND)://Unbounded
1.134 + // return INFINITE;
1.135 + case LEMON_LPX(I_FEAS)://Feasible
1.136 + return FEASIBLE;
1.137 + case LEMON_LPX(I_OPT)://Feasible
1.138 + return OPTIMAL;
1.139 + default:
1.140 + return UNDEFINED; //to avoid gcc warning
1.141 + //FIXME error
1.142 + }
1.143 + }
1.144 + else
1.145 + return UNDEFINED; //Maybe we could refine this: what does the LP
1.146 + //relaxation look like
1.147 +
1.148 + }
1.149 +
1.150 + MipGlpk::Value MipGlpk::_getPrimal(int i) const {
1.151 + return LEMON_glp(mip_col_val)(lp,i);
1.152 + }
1.153 +
1.154 + MipGlpk::Value MipGlpk::_getPrimalValue() const {
1.155 + return LEMON_glp(mip_obj_val)(lp);
1.156 + }
1.157 +} //END OF NAMESPACE LEMON