tupledict.prod() with partial dictionary key
AnsweredHi,
Similar to that in the documentation, suppose that I have 3D variable x:
# My trial:
x = m.addVars([(1,2,0), (1,3,0), (2,3,0)]) # The indices are generated from tuplelist, in which the last index can span to T.
coeff = dict([((1,2), 2.0), ((1,3), 2.1), ((2,3), 3.3)])
expr = x.prod(coeff,1,'*','*')
# The result:
<gurobi.LinExpr: 0.0>
# Desired result:
2.0 x[1,2,0] + 2.1 x[1,3,0] + 3.3 x[2,3,0]

You are getting a \(0\) result, because the tuple key for your variables are of 3 while the ones for coeff are of length 2.
You can do
# My trial:
x = m.addVars([(1,2,0), (1,3,0), (2,3,0)]) # The indices are generated from tuplelist, in which the last index can span to T.
m.update()
coeff = dict([((1,2,0), 2.0), ((1,3,0), 2.1), ((2,3,0), 3.3)])
expr = x.prod(coeff,'*',3,'*')
print(expr)
> 2.1 C1 + 3.3 C2The pattern states to use only the entries with \(3\) in the second place.
0 
Thank you for your response.
I know that is a way to do that.
Let's say that the index is a tuple (i,j,t), where t < T.
I maintain parameter coeff to have 2 key lengths to avoid iterating coeff over T.
This is a simple reproducible code, where the actual simulation has more than 100 (i,j) pairs and T > 100.So, is it still impossible to use variable x and coeff with different key lengths?
Is there any other workaround? Or is it okay to just copy the coeff T times?0 
So, is it still impossible to use variable x and coeff with different key lengths?
No, this is not possible.
Is there any other workaround? Or is it okay to just copy the coeff T times?
There may be a workaround but I am not aware of one. Copying coeff T times should work well enough.
1 
Hi Panggah,
Jarek has given me the green light to post some creative solutions if you want to keep your data in its current format, which does have it's advantages  not sure if speed is one of them though.
# import gurobipy as gp
gp.quicksum(coeff[k1,k2]*v for (k1,k2,_),v in x.items())
gp.quicksum(coeff*x.sum(*k,"*") for k,coeff in coeff.items())
gp.quicksum(coeff*x.sum(k1,k2,"*") for (k1,k2),coeff in coeff.items())
gp.tupledict({k:x.sum(*k,"*") for k in coeff.keys()}).prod(coeff) Riley
1 
Thank you for your answers, Jaromil and Riley.
I will test the creation speeds of those options. Very interesting.0 
No problem, my advice for comparison is to use the following approach as an example:
import numpy as np
import timeit
setup = """
import gurobipy as gp
m = gp.Model()
x = m.addVar()
y = m.addVar()
"""
statement1= """
m.addConstr(x <= 2)
"""
statement2= """
m.addLConstr(x,"<=",2)
"""
factor = np.divide(
np.min(timeit.repeat(stmt=statement1, setup=setup, number=1, repeat=1000)),
np.min(timeit.repeat(stmt=statement2, setup=setup, number=1, repeat=1000)),
)It runs the code many times, then takes the minimum for comparison, to reduce the effect of noise on your machine.
 Riley
1
Please sign in to leave a comment.
Comments
6 comments