Hints for building models efficiently
The Xpress Python interface allows for creating optimization models using methods described in this and other sections. As happens with other interpreted languages, using explicit loops may result in a slow Python script. When using the Xpress Python interface, this can be noticeable in large optimization models if multiple calls to addVariable, addConstraint, or addSOS are made. For this reason, the Xpress module allows for generators and list, dictionaries, and sequences as arguments to these methods, to ensure faster execution.
Let us consider an example:
import xpress as xp N = 100000 S = range(N) x = [xp.var() for i in S] y = [xp.var(vartype=xp.binary) for i in S] for i in S: m.addVariable(x[i]) m.addVariable(y[i]) for i in S: m.addConstraint(x[i] <= y[i]) m.solve()
While the declaration of x and y is correct and efficient, the two subsequent loops are very inefficient: they imply 2N calls to addVariable and N calls to addConstraint. Both methods add some overhead due to the conversion of Python object into data that can be read by the Optimizer, and the total overhead can be large.
Most methods of the Xpress Python interface allow for passing sequences (lists, dictionaries, NumPy arrays, etc.) as parameters, and are automatically recognized as such. Hence the first loop can be replaced by two calls to addVariable:
m.addVariable(x) m.addVariable(y)
or, more compact and slightly more efficient:
m.addVariable(x, y)
The largest gain in performance, though, comes from replacing the second loop with a single call to addConstraint:
m.addConstraint(x[i] <= y[i] for i in S)
This line is equivalent to the second loop above, and it is much faster and more elegant.
When declaring x and y as NumPy vectors, an equally efficient and even more compact model can be written:
import xpress as xp import numpy as np N = 100000 S = range(N) x = np.array([xp.var() for i in S], dtype=xp.npvar) y = np.array([xp.var(vartype=xp.binary) for i in S], dtype=xp.npvar) m.addVariable(x, y) m.addConstraint(x <= y) m.solve()
See Chapter Using Python numerical libraries for more information on how to use NumPy arrays in the Xpress Python interface.