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

Using result of a decisionvariable for further computations

回答済み

コメント

6件のコメント

  • 正式なコメント
    Simranjit Kaur
    • Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • Eli Towle
    • Gurobi Staff

    Hi Simon,

    The current formulation won't work because you cannot use model variables to index other variables/parameters. However, we can model this as follows. Let \( c \) denote the first dictionary, \( d \) the second dictionary, and \( v \) the variable you call "result" in your code. We add the following constraint to the model:

    $$\begin{align*}v &= \sum_{i \in J_1} \sum_{j \in J_2} y_i x_j(c_{ij} + d_{c_{ij}}). \end{align*}$$

    Because exactly one \( y_i \) and one \( x_j \) are \( 1 \), exactly one \( y_i x_j \) term in the summation is equal to \( 1 \) (the rest are \( 0 \)). Thus, the equation simplifies to \( v = c_{ij} + d_{c_{ij}} \), where \( y_i = x_j = 1 \).

    Translated to Python code, this is:

    model.addConstr(result == quicksum(y[i] * x[j] * (dictionary1[i,j] + dictionary2[dictionary1[i,j]]) for i in J1 for j in J2))

    Could you try this out? Thanks!

    Eli

    0
  • Simon Lackmann
    • Gurobi-versary
    • First Comment
    • First Question

    Hey Eli,

    Thank you for your reply. Your answer would perfectly fit my simplified model. Unfortunately, my simplified model is too loose, because I made a mistake simplifying it and so the suggested solution wouldn't work for me. Sorry for that!

    I'll give it a more precise try, please have a look at the following:

    I have an array, let's say 'membersArray' and I need to calculate the sum for each member. If this array has 3 entries,

    I would get three constraints, which I can sum up to: result == z[firstMember]+z[secondMember]+z[thirdMember].

    In my python code, it looks like:

    for member in membersArray:
    model.addConstr(z[member] == quicksum((y[j1]*x[member,j2] * dictionary1[j1,j2] for j1 in J1 for j2 in J2)

    This 'result' value, which I could define as:

    model.addConstr(result == quicksum(z[member] for member in membersArray)

    is what I need to look up in the second dictionary (for the only y which is 1, so I don't need the j2 for this).

    The second dictionary look-up would look like:

    dictionary2[result]

    As I cannot use model variables to index other variables or parameters, this wouldn't be feasible, would it?

    Simon

     

    0
  • Simon Lackmann
    • Gurobi-versary
    • First Comment
    • First Question

    As the result is some Integer value between -5 and 5, I thought about something like an implication. But the only way I could imagine this is as follows (with an example value of 3):

     model.addConstr(result==3 <= u_3)

    where u is some binary variable for each of the 11 outcomes. But of course this would also not work, as 'result' has no bool value. Is there any workaround?

    Simon

    0
  • Eli Towle
    • Gurobi Staff

    Hi Simon,

    This should still be possible with a different formulation. Again, let \( v \) be the variable you call "result," and let \( d \) be the second dictionary. In addition to the constraints you have written, we introduce variables \( u \in \{0,1\}^{11} \) (there are 11 possible values for \( v \)). Then, we add the following constraints:

    $$\begin{align*}\sum_{i = 1}^{11} (i-6) u_i &= v \\ \sum_{i = 1}^{11} u_i &= 1. \end{align*}$$

    The idea is that exactly one the \( u_i \) variables will be equal to \( 1 \), and this index \( i \) will satisfy \( v = i - 6 \). Finally, we introduce a new variable \( w \) and set it equal to the value of "dictionary2[result]" with the constraint:

    $$w = \sum_{i = 1}^{11} d_{i - 6} u_i.$$

    In Python, we can equivalently write this as:

    # Integers from -5 to 5
    M = range(-5,6)

    # Add auxiliary variables
    u = model.addVars(M, vtype=GRB.BINARY, name="u")
    w = model.addVar(lb=-GRB.INFINITY, name="w")

    # Exactly one u_i is 1, such that result = i
    model.addConstr(u.sum() == 1)
    model.addConstr(result == quicksum(i*u[i] for i in M))

    # Set w equal to dictionary2[result]
    model.addConstr(w == u.prod(dictionary2))

    Does this work? Thanks!

    Eli

    0
  • Simon Lackmann
    • Gurobi-versary
    • First Comment
    • First Question

    Hello Eli,

    Thanks again for your reply. Your approach helped me to understand my problem and I was able to solve it :)

    Simon

     

    0

投稿コメントは受け付けていません。