def get_row(self, row): '''get a row of the LP matrix as a csr_matrix ''' lp_rows = self.get_num_rows() lp_cols = self.get_num_cols() assert 0 <= row < lp_rows inds_row = glpk.intArray(lp_cols + 1) vals_row = glpk.doubleArray(lp_cols + 1) got_len = glpk.glp_get_mat_row(self.lp, row+1, inds_row, vals_row) data = np.zeros((got_len,), dtype=float) inds = np.zeros((got_len,), dtype=np.int32) data_index = 0 for i in range(1, got_len + 1): data[data_index] = vals_row[i] inds[data_index] = inds_row[i] - 1 data_index += 1 indptr = [0, data_index] csr_mat = csr_matrix((data, inds, indptr), shape=(1, lp_cols), dtype=float) csr_mat.check_format() return csr_mat
def set_linear_coefficients(self, coefficients): if self.problem is not None: problem = self.problem.problem self.problem.update() num_cols = glp_get_num_cols(problem) ia = intArray(num_cols + 1) va = doubleArray(num_cols + 1) num_rows = glp_get_mat_row(self.problem.problem, self._index, ia, va) variables_and_coefficients = {var.name: coeff for var, coeff in six.iteritems(coefficients)} final_variables_and_coefficients = { glp_get_col_name(problem, ia[i]): va[i] for i in range(1, num_rows + 1) } final_variables_and_coefficients.update(variables_and_coefficients) ia = intArray(num_cols + 1) va = doubleArray(num_cols + 1) for i, (name, coeff) in enumerate(six.iteritems(final_variables_and_coefficients)): ia[i + 1] = self.problem._variables[name]._index va[i + 1] = float(coeff) glp_set_mat_row(problem, self._index, len(final_variables_and_coefficients), ia, va) else: raise Exception("Can't change coefficients if constraint is not associated with a model.")
def set_linear_coefficients(self, coefficients): if self.problem is not None: problem = self.problem.problem num_cols = glp_get_num_cols(problem) ia = intArray(num_cols + 1) va = doubleArray(num_cols + 1) num_rows = glp_get_mat_row(self.problem.problem, self._index, ia, va) variables_and_coefficients = {var.name: coeff for var, coeff in six.iteritems(coefficients)} final_variables_and_coefficients = { glp_get_col_name(problem, ia[i]): va[i] for i in range(1, num_rows + 1) } final_variables_and_coefficients.update(variables_and_coefficients) ia = intArray(num_cols + 1) va = doubleArray(num_cols + 1) for i, (name, coeff) in enumerate(six.iteritems(final_variables_and_coefficients)): ia[i + 1] = self.problem._variables[name]._index va[i + 1] = coeff glp_set_mat_row(problem, self._index, len(final_variables_and_coefficients), ia, va) else: raise Exception("Can't change coefficients if constraint is not associated with a model.")
def get_constraints_csr(self): '''get the LP matrix as a csr_matrix ''' lp_rows = self.get_num_rows() lp_cols = self.get_num_cols() nnz = glpk.glp_get_num_nz(self.lp) data = np.zeros((nnz, ), dtype=float) inds = np.zeros((nnz, ), dtype=np.int32) indptr = np.zeros((lp_rows + 1, ), dtype=np.int32) inds_row = SwigArray.get_int_array(lp_cols + 1) vals_row = SwigArray.get_double_array(lp_cols + 1) data_index = 0 indptr[0] = 0 for row in range(1, lp_rows + 1): got_len = glpk.glp_get_mat_row(self.lp, row, inds_row, vals_row) for i in range(1, got_len + 1): data[data_index] = vals_row[i] inds[data_index] = inds_row[i] - 1 data_index += 1 indptr[row] = data_index csr_mat = csr_matrix((data, inds, indptr), shape=(lp_rows, lp_cols), dtype=float) csr_mat.check_format() return csr_mat
def test_set_linear_coefficients_constraint(self): constraint = self.model.constraints.M_atp_c constraint.set_linear_coefficients({self.model.variables.R_Biomass_Ecoli_core_w_GAM: 666.}) num_cols = glp_get_num_cols(self.model.problem) ia = intArray(num_cols + 1) da = doubleArray(num_cols + 1) index = constraint._index num = glp_get_mat_row(self.model.problem, index, ia, da) for i in range(1, num + 1): col_name = glp_get_col_name(self.model.problem, ia[i]) if col_name == 'R_Biomass_Ecoli_core_w_GAM': self.assertEqual(da[i], 666.)
def _get_expression(self): if self.problem is not None: col_num = glp_get_num_cols(self.problem.problem) ia = intArray(col_num + 1) da = doubleArray(col_num + 1) nnz = glp_get_mat_row(self.problem.problem, self._index, ia, da) constraint_variables = [self.problem._variables[glp_get_col_name(self.problem.problem, ia[i])] for i in range(1, nnz + 1)] expression = symbolics.add( [symbolics.mul((symbolics.Real(da[i]), constraint_variables[i - 1])) for i in range(1, nnz + 1)]) self._expression = expression return self._expression
def _get_expression(self): if self.problem is not None: col_num = glp_get_num_cols(self.problem.problem) ia = intArray(col_num + 1) da = doubleArray(col_num + 1) nnz = glp_get_mat_row(self.problem.problem, self.index, ia, da) constraint_variables = [self.problem._variables[glp_get_col_name(self.problem.problem, ia[i])] for i in range(1, nnz + 1)] expression = sympy.Add._from_args( [sympy.Mul._from_args((sympy.RealNumber(da[i]), constraint_variables[i - 1])) for i in range(1, nnz + 1)]) self._expression = expression return self._expression
def test_set_linear_coefficients_constraint(self): constraint = self.model.constraints.M_atp_c constraint.set_linear_coefficients( {self.model.variables.R_Biomass_Ecoli_core_w_GAM: 666.}) num_cols = glp_get_num_cols(self.model.problem) ia = intArray(num_cols + 1) da = doubleArray(num_cols + 1) index = constraint._index num = glp_get_mat_row(self.model.problem, index, ia, da) for i in range(1, num + 1): col_name = glp_get_col_name(self.model.problem, ia[i]) if col_name == 'R_Biomass_Ecoli_core_w_GAM': self.assertEqual(da[i], 666.)
def get_linear_coefficients(self, variables): if self.problem is not None: num_cols = glp_get_num_cols(self.problem.problem) ia = intArray(num_cols + 1) da = doubleArray(num_cols + 1) nnz = glp_get_mat_row(self.problem.problem, self._index, ia, da) return { self.problem._variables[ia[i + 1] - 1]: da[i + 1] for i in range(nnz) } else: raise Exception( "Can't get coefficients from solver if constraint is not in a model" )
def get_linear_coefficients(self, variables): if self.problem is not None: self.problem.update() num_cols = glp_get_num_cols(self.problem.problem) ia = intArray(num_cols + 1) da = doubleArray(num_cols + 1) nnz = glp_get_mat_row(self.problem.problem, self._index, ia, da) coefs = dict.fromkeys(variables, 0.0) coefs.update({ self.problem._variables[ia[i + 1] - 1]: da[i + 1] for i in range(nnz) if self.problem._variables[ia[i + 1] - 1] in variables}) return coefs else: raise Exception("Can't get coefficients from solver if constraint is not in a model")
def _get_expression(self): if self.problem is not None: col_num = glp_get_num_cols(self.problem.problem) ia = intArray(col_num + 1) da = doubleArray(col_num + 1) nnz = glp_get_mat_row(self.problem.problem, self.index, ia, da) constraint_variables = [ self.problem._variables[glp_get_col_name( self.problem.problem, ia[i])] for i in range(1, nnz + 1) ] expression = sympy.Add._from_args([ sympy.Mul._from_args( (sympy.RealNumber(da[i]), constraint_variables[i - 1])) for i in range(1, nnz + 1) ]) self._expression = expression return self._expression
def _constraints_str(self, zero_print): 'get the constraints matrix lines for __str__' rv = "" lp = self.lp rows = self.get_num_rows() cols = self.get_num_cols() stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS"] inds = SwigArray.get_int_array(cols + 1) vals = SwigArray.get_double_array(cols + 1) for row in range(1, rows + 1): stat = glpk.glp_get_row_stat(lp, row) assert 0 <= stat <= len(stat_labels) rv += "{:2}: {} ".format(row, stat_labels[stat]) num_inds = glpk.glp_get_mat_row(lp, row, inds, vals) for col in range(1, cols + 1): val = 0 for index in range(1, num_inds + 1): if inds[index] == col: val = vals[index] break num = str(val) num = num.rjust(6)[:6] # fix width to exactly 6 rv += (zero_print(num) if val == 0 else num) + " " row_type = glpk.glp_get_row_type(lp, row) assert row_type == glpk.GLP_UP val = glpk.glp_get_row_ub(lp, row) rv += " <= " num = str(val) num = num.rjust(6)[:6] # fix width to exactly 6 rv += (zero_print(num) if val == 0 else num) + " " rv += "\n" return rv
def _set_coefficients_low_level(self, variables_coefficients_dict): if self.problem is not None: problem = self.problem.problem indices_coefficients_dict = dict( [(variable.index, coefficient) for variable, coefficient in six.iteritems(variables_coefficients_dict)]) num_cols = glp_get_num_cols(problem) ia = intArray(num_cols + 1) da = doubleArray(num_cols + 1) index = self.index num = glp_get_mat_row(self.problem.problem, index, ia, da) for i in range(1, num + 1): try: da[i] = indices_coefficients_dict[ia[i]] except KeyError: pass glp_set_mat_row(self.problem.problem, index, num, ia, da) else: raise Exception( '_set_coefficients_low_level works only if a constraint is associated with a solver instance.')
def serialize(self): 'serialize self.lp from a glpk instance into a tuple' Timers.tic('serialize') # get constraints as csr matrix lp_rows = self.get_num_rows() lp_cols = self.get_num_cols() inds_row = SwigArray.get_int_array(lp_cols + 1) vals_row = SwigArray.get_double_array(lp_cols + 1) data = [] glpk_indices = [] indptr = [0] for row in range(lp_rows): got_len = glpk.glp_get_mat_row(self.lp, row + 1, inds_row, vals_row) for i in range(1, got_len + 1): data.append(vals_row[i]) glpk_indices.append(inds_row[i]) indptr.append(len(data)) # rhs rhs = [] for row in range(lp_rows): assert glpk.glp_get_row_type(self.lp, row + 1) == glpk.GLP_UP rhs.append(glpk.glp_get_row_ub(self.lp, row + 1)) col_bounds = self.get_col_bounds() # remember to free lp object before overwriting with tuple glpk.glp_delete_prob(self.lp) self.lp = (data, glpk_indices, indptr, rhs, col_bounds) Timers.toc('serialize')
def get_dense_constraints(self, x, y, w, h): 'get a subconstraint matrix from the lpi as a dense matrix' rv = np.zeros((h, w)) lp_rows = self.get_num_rows() lp_cols = self.get_num_cols() assert x >= 0 and w >= 0 and x + w <= lp_cols, "invalid x range requested" assert y >= 0 and h >= 0 and y + h <= lp_rows, "invalid y range requested" inds_row = glpk.intArray(lp_cols + 1) vals_row = glpk.doubleArray(lp_cols + 1) for row in range(y + 1, y + h + 1): row_offset = row - (y + 1) got_len = glpk.glp_get_mat_row(self.lp, row, inds_row, vals_row) for i in range(1, got_len + 1): if inds_row[i] > x and inds_row[i] <= x + w: col_offset = inds_row[i] - (x + 1) rv[row_offset, col_offset] = vals_row[i] return rv
def test_add_constraints(self): x = self.interface.Variable('x', lb=0, ub=1, type='binary') y = self.interface.Variable('y', lb=-181133.3, ub=12000., type='continuous') z = self.interface.Variable('z', lb=0., ub=10., type='integer') constr1 = self.interface.Constraint(0.3 * x + 0.4 * y + 66. * z, lb=-100, ub=0., name='test') constr2 = self.interface.Constraint(2.333 * x + y + 3.333, ub=100.33, name='test2') constr3 = self.interface.Constraint(2.333 * x + y + z, lb=-300) constr4 = self.interface.Constraint(x, lb=-300, ub=-300) constr5 = self.interface.Constraint(3 * x) self.model.add(constr1) self.model.add(constr2) self.model.add(constr3) self.model.add([constr4, constr5]) self.assertIn(constr1.name, self.model.constraints) self.assertIn(constr2.name, self.model.constraints) self.assertIn(constr3.name, self.model.constraints) self.assertIn(constr4.name, self.model.constraints) self.assertIn(constr5.name, self.model.constraints) # constr1 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr1._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 0.3, 'y': 0.4, 'z': 66.}) self.assertEqual(glp_get_row_type(self.model.problem, constr1._index), GLP_DB) self.assertEqual(glp_get_row_lb(self.model.problem, constr1._index), -100) self.assertEqual(glp_get_row_ub(self.model.problem, constr1._index), 0) # constr2 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr2._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1.}) self.assertEqual(glp_get_row_type(self.model.problem, constr2._index), GLP_UP) self.assertEqual(glp_get_row_lb(self.model.problem, constr2._index), -1.7976931348623157e+308) self.assertEqual(glp_get_row_ub(self.model.problem, constr2._index), 96.997) # constr3 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr3._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1., 'z': 1.}) self.assertEqual(glp_get_row_type(self.model.problem, constr3._index), GLP_LO) self.assertEqual(glp_get_row_lb(self.model.problem, constr3._index), -300) self.assertEqual(glp_get_row_ub(self.model.problem, constr3._index), 1.7976931348623157e+308) # constr4 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr4._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 1}) self.assertEqual(glp_get_row_type(self.model.problem, constr4._index), GLP_FX) self.assertEqual(glp_get_row_lb(self.model.problem, constr4._index), -300) self.assertEqual(glp_get_row_ub(self.model.problem, constr4._index), -300) # constr5 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr5._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 3}) self.assertEqual(glp_get_row_type(self.model.problem, constr5._index), GLP_FR) self.assertLess(glp_get_row_lb(self.model.problem, constr5._index), -1e30) self.assertGreater(glp_get_row_ub(self.model.problem, constr5._index), 1e30)
def test_add_constraints(self): x = Variable('x', lb=0, ub=1, type='binary') y = Variable('y', lb=-181133.3, ub=12000., type='continuous') z = Variable('z', lb=0., ub=10., type='integer') constr1 = Constraint(0.3 * x + 0.4 * y + 66. * z, lb=-100, ub=0., name='test') constr2 = Constraint(2.333 * x + y + 3.333, ub=100.33, name='test2') constr3 = Constraint(2.333 * x + y + z, lb=-300) constr4 = Constraint(x, lb=-300, ub=-300) constr5 = Constraint(3 * x) self.model.add(constr1) self.model.add(constr2) self.model.add(constr3) self.model.add([constr4, constr5]) self.assertIn(constr1.name, self.model.constraints) self.assertIn(constr2.name, self.model.constraints) self.assertIn(constr3.name, self.model.constraints) self.assertIn(constr4.name, self.model.constraints) self.assertIn(constr5.name, self.model.constraints) # constr1 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr1._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 0.3, 'y': 0.4, 'z': 66.}) self.assertEqual(glp_get_row_type(self.model.problem, constr1._index), GLP_DB) self.assertEqual(glp_get_row_lb(self.model.problem, constr1._index), -100) self.assertEqual(glp_get_row_ub(self.model.problem, constr1._index), 0) # constr2 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr2._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1.}) self.assertEqual(glp_get_row_type(self.model.problem, constr2._index), GLP_UP) self.assertEqual(glp_get_row_lb(self.model.problem, constr2._index), -1.7976931348623157e+308) self.assertEqual(glp_get_row_ub(self.model.problem, constr2._index), 96.997) # constr3 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr3._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 2.333, 'y': 1., 'z': 1.}) self.assertEqual(glp_get_row_type(self.model.problem, constr3._index), GLP_LO) self.assertEqual(glp_get_row_lb(self.model.problem, constr3._index), -300) self.assertEqual(glp_get_row_ub(self.model.problem, constr3._index), 1.7976931348623157e+308) # constr4 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr4._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 1}) self.assertEqual(glp_get_row_type(self.model.problem, constr4._index), GLP_FX) self.assertEqual(glp_get_row_lb(self.model.problem, constr4._index), -300) self.assertEqual(glp_get_row_ub(self.model.problem, constr4._index), -300) # constr5 ia = intArray(glp_get_num_rows(self.model.problem) + 1) da = doubleArray(glp_get_num_rows(self.model.problem) + 1) nnz = glp_get_mat_row(self.model.problem, constr5._index, ia, da) coeff_dict = dict() for i in range(1, nnz + 1): coeff_dict[glp_get_col_name(self.model.problem, ia[i])] = da[i] self.assertDictEqual(coeff_dict, {'x': 3}) self.assertEqual(glp_get_row_type(self.model.problem, constr5._index), GLP_FR) self.assertLess(glp_get_row_lb(self.model.problem, constr5._index), -1e30) self.assertGreater(glp_get_row_ub(self.model.problem, constr5._index), 1e30)
def _constraints_str(self, bm_print, input_print, zero_print): 'get the constraints matrix lines for __str__' rv = "" lp = self.lp rows = self.get_num_rows() cols = self.get_num_cols() stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS"] inds = glpk.intArray(cols + 1) vals = glpk.doubleArray(cols + 1) for row in range(1, rows + 1): stat = glpk.glp_get_row_stat(lp, row) assert 0 <= stat <= len(stat_labels) rv += "{:2}: {} ".format(row, stat_labels[stat]) num_inds = glpk.glp_get_mat_row(lp, row, inds, vals) for col in range(1, cols + 1): val = 0 for index in range(1, num_inds + 1): if inds[index] == col: val = vals[index] break num = str(val) if len(num) < 6: num = (" " * (6 - len(num))) + num else: num = num[0:6] if self.basis_mat_rect[1] <= row - 1 < self.basis_mat_rect[0] + self.basis_mat_rect[3] and \ self.basis_mat_rect[0] <= col - 1 < self.basis_mat_rect[1] + self.basis_mat_rect[2]: rv += bm_print(num) + " " else: rv += (zero_print(num) if val == 0 else num) + " " row_type = glpk.glp_get_row_type(lp, row) if row_type == glpk.GLP_FX: val = glpk.glp_get_row_ub(lp, row) rv += " == " else: assert row_type == glpk.GLP_UP val = glpk.glp_get_row_ub(lp, row) rv += " <= " num = str(val) if len(num) < 6: num = (" " * (6 - len(num))) + num else: num = num[0:6] rv += (zero_print(num) if val == 0 else num) + " " rv += "\n" return rv
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 _initialize_model_from_problem(self, problem): 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 = symbolics.Integer(lhs) elif isinstance(lhs, float): lhs = symbolics.Real(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( symbolics.add( [symbolics.mul((symbolics.Real(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 _constraints_str(self, bm_print, input_print, zero_print): 'get the constraints matrix lines for __str__' rv = "" lp = self.lp rows = self.get_num_rows() cols = self.get_num_cols() stat_labels = ["?(0)?", "BS", "NL", "NU", "NF", "NS", "?(6)?"] inds = glpk.intArray(cols + 1) vals = glpk.doubleArray(cols + 1) for row in range(1, rows + 1): rv += "{:2}: {} ".format(row-1, stat_labels[glpk.glp_get_row_stat(lp, row)]) num_inds = glpk.glp_get_mat_row(lp, row, inds, vals) for col in range(1, cols + 1): val = 0 for index in range(1, num_inds+1): if inds[index] == col: val = vals[index] break num = str(val) if len(num) < 6: num = (" " * (6 - len(num))) + num else: num = num[0:6] if self.basis_mat_pos[0] <= row - 1 < self.basis_mat_pos[0] + self.dims and \ self.basis_mat_pos[1] <= col - 1 < self.basis_mat_pos[1] + self.dims: rv += bm_print(num) + " " elif self.input_effects_offsets is not None and \ self.input_effects_offsets[0] <= row - 1 < self.input_effects_offsets[0] + self.dims and \ self.input_effects_offsets[1] <= col - 1 < self.input_effects_offsets[1] + self.dims: rv += input_print(num) + " " else: rv += (zero_print(num) if val == 0 else num) + " " row_type = glpk.glp_get_row_type(lp, row) if row_type == glpk.GLP_FX: val = glpk.glp_get_row_ub(lp, row) rv += " == " elif row_type == glpk.GLP_UP: val = glpk.glp_get_row_ub(lp, row) rv += " <= " elif row_type == glpk.GLP_LO: val = glpk.glp_get_row_lb(lp, row) rv += " >= " else: rv += " <?> (unknown bounds)" val = '?' num = str(val) if len(num) < 6: num = (" " * (6 - len(num))) + num else: num = num[0:6] rv += (zero_print(num) if val == 0 else num) + " " rv += "\n" return rv