lemon/mip_glpk.cc
author kpeter
Mon, 18 Feb 2008 03:32:06 +0000
changeset 2575 e866e288cba6
parent 2458 93b4132ac1e8
permissions -rw-r--r--
Major improvements in NetworkSimplex.

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