def _initialize_problem(self): self.problem = glp_create_prob() glp_create_index(self.problem) glp_scale_prob(self.problem, GLP_SF_AUTO) if self.name is not None: _glpk_validate_id(self.name) glp_set_prob_name(self.problem, str(self.name))
def test_swiglpk(self): """Test the underlying GLPK lib and its SWIG interface based on the example from https://github.com/biosustain/swiglpk """ ia = glp.intArray(1 + 1000) ja = glp.intArray(1 + 1000) ar = glp.doubleArray(1 + 1000) lp = glp.glp_create_prob() smcp = glp.glp_smcp() glp.glp_init_smcp(smcp) smcp.msg_lev = glp.GLP_MSG_ALL # use GLP_MSG_ERR? glp.glp_set_prob_name(lp, "sample") glp.glp_set_obj_dir(lp, glp.GLP_MAX) glp.glp_add_rows(lp, 3) glp.glp_set_row_name(lp, 1, "p") glp.glp_set_row_bnds(lp, 1, glp.GLP_UP, 0.0, 100.0) glp.glp_set_row_name(lp, 2, "q") glp.glp_set_row_bnds(lp, 2, glp.GLP_UP, 0.0, 600.0) glp.glp_set_row_name(lp, 3, "r") glp.glp_set_row_bnds(lp, 3, glp.GLP_UP, 0.0, 300.0) glp.glp_add_cols(lp, 3) glp.glp_set_col_name(lp, 1, "x1") glp.glp_set_col_bnds(lp, 1, glp.GLP_LO, 0.0, 0.0) glp.glp_set_obj_coef(lp, 1, 10.0) glp.glp_set_col_name(lp, 2, "x2") glp.glp_set_col_bnds(lp, 2, glp.GLP_LO, 0.0, 0.0) glp.glp_set_obj_coef(lp, 2, 6.0) glp.glp_set_col_name(lp, 3, "x3") glp.glp_set_col_bnds(lp, 3, glp.GLP_LO, 0.0, 0.0) glp.glp_set_obj_coef(lp, 3, 4.0) ia[1] = 1; ja[1] = 1; ar[1] = 1.0 # a[1,1] = 1 ia[2] = 1; ja[2] = 2; ar[2] = 1.0 # a[1,2] = 1 ia[3] = 1; ja[3] = 3; ar[3] = 1.0 # a[1,3] = 1 ia[4] = 2; ja[4] = 1; ar[4] = 10.0 # a[2,1] = 10 ia[5] = 3; ja[5] = 1; ar[5] = 2.0 # a[3,1] = 2 ia[6] = 2; ja[6] = 2; ar[6] = 4.0 # a[2,2] = 4 ia[7] = 3; ja[7] = 2; ar[7] = 2.0 # a[3,2] = 2 ia[8] = 2; ja[8] = 3; ar[8] = 5.0 # a[2,3] = 5 ia[9] = 3; ja[9] = 3; ar[9] = 6.0 # a[3,3] = 6 glp.glp_load_matrix(lp, 9, ia, ja, ar) glp.glp_simplex(lp, smcp) Z = glp.glp_get_obj_val(lp) x1 = glp.glp_get_col_prim(lp, 1) x2 = glp.glp_get_col_prim(lp, 2) x3 = glp.glp_get_col_prim(lp, 3) self.assertAlmostEqual(Z, 733.3333, 4) self.assertAlmostEqual(x1, 33.3333, 4) self.assertAlmostEqual(x2, 66.6667, 4) self.assertAlmostEqual(x3, 0) glp.glp_delete_prob(lp)
def setup_linprog( recipes: Dict[str, 'Recipe'], min_rates: Optional[Dict[str, float]] = None, min_clocks: Optional[Dict[str, int]] = None, fixed_clocks: Optional[Dict[str, int]] = None, ) -> SwigPyObject: if min_rates is None: min_rates = {} if min_clocks is None: min_clocks = {} if fixed_clocks is None: fixed_clocks = {} resources = sorted({p for r in recipes.values() for p in r.rates.keys()}) resource_indices: Dict[str, int] = {r: i for i, r in enumerate(resources, 1)} m = len(resources) n = len(recipes) problem: SwigPyObject = lp.glp_create_prob() lp.glp_set_prob_name(problem, 'satisfactory') lp.glp_set_obj_name(problem, 'percentage_sum') lp.glp_set_obj_dir(problem, lp.GLP_MIN) lp.glp_add_rows(problem, m) lp.glp_add_cols(problem, n) for i, resource in enumerate(resources, 1): setup_row(problem, i, resource, min_rates.get(resource, 0)) for j, recipe in enumerate(recipes.values(), 1): setup_col( problem, j, recipe, resource_indices, min_clocks.get(recipe.name), fixed_clocks.get(recipe.name), ) lp.glp_create_index(problem) return problem
def __init__(self, problem=None, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) self.configuration = Configuration() if problem is None: self.problem = glp_create_prob() glp_create_index(self.problem) if self.name is not None: glp_set_prob_name(self.problem, str(self.name)) else: try: self.problem = problem glp_create_index(self.problem) except TypeError: raise TypeError("Provided problem is not a valid GLPK model.") row_num = glp_get_num_rows(self.problem) col_num = glp_get_num_cols(self.problem) for i in range(1, col_num + 1): var = Variable(glp_get_col_name(self.problem, i), lb=glp_get_col_lb(self.problem, i), ub=glp_get_col_ub(self.problem, i), problem=self, type=_GLPK_VTYPE_TO_VTYPE[glp_get_col_kind( self.problem, i)]) # This avoids adding the variable to the glpk problem super(Model, self)._add_variables([var]) variables = self.variables for j in range(1, row_num + 1): ia = intArray(col_num + 1) da = doubleArray(col_num + 1) nnz = glp_get_mat_row(self.problem, j, ia, da) constraint_variables = [ variables[ia[i] - 1] for i in range(1, nnz + 1) ] # Since constraint expressions are lazily retrieved from the solver they don't have to be built here # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1] # for i in range(1, nnz + 1)]) lhs = 0 glpk_row_type = glp_get_row_type(self.problem, j) if glpk_row_type == GLP_FX: row_lb = glp_get_row_lb(self.problem, j) row_ub = row_lb elif glpk_row_type == GLP_LO: row_lb = glp_get_row_lb(self.problem, j) row_ub = None elif glpk_row_type == GLP_UP: row_lb = None row_ub = glp_get_row_ub(self.problem, j) elif glpk_row_type == GLP_DB: row_lb = glp_get_row_lb(self.problem, j) row_ub = glp_get_row_ub(self.problem, j) elif glpk_row_type == GLP_FR: row_lb = None row_ub = None else: raise Exception( "Currently, optlang does not support glpk row type %s" % str(glpk_row_type)) log.exception() if isinstance(lhs, int): lhs = sympy.Integer(lhs) elif isinstance(lhs, float): lhs = sympy.RealNumber(lhs) constraint_id = glp_get_row_name(self.problem, j) for variable in constraint_variables: try: self._variables_to_constraints_mapping[ variable.name].add(constraint_id) except KeyError: self._variables_to_constraints_mapping[ variable.name] = set([constraint_id]) super(Model, self)._add_constraints([ Constraint(lhs, lb=row_lb, ub=row_ub, name=constraint_id, problem=self, sloppy=True) ], sloppy=True) term_generator = ((glp_get_obj_coef(self.problem, index), variables[index - 1]) for index in range(1, glp_get_num_cols(problem) + 1)) self._objective = Objective(_unevaluated_Add(*[ _unevaluated_Mul(sympy.RealNumber(term[0]), term[1]) for term in term_generator if term[0] != 0. ]), problem=self, direction={ GLP_MIN: 'min', GLP_MAX: 'max' }[glp_get_obj_dir(self.problem)]) glp_scale_prob(self.problem, GLP_SF_AUTO)
def __init__(self, problem=None, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) self.configuration = Configuration() if problem is None: self.problem = glp_create_prob() glp_create_index(self.problem) if self.name is not None: glp_set_prob_name(self.problem, str(self.name)) else: try: self.problem = problem glp_create_index(self.problem) except TypeError: raise TypeError("Provided problem is not a valid GLPK model.") row_num = glp_get_num_rows(self.problem) col_num = glp_get_num_cols(self.problem) for i in range(1, col_num + 1): var = Variable( glp_get_col_name(self.problem, i), lb=glp_get_col_lb(self.problem, i), ub=glp_get_col_ub(self.problem, i), problem=self, type=_GLPK_VTYPE_TO_VTYPE[ glp_get_col_kind(self.problem, i)] ) # This avoids adding the variable to the glpk problem super(Model, self)._add_variables([var]) variables = self.variables for j in range(1, row_num + 1): ia = intArray(col_num + 1) da = doubleArray(col_num + 1) nnz = glp_get_mat_row(self.problem, j, ia, da) constraint_variables = [variables[ia[i] - 1] for i in range(1, nnz + 1)] # Since constraint expressions are lazily retrieved from the solver they don't have to be built here # lhs = _unevaluated_Add(*[da[i] * constraint_variables[i - 1] # for i in range(1, nnz + 1)]) lhs = 0 glpk_row_type = glp_get_row_type(self.problem, j) if glpk_row_type == GLP_FX: row_lb = glp_get_row_lb(self.problem, j) row_ub = row_lb elif glpk_row_type == GLP_LO: row_lb = glp_get_row_lb(self.problem, j) row_ub = None elif glpk_row_type == GLP_UP: row_lb = None row_ub = glp_get_row_ub(self.problem, j) elif glpk_row_type == GLP_DB: row_lb = glp_get_row_lb(self.problem, j) row_ub = glp_get_row_ub(self.problem, j) elif glpk_row_type == GLP_FR: row_lb = None row_ub = None else: raise Exception( "Currently, optlang does not support glpk row type %s" % str(glpk_row_type) ) log.exception() if isinstance(lhs, int): lhs = sympy.Integer(lhs) elif isinstance(lhs, float): lhs = sympy.RealNumber(lhs) constraint_id = glp_get_row_name(self.problem, j) for variable in constraint_variables: try: self._variables_to_constraints_mapping[variable.name].add(constraint_id) except KeyError: self._variables_to_constraints_mapping[variable.name] = set([constraint_id]) super(Model, self)._add_constraints( [Constraint(lhs, lb=row_lb, ub=row_ub, name=constraint_id, problem=self, sloppy=True)], sloppy=True ) term_generator = ( (glp_get_obj_coef(self.problem, index), variables[index - 1]) for index in range(1, glp_get_num_cols(problem) + 1) ) self._objective = Objective( _unevaluated_Add( *[_unevaluated_Mul(sympy.RealNumber(term[0]), term[1]) for term in term_generator if term[0] != 0.]), problem=self, direction={GLP_MIN: 'min', GLP_MAX: 'max'}[glp_get_obj_dir(self.problem)]) glp_scale_prob(self.problem, GLP_SF_AUTO)