Using a for loop for a single or specific value in variable list in constraint formulation
回答済みtime = list()
for x in range(0,int(num_t)):
time.append(x)
Resources=steel.addVars(res_list,time,vtype=GRB.INTEGER,name="Resources")
Tasks=steel.addVars(task_list,time,vtype= GRB.BINARY,name="Tasks")
My res_list is also a list
My time is also a list
Now When I am writing this,
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in x)==1 for res in res_list3),name="Endresources")
where
x=[]
x.append(time[95])
But In Constraints it is showing,
Endresources[150],Endresources[151]........
Instead it should show:
Endresources[150,95],Endresources[151,95]......
How can I use "time" in Constraint instead of "x"
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in x )==1 for res in res_list3),name="Endresources")
-
It will be easier to think if you post your constraints math equation. Anyway,
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in x )==1 for res in res_list3),name="Endresources")
"for res in res_list3" at the end of the code means for all
say we have i = [1,2], k =[ 4,5] then, the above equation becomes D_1, D_2 (excluding D_1,4 and so on)
If you dont need for all in your equation, you can try something like below to produce D_1,4 ; D_1,5; D_2,4, D_2,5
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t]==1)
for t in x for res in res_list3),name="Endresources")0 -
Comment outside of your question: Its better to be consistent on naming the variables e.g. all INDICES with small_loc two/few letters e.g. time, res and then associated SET with CapLock maybe. e.g. Time, Resources
for time in Time for res in Resources
compared to
for t in r for res in res_listAlso, we already know that Resources is a Python list since it is a SET in the model equation. Typically, we can adapt direct words/notation from the math equation from the manuscript/related documents. easier to track which one is index and which one is set in the model.
0 -
Note that
(gp.quicksum(Resources[res,t]==1)
will not work because quicksum requires a list of terms.
How can I use "time" in Constraint instead of "x"
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in time )==1 for res in res_list3),name="Endresources")
Regarding the naming of constraints, could you please elaborate more what exactly you want to achieve?
Currently you construct your constraint over the \(\texttt{res_list3}\) so the constraint names are indexed over the \(\texttt{res_list3}\) list. Now you seem to have an additional single value \(95\) which you would like to add to the name? Is this correct? You could just hard code it
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in time )==1 for res in res_list3),name="Endresources_95")
0 -
Hi Jaromil, First of all many thanks for the reply.
Let me clear out some points.
Data:
[res_cat2idx, res_num] = [OrderedDict([('EAF', [1]), ('AOD', [2]), ('LF', [3]), ('CC1', [4]), ('CC2', [5]), ('H_A_S1', range(6, 30)), ('H_A_S2', range(30, 54)), ('H_B_S2', range(54, 78)), ('H_A_S3', range(78, 102)), ('H_B_S3', range(102, 126)), ('H_A_S4', range(126, 150)), ('H_B_S4', range(150, 174)), ('EN', [174])]), 174]
[tasks, task_num] =[OrderedDict([('EAF', range(1, 25)), ('TR_S1', range(25, 49)), ('AOD', range(49, 73)), ('TR_S2', range(73, 97)), ('LF', range(97, 121)), ('TR_S3', range(121, 145)), ('CC1', range(145, 151)), ('CC2', range(151, 157))]), 156]
time = list()
for x in range(0,int(num_t)):
time.append(x)
res_list = [res for cat, cat_res in res_cat2idx.items() for res in cat_res]
task_list=[task for cat, cat_task in tasks.items() for task in cat_task]Now I am defining my Variables:
Resources=steel.addVars(res_list,time,vtype=GRB.INTEGER,name="Resources")
Tasks=steel.addVars(task_list,time,vtype= GRB.BINARY,name="Tasks")I have this constraint:
where
1)R : Resources(Variable)
2)H should be some values from res_list :(like)
res_list3 = [res for cat, cat_res in res_cat2idx.items() if cat == 'H_B_S4' for res in cat_res]
3)T should be (time[95]) , means the value is also 95(if you see time list)
So I have done:
x=[]
x.append(time[95])& with this, I have formulated my constraint like:
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in x)==1 for res in res_list3 for t in x),name="Endresources")
BUT:
I wanted to ask that:
The constraint should be formulated using the attributes of Variables right?
By this, I mean:
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in time)==1 for res in res_list for t in x),name="Endresources")
BUT, How Can I use specific values from those lists which are passed as a attribute in Variables?
And Suppose If I dont do so, Will Gurobi use incorrect Variables?
0 -
Apologies, but I think I still don't fully understand your issue with the \(\texttt{Endresources}\) constraints.
BUT, How Can I use specific values from those lists which are passed as a attribute in Variables?
And Suppose If I dont do so, Will Gurobi use incorrect Variables?
What do you exactly mean by pass as an attribute in Variables? Do you want to use a variable with a specific index? Do you want to set some variable attributes? Note that variable attributes such as the solution value are filled by Gurobi after optimization has been performed.
Regarding your \(\texttt{Endresources}\) constraints
Endresources=steel.addConstrs((gp.quicksum(Resources[res,t] for t in time)==1 for res in res_list for t in x),name="Endresources")
You are using variable \(\texttt{t}\) twice which may lead to wrong results, so it is better to one of those by, e.g., \(\texttt{t1}\). The above statement will generate constraints
\[\begin{align*}
\sum_t Resources_{res,t} = 1 \quad \forall res
\end{align*}\]
The \(\texttt{for t in x}\) does not really do anything because \(\texttt{x}\) holds only 1 item.To get more clarity on what exactly is happening and how your constraints look like, please generate a human-readable LP file after you added all constraints via
steel.write("steel.lp")
The above command will generate a file called \(\texttt{steel.lp}\) which you can inspect and see what model you constructed.
If this does not help, please write what constraint you are currently constructing as you will see in the \(\texttt{steel.lp}\) file and state what the constraint should actually look like.
0 -
Steel.lp
returns me only the "WARNING"
It doesn't return me the human readable form.
I am writing what I am expecting:
"Do you want to use a variable with a specific index?"
YES
where:
res= (Specific indexes from res_list)
res_list3 = [res for cat, cat_res in res_cat2idx.items() if cat == 'H_B_S4' for res in cat_res]
t= (Last index of time)
time[95]
What do you exactly mean by pass as an attribute in Variables?
As you see I am using res_list 3 in my for loop instead of res_list (which is a attribute of my variable)
Will this create an ISSUE?
0 -
Thanks for the clarification.
returns me only the "WARNING"
The file will still be generated and you can look at it in any text editor.
"Do you want to use a variable with a specific index?"
YES
Then you have to loop the quicksum over res instead of time.
Endresources=steel.addConstr((gp.quicksum(Resources[res,time[95]] for res in res_list3)==1 ),name="Endresources_time[95]")
As you see I am using res_list 3 in my for loop instead of res_list (which is a attribute of my variable)
I think this is causing some confusion. It is not an attribute of the variable but the index of the respective tupledict. Variable attributes are listed in the documentation.
Will this create an ISSUE?
No, it should not create an issue.
0 -
Many thanks Jaromil for the infotmation:
My last question to make it very clear from the above explanation:
The Data is posted in previous comments.
y=[]
for res_cat, resources in res_cat2idx.items():
if 'H_A_' not in res_cat:
continue
y.append(resources)Transfertime=steel.addConstrs((((Resources[res,t] for res in y) == 0)for res in y for t in time),name ="Transfertime")
As you can see, it is using range , But I want every element from that range:
Can you please explain?
By this I feel I will now understand writing constraints.0 -
You have to turn the ranges saved in \(\texttt{y}\) to lists. Otherwise, it is interpreted as a string in this case.
Transfertime=steel.addConstrs((((Resources[res,t] for res in list(y)) == 0) for t in time),name ="Transfertime")
Please note that I removed the second \(\texttt{for res in y}\) because otherwise you would loop over \(\texttt{y}\) in each quicksum and when constructing constraints via addConstrs, so you would have the same constraint multiple times but with a different name.
If you are using the range object in a similar manner across the rest of your code, you should adjust the quicksum and addConstrs calls as above.
0 -
Yes Jaromil I understood your point.
But doing so, There is some issue.
See now my constraint is looking like:
.
Instead it should look like:
(6,0)
(6,1)
(6,2)........so on.....till last element: (150,95)0 -
Yes Ofcourse:
0 -
The issue with range is even bigger because it gets interpreted as a string when constructing constraints. It would be best if you would work with lists instead of the range object. So you should go with
# intermediate products and final products, A - after, B - before
for stage in range(1, num_stage+1):
res_cat2idx['H_A_S%s' % stage] = list(range(r_idx, r_idx + num_heats)) #'H_A_S1'=EAd1 (after stage1) 'H_B_S4'=EAs4(before stage4) #'H_A_S4'=intermediate product after stage 4 i.e final products heats
r_idx = r_idx + num_heats
if int(stage) == 1:
continue
res_cat2idx['H_B_S%s' % stage] = list(range(r_idx, r_idx + num_heats))
r_idx =r_idx + num_heatsThere are possibly other place which would need adjustment.
For Transfertime the following should work
y={}
for res_cat, resources in res_cat2idx.items():
if 'H_A_' not in res_cat:
continue
y[res_cat]= list(resources)
Transfertime=steel.addConstrs(((gp.quicksum(Resources[res,t] for res in y[y1]) == 0) for y1 in y for t in time),name ="Transfertime")Please note that Transfertime was missing a quicksum. This is the reason why from time to time you definitely should write a \(\texttt{steel.lp}\) file and have a look at what you actually constructed.
0 -
As you can see My variables looks like:
Reources(res_cat,time)
instead It should look like:
Resources(resources,time)
0 -
This is the reason why from time to time you definitely should write a steel.lp file and have a look at what you actually constructed.
Can we write steel.lp before optimising it?
0 -
Can we write steel.lp before optimising it?
Yes
0 -
Ok Jaromil but can you please elaborate why the constraints are looking thus?
Do you want me to provide my queries here in a single post?
Just to make it very clear !
0 -
Do you want me to provide my queries here in a single post?
Yes, please elaborate which constraints you mean, how they look now and how they should look like. It would be great if you could provide a code snippet which constructs only the constraints of interest and holds all lists and dictionaries that are needed. The snippet should be self contained.
Please do not post your whole code.
0 -
Variables:
res_list = [res for cat, cat_res in res_cat2idx.items() for res in cat_res]
task_list=[task for cat, cat_task in tasks.items() for task in cat_task]
[res_cat2idx,tasks ,time- already provided above)
Resources=steel.addVars(res_list,time,vtype=GRB.INTEGER,name="Resources")
Tasks=steel.addVars(task_list,time,vtype= GRB.BINARY,name="Tasks")Constraint:
It looks like:
where: task =
heat2tasks = [task for task_cat, task_list2 in tasks.items()
if 'CC' not in task_cat for task in task_list2]
It should look like:
Constraint:
where res :
Values of H_A_S1,H_A_S2,H_A_S3,H_A_S4 in res_cat2idx.
It looks like:
Instead: It should look like:
(Note: H_A_S1 = List =[6,7,8,9....30])
Constraint:
where:x={}
for res_cat, resources in res_cat2idx.items():
if 'H_B_' not in res_cat:
continue
max_wait_time = trans_time_max['TR
_S%d' % (int(res_cat[-1]) - 1)]
min_tran_time = trans_time['TR_S%d' % (int(res_cat[-1]) - 1)]
for res in resources: # each heat a constraint
x[res] = (math.ceil((max_wait_time-min_tran_time)/rtn_t0))
Transfertime1= steel.addConstrs((gp.quicksum(Resources[res,t] for t in time )<=x[res]
for res in x.keys()),name="Transfertime1")
It looks like:
Instead it should look like:
Constraint:
where:
res = res_list3 = [res for cat, cat_res in res_cat2idx.items() if cat == 'H_B_S4' for res in cat_res]
It looks like:
Instead it should look like:
I hope I made it brief.Kindly Jaromil let me know what are the tiny things I am missing out, As this is the very initial of me doing GUROBI.
0 -
Let's do it step by step and start with \(\texttt{Taskexecution}\). You are currently constructing the constraints
\[\begin{align*}
\sum_{t \in time} Tasks_{task,t} = 1 \quad \forall task \in heat2task
\end{align*}\]The constraints are called \(\texttt{Taskexecution[task]}\) with \(\texttt{task in heat2task}\), which look exactly as you wanted \(\sum_t N_{task,t} = 1 \forall task\). You can verify it by writing the model
steel.write("steel.lp")
opening the \(\texttt{steel.lp}\) file in any standard text editor and looking at \(\texttt{Taskexecution}\) constraints. You will see
Taskexecution[1]: Tasks[1,0] + Tasks[1,1] + ... = 1
Taskexecution[2]: Tasks[2,0] + Tasks[2,1] + ... = 1
...which look exactly as expected.
You say you want that the constraints look like \(N_{task,0}, N_{task,1}, \dots \) but this does not correspond to \(\sum_t N_{task,t} = 1 \forall task\).
Could you please clarify whether you want constraints \(\sum_t N_{task,t} = 1 \forall task\) or some other constraints called \(N_{task,0}, N_{task,1}, \dots \).
0 -
Okay, Lets do step by step... I will share my ".lp" file also.So it is very clear:
1)Task Excecution Constraint:
Taskexecution=steel.addConstrs((gp.quicksum(Tasks[task,t] for t in time)==1 for task in heat2tasks for t in time),name="Taskexecution")
Output:
1)
Last Constraint: [ I hope that is what is wanted but one thing: It should be called Task Execution[task] , instead it is showing: Taskexecution[task,t] ]
0 -
It does that because you have a redundat \(\texttt{for t in time}\) loop to construct constraints
Taskexecution=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time)==1
for task in heat2tasks
for t in time )
,name="Taskexecution")which should rather be
Taskexecution=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time)==1
for task in heat2tasks)
,name="Taskexecution")Does this work now?
0 -
Yes Jaromil, It works now. THANKS.
Lets move to second one.
2) Transfer time constraint:
y={}
for res_cat, resources in res_cat2idx.items():
if 'H_A_' not in res_cat:
continue
y[res_cat]= list(resources)
Transfertime=steel.addConstrs(((gp.quicksum(Resources[res,t] for res in y[y1]) == 0) for y1 in y for t in time),name ="Transfertime")Ouput:[WRONG]
IT SHOULD BE:
Transfertime[0]: Resources[6,0] = 0
Resources[7,0] =0
Resources[8,0]= 0
Resources[9,0] = 0
Resources[10,0] = 0
Resources[11,0] = 0
Resources[12,0]= 0
Resources[13,0] =0
Resources[14,0] =0
Resources[15,0] =
Resources[16,0]=0
Resources[17,0] =0
Resources[18,0] = 0
Resources[19,0] = 0
Resources[20,0]= 0
Resources[21,0] =0
Resources[22,0] =0
Resources[23,0] = 0
Resources[24,0]=0
Resources[25,0] = 0
Resources[26,0] = 0
Resources[27,0] = 0
Resources[28,0]= 0
Resources[29,0] = 0
Transfertime[1]:
Resources[6,1] =0
Resources[7,1] =0
Resources[8,1] = 0........0 -
Please note that
Transfertime[0]: Resources[6,0] = 0
Resources[7,0] =0
Resources[8,0]= 0
Resources[9,0] = 0
Resources[10,0] = 0
Resources[11,0] = 0
Resources[12,0]= 0
Resources[13,0] =0
Resources[14,0] =0
Resources[15,0] =
Resources[16,0]=0
Resources[17,0] =0
Resources[18,0] = 0
Resources[19,0] = 0
Resources[20,0]= 0
Resources[21,0] =0
Resources[22,0] =0
Resources[23,0] = 0
Resources[24,0]=0
Resources[25,0] = 0
Resources[26,0] = 0
Resources[27,0] = 0
Resources[28,0]= 0
Resources[29,0] = 0is not possible, because every equality \(\texttt{Resource[x,y]=0}\) is a constraints and thus, has to have a unique constraint name. The best you could do is
Transfertime[6,0]: Resources[6,0] = 0
Transfertime[6,1]: Resources[6,1] = 0
Transfertime[6,2]: Resources[6,2] = 0
Transfertime[6,3]: Resources[6,3] = 0
Transfertime[6,4]: Resources[6,4] = 0
Transfertime[6,5]: Resources[6,5] = 0
Transfertime[6,6]: Resources[6,6] = 0
Transfertime[6,7]: Resources[6,7] = 0
Transfertime[6,8]: Resources[6,8] = 0
Transfertime[6,9]: Resources[6,9] = 0
Transfertime[6,10]: Resources[6,10] = 0
...This can be done with
y={}
for res_cat, resources in res_cat2idx.items():
if 'H_A_' not in res_cat:
continue
y[res_cat]= list(resources)
for key in y:
y_list = y[key]
Transfertime=steel.addConstrs((Resources[res,t] == 0 for res in y_list for t in time),name ="Transfertime")Note that you have to use an additional \(\texttt{for}\)-loop to get the correct list out of your \(\texttt{y}\) dictionary.
0 -
I understand what you are trying to say : but:
YOUR OUTPUT SAYS:
your loop runs FIRST for t
THEN for res
But,
your code says :
loop is running for res first & t later...
Just for understanding.
0 -
I am writing next constraint (which has a issue) for further discussion :
Constraint:
Taskexecution1=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time)==1
for task in group2tasks
for group in range(1, num_groups + 1))
,name="Taskexecution1")where:
group2tasks = dict()
for group in range(1, num_groups + 1):
group2tasks[group] = [tasks[caster][group - 1] for caster in stage2units['4'].keys()]
num_groups=6
stage2units = {'1': {'EAF': 2}, '2': {'AOD': 2}, '3': {'LF': 2}, '4': {'CC1': 1, 'CC2': 1}}Output:[WRONG]
Taskexecution1[1,1]: Tasks[1,0] + Tasks[1,1] + Tasks[1,2] + Tasks[1,3]
+ Tasks[1,4] + Tasks[1,5] + Tasks[1,6] + Tasks[1,7] + Tasks[1,8]
+ Tasks[1,9] + Tasks[1,10] + Tasks[1,11] + Tasks[1,12] + Tasks[1,13]
+ Tasks[1,14] + Tasks[1,15] + Tasks[1,16] + Tasks[1,17] + Tasks[1,18]
+ Tasks[1,19] + Tasks[1,20] + Tasks[1,21] + Tasks[1,22] + Tasks[1,23]
+ Tasks[1,24] + Tasks[1,25] + Tasks[1,26] + Tasks[1,27] + Tasks[1,28]
+ Tasks[1,29] + Tasks[1,30] + Tasks[1,31] + Tasks[1,32] + Tasks[1,33]
+ Tasks[1,34] + Tasks[1,35] + Tasks[1,36] + Tasks[1,37] + Tasks[1,38]
+ Tasks[1,39] + Tasks[1,40] + Tasks[1,41] + Tasks[1,42] + Tasks[1,43]
+ Tasks[1,44] + Tasks[1,45] + Tasks[1,46] + Tasks[1,47] + Tasks[1,48]
+ Tasks[1,49] + Tasks[1,50] + Tasks[1,51] + Tasks[1,52] + Tasks[1,53]
+ Tasks[1,54] + Tasks[1,55] + Tasks[1,56] + Tasks[1,57] + Tasks[1,58]
+ Tasks[1,59] + Tasks[1,60] + Tasks[1,61] + Tasks[1,62] + Tasks[1,63]
+ Tasks[1,64] + Tasks[1,65] + Tasks[1,66] + Tasks[1,67] + Tasks[1,68]
+ Tasks[1,69] + Tasks[1,70] + Tasks[1,71] + Tasks[1,72] + Tasks[1,73]
+ Tasks[1,74] + Tasks[1,75] + Tasks[1,76] + Tasks[1,77] + Tasks[1,78]
+ Tasks[1,79] + Tasks[1,80] + Tasks[1,81] + Tasks[1,82] + Tasks[1,83]
+ Tasks[1,84] + Tasks[1,85] + Tasks[1,86] + Tasks[1,87] + Tasks[1,88]
+ Tasks[1,89] + Tasks[1,90] + Tasks[1,91] + Tasks[1,92] + Tasks[1,93]
+ Tasks[1,94] + Tasks[1,95] = 1
Taskexecution1[1,2]: Tasks[1,0] + Tasks[1,1] + Tasks[1,2] + Tasks[1,3]
+ Tasks[1,4] + Tasks[1,5] + Tasks[1,6] +.......IT SHOULD BE:
Taskexecution1[145]: Tasks[145,0] + Tasks[145,1] + Tasks[145,2] + Tasks[145,3]
+ Tasks[145,4] + Tasks[145,5] + Tasks[145,6] + Tasks[145,7] + Tasks[145,8]
+ Tasks[145,9] + Tasks[145,10] + Tasks[145,11] + Tasks[145,12] + Tasks[145,13]
+ Tasks[145,14] + Tasks[145,15] + Tasks[145,16] + Tasks[145,17] + Tasks[145,18]
+ Tasks[145,19] + Tasks[145,20] + Tasks[145,21] + Tasks[145,22] + Tasks[145,23]
+ Tasks[145,24] + Tasks[145,25] + Tasks[145,26] + Tasks[145,27] .......+Tasks[145,95]= 1
Taskexecution1[151]: Tasks[151,0] + Tasks[151,1] + Tasks[151,2] + Tasks[151,3]
+ Tasks[151,4] + Tasks[151,5] + Tasks[151,6] +.....+Tasks[151,95] =1
Taskexecution[156]:.....I think it has been coded also perfectly. I am unsure why it is throwing output like this.
0 -
I understand what you are trying to say : but:
YOUR OUTPUT SAYS:
your loop runs FIRST for t
THEN for res
But,
your code says :
loop is running for res first & t later...
Just for understanding.
There is no first and second loop. There is an outer loop \(\texttt{for res in y_list}\) and an inner loop \(\texttt{for t in time}\). So the code
for key in y:
y_list = y[key]
Transfertime=steel.addConstrs((Resources[res,t] == 0 for res in y_list for t in time),name ="Transfertime")is equivalent to
for key in y:
y_list = y[key]
for res in y_list:
for t in time:
Transfertime=steel.addConstr((Resources[res,t] == 0 ),name ="Transfertime[%d,%d]"%(res,t))and produces
Transfertime[6,0]: Resources[6,0] = 0
Transfertime[6,1]: Resources[6,1] = 0
Transfertime[6,2]: Resources[6,2] = 0
Transfertime[6,3]: Resources[6,3] = 0
Transfertime[6,4]: Resources[6,4] = 0
Transfertime[6,5]: Resources[6,5] = 0
Transfertime[6,6]: Resources[6,6] = 0
...If you want to switch the indices, you just have to switch the inner and outer loop
for key in y:
y_list = y[key]
Transfertime=steel.addConstrs((Resources[res,t] == 0 for t in time for res in y_list ),name ="Transfertime")will produce
Transfertime[0,6]: Resources[6,0] = 0
Transfertime[0,7]: Resources[7,0] = 0
Transfertime[0,8]: Resources[8,0] = 0
Transfertime[0,9]: Resources[9,0] = 0
Transfertime[0,10]: Resources[10,0] = 0
Transfertime[0,11]: Resources[11,0] = 0
Transfertime[0,12]: Resources[12,0] = 0
...You can always write the LP file and inspect it to verify any change yourself. It is way easier and more convincing to start verifying things on your own.
0 -
You can see that in the following constraint
Taskexecution1=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time)==1
for task in group2tasks
for group in range(1, num_groups + 1))
,name="Taskexecution1")you dont use \(\texttt{group}\) at all but it will still generate an additional loop and an additional index layer. Simply removing it to get
Taskexecution1=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time ) ==1
for task in group2tasks),
name="Taskexecution1")which generates
Taskexecution1[1]: Tasks[1,0] + Tasks[1,1] + Tasks[1,2] + Tasks[1,3]
+ Tasks[1,4] + Tasks[1,5] + Tasks[1,6] + Tasks[1,7] + Tasks[1,8]
+ Tasks[1,9] + Tasks[1,10] + Tasks[1,11] + Tasks[1,12] + Tasks[1,13]
+ Tasks[1,14] + Tasks[1,15] + Tasks[1,16] + Tasks[1,17] + Tasks[1,18]
+ Tasks[1,19] + Tasks[1,20] + Tasks[1,21] + Tasks[1,22] + Tasks[1,23]
+ Tasks[1,24] + Tasks[1,25] + Tasks[1,26] + Tasks[1,27] + Tasks[1,28]
+ Tasks[1,29] + Tasks[1,30] + Tasks[1,31] + Tasks[1,32] + Tasks[1,33]
+ Tasks[1,34] + Tasks[1,35] + Tasks[1,36] + Tasks[1,37] + Tasks[1,38]
+ Tasks[1,39] + Tasks[1,40] + Tasks[1,41] + Tasks[1,42] + Tasks[1,43]
+ Tasks[1,44] + Tasks[1,45] + Tasks[1,46] + Tasks[1,47] + Tasks[1,48]
+ Tasks[1,49] + Tasks[1,50] + Tasks[1,51] + Tasks[1,52] + Tasks[1,53]
+ Tasks[1,54] + Tasks[1,55] + Tasks[1,56] + Tasks[1,57] + Tasks[1,58]
+ Tasks[1,59] + Tasks[1,60] + Tasks[1,61] + Tasks[1,62] + Tasks[1,63]
+ Tasks[1,64] + Tasks[1,65] + Tasks[1,66] + Tasks[1,67] + Tasks[1,68]
+ Tasks[1,69] + Tasks[1,70] + Tasks[1,71] + Tasks[1,72] + Tasks[1,73]
+ Tasks[1,74] + Tasks[1,75] + Tasks[1,76] + Tasks[1,77] + Tasks[1,78]
+ Tasks[1,79] + Tasks[1,80] + Tasks[1,81] + Tasks[1,82] + Tasks[1,83]
+ Tasks[1,84] + Tasks[1,85] + Tasks[1,86] + Tasks[1,87] + Tasks[1,88]
+ Tasks[1,89] + Tasks[1,90] + Tasks[1,91] + Tasks[1,92] + Tasks[1,93]
+ Tasks[1,94] + Tasks[1,95] + Tasks[1,96] = 1
Taskexecution1[2]: Tasks[2,0] + Tasks[2,1] + Tasks[2,2] + Tasks[2,3]
...0 -
group2tasks:{
1: [145, 151],
2: [146, 152],
3: [147, 153],
4: [148, 154],
5: [149, 155],
6: [150, 156]
}This is my group2tasks dict.
Hence by OUTPUT SHOULD BE:Taskexecution1[145]: Tasks[145,0] + Tasks[145,1] + Tasks[145,2] + Tasks[145,3]
+ Tasks[145,4] + Tasks[145,5] + Tasks[145,6] + Tasks[145,7] + Tasks[145,8]
+ Tasks[145,9] + Tasks[145,10] + Tasks[145,11] + Tasks[145,12] + Tasks[145,13]
+ Tasks[145,14] + Tasks[145,15] + Tasks[145,16] + Tasks[145,17] + Tasks[145,18]
+ Tasks[145,19] + Tasks[145,20] + Tasks[145,21] + Tasks[145,22] + Tasks[145,23]
+ Tasks[145,24] + Tasks[145,25] + Tasks[145,26] + Tasks[145,27] .......+Tasks[145,95]= 1
Taskexecution1[151]: Tasks[151,0] + Tasks[151,1] + Tasks[151,2] + Tasks[151,3]
+ Tasks[151,4] + Tasks[151,5] + Tasks[151,6] +.....+Tasks[151,95] =1
Taskexecution[156]:....0 -
"You can always write the LP file and inspect it to verify any change yourself. It is way easier and more convincing to start verifying things on your own."-
That was a wonderful explanation Jaromil.
0 -
When you loop over a dictionary such as \(\texttt{group2tasks}\) via, e.g., \(\texttt{for task in group2tasks}\) then \(\texttt{tasks}\) will attain the key values of the dictionary and not its actual item values. You can add an additional \(\texttt{for}\)-loop to actually go over the dictionary items which are lists.
for key in group2tasks:
Taskexecution1=steel.addConstrs(
(gp.quicksum(Tasks[task,t] for t in time ) ==1
for task in group2tasks[key]),name="Taskexecution1")I would recommend to have a look at some Python tutorials to better understand how basic Python data structures work which would help you avoid such issues. I fully understand that working with Gurobi for the first time can be overwhelming (I have been there myself). This is the reason why understanding the programming language behavior as good as possible is a tremendous help.
0
サインインしてコメントを残してください。
コメント
207件のコメント