Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# piecewise.py

    #!/usr/bin/env python3

    # Copyright 2025, 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

        x = m.addVar(lb, ub, name="x")
        y = m.addVar(lb, ub, name="y")
        z = m.addVar(lb, ub, name="z")

        # 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(f"IsMIP: {m.IsMIP}")
        for v in m.getVars():
            print(f"{v.VarName} {v.X:g}")
        print(f"Obj: {m.ObjVal:g}")
        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(f"IsMIP: {m.IsMIP}")
        for v in m.getVars():
            print(f"{v.VarName} {v.X:g}")
        print(f"Obj: {m.ObjVal:g}")

    except gp.GurobiError as e:
        print(f"Error code {e.errno}: {e}")

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

Help and Feedback

Press `/` or click to search this documentation | Gurobi website | Gurobi community forum
Go to other Gurobi documentation | Gurobi download | Contact support