5. Model FormulationΒΆ
A combinatorial optimization problem comprises decision variables, objective functions, and constraints. In β2. Creating Decision Variables,β β3. Polynomials and Objective Functions,β and β4. Constructing Constraints,β we explained that you can create decision variables using VariableGenerator
. At the same time, you can construct objective functions and constraints using Poly
and Constraint
.
This page describes how these can be combined and used together to express combinatorial optimization problems in program code.
See also
In addition to the Poly
class, you can use instances of the coefficient matrix Matrix
class as an objective function. When you construct the objective function as Matrix
, you can use it in the same way described on this page.
For details on the format of the coefficient matrix, see βObjective Function with a Coefficient Matrixβ.
5.1. Model constructionΒΆ
The Amplify SDK represents combinatorial optimization problems as instances of the Model
class.
For a combinatorial optimization problem with an objective function and constraints, a simple way is to add a Poly
representing the objective function and a Constraint
or ConstraintList
defining the constraints.
from amplify import VariableGenerator, Model, equal_to, one_hot
gen = VariableGenerator()
q = gen.array("Binary", shape=(2, 3))
objective = q[0, 0] * q[0, 1] - q[0, 2]
constraint1 = equal_to(q[0, 0] + q[0, 1] - q[0, 2], 0)
constraint2 = one_hot(q[1, :])
constraint_list = constraint1 + constraint2
Constructing the model by adding the objective function and constraints:
>>> model = objective + constraint1
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
Constructing the model by adding the objective function and the constraint list:
>>> model = objective + constraint_list
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1),
q_{1,0} + q_{1,1} + q_{1,2} == 1 (weight: 1)
For a combinatorial optimization problem consisting of either an objective function or constraints, you can pass a Poly
(or Matrix
) instance to the constructor of the Model
class to represent the objective function or a Constraint
or ConstraintList
instance to represent the constraints.
Constructing a model from the objective function (
Poly
):
>>> model = Model(objective)
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
Constructing a model from a single constraint object (
Constraint
):
>>> model = Model(constraint1)
>>> print(model)
minimize:
0
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
Constructing a model from multiple constraint objects (
ConstraintList
):
>>> model = Model(constraint_list)
>>> print(model)
minimize:
0
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1),
q_{1,0} + q_{1,1} + q_{1,2} == 1 (weight: 1)
You can also add constraints (Constraint
or {py:class}`~amplify.ConstraintList) after the model is constructed.
>>> model = Model(objective)
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
>>> model += constraint1
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
If the model has the objective function as an instance of the polynomial Poly
class, addition and subtraction of the objective function are also possible.
>>> model += q[0, 0] * q[0, 1]
>>> print(model)
minimize:
2 q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
>>> model -= q[0, 0]
>>> print(model)
minimize:
2 q_{0,0} q_{0,1} - q_{0,0} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
5.2. Model attributesΒΆ
The objective
property allows you to retrieve the objective function of the Model
class.
from amplify import VariableGenerator, equal_to
gen = VariableGenerator()
q = gen.array("Binary", 2, 3)
objective = q[0,0] * q[0,1] - q[0,2]
constraint = equal_to(q[0,0] + q[0,1] - q[0,2], 0)
model = objective + constraint
>>> print(model.objective)
q_{0,0} q_{0,1} - q_{0,2}
The constraints
property allows the user to retrieve the constraints the Model
class holds. This property returns an instance of the ConstraintList
class.
>>> print(model.constraints)
[q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)]
Note
Note that the Model stores the objective function and constraints without copying them. Therefore, changing the objective function or constraints in the model will also change the variables before model construction.
model = Model(objective)
model += q[0, 0]
assert model.objective == objective
5.3. Changing the constraint weight in the modelΒΆ
After the model is constructed, you may want to change the weight of the constraint included in the model.
Note
See βPenalty function weightβ for information on adjusting the weights of constraints.
In the following example, the weight of a constraint is doubled.
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 1)
>>> model.constraints[0] *= 2
>>> print(model)
minimize:
q_{0,0} q_{0,1} - q_{0,2}
subject to:
q_{0,0} + q_{0,1} - q_{0,2} == 0 (weight: 2)