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

## コメント

14件のコメント

• Gurobi Staff

Variable objects don't have a value and thus, cannot be used in $$\texttt{if}$$-clauses or any similar checks. This means that the check $$\texttt{x[f] <= t}$$ cannot be evaluated when constructing the model. You have to formulate the conditional statement via additional binary variables and constraints. Please have a look at How do I model conditional statements in Gurobi? for more details.

Once you have formulated the conditional statements, you can use Gurobi's addGenConstrAnd method to formulate the "and" condition in your first $$\texttt{if}$$-clause.

You second $$\texttt{if}$$-clause actually reads $$\texttt{if x[f] = t then add constraints}$$. Formulating an equality check where $$x$$ is a continuous variable is tricky. The stackexchange post In an integer program, how I can force a binary variable to equal 1 if some condition holds? describes a good way to approach this.

Best regards,
Jaromił

Thanks a lot! However, there was a typing error for the second if-clause, the code is actually:

t = 0
for t in range(288):
for f in tof.keys():
if x[f] <= t and t <= x[f] + 6:
else:
t += 1
if x[f] <= t <= z[f]:
for p in fleetType:
else:
t += 1

I guess it could be solved using the same method as the first if-clause?

Hi again! I revised the code compression like this:

for t in range(288):
for f in tof.keys():
m.addConstr(t >= x[f] - M * (1-s), 'BigM1-1')
m.addConstr(t <= x[f] + M * s, 'BigM1-2')

m.addConstr(x[f] + 6 >= t - M * (1-h), 'BigM2-1')
m.addConstr(x[f] + 6 <= t + M * h, 'BigM2-2')

m.addConstr(z[f] >= t - M * (1-h2), 'BigM3-1')
m.addConstr(z[f] <= t + M * h2, 'BigM3-2')

t = 0
for t in range(288):
if x2 == 1:
else:
t += 1

if y2 == 1:
for p in fleetType:
else:
t += 1

However, the error still occurs:

Error code 0: Constraint has no bool value (are you trying "lb <= expr <= ub"?)

Is there anything I didn't get?

• Gurobi Staff

I guess it could be solved using the same method as the first if-clause?

Yes, exactly.

However, the error still occurs:

Error code 0: Constraint has no bool value (are you trying "lb <= expr <= ub"?)

Is there anything I didn't get?

As mentioned in my first message, it is not possible to use Var objects for comparisons. Thus, the $$\texttt{if}$$-clause $$\texttt{if x2 == 1}$$ and $$\texttt{if y2 == 1}$$ result in an error. You have to formulate these $$\texttt{if}$$-statements with the help of binary variables and (in)equality constraints. Luckily, in your case you can use Gurobi's indicator constraints to formulate your $$\texttt{if}$$-statements.

What I don't understand is, why you loop over $$\texttt{t}$$, when you have only exactly one variable $$\texttt{x2}$$ and $$\texttt{y2}$$.

Best regards,
Jaromił

I got it. I need to set the variables differently so that it would go with the loop for t. Thanks for your time help!!!!

Hi Jaromił,

I've tried again using the code like this:

try:
m = Model()

x = m.addVars(tof.keys(), lb = 0, ub= 287, vtype=GRB.CONTINUOUS, name='x')

z = m.addVars(tdf.keys(), lb = 0, ub = 287, vtype=GRB.CONTINUOUS, name='z')

for t in range(288):
for f in tof.keys():
m.addConstr(t >= x[f] - M * (1-s[t]), 'BigM1-1')
m.addConstr(t <= x[f] + M * s[t], 'BigM1-2')

m.addConstr(x[f] + 6 >= t - M * (1-h[t]), 'BigM2-1')
m.addConstr(x[f] + 6 <= t + M * h[t], 'BigM2-2')

m.addConstr(z[f] >= t - M * (1-h2[t]), 'BigM3-1')
m.addConstr(z[f] <= t + M * h2[t], 'BigM3-2')

for t in range(288):

for t in range(288):
m.addGenConstrIndicator(x2[t], True, y.sum('*', '*') <= qk, 'c2')
m.addGenConstrIndicator(y2[t], True, y.sum('*', p) <= xp, 'c8')

However, the error: Error code 10003: Additional sense argument provided for general constraint of indicator type occurs.

Perhaps by using the addGenConstrIndicator the x2[t] and y2[t] cannot be decision variables?

In that way, I'm wondering how to form the code with the logics states that if the if x2[t] == 1(which is decided by the constraints 'andConstr1' and 'andConstr2') then the constraint must be satisfied.

Thank you！

Best regards，

Jingyue

• Gurobi Staff

Hi Jingyue,

The addGenConstrIndicator method has the arguments $$\texttt{(binvar, binval, lhs, sense=None, rhs=None, name="" )}$$. The $$\texttt{lhs}$$ argument can be a float, Var, LinExpr, or a TempConstr object. If you provide a TempConstr object for the $$\texttt{lhs}$$ argument, you won't provide the $$\texttt{sense}$$ and $$\texttt{rhs}$$ argument. In this case, you have to explicitly specify that you define the $$\texttt{name}$$ argument.

for t in range(288):  m.addGenConstrIndicator(x2[t], True, y.sum('*', '*') <= qk, name='c2')  m.addGenConstrIndicator(y2[t], True, y.sum('*', p) <= xp, name='c8')

Best regards,
Jaromił

Hi Jaromił,

Today I reviewed my code and discovers that the logic might be wrong.

The logic I'm trying to express is:

't' stands for discrete time, and there are 288 time windows. For any time t, if the big M constraints about decision variables x[f] and z[f] are satisfied (s,h,h2,x2,y2,z2 are the binary variables for any time t), then the andconstrs occurs, however now my code looks like that t is an integer and it's looping from 0 to 287.

try:
m = Model()
print('building model')

x = m.addVars(tof.keys(), lb = 0, ub= 287,

vtype=GRB.CONTINUOUS, name='x')

z = m.addVars(tdf.keys(), lb = 0, ub = 287, vtype=GRB.CONTINUOUS, name='z')

for t in range(288):
for f in tof.keys():
m.addConstr(t[f] >= x[f] - M * (1-s[t]), 'BigM1-1')
m.addConstr(t[f] <= x[f] + M * s[t], 'BigM1-2')

m.addConstr(x[f] + 6 >= t[f] - M * (1-h[t]), 'BigM2-1')
m.addConstr(x[f] + 6 <= t[f] + M * h[t], 'BigM2-2')

m.addConstr(z[f] >= t[f] - M * (1-h2[t]), 'BigM3-1')
m.addConstr(z[f] <= t[f] + M * h2[t], 'BigM3-2')
for t in range(288):

for t in range(288):
m.addGenConstrIndicator(x2[t], True, y.sum('*', '*'), GRB.LESS_EQUAL, qk, 'c2')
m.addGenConstrIndicator(y2[t], True, y.sum('*', p), GRB.LESS_EQUAL, xp, 'c8')

I'm wondering is there any way to express the logic right?

Yours,

Jingyue

• Gurobi Staff

You would have to model a variable index as an optimization variable. This is possible but quite expensive. It is discussed in the Community post use a decision variable as an index.

Best regards,
Jaromił

Hi Jaromił,

I think I almost got it from the post you shared. It expresses a way to index x[t] andy[t] for Andconstraints.

However, I still quite not get how to express the bold part of "For any time t, if the big M constraints about decision variables x[f] and z[f] are satisfied (s,h,h2,x2,y2,z2 are the binary variables for any time t), then the andconstrs occurs".

Sorry to bother you if my question is silly :)

• Gurobi Staff

This is where it gets tricky. You would have to introduce 288 $$\times$$ tof.keys() t variables and model the big-M constraints with the particular t[i, f]. Then, you can use t[i, f] as index in your andconstr.

Hi Jaromił,

I defined the  t[i,f] and tried like this:

for i in range(288):
for f in flights:
tindex[i,f] = 0

try:
m = Model()

x = m.addVars(tof.keys(), lb = 0, ub= 287, vtype=GRB.CONTINUOUS, name='x')
z = m.addVars(tdf.keys(), lb = 0, ub = 287, vtype=GRB.CONTINUOUS, name='z')
ui = m.addVars(288,vtype=GRB.BINARY, name = 'ui')
t = m.addVars(tindex.keys(), vtype = GRB.BINARY, name = 't')

for i in range(288):
for f in tof.keys():

m.addConstr(t[i,f] >= x[f] - M * (1-s[f]), 'BigM1-1')
m.addConstr(t[i,f] <= x[f] + M * s[f], 'BigM1-2')

m.addConstr(x[f] + 6 >= t[i,f] - M * (1-h[f]), 'BigM2-1')
m.addConstr(x[f] + 6 <= t[i,f] + M * h[f], 'BigM2-2')

m.addConstr(z[f] >= t[i,f] - M * (1-h2[f]), 'BigM3-1')
m.addConstr(z[f] <= t[i,f] + M * h2[f], 'BigM3-2')

for t in range(288):
m.addGenConstrIndicator(x2[t], True, y.sum('*', '*'), GRB.LESS_EQUAL, qk, 'c2')
m.addGenConstrIndicator(y2[t], True, y.sum('*', p), GRB.LESS_EQUAL, xp, 'c8')

The error occurs:KeyError: '3848669'

'3848669' is the a key in tof.keys()

Also, if I try with this constraint:

for i in range(288):
for f in tof.keys():
"TypeError: 'gurobipy.LinExpr' object is not iterable" occurs.

I'm confused and wondering where it went wrong.

• Gurobi Staff

The error about not iterable object occurs because the $$\texttt{i* ui[i] }$$ is a LinExpr object which is not an iterable object such as a list for example. If you want to sum over all indices $$\texttt{i}$$, you should try

for f in tof.keys():  m.addConstr(quicksum(i* ui[i] for i in range(288)) == t.sum('*',f), 'index1')

I don't know about the KeyError. It points to an "out-of-array" access. I guess that it is some mismatch between $$\texttt{flights}$$ and $$\texttt{tof.keys()}$$.

Note that you defined $$\texttt{t}$$ as optimization variables so you definitely should not use it in your $$\texttt{for}$$-loop.

for i in range(288):  m.addGenConstrIndicator(x2[i], True, y.sum('*', '*'), GRB.LESS_EQUAL, qk, 'c2')  m.addGenConstrIndicator(y2[i], True, y.sum('*', p), GRB.LESS_EQUAL, xp, 'c8')

Hope this helps.

Thank you very much！！！！

I tried and it works!

サインインしてコメントを残してください。