In the model transport.py in CPLEX_Studio2211\cplex\examples\src\python
You have an example
# Add the PWL constraints
for i in range(n):
# preslope is the slope before the first breakpoint. Since the
# first breakpoint is (0, 0) and the lower bound of y is 0, it is
# not meaningful here. To keep things simple, we re-use the
# first item in pwl_slope.
# Similarly, postslope is the slope after the last breakpoint.
# We just use the same slope as in the last segment; we re-use
# the last item in pwl_slope.
model.pwl_constraints.add(vary=n + i,
varx=i,
preslope=pwl_slope[0],
postslope=pwl_slope[-1],
breakx=pwl_x[i],
breaky=pwl_y[i],
name="p{0}".format(i + 1))
With docplex python API, piecewise are easy to write as can be seen in https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoopiecewise.py
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
#after 4 buses, additional buses of a given size are cheaper
f=mdl.piecewise(0, [(0, 0),(4,4)], 0.8)
mdl.minimize(f(nbbus40)*500 + f(nbbus30)*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
which is the same as
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
obj = mdl.integer_var(name='obj')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
f=mdl.piecewise(0, [(0, 0),(4,4)], 0.8)
mdl.add_constraint(obj==f(nbbus40)*500 + f(nbbus30)*400)
mdl.minimize(obj)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
Just to show how you can move the objective to a constraint