Skip to main content

Build an objective function with Log and Exponential inside.

Answered

Comments

6 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Athanasios,

    Gurobi does not have built in non-linear functions other than the bilinear product of two variables.
    You can use the addGenConstrExp and addGenConstrLog functions to implement a piecewise-linear approximation of the \(\exp\) and \(\log\) functions. Note that you need to introduce auxiliary variables when using these functions, because they only accept a single variable as input and output, i.e., you would have to model the \(\exp\) part of you objective as

    \[\begin{align}
    z &= - \sum_{j=1}^p b_j x_{i,j} \\
      y &= \exp(z)
    \end{align}\]

    The \(\log\) part would have to be modeled in an analogous way.

    Moreover, you cannot access the \(\texttt{score}\) variables via

    for j in range(j_len):
    print(score[b_list[j]])

    but rather as

    for b in b_list:
    print(score[b])

    unless the object \(\texttt{b_list}\) has some properties which are not listed in your post.

    Best regards,
    Jaromił

    1
  • Athanasios Papadakis
    Gurobi-versary
    First Comment
    First Question

    Dear Jaromil,

    Thank you for your answer. I have considered your answer and i have concluded to the modelling shown in the picture1 below which gives me the results shown in picture2:

    1)

     

    2)

    I want to believe that this is what you meant in your answer, correct me if i am mistaken. Furthermore when i am trying to change a lit the subjective function as shown in bold in order to add the bj!=0 constrain

    m.setObjective((y2 + l_param*gp.quicksum(1 for i in range(j_len) if score[b_list[i]]!=0)) , GRB.MINIMIZE)

    it produces the error:

    GurobiError: Inequality constraints not supported

    Is it a way to add the if-statement and make it work?

     

    P.S:

    I considered what did you mentioned for the b_list and the "score". Both the loops are essentially resulting in the same outcome as i checked and they are not producing me an error.

    a) for j in range(j_len):
    print(score[b_list[j]])

    b) for b in b_list:
    print(score[b])

    Again thank you for your answer and i would be pleased to continue our discussion.

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Athanasios,

    Your model looks correct.

    However, the final solution has large constraint violations, see the Warning in the last lines of the LOG file. This is most likely cause by the huge coefficient matrix range \(\texttt{[9e-02, 1e+09]}\). You should try to reformulate or rescale your model. Our Guidelines for Numerical Issues are a good starting point.

    Regarding the error. You are trying to check whether the variables \(\texttt{score}\) are \(\neq 0\). This is not possible at the time of model construction, because the variable objects don't have any values. Modeling \(\texttt{if-then}\)-statements has been already discussed in multiple Community Forum posts. You might also want to have a look at the stackexchange post How to write if else statement in linear programming?

    Best regards,
    Jaromił

    0
  • Athanasios Papadakis
    Gurobi-versary
    First Comment
    First Question

    Hi Jaromil,

    Thank you for your answer. As i understand it, although if i model correctly the if-statement, i t would not be feasible to apply it in the current problem for the reason you described.

    Furthermore, as far as the huge coefficient matrix range, i tried to round my dataset's values but the only thing i was able to succeed is to limit the range of the matrix values but it still remains chaotic as you can see:

     

    I have read the documentation but to be honest i am a bit lost. Do you think that there is anything else to do in the current situation?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    Hi Athanasios,

    You could try experimenting with the NumericFocus and the Presolve parameter. The parameters FuncPieces and FuncPieceError can be used to adjust the quality of the piecewise-linear approximation. It may already be enough to provide a good quality solution. You should provide tight bounds for every variable occurring in a nonlinear term. For variables occurring in \(\log\) terms, the lower bound should be \(>0\). A reformulation may improve numerical behavior. You could also use the write() function to write an LP file and inspect the model by hand.

    Best regards,
    Jaromił

    0
  • Athanasios Papadakis
    Gurobi-versary
    First Comment
    First Question

    Hi again Jaromil,

    I tried to use the functions you mentioned as the image shows.

    Unfortunately, the matrix range still remains huge as you can observe.

    The only thing i have not understood from the FuncPieces documentation is the:

    This parameter only applies to function constraints whose FuncPieces attribute has been set to .

    which is mentioned but maybe it does not play an important role. 

    I am tending to believe that the current problem it is not solvable at all with the above approach. However, i would like to thank you for the help you provided me.

    Best regards,

    Thanasis

     

    0

Please sign in to leave a comment.