Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions mip/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ class LinExpr:
.. code:: python

m += x1 + x2 + x3 == 1

If used in intermediate calculations, the solved value of the linear
expression can be obtained with the ``x`` parameter, just as with
a ``Var``.

.. code:: python

a = 10*x1 + 7*x4
print(a.x)

"""

def __init__(
Expand Down Expand Up @@ -348,6 +358,18 @@ def violation(self: "LinExpr"):

return viol

@property
def x(self) -> Optional[numbers.Real]:
"""Value of this linear expression in the solution. None
is returned if no solution is available."""
x = self.__const
for var, coef in self.__expr.items():
var_x = var.x
if var_x is None:
return None
x += var_x * coef
return x


class Constr:
""" A row (constraint) in the constraint matrix.
Expand Down
28 changes: 28 additions & 0 deletions test/mip_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,31 @@ def test_variable_bounds(solver: str, val: int):
assert round(m.objective_value) == val
assert round(x.x) == 2 * val
assert round(y.x) == val


@pytest.mark.parametrize("val", range(1, 4))
@pytest.mark.parametrize("solver", SOLVERS)
def test_linexpr_x(solver: str, val: int):
m = Model("bounds", solver_name=solver)

x = m.add_var(lb=0, ub=2 * val)
y = m.add_var(lb=val, ub=2 * val)
obj = x - y

assert obj.x is None # No solution yet.

m.objective = maximize(obj)
m.optimize()

assert m.status == OptimizationStatus.OPTIMAL
assert round(m.objective_value) == val
assert round(x.x) == 2 * val
assert round(y.x) == val

# Check that the linear expression value is equal to the same expression
# calculated from the values of the variables.
assert abs((x + y).x - (x.x + y.x)) < TOL
assert abs((x + 2*y).x - (x.x + 2*y.x)) < TOL
assert abs((x + 2*y + x).x - (x.x + 2*y.x + x.x)) < TOL
assert abs((x + 2*y + x + 1).x - (x.x + 2*y.x + x.x + 1)) < TOL
assert abs((x + 2*y + x + 1 + x/2).x - (x.x + 2*y.x + x.x + 1 + x.x/2)) < TOL