tupledict.prod() with partial dictionary key
AnsweredHi,
Similar to that in the documentation, suppose that I have 3-D 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