メインコンテンツへスキップ

How to model a piecewise linear function?

回答済み

コメント

3件のコメント

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Dejan,

    Strangely enough, it doesn't work with addGenConstrExp(). How do I get it to work?

    Could you please elaborate what exactly does not work?

    Note that you have to introduce an auxiliary variable to capture the \(\exp\) function. This means that you would have to model something like

    z = Model.addVars(I, T, name="z") # add auxiliary variable for exp
    w = Model.addVars(I, T, name="w") # add auxiliary variable for -0.5 * Sum[i,t]
    for i in I:   for t in T:       Model.addLConstr(Sum[i, t] == gu.quicksum(y[i, j, d] for j in J for d in range(1, t + 1)))
           # w[i,t] = -0.5 * Sum[i,t]
    Model.addConstr(w[i,t] == -0.5 * Sum[i,t])
           # z[i,t] = exp(w[i,t])
    Model.addGenConstrExp(w[i,t], z[i,t])
           # Para[i,t] = 1 - z[i,t]
    Model.addConstr(Para[i,t] == 1 - z[i,t])

    Model.setParam("Funcnonlinear", 0) # tell Gurobi to handle all general constraints via PWL approximation

    Alternatively, you could avoid using a piecewise-linear approximation and let Gurobi handle the nonlinear constraints directly. For this, you would have to set the FuncNonlinear parameter to 1. Note that the FuncNonlinear parameter is only available starting with version 11. If you are using an older version, then Gurobi will automatically compute a PWL approximation of function constraints introduced by \(\texttt{addGenConstrExp}\).

    If you are using Gurobi version 12, you can use the new nonlinear expression API to write

    for i in I:
      for t in T:
            Model.addLConstr(Sum[i, t] == gu.quicksum(y[i, j, d] for j in J for d in range(1, t + 1)))
          # Para[i,t] = 1 - exp(-0.5 * Sum[i,t])
    Model.addGenConstrNL(Para[i,t], 1 - gu.nlfunc.exp(-0.5 * Sum[i,t]))

    Note that in the above formulation, Gurobi will handle the nonlinear constraints directly and not via a piecewise-linear approximation.

    Best regards, 
    Jaromił

    0
  • Dejan Salch
    Gurobi-versary
    First Comment
    First Question

    Dear Jaromił Najman. Thank you for your anwser. Sadly i cannot reproduce the error i was facing. Now it work. Cann i also model functions such a power or a sigmoid function without using addGenConstrPWL?  Which command would i use for that?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Cann i also model functions such a power or a sigmoid function without using addGenConstrPWL?  Which command would i use for that?

    With version 11 you can use the addGenConstrPow method to add powers. For a sigmoid function, you can use addGenConstrLogistic.

    Starting with version 12, we recommend to use the addGenConstrNL method. You could add a power and a logistic term in one equality constraint via

    # add constraint resvar = x^3 + logistic(y)
    Model.addGenConstrNL(resvar, x ** 3 + gu.nlfunc.logistic(y))

    Best regards, 
    Jaromił

    0

サインインしてコメントを残してください。