Skip to main content

Constraint

Constraint​

Returned by Model.constraint. Rows over an expression's frame, bounded by a right-hand side.

Model.constraint(name, relation, where=None, over=None)
ArgumentMeaning
namethe name Solution.dual reads it back by
relationan expression, a sense and a right-hand side
wherea domain intersecting the rows
overthe rows, given explicitly
MemberReturns
n_rowsthe number of rows it produces
nnzthe number of coefficients they contain
labels_at(positions)the labels of the rows at those positions, per free dimension
position_of(coords)the position of the row at a coordinate, one label per free dimension
row_at(position)the columns, the coefficients and the lower and upper bound of the row at that position
row_of(name) on the Assembledthe position of those rows in the matrix

A row derived from the terms exists where every term has a value and the right-hand side has a value. A coefficient absent inside a sum removes a term and keeps the row. A term absent along a free dimension removes the row: a row missing one of its terms would express a constraint that was not written.

over= gives the rows explicitly instead, and a term covering some of them contributes where it has values. A condition given with where= intersects the row domain, and a row outside the condition is not produced.

The expression is symbolic, and the constraint stores the term list and no block. The expression is materialised once to compute its shape and once to write it, and it stores nothing between the two.

import numpy as np
from nimopt import Model, Param, Set, Sum

P = Set("P", np.array(["lisbon", "porto"]))
W = Set("W", np.array(["berlin", "paris", "rome"]))
supply = Param.from_dense("supply", (P,), np.array([30.0, 25.0]))

m = Model("transport")
x = m.var("x", (P, W))

rows = m.constraint("supply", Sum(W, x[P, W]) <= supply[P])
print(rows.n_rows, rows.nnz)
print(m.assemble().row_of("supply"))
Output
2 6
slice(0, 2, None)

The right-hand side is a number, applied to every row, or a parameter over exactly the free dimensions of the constraint. A parameter gives each row its own value. A parameter over other dimensions raises ValueError, and the message gives both sets of dimensions.

import numpy as np
from nimopt import Model, Param, Set, Sum

P = Set("P", np.array(["lisbon", "porto"]))
W = Set("W", np.array(["berlin", "paris", "rome"]))
demand = Param.from_dense("demand", (W,), np.array([20.0, 15.0, 15.0]))

m = Model("transport")
x = m.var("x", (P, W))

m.constraint("supply", Sum(W, x[P, W]) <= demand[W])
Raises ValueError
ValueError: constraint 'supply' has free dimensions ('P',); its right-hand side 'demand' is over ('W',)