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

Answered-
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 -
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] = 0Would this be the correct formulation then?

0 -
Hi,

You could go for

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

Best regards,

Jaromił1 -
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 -
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 -
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,

Manie0 -
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 -
Dear Hendrik,

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

Please sign in to leave a comment.

## Comments

8 comments