Simple Example#
Let’s model the following linear problem:
\[\begin{split}\min \ c_1 x + c_2 y \\
\text{s.t.} \
\ a x + b y \leq c \\
x, y \geq 0\end{split}\]
The complete model file is shown below. This example demonstrates the basic structure of a DecisionAI model, including:
An input data class that inherits from
decision_ai.InputDataA variables class that inherits from
decision_ai.PulpVariablesA model class that inherits from
decision_ai.PulpDecisionAIModelUse of the
decision_ai.constraint()decorator to define constraints
import pulp
from pydantic import Field
from decision_ai import InputData, PulpDecisionAIModel, PulpVariables, Solution, constraint
from decision_ai.typing import ConstraintGenerator
class ExampleInputData(InputData):
a: int
b: int
c: int
cost: dict[str, int]
class Variables(PulpVariables):
x: pulp.LpVariable = Field(..., description="Variable x")
y: pulp.LpVariable = Field(..., description="Variable y")
@staticmethod
def init_x(input_: ExampleInputData) -> pulp.LpVariable: # noqa: ARG004
return pulp.LpVariable("x", lowBound=0)
@staticmethod
def init_y(input_: ExampleInputData) -> pulp.LpVariable: # noqa: ARG004
return pulp.LpVariable("y", lowBound=0)
class Model(PulpDecisionAIModel[ExampleInputData, Variables]):
variables_class = Variables
@constraint
def constraint_1(input_: ExampleInputData, variables: Variables) -> ConstraintGenerator:
yield input_.a * variables.x + input_.b * variables.y <= input_.c
def set_up_objective(self, input_: ExampleInputData, prob: pulp.LpProblem, variables: Variables) -> pulp.LpProblem:
prob += pulp.lpSum([input_.cost["c1"] * variables.x, input_.cost["c2"] * variables.y])
return prob
def solution_to_str(self, input_: ExampleInputData, solution: Solution) -> str:
return f"Objective value: {solution.objective}\n\nStatus: {solution.status}"
def solve(self, prob: pulp.LpProblem, variables: Variables, input_: ExampleInputData, **kwargs) -> Solution:
prob.solve()
return self._create_solution(prob, variables)