From f058999766cd126f8237c38fe28086257c903946 Mon Sep 17 00:00:00 2001 From: Christian Diener Date: Thu, 18 Mar 2021 12:11:35 -0700 Subject: [PATCH 1/2] enable more parameters in interface --- src/optlang/glpk_interface.py | 41 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/optlang/glpk_interface.py b/src/optlang/glpk_interface.py index 746a7f4..e16b6d0 100644 --- a/src/optlang/glpk_interface.py +++ b/src/optlang/glpk_interface.py @@ -15,7 +15,7 @@ """ -Interface for the GNU Linear Programming Kit (GLPK) +Interface for the GNU Linear Programming Kit (GLPK). Wraps the GLPK solver by subclassing and extending :class:`Model`, :class:`Variable`, and :class:`Constraint` from :mod:`interface`. @@ -26,7 +26,6 @@ """ import logging -import os import six from optlang.util import inheritdocstring, TemporaryFilename @@ -34,8 +33,6 @@ from optlang import interface from optlang import symbolics -log = logging.getLogger(__name__) - from swiglpk import glp_find_col, glp_get_col_prim, glp_get_col_dual, GLP_CV, GLP_IV, GLP_BV, GLP_UNDEF, GLP_FEAS, \ GLP_INFEAS, GLP_NOFEAS, GLP_OPT, GLP_UNBND, \ glp_set_col_kind, glp_find_row, glp_get_row_prim, glp_get_row_dual, glp_get_obj_val, glp_set_obj_dir, glp_init_smcp, \ @@ -46,10 +43,9 @@ glp_set_col_name, intArray, glp_del_cols, glp_add_rows, glp_set_row_name, doubleArray, glp_write_lp, glp_write_prob, \ glp_set_mat_row, glp_set_col_bnds, glp_set_row_bnds, GLP_FR, GLP_UP, GLP_LO, GLP_FX, GLP_DB, glp_del_rows, \ glp_get_mat_row, glp_get_row_ub, glp_get_row_type, glp_get_row_lb, glp_get_row_name, glp_get_obj_coef, \ - glp_get_obj_dir, glp_scale_prob, GLP_SF_AUTO, glp_get_num_int, glp_get_num_bin, glp_mip_col_val, \ + glp_get_obj_dir, glp_scale_prob, GLP_SF_AUTO, glp_get_num_int, glp_mip_col_val, \ glp_mip_obj_val, glp_mip_status, GLP_ETMLIM, glp_adv_basis, glp_read_lp, glp_mip_row_val, \ - get_col_primals, get_col_duals, get_row_primals, get_row_duals, glp_delete_prob - + get_col_primals, get_col_duals, get_row_primals, get_row_duals _GLPK_STATUS_TO_STATUS = { @@ -71,6 +67,8 @@ [(val, key) for key, val in six.iteritems(_GLPK_VTYPE_TO_VTYPE)] ) +log = logging.getLogger(__name__) + def _glpk_validate_id(name): if name is None: @@ -152,7 +150,6 @@ def name(self, value): glp_set_col_name(self.problem.problem, glp_find_col(self.problem.problem, old_name), str(value)) - @six.add_metaclass(inheritdocstring) class Constraint(interface.Constraint): _INDICATOR_CONSTRAINT_SUPPORT = False @@ -376,7 +373,6 @@ def get_linear_coefficients(self, variables): raise Exception("Can't get coefficients from solver if objective is not in a model") - @six.add_metaclass(inheritdocstring) class Configuration(interface.MathematicalProgrammingConfiguration): def __init__(self, presolve="auto", verbosity=0, timeout=None, *args, **kwargs): @@ -414,7 +410,7 @@ def __setstate__(self, state): def _set_presolve(self, value): self._smcp.presolve = {False: GLP_OFF, True: GLP_ON, "auto": GLP_OFF}[value] - self._iocp.presolve = {False: GLP_OFF, True: GLP_ON, "auto": GLP_OFF}[value] + self._iocp.presolve = {False: GLP_OFF, True: GLP_ON, "auto": GLP_ON}[value] def _set_verbosity(self, value): if value == 0: @@ -453,10 +449,24 @@ def _get_feasibility(self): def _set_feasibility(self, value): return setattr(self._smcp, "tol_bnd", value) + def _get_optimality(self): + return getattr(self._smcp, "tol_dj") + + def _set_optimality(self, value): + return setattr(self._smcp, "tol_dj", value) + + def _get_integrality(self): + return getattr(self._iocp, "tol_int") + + def _set_integrality(self, value): + return setattr(self._iocp, "tol_int", value) + def _tolerance_functions(self): return { - "feasibility": (self._get_feasibility, self._set_feasibility) - } + "feasibility": (self._get_feasibility, self._set_feasibility), + "optimality": (self._get_optimality, self._set_optimality), + "integrality": (self._get_integrality, self._set_integrality) + } @property def presolve(self): @@ -599,14 +609,17 @@ def __setstate__(self, repr_dict): if code != 0: with open(tmp_file_name) as tmp_file: invalid_problem = tmp_file.read() - raise Exception("The GLPK file " + tmp_file_name + " does not seem to contain a valid GLPK problem:\n\n" + invalid_problem) + raise Exception("The GLPK file " + tmp_file_name + + " does not seem to contain a valid GLPK problem:\n\n" + + invalid_problem) self.__init__(problem=problem) self.configuration = Configuration.clone(repr_dict['config'], problem=self) if repr_dict['glpk_status'] == 'optimal': self.optimize() # since the start is an optimal solution, nothing will happen here # def __del__(self): # To make sure that the glpk problem is deleted when this is garbage collected - # Gotcha: When objects with a __del__ method are part of a referencing cycle, the entire cycle is never automatically garbage collected + # Gotcha: When objects with a __del__ method are part of a referencing cycle, the entire + # cycle is never automatically garbage collected # glp_delete_prob(self.problem) @property From a53e26fb0de30ef3fbab1b5453f023f099d75a9e Mon Sep 17 00:00:00 2001 From: Christian Diener Date: Thu, 18 Mar 2021 13:33:03 -0700 Subject: [PATCH 2/2] remove optimality --- src/optlang/glpk_interface.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/optlang/glpk_interface.py b/src/optlang/glpk_interface.py index e16b6d0..83c730d 100644 --- a/src/optlang/glpk_interface.py +++ b/src/optlang/glpk_interface.py @@ -449,12 +449,6 @@ def _get_feasibility(self): def _set_feasibility(self, value): return setattr(self._smcp, "tol_bnd", value) - def _get_optimality(self): - return getattr(self._smcp, "tol_dj") - - def _set_optimality(self, value): - return setattr(self._smcp, "tol_dj", value) - def _get_integrality(self): return getattr(self._iocp, "tol_int") @@ -464,7 +458,6 @@ def _set_integrality(self, value): def _tolerance_functions(self): return { "feasibility": (self._get_feasibility, self._set_feasibility), - "optimality": (self._get_optimality, self._set_optimality), "integrality": (self._get_integrality, self._set_integrality) }