# piecewise.py

Filter Content By
Version
Languages

### piecewise.py

#!/usr/bin/env python3.7

# Copyright 2021, Gurobi Optimization, LLC

# This example considers the following separable, convex problem:
#
#   minimize    f(x) - y + g(z)
#   subject to  x + 2 y + 3 z <= 4
#               x +   y       >= 1
#               x,    y,    z <= 1
#
# where f(u) = exp(-u) and g(u) = 2 u^2 - 4 u, for all real u. It
# formulates and solves a simpler LP model by approximating f and
# g with piecewise-linear functions. Then it transforms the model
# into a MIP by negating the approximation for f, which corresponds
# to a non-convex piecewise-linear function, and solves it again.

import gurobipy as gp
from math import exp

def f(u):
return exp(-u)

def g(u):
return 2 * u * u - 4 * u

try:

# Create a new model

m = gp.Model()

# Create variables

lb = 0.0
ub = 1.0

# Set objective for y

m.setObjective(-y)

# Add piecewise-linear objective functions for x and z

npts = 101
ptu = []
ptf = []
ptg = []

for i in range(npts):
ptu.append(lb + (ub - lb) * i / (npts - 1))
ptf.append(f(ptu[i]))
ptg.append(g(ptu[i]))

m.setPWLObj(x, ptu, ptf)
m.setPWLObj(z, ptu, ptg)

# Add constraint: x + 2 y + 3 z <= 4

m.addConstr(x + 2 * y + 3 * z <= 4, 'c0')

# Add constraint: x + y >= 1

m.addConstr(x + y >= 1, 'c1')

# Optimize model as an LP

m.optimize()

print('IsMIP: %d' % m.IsMIP)
for v in m.getVars():
print('%s %g' % (v.VarName, v.X))
print('Obj: %g' % m.ObjVal)
print('')

# Negate piecewise-linear objective function for x

for i in range(npts):
ptf[i] = -ptf[i]

m.setPWLObj(x, ptu, ptf)

# Optimize model as a MIP

m.optimize()

print('IsMIP: %d' % m.IsMIP)
for v in m.getVars():
print('%s %g' % (v.VarName, v.X))
print('Obj: %g' % m.ObjVal)

except gp.GurobiError as e:
print('Error code ' + str(e.errno) + ": " + str(e))

except AttributeError:
print('Encountered an attribute error')