User guide · 2.0 development

Creating Variables

Variables are the fundamental building blocks of optimization problems. SHOTpy supports:

  • Real (continuous) variables

  • Integer variables

  • Binary variables

A variable can be created on its own and added to a problem with problem.addVariable(variable), or created and added in one step with problem.addVariable(name, type, lowerBound, upperBound), which returns the variable. Without bounds, a binary variable has the bounds 0 and 1, and other variables have none. A bound of inf or -inf also means that there is no bound, and a bound of NaN raises a ValueError.

Variables and constraints are numbered by the problem they are added to: addVariable and addConstraint assign an index matching the position in the problem, and it is readable afterwards as .index. The index is what SHOT uses to address a variable in a solution point and in the solver it hands the problem to, so it is read only – you do not pass one in, and you cannot set one.

Most examples in this tutorial write the objective and the constraints as expressions, such as problem.addConstraint(x + 2*y <= 8, "c"), and finalize() extracts the linear and quadratic terms from them. The terms can also be created one at a time as LinearTerm and QuadraticTerm objects; for large problems, see Building Large Problems Efficiently.

# Create a continuous variable: x ∈ [0, 10]
x = SHOTpy.Variable("x", SHOTpy.VariableType.Real, 0.0, 10.0)

# Create an integer variable: y ∈ {0, 1, 2, ..., 5}
y = SHOTpy.Variable("y", SHOTpy.VariableType.Integer, 0.0, 5.0)

# Create a binary variable: z ∈ {0, 1}
z = SHOTpy.Variable("z", SHOTpy.VariableType.Binary, 0.0, 1.0)

print(f"Created variables: {x.name}, {y.name}, {z.name}")

# Or create a variable and add it to a problem in one step; addVariable returns the variable
problem = SHOTpy.Problem(solver)
u = problem.addVariable("u", SHOTpy.VariableType.Real, 0.0, 10.0)
v = problem.addVariable("v", SHOTpy.VariableType.Binary)  # bounds 0 and 1
w = problem.addVariable("w")                               # real, without bounds

print(f"Added variables: {[(var.name, var.index) for var in problem.allVariables]}")