Initializing help system before first use

Using loadproblem for efficiency

The high-level functions problem.addConstraint and problem.addVariable allow for efficient, concise, and understandable modeling of any optimization problem. An even faster way to create a problem is through the problem.loadproblem function, which uses a more direct interface to the Optimizer's libraries and is hence preferable with very large problems and when efficiency in model creation is necessary.

The functon problem.loadproblem can be used to create problems with linear and/or quadratic constraints, a linear and/or quadratic objective function, and with continuous and/or discrete variables. Its syntax with default parameter values allows for specifying only the components of interest. We refer the reader to its entry in Chapter Reference Manual, and present here a few examples of usages. More examples are shown in Chapter Examples of use.

The first example uses loadproblem to create a problem similar to that created earlier in this chapter. We first write the problem using standard modeling functions:

import xpress as xp
x = xp.var(vartype=xp.integer, name='x1', lb=-10, ub=10)
y = xp.var(name='x2')
p = xp.problem(name='myexample')
p.addVariable(x, y)
p.setObjective(x**2 + 2*y)
p.addConstraint(x + 3*y <= 4)
p.addConstraint(7*x + 4*y >= 8)

The following code creates a problem with the same features, including variable names and their types

import xpress as xp
p = xp.problem()
p.loadproblem(probname='myexample',
              qrtypes=['L', 'G'],    # constraint senses
              rhs=[4, 8],            # right-hand sides
              range=None,
              obj=[0, 2],            # linear obj. coeff.
              mstart=[0, 2, 4],      # start pos. of all columns
              mrwind=[0, 1, 0, 1],   # row index in each column
              dmatval=[1, 7, 3, 4],  # coefficients
              mnel=None,
              dlb=[-10,0],           # variable lower bounds
              dub=[10,xp.infinity],  #          upper bounds
              mqcol1=[0],            # quadratic obj. terms, column 1
              mqcol2=[0],            #                       column 2
              dqe=[2],               #                       coeff
              qgtype=['I'],          # variable types
              mgcols=[0],
              colnames=['x1', 'x2'])

Apart from the intuitive lists qrtypes (for constraint types: 'L' for "lesser-than", 'G' for "greater-than", 'E' for "equal-to"), rhs (constraints' right-hand sides), obj (objective linear coefficients), dlb and dub (variables' lower and upper bounds), a few paramters deserve some attention. The three lists mstart, mrwind, dmatval describe the coefficient matrix: mrwind and dmatval contain, respectively, the row indices and the coefficients, while mstart is a list of n+1 integers (where n is the number of variables, i.e., the size of obj, dlb, and dub); mstart[i] indicates the position, within mrwind and dmatval, of the indices and coefficients of the i-th column. The last element mstart[n+1] indicates the number of nonzeros in the matrix.

The following shows two equivalent knapsack problems, again created first using the high-level modeling routines and then the lower-level API function.

import xpress as xp
N = 6
x = [xp.var(vartype=xp.binary) for _ in range(N)]
value = [1, 4, 6, 4, 7, 3]
weight = [1, 3, 5, 5, 8, 4]
p = xp.problem(name='knapsack')
p.addVariable(x)
p.setObjective(xp.Sum(value[i] * x[i] for i in range(N)), sense=xp.maximize)
p.addConstraint(xp.Sum(weight[i] * x[i] for i in range(N)) <= 12)

Note that problem.loadproblem assumes that the optimization sense is minimization and hence a call to problem.chgobjsense is necessary to set the sense to maximization.

import xpress as xp
p = xp.problem()
N = 6
value = [1, 4, 6, 4, 7, 3]
weight = [1, 3, 5, 5, 8, 4]
p.loadproblem(probname='knapsack',
              qrtypes=['L'],         # constraint senses
              rhs=[12],              # right-hand sides
              range=None,
              obj=value,             # linear obj. coeff.
              mstart=range(N+1),     # start pos. of all columns
              mrwind=[0] * N,        # row index in each column (always 0)
              dmatval=weight,        # coefficients
              mnel=None,
              dlb=[0] * N,           # variable lower bounds
              dub=[1] * N,           #          upper bounds
              qgtype=['B'] * N,      # variable types
              mgcols=range(N))
p.chgobjsense(xp.maximize)