def test_construct_with_sloppy(self): x, y, z, w = self.model.variables[:4] obj = self.interface.Objective( symbolics.add([symbolics.mul((symbolics.One, var)) for var in [x, y, z]]), direction="min", sloppy=True ) self.model.objective = obj self.assertTrue(obj.get_linear_coefficients([x, y, z, w]) == {x: 1, y: 1, z: 1, w: 0})
def _get_expression(self): if self.problem is not None: variables = self.problem._variables all_coefs = self.problem.problem.constraint_coefs coefs = [(v, all_coefs.get((self.name, v.name), 0.0)) for v in variables] expression = add( [mul((symbolics.Real(co), v)) for (v, co) in coefs]) self._expression = expression return self._expression
def test_construct_with_sloppy(self): x, y, z, w = self.model.variables[:4] const = self.interface.Constraint( symbolics.add([symbolics.mul(symbolics.One, var) for var in [x, y, z]]), lb=0, sloppy=True ) self.model.add(const) self.model.update() self.assertTrue(const.get_linear_coefficients([x, y, z, w]) == {x: 1, y: 1, z: 1, w: 0})
def _get_expression(self): if self.problem is not None: cplex_problem = self.problem.problem cplex_row = cplex_problem.linear_constraints.get_rows(self.name) variables = self.problem._variables expression = add([ mul((symbolics.Real(cplex_row.val[i]), variables[ind])) for i, ind in enumerate(cplex_row.ind) ]) 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 = 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 and self._expression_expired: variables = self.problem._variables def term_generator(): for index in range(1, glp_get_num_cols(self.problem.problem) + 1): coeff = glp_get_obj_coef(self.problem.problem, index) if coeff != 0.: yield (symbolics.Real(coeff), variables[index - 1]) expression = symbolics.add([symbolics.mul(term) for term in term_generator()]) self._expression = expression + getattr(self.problem, "_objective_offset", 0) self._expression_expired = False return self._expression
def _get_expression(self): if self.problem is not None: gurobi_problem = self.problem.problem gurobi_constraint = self._internal_constraint row = gurobi_problem.getRow(gurobi_constraint) terms = [] for i in range(row.size()): internal_var_name = row.getVar(i).VarName if internal_var_name == self.name + '_aux': continue variable = self.problem._variables[internal_var_name] coeff = symbolics.Real(row.getCoeff(i)) terms.append(symbolics.mul((coeff, variable))) self._expression = symbolics.add(terms) return self._expression
def _get_expression(self): if self.problem is not None: cplex_problem = self.problem.problem try: cplex_row = cplex_problem.linear_constraints.get_rows(self.name) except CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: cplex_row = cplex_problem.indicator_constraints.get_linear_components(self.name) variables = self.problem._variables expression = add( [mul((symbolics.Real(cplex_row.val[i]), variables[ind])) for i, ind in enumerate(cplex_row.ind)]) self._expression = expression return self._expression
def parse_expr(expr, local_dict=None): """ Parses a json-object created with 'expr_to_json' into a Sympy expression. If a local_dict argument is passed, symbols with be looked up by name, and a new symbol will be created only if the name is not in local_dict. """ if local_dict is None: local_dict = {} if expr["type"] == "Add": return add([parse_expr(arg, local_dict) for arg in expr["args"]]) elif expr["type"] == "Mul": return mul([parse_expr(arg, local_dict) for arg in expr["args"]]) elif expr["type"] == "Pow": return Pow(parse_expr(arg, local_dict) for arg in expr["args"]) elif expr["type"] == "Symbol": try: return local_dict[expr["name"]] except KeyError: return symbolics.Symbol(expr["name"]) elif expr["type"] == "Number": return symbolics.sympify(expr["value"]) else: raise NotImplementedError(expr["type"] + " is not implemented")
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 __init__(self, problem=None, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) if problem is None: self.problem = cplex.Cplex() elif isinstance(problem, cplex.Cplex): self.problem = problem zipped_var_args = zip(self.problem.variables.get_names(), self.problem.variables.get_lower_bounds(), self.problem.variables.get_upper_bounds(), # self.problem.variables.get_types(), # TODO uncomment when cplex is fixed ) for name, lb, ub in zipped_var_args: var = Variable(name, lb=lb, ub=ub, problem=self) # Type should also be in there super(Model, self)._add_variables([var]) # This avoids adding the variable to the glpk problem zipped_constr_args = zip(self.problem.linear_constraints.get_names(), self.problem.linear_constraints.get_rows(), self.problem.linear_constraints.get_senses(), self.problem.linear_constraints.get_rhs() ) variables = self._variables for name, row, sense, rhs in zipped_constr_args: constraint_variables = [variables[i - 1] for i in row.ind] # Since constraint expressions are lazily retrieved from the solver they don't have to be built here # lhs = _unevaluated_Add(*[val * variables[i - 1] for i, val in zip(row.ind, row.val)]) lhs = symbolics.Integer(0) if sense == 'E': constr = Constraint(lhs, lb=rhs, ub=rhs, name=name, problem=self) elif sense == 'G': constr = Constraint(lhs, lb=rhs, name=name, problem=self) elif sense == 'L': constr = Constraint(lhs, ub=rhs, name=name, problem=self) elif sense == 'R': range_val = self.problem.linear_constraints.get_range_values(name) if range_val > 0: constr = Constraint(lhs, lb=rhs, ub=rhs + range_val, name=name, problem=self) else: constr = Constraint(lhs, lb=rhs + range_val, ub=rhs, name=name, problem=self) else: # pragma: no cover raise Exception('%s is not a recognized constraint sense.' % sense) for variable in constraint_variables: try: self._variables_to_constraints_mapping[variable.name].add(name) except KeyError: self._variables_to_constraints_mapping[variable.name] = set([name]) super(Model, self)._add_constraints( [constr], sloppy=True ) try: objective_name = self.problem.objective.get_name() except CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: linear_expression = add( [mul(symbolics.Real(coeff), variables[index]) for index, coeff in enumerate(self.problem.objective.get_linear()) if coeff != 0.] ) try: quadratic = self.problem.objective.get_quadratic() except IndexError: quadratic_expression = Zero else: quadratic_expression = self._get_quadratic_expression(quadratic) self._objective = Objective( linear_expression + quadratic_expression, problem=self, direction= {self.problem.objective.sense.minimize: 'min', self.problem.objective.sense.maximize: 'max'}[ self.problem.objective.get_sense()], name=objective_name ) else: raise TypeError("Provided problem is not a valid CPLEX model.") self.configuration = Configuration(problem=self, verbosity=0)
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: _glpk_validate_id(self.name) 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 = 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 __init__(self, problem=None, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) if problem is None: self.problem = cplex.Cplex() elif isinstance(problem, cplex.Cplex): self.problem = problem zipped_var_args = zip( self.problem.variables.get_names(), self.problem.variables.get_lower_bounds(), self.problem.variables.get_upper_bounds(), # self.problem.variables.get_types(), # TODO uncomment when cplex is fixed ) for name, lb, ub in zipped_var_args: var = Variable(name, lb=lb, ub=ub, problem=self) # Type should also be in there super(Model, self)._add_variables([ var ]) # This avoids adding the variable to the glpk problem zipped_constr_args = zip( self.problem.linear_constraints.get_names(), self.problem.linear_constraints.get_rows(), self.problem.linear_constraints.get_senses(), self.problem.linear_constraints.get_rhs()) variables = self._variables for name, row, sense, rhs in zipped_constr_args: constraint_variables = [variables[i - 1] for i in row.ind] # Since constraint expressions are lazily retrieved from the solver they don't have to be built here # lhs = _unevaluated_Add(*[val * variables[i - 1] for i, val in zip(row.ind, row.val)]) lhs = symbolics.Integer(0) if sense == 'E': constr = Constraint(lhs, lb=rhs, ub=rhs, name=name, problem=self) elif sense == 'G': constr = Constraint(lhs, lb=rhs, name=name, problem=self) elif sense == 'L': constr = Constraint(lhs, ub=rhs, name=name, problem=self) elif sense == 'R': range_val = self.problem.linear_constraints.get_range_values( name) if range_val > 0: constr = Constraint(lhs, lb=rhs, ub=rhs + range_val, name=name, problem=self) else: constr = Constraint(lhs, lb=rhs + range_val, ub=rhs, name=name, problem=self) else: # pragma: no cover raise Exception( '%s is not a recognized constraint sense.' % sense) for variable in constraint_variables: try: self._variables_to_constraints_mapping[ variable.name].add(name) except KeyError: self._variables_to_constraints_mapping[ variable.name] = set([name]) super(Model, self)._add_constraints([constr], sloppy=True) try: objective_name = self.problem.objective.get_name() except CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: linear_expression = add([ mul(symbolics.Real(coeff), variables[index]) for index, coeff in enumerate(self.problem.objective.get_linear()) if coeff != 0. ]) try: quadratic = self.problem.objective.get_quadratic() except IndexError: quadratic_expression = Zero else: quadratic_expression = self._get_quadratic_expression( quadratic) self._objective = Objective( linear_expression + quadratic_expression, problem=self, direction={ self.problem.objective.sense.minimize: 'min', self.problem.objective.sense.maximize: 'max' }[self.problem.objective.get_sense()], name=objective_name) else: raise TypeError("Provided problem is not a valid CPLEX model.") self.configuration = Configuration(problem=self, verbosity=0)