ommx.v1.Solution#
OMMX has several structures that represent the solution of mathematical models.
Data Structure |
Description |
|---|---|
Holds the solution value for the decision variable ID. The simplest representation of a solution. |
|
A representation of the solution intended to be human-readable. In addition to the values of the decision variables and the evaluation values of the constraints, it also holds metadata for the decision variables and constraints added to the |
Most solvers are software designed to solve mathematical models, so they return minimal information equivalent to ommx.v1.State, but OMMX mainly handles ommx.v1.Solution, which allows users to easily check the optimization results.
ommx.v1.Solution is generated by passing ommx.v1.State or equivalent dict[int, float] to the ommx.v1.Instance.evaluate method. Let’s consider the simple optimization problem we saw in the previous section again:
It is clear that this has a feasible solution \(x = 1, y = 0\).
from ommx.v1 import Instance, DecisionVariable
# Create a simple instance
x = DecisionVariable.binary(1, name='x')
y = DecisionVariable.binary(2, name='y')
instance = Instance.from_components(
decision_variables=[x, y],
objective=x + y,
constraints={0: x * y == 0},
sense=Instance.MAXIMIZE
)
# Create a solution
solution = instance.evaluate({1: 1, 2: 0}) # x=1, y=0
The generated ommx.v1.Solution inherits most of the information from the ommx.v1.Instance. Let’s first look at the decision variables.
solution.decision_variables_df
In addition to the required attributes—ID, kind, lower, and upper—it also inherits metadata such as name. Additionally, the value assigned in evaluate is stored. Similarly, the evaluation value is added to the constraints as value.
solution.constraints_df
The objective property contains the value of the objective function, and the feasible property contains whether the constraints are satisfied.
print(f"{solution.objective=}, {solution.feasible=}")
Since \(xy = 0\) when \(x = 1, y = 0\), all constraints are satisfied, so feasible is True. The value of the objective function is \(x + y = 1\).
What happens in the case of an infeasible solution, \(x = 1, y = 1\)?
solution11 = instance.evaluate({1: 1, 2: 1}) # x=1, y=1
print(f"{solution11.objective=}, {solution11.feasible=}")
feasible = False indicates that it is an infeasible solution.