# Construct a problem from scratch with variables of various
# types. Adds indicator constraints and shows how to retrieve
# such data once it has been added to the problem using the
# API functions.
# - Example discussed in mipformref whitepaper -
#
# (C) 1983-2026 Fair Isaac Corporation
import xpress as xp
m = xp.problem()
m.controls.miprelstop = 0
# All variables used in this example.
v1 = m.addVariable(lb=0, ub=10, vartype=xp.continuous)
v2 = m.addVariable(lb=1, ub=7, vartype=xp.continuous)
v3 = m.addVariable(lb=5, ub=10, threshold=7, vartype=xp.semicontinuous)
vb = m.addVariable(vartype=xp.binary)
# Indicator constraints consist of a tuple with a condition on a
# binary variable and a constraint.
ind1 = (vb == 0, v1 + v2 >= 6)
ind2 = (vb == 1, v1 + v3 >= 4)
# Adds the first indicator constraint.
m.addIndicator(ind1)
# Adds another indicator constraint and the second one defined above.
m.addIndicator((vb == 1, v2 + v3 >= 5), ind2)
# Returns the indicator constraint condition (indicator variable and complement flag)
# associated to the rows in a given range.
ind_inds, ind_flags = m.getIndicators(0, 2)
print("Indicator variables and flags: ", ind_inds, ind_flags)
m.setObjective(xp.Sum(v1,v2,v3))
m.optimize()
print("v1: ", m.getSolution(v1),
", v2: ", m.getSolution(v2),
"; sol vector: ", m.getSolution(),
"; obj: ", m.attributes.objval,
sep="") # Default separator between strings is " ". |
# Indicator constraint definition with nonlinear constraints.
# - Example discussed in mipformref whitepaper -
#
# min b1 + b2
# s.t. b1 = 1 -> x1*x2 = 12
# b2 = 0 -> sin(x2) >= 0.5
# b1, b2 in {0,1}
#
# (C) 2026 Fair Isaac Corporation
import xpress as xp
from xpress.enums import SolStatus
p = xp.problem(name="NL indicator constraints")
x = p.addVariables(2, name="x")
# Binary variables driving the indicator constraints
b = p.addVariables(2, vartype=xp.binary, name="b")
# Indicator constraint: condition (b[i] == 0 or 1) paired with the
# constraint that must hold when the condition is true.
ind1 = (b[0] == 1, x[0] * x[1] == 12) # b[0]=1 -> x[0]*x[1]=12
ind2 = (b[1] == 0, xp.sin(x[1]) >= 0.5) # b[1]=0 -> sin(x[1])>=0.5
# Both constraints are nonlinear (quadratic / trigonometric)
p.addIndicator(ind1, ind2)
p.setObjective(b[0] + b[1], sense=xp.ObjSense.MINIMIZE)
p.optimize()
print("Problem status:", p.attributes.solstatus.name)
if p.attributes.solstatus in [SolStatus.FEASIBLE, SolStatus.OPTIMAL]:
for i in range(2):
print(f"x[{i}] = {p.getSolution(x[i])}")
# getIndicators returns the indicator variable index and the sense flag
# for each row.
ind_vars, ind_flags = p.getIndicators(0, 1)
for i in range(2):
print(f"indicator {i}: b[{i}] = {p.getSolution(b[i])}, flag = {ind_flags[i]}")
|