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

Set value for variable based on condition (if marketer has access to arc)

回答済み

コメント

9件のコメント

  • 正式なコメント
    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?.
  • Jaromił Najman
    • Gurobi Staff

    Hi,

    Could you provide a mathematical formulation? This would ease the understanding of what you are trying to model, see Posting to the Community Forum for details on how to use MathJax. Additionally, please post a minimal working example reproducing your issue. You don't have to post the full code, just the parts which are enough to reproduce the error.

    Best regards,
    Jaromił

    1
  • Maniesegaran Sagadevan
    • Gurobi-versary
    • First Comment
    • First Question

    Dear Jaromil, thanks for your prompt response! 

    This is the code that i currently have.

    import gurobipy as gp
    from gurobipy import GRB

    ggm = gp.Model("Global Gas Model")

    A = {"BRA_USA", "ARG_CHI"}
    T = {"BRA"}

    t_acc_a = {("BRA","BRA_USA"): 1 }

    F_A= ggm.addVars(t_acc_a.keys(),vtype=GRB.CONTINUOUS,name="TraderArcFlow(mcm/year)")

    eq_mass_bal = {(t,a):  
    ggm.addConstr(
            lhs=2,
            sense=gp.GRB.EQUAL,
            rhs=gp.quicksum(F_A[t,a] for a in A),  
            name="Sum of sales cannot exceed arc flow".format(t,a))
        for t in T for a in A }

    It throws a key however since there is no key for ("BRA","ARG_CHI") in the dictionary t_acc_a. (marketer , t access to arc, a). The only workaround i can think of currently is to add a key ("BRA","ARG_CHI") with value 0 in the dictionary. This would mean however the the variable for arc flow F_A["BRA","ARG_CHI"] must be equal 0 (since the marketer does not have access to this arc. 

    I presume it will be something along the lines of: 

    for t in T:
    for a in A:
    if not t_acc_a[t,a]:
    F_A[t,a] = 0

    Would this be the correct formulation then?

    0
  • Jaromił Najman
    • Gurobi Staff

    Hi,

    You could go for

    gp.quicksum(F_A[t,a] for t,a in t_acc_a)

    Best regards,
    Jaromił

    1
  • Maniesegaran Sagadevan
    • Gurobi-versary
    • First Comment
    • First Question

    Thanks Jaromil,

    That doesnt work however, as the original equation is a lot more complex than the one presented here. 

    eq_mass_bal = {(t,n,d,y): 
    ggm.addConstr(
    lhs=grb.quicksum(Q_P[t,n,r,d,y] for r in R if t_acc_np[t,n])+grb.quicksum(F_A[t,a,d,y]*(1-l_a[a]) \
    for a in A if a_e[a,n])+grb.quicksum(F_X[t,n,w,d,y] for w in W),
    sense=grb.GRB.EQUAL,
    rhs=Q_S[t,n,d,y] + grb.quicksum(F_A[t,a,d,y] for a in A if a_s[a,n]) + grb.quicksum(F_I[t,n,w,d,y]for w in W),
    name="Sum of sales + injections + exports cannot exceed purchases + extractions + loss-adjusted imports".format(t,n,d,y))
    for t in T for n in N for d in D.keys() for y in Y}

    I am looking more for a way to set the value of variable F_A[t,a,d,y] based on whether it fulfills certain conditions. Thanks again ! :)

    0
  • Hendrik Weber
    • Gurobi-versary
    • First Question
    • Conversationalist

    Hey Maniesegaran,

    I see this question very often and I always refer to this video then: https://youtu.be/aKsfqB-ONfk?t=1686 

    I have linked to the part "sparsity done right", I found it very helpful [around minute 28].

    I also would advise against your proposed fix of simply defining the variables [to prevent any key errors] and then setting them to zero. This can be done in a more elegant fashion.

    I will check tomorrow at work whether I can find an example and let you know.
    Sometimes I do this via an "if-statement" in the grb.quicksum list comprehension to be as close to the mathematical set notation as possible. [Sum over all items of a set and that set only includes elements based on a specific logic, this is also addressed in the video at time stamp: 35:40]

    However I think for you these tuplelist.select and tupledict.selet might be of help:

    https://www.gurobi.com/documentation/9.1/refman/py_tuplelist_select.html

    https://www.gurobi.com/documentation/9.1/refman/py_tupledict_select.html 

    Regards

    Hendrik

    1
  • Maniesegaran Sagadevan
    • Gurobi-versary
    • First Comment
    • First Question

    Hey Hendrik !

    Thanks for your response, the video did clear some things up for me! I have indeed now solved most of the problems using a "if statement" in the grb.quicksum list. 

    eq_mass_bal = {(t,n,d,y):  
    ggm.addConstr(
    lhs=grb.quicksum(Q_P[t,n,r,d,y] for r in R if t_acc_np[t,n])+grb.quicksum(F_A[t,a,d,y]*(1-l_a[a]) \
    for a in A if a_e[a,n] if t_acc_a[t,a])+grb.quicksum(F_X[t,n,w,d,y] for w in W if t_acc_n[t,n] if map_w_n[w,n]),
    sense=grb.GRB.EQUAL,
    rhs= Q_S[t,n,d,y] + grb.quicksum(F_A[t,a,d,y] for a in A if a_s[a,n] if t_acc_a[t,a]) + grb.quicksum(F_I[t,n,w,d,y]for w in W if t_acc_n[t,n] if map_w_n[w,n]),
    name="Sum of sales + injections + exports cannot exceed purchases + extractions + loss-adjusted imports".format(t,n,d,y))
    for t in T for n in N for d in D.keys() for y in Y}

    I just have one question more. How would the code look if i used a conditional statement for a variable (Q_S on the rhs in this case) if im not summing it. If i simply write it as

    rhs= Q_S[t,n,d,y] if t_acc_n[t,n] + grb.quicksum(F_A[t,a,d,y]......

    it throws a syntax Error. Thanks again for your insights. I would also welcome the examples that you mentioned if you manage to find them !

    Regards,
    Manie

    0
  • Hendrik Weber
    • Gurobi-versary
    • First Question
    • Conversationalist

    Hey Manie,

    most of the things I do are also based on trial and error, so please take this with a grain of salt.
    One quick fix would be to also use quicksum and only sum over Q_S[t,n,d,y] using the list comprehension idea that you previously implemented:
    If Q_S[t,n,d,y] is defined for a specific combination of t,n,d,y, then you would be summing up over a list with length 1, only including that specific variable Q_S[t,n,d,y]. If Q_S[t,n,d,y] however is not defined, then the list comprehension would return an empty list, effectively summing up over 0 elements [making it 0 as intended].

    This seems kind of clunky however.

    1
  • Maniesegaran Sagadevan
    • Gurobi-versary
    • First Comment
    • First Question

    Dear Hendrik,

    Thank you so much for your insights. Helped me a lot. How do i set the question as solved then?

    0

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