X-Git-Url: https://svn.cri.ensmp.fr/git/linpy.git/blobdiff_plain/b4f536e238161d59db61f4bb5fc6e87d4b7baffe..a16251fd5fb481e97f05fd488ad718ba2147396b:/linpy/polyhedra.py diff --git a/linpy/polyhedra.py b/linpy/polyhedra.py index b88cfd1..bfc7efe 100644 --- a/linpy/polyhedra.py +++ b/linpy/polyhedra.py @@ -281,9 +281,33 @@ class Polyhedron(Domain): def __repr__(self): strings = [] for equality in self.equalities: - strings.append('Eq({}, 0)'.format(equality)) + left, right, swap = 0, 0, False + for i, (symbol, coefficient) in enumerate(equality.coefficients()): + if coefficient > 0: + left += coefficient * symbol + else: + right -= coefficient * symbol + if i == 0: + swap = True + if equality.constant > 0: + left += equality.constant + else: + right -= equality.constant + if swap: + left, right = right, left + strings.append('{} == {}'.format(left, right)) for inequality in self.inequalities: - strings.append('Ge({}, 0)'.format(inequality)) + left, right = 0, 0 + for symbol, coefficient in inequality.coefficients(): + if coefficient < 0: + left -= coefficient * symbol + else: + right += coefficient * symbol + if inequality.constant < 0: + left -= inequality.constant + else: + right += inequality.constant + strings.append('{} <= {}'.format(left, right)) if len(strings) == 1: return strings[0] else: @@ -364,63 +388,77 @@ class UniverseType(Polyhedron): Universe = UniverseType() -def _polymorphic(func): +def _pseudoconstructor(func): @functools.wraps(func) - def wrapper(left, right): - if not isinstance(left, LinExpr): - if isinstance(left, numbers.Rational): - left = Rational(left) - else: - raise TypeError('left must be a a rational number ' - 'or a linear expression') - if not isinstance(right, LinExpr): - if isinstance(right, numbers.Rational): - right = Rational(right) - else: - raise TypeError('right must be a a rational number ' - 'or a linear expression') - return func(left, right) + def wrapper(expr1, expr2, *exprs): + exprs = (expr1, expr2) + exprs + for expr in exprs: + if not isinstance(expr, LinExpr): + if isinstance(expr, numbers.Rational): + expr = Rational(expr) + else: + raise TypeError('arguments must be rational numbers ' + 'or linear expressions') + return func(*exprs) return wrapper -@_polymorphic -def Lt(left, right): +@_pseudoconstructor +def Lt(*exprs): """ Create the polyhedron with constraints expr1 < expr2 < expr3 ... """ - return Polyhedron([], [right - left - 1]) + inequalities = [] + for left, right in zip(exprs, exprs[1:]): + inequalities.append(right - left - 1) + return Polyhedron([], inequalities) -@_polymorphic -def Le(left, right): +@_pseudoconstructor +def Le(*exprs): """ Create the polyhedron with constraints expr1 <= expr2 <= expr3 ... """ - return Polyhedron([], [right - left]) + inequalities = [] + for left, right in zip(exprs, exprs[1:]): + inequalities.append(right - left) + return Polyhedron([], inequalities) -@_polymorphic -def Eq(left, right): +@_pseudoconstructor +def Eq(*exprs): """ Create the polyhedron with constraints expr1 == expr2 == expr3 ... """ - return Polyhedron([left - right], []) + equalities = [] + for left, right in zip(exprs, exprs[1:]): + equalities.append(left - right) + return Polyhedron(equalities, []) -@_polymorphic -def Ne(left, right): +@_pseudoconstructor +def Ne(*exprs): """ Create the domain such that expr1 != expr2 != expr3 ... The result is a - Domain, not a Polyhedron. + Domain object, not a Polyhedron. """ - return ~Eq(left, right) + domain = Universe + for left, right in zip(exprs, exprs[1:]): + domain &= ~Eq(left, right) + return domain -@_polymorphic -def Ge(left, right): +@_pseudoconstructor +def Ge(*exprs): """ Create the polyhedron with constraints expr1 >= expr2 >= expr3 ... """ - return Polyhedron([], [left - right]) + inequalities = [] + for left, right in zip(exprs, exprs[1:]): + inequalities.append(left - right) + return Polyhedron([], inequalities) -@_polymorphic -def Gt(left, right): +@_pseudoconstructor +def Gt(*exprs): """ Create the polyhedron with constraints expr1 > expr2 > expr3 ... """ - return Polyhedron([], [left - right - 1]) + inequalities = [] + for left, right in zip(exprs, exprs[1:]): + inequalities.append(left - right - 1) + return Polyhedron([], inequalities)