def __init__(self, problem=None, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) if problem is None: self.problem = gurobipy.Model() self.problem.params.OutputFlag = 0 if self.name is not None: self.problem.setAttr('ModelName', self.name) self.problem.update() elif isinstance(problem, gurobipy.Model): self.problem = problem variables = [] for gurobi_variable in self.problem.getVars(): variables.append(Variable( gurobi_variable.getAttr("VarName"), lb=gurobi_variable.getAttr("lb"), ub=gurobi_variable.getAttr("ub"), problem=self, type=_GUROBI_VTYPE_TO_VTYPE[gurobi_variable.getAttr("vType")] )) super(Model, self)._add_variables(variables) constraints = [] for gurobi_constraint in self.problem.getConstrs(): sense = gurobi_constraint.Sense name = gurobi_constraint.getAttr("ConstrName") rhs = gurobi_constraint.RHS row = self.problem.getRow(gurobi_constraint) lhs = _unevaluated_Add( *[sympy.RealNumber(row.getCoeff(i)) * self.variables[row.getVar(i).VarName] for i in range(row.size())]) if sense == '=': constraint = Constraint(lhs, name=name, lb=rhs, ub=rhs, problem=self) elif sense == '>': constraint = Constraint(lhs, name=name, lb=rhs, ub=None, problem=self) elif sense == '<': constraint = Constraint(lhs, name=name, lb=None, ub=rhs, problem=self) else: raise ValueError('{} is not a valid sense'.format(sense)) constraints.append(constraint) super(Model, self)._add_constraints(constraints, sloppy=True) gurobi_objective = self.problem.getObjective() linear_expression = _unevaluated_Add( *[sympy.RealNumber(gurobi_objective.getCoeff(i)) * self.variables[gurobi_objective.getVar(i).VarName] for i in range(gurobi_objective.size())]) self._objective = Objective( linear_expression, problem=self, direction={1: 'min', -1: 'max'}[self.problem.getAttr('ModelSense')] ) else: raise TypeError("Provided problem is not a valid Gurobi model.") self.configuration = Configuration(problem=self, verbosity=0)
def _eval_rewrite_as_Add(self, *args, **kwargs): """return Equation(L, R) as L - R. To control the evaluation of the result set pass `evaluate=True` to give L - R; if `evaluate=None` then terms in L and R will not cancel but they will be listed in canonical order; otherwise non-canonical args will be returned. Examples ======== >>> from sympy import Eq, Add >>> from sympy.abc import b, x >>> eq = Eq(x + b, x - b) >>> eq.rewrite(Add) 2*b >>> eq.rewrite(Add, evaluate=None).args (b, b, x, -x) >>> eq.rewrite(Add, evaluate=False).args (b, x, b, -x) """ L, R = args evaluate = kwargs.get('evaluate', True) if evaluate: # allow cancellation of args return L - R args = Add.make_args(L) + Add.make_args(-R) if evaluate is None: # no cancellation, but canonical return _unevaluated_Add(*args) # no cancellation, not canonical return Add._from_args(args)
def _convert_to_Add(eq, evaluate=True): # Mimic Equality._eval_rewrite_as_Add. args = eq.lhs, eq.rhs L, R = args if evaluate: # allow cancellation of args return L - R args = Add.make_args(L) + Add.make_args(-R) if evaluate is None: # no cancellation, but canonical return _unevaluated_Add(*args) # no cancellation, not canonical return Add._from_args(args)
def quad_expression_getter(self, quadratic=None): if quadratic is None: try: quadratic = self.LP_Problem.Objective_Obj.get_quadratic() except IndexError: return Zero express_terms = [] for i, SparsePair_maker in enumerate(quadratic): for j, val in zip(SparsePair_maker.ind, SparsePair_maker.val): if i < j: express_terms.append(val*self.LP_Vars[i]*self.LP_Vars[j]) elif i == j: express_terms.append(0.5*val*self.LP_Vars[i]**2) else: pass # Only look at upper triangle for solving return _unevaluated_Add(*express_terms)
def _get_quadratic_expression(self, quadratic=None): if quadratic is None: try: quadratic = self.problem.objective.get_quadratic() except IndexError: return Zero terms = [] for i, sparse_pair in enumerate(quadratic): for j, val in zip(sparse_pair.ind, sparse_pair.val): if i < j: terms.append(val * self._variables[i] * self._variables[j]) elif i == j: terms.append(0.5 * val * self._variables[i] ** 2) else: pass # Only look at upper triangle return _unevaluated_Add(*terms)
def _get_quadratic_expression(self, quadratic=None): if quadratic is None: try: quadratic = self.problem.objective.get_quadratic() except IndexError: return Zero terms = [] for i, sparse_pair in enumerate(quadratic): for j, val in zip(sparse_pair.ind, sparse_pair.val): i_name, j_name = self.problem.variables.get_names([i, j]) if i < j: terms.append(val * self._variables[i_name] * self._variables[j_name]) elif i == j: terms.append(0.5 * val * self._variables[i_name] ** 2) else: pass # Only look at upper triangle return _unevaluated_Add(*terms)
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) 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 = 0 if isinstance(lhs, int): lhs = sympy.Integer(lhs) elif isinstance(lhs, float): lhs = sympy.RealNumber(lhs) 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_rhs(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: 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 cplex.exceptions.CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: linear_expression = _unevaluated_Add(*[ _unevaluated_Mul(sympy.RealNumber(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 collect_const(expr, *vars, Numbers=True): """A non-greedy collection of terms with similar number coefficients in an Add expr. If ``vars`` is given then only those constants will be targeted. Although any Number can also be targeted, if this is not desired set ``Numbers=False`` and no Float or Rational will be collected. Parameters ========== expr : sympy expression This parameter defines the expression the expression from which terms with similar coefficients are to be collected. A non-Add expression is returned as it is. vars : variable length collection of Numbers, optional Specifies the constants to target for collection. Can be multiple in number. Numbers : bool Specifies to target all instance of :class:`sympy.core.numbers.Number` class. If ``Numbers=False``, then no Float or Rational will be collected. Returns ======= expr : Expr Returns an expression with similar coefficient terms collected. Examples ======== >>> from sympy import sqrt >>> from sympy.abc import s, x, y, z >>> from sympy.simplify.radsimp import collect_const >>> collect_const(sqrt(3) + sqrt(3)*(1 + sqrt(2))) sqrt(3)*(sqrt(2) + 2) >>> collect_const(sqrt(3)*s + sqrt(7)*s + sqrt(3) + sqrt(7)) (sqrt(3) + sqrt(7))*(s + 1) >>> s = sqrt(2) + 2 >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7)) (sqrt(2) + 3)*(sqrt(3) + sqrt(7)) >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7), sqrt(3)) sqrt(7) + sqrt(3)*(sqrt(2) + 3) + sqrt(7)*(sqrt(2) + 2) The collection is sign-sensitive, giving higher precedence to the unsigned values: >>> collect_const(x - y - z) x - (y + z) >>> collect_const(-y - z) -(y + z) >>> collect_const(2*x - 2*y - 2*z, 2) 2*(x - y - z) >>> collect_const(2*x - 2*y - 2*z, -2) 2*x - 2*(y + z) See Also ======== collect, collect_sqrt, rcollect """ if not expr.is_Add: return expr recurse = False if not vars: recurse = True vars = set() for a in expr.args: for m in Mul.make_args(a): if m.is_number: vars.add(m) else: vars = sympify(vars) if not Numbers: vars = [v for v in vars if not v.is_Number] vars = list(ordered(vars)) for v in vars: terms = defaultdict(list) Fv = Factors(v) for m in Add.make_args(expr): f = Factors(m) q, r = f.div(Fv) if r.is_one: # only accept this as a true factor if # it didn't change an exponent from an Integer # to a non-Integer, e.g. 2/sqrt(2) -> sqrt(2) # -- we aren't looking for this sort of change fwas = f.factors.copy() fnow = q.factors if not any(k in fwas and fwas[k].is_Integer and not fnow[k].is_Integer for k in fnow): terms[v].append(q.as_expr()) continue terms[S.One].append(m) args = [] hit = False uneval = False for k in ordered(terms): v = terms[k] if k is S.One: args.extend(v) continue if len(v) > 1: v = Add(*v) hit = True if recurse and v != expr: vars.append(v) else: v = v[0] # be careful not to let uneval become True unless # it must be because it's going to be more expensive # to rebuild the expression as an unevaluated one if Numbers and k.is_Number and v.is_Add: args.append(_keep_coeff(k, v, sign=True)) uneval = True else: args.append(k*v) if hit: if uneval: expr = _unevaluated_Add(*args) else: expr = Add(*args) if not expr.is_Add: break return expr
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 = 0 if isinstance(lhs, int): lhs = sympy.Integer(lhs) elif isinstance(lhs, float): lhs = sympy.RealNumber(lhs) 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_rhs(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: 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 cplex.exceptions.CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: linear_expression = _unevaluated_Add( *[_unevaluated_Mul(sympy.RealNumber(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 collect_const(expr, *vars, **kwargs): """A non-greedy collection of terms with similar number coefficients in an Add expr. If ``vars`` is given then only those constants will be targeted. Although any Number can also be targeted, if this is not desired set ``Numbers=False`` and no Float or Rational will be collected. Examples ======== >>> from sympy import sqrt >>> from sympy.abc import a, s, x, y, z >>> from sympy.simplify.radsimp import collect_const >>> collect_const(sqrt(3) + sqrt(3)*(1 + sqrt(2))) sqrt(3)*(sqrt(2) + 2) >>> collect_const(sqrt(3)*s + sqrt(7)*s + sqrt(3) + sqrt(7)) (sqrt(3) + sqrt(7))*(s + 1) >>> s = sqrt(2) + 2 >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7)) (sqrt(2) + 3)*(sqrt(3) + sqrt(7)) >>> collect_const(sqrt(3)*s + sqrt(3) + sqrt(7)*s + sqrt(7), sqrt(3)) sqrt(7) + sqrt(3)*(sqrt(2) + 3) + sqrt(7)*(sqrt(2) + 2) The collection is sign-sensitive, giving higher precedence to the unsigned values: >>> collect_const(x - y - z) x - (y + z) >>> collect_const(-y - z) -(y + z) >>> collect_const(2*x - 2*y - 2*z, 2) 2*(x - y - z) >>> collect_const(2*x - 2*y - 2*z, -2) 2*x - 2*(y + z) See Also ======== collect, collect_sqrt, rcollect """ if not expr.is_Add: return expr recurse = False Numbers = kwargs.get('Numbers', True) if not vars: recurse = True vars = set() for a in expr.args: for m in Mul.make_args(a): if m.is_number: vars.add(m) else: vars = sympify(vars) if not Numbers: vars = [v for v in vars if not v.is_Number] vars = list(ordered(vars)) for v in vars: terms = defaultdict(list) Fv = Factors(v) for m in Add.make_args(expr): f = Factors(m) q, r = f.div(Fv) if r.is_one: # only accept this as a true factor if # it didn't change an exponent from an Integer # to a non-Integer, e.g. 2/sqrt(2) -> sqrt(2) # -- we aren't looking for this sort of change fwas = f.factors.copy() fnow = q.factors if not any(k in fwas and fwas[k].is_Integer and not fnow[k].is_Integer for k in fnow): terms[v].append(q.as_expr()) continue terms[S.One].append(m) args = [] hit = False uneval = False for k in ordered(terms): v = terms[k] if k is S.One: args.extend(v) continue if len(v) > 1: v = Add(*v) hit = True if recurse and v != expr: vars.append(v) else: v = v[0] # be careful not to let uneval become True unless # it must be because it's going to be more expensive # to rebuild the expression as an unevaluated one if Numbers and k.is_Number and v.is_Add: args.append(_keep_coeff(k, v, sign=True)) uneval = True else: args.append(k*v) if hit: if uneval: expr = _unevaluated_Add(*args) else: expr = Add(*args) if not expr.is_Add: break return expr
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, LP_Problem=None, *args, **kwargs): super(Prob_Model, self).__init__(*args, **kwargs) if LP_Problem is None: self.LP_Problem = cplex.Cplex() elif isinstance(LP_Problem, cplex.Cplex): self.LP_Problem = LP_Problem zipped_var_args = zip(self.LP_Problem.LP_Vars.get_names(), self.LP_Problem.LP_Vars.get_lower_bounds(), self.LP_Problem.LP_Vars.get_upper_bounds() ) for name, Lower_Bound, Upper_Bound in zipped_var_args: var = Prob_Variable(name, Lower_Bound=Lower_Bound, Upper_Bound=Upper_Bound, LP_Problem=self) super(Prob_Model, self).Add_Variable_Prob(var) # To addtion of the variable to the glpk LP_Problem zipped_constr_args = zip(self.LP_Problem.linear_constraints.get_names(), self.LP_Problem.linear_constraints.get_rows(), self.LP_Problem.linear_constraints.get_senses(), self.LP_Problem.linear_constraints.get_rhs() ) LP_Vars = self.LP_Vars for name, row, eq_Sense, rhs in zipped_constr_args: constraint_variables = [LP_Vars[i - 1] for i in row.ind] lhs = _unevaluated_Add(*[val * LP_Vars[i - 1] for i, val in zip(row.ind, row.val)]) if isinstance(lhs, int): lhs = sympy.Integer(lhs) elif isinstance(lhs, float): lhs = sympy.RealNumber(lhs) if eq_Sense == 'E': constr = Prob_Constraint(lhs, Lower_Bound=rhs, Upper_Bound=rhs, name=name, LP_Problem=self) elif eq_Sense == 'G': constr = Prob_Constraint(lhs, Lower_Bound=rhs, name=name, LP_Problem=self) elif eq_Sense == 'L': constr = Prob_Constraint(lhs, Upper_Bound=rhs, name=name, LP_Problem=self) elif eq_Sense == 'R': range_val = self.LP_Problem.linear_constraints.get_rhs(name) if range_val > 0: constr = Prob_Constraint(lhs, Lower_Bound=rhs, Upper_Bound=rhs + range_val, name=name, LP_Problem=self) else: constr = Prob_Constraint(lhs, Lower_Bound=rhs + range_val, Upper_Bound=rhs, name=name, LP_Problem=self) else: raise Exception('%s is not a known constraint eq_Sense.' % eq_Sense) for variable in constraint_variables: try: self.Vars_To_Constr_Map[variable.name].add(name) except KeyError: self.Vars_To_Constr_Map[variable.name] = set([name]) super(Prob_Model, self).Constraint_Adder( constr, sloppy=True ) try: objective_name = self.LP_Problem.Objective_Obj.get_name() except cplex.exceptions.CplexSolverError as e: if 'CPLEX Error 1219:' not in str(e): raise e else: linear_expression = _unevaluated_Add(*[_unevaluated_Mul(sympy.RealNumber(coeff), LP_Vars[index]) for index, coeff in enumerate(self.LP_Problem.Objective_Obj.get_linear()) if coeff != 0.]) try: quadratic = self.LP_Problem.Objective_Obj.get_quadratic() except IndexError: quadratic_expression = Zero else: quadratic_expression = self.quad_expression_getter(quadratic) self.objective_var = Prob_Objective( linear_expression + quadratic_expression, LP_Problem=self, Max_Or_Min_type={self.LP_Problem.Objective_Obj.eq_Sense.minimize: 'min', self.LP_Problem.Objective_Obj.eq_Sense.maximize: 'max'}[ self.LP_Problem.Objective_Obj.get_sense()], name=objective_name ) else: raise Exception("the given Problem is not CPLEX model in nature.") self.configuration = Prob_Configure(LP_Problem=self, Verbosity_Level=0)