Using a for loop for a single or specific value in variable list in constraint formulation
Answeredtime = 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")
-
Hi Jaromil,
I don't have a LP file generated rather I have the code. Do you want me to share the link to it?
And yes, I will also write how Resource balance constraint should look like. Give me 10 mins.
0 -
I don't have a LP file generated rather I have the code. Do you want me to share the link to it?
No, this would not help. I think that your description should be enough.
0 -
Hi Jaromil,
I have tried to formulate the constraint: I have examined one thing, Wherever Tasks[x,0] takes place, there is an issue. I mean whenever in the formulation if we have Task[x,0], there is an issue.
I will state below first few constraints:
Resourcebalance[1,0]: Resources[1,0] = 2
Resourcebalane[1,1]: - Resources[1,0] + Resources[1,1] + Tasks[1,1]
+ Tasks[2,1] + Tasks[3,1] + Tasks[4,1] + Tasks[5,1] + Tasks[6,1]
+ Tasks[7,1] + Tasks[8,1] + Tasks[9,1] + Tasks[10,1] + Tasks[11,1]
+ Tasks[12,1] + Tasks[13,1] + Tasks[14,1] + Tasks[15,1] + Tasks[16,1]
+ Tasks[17,1] + Tasks[18,1] + Tasks[19,1] + Tasks[20,1] + Tasks[21,1]
+ Tasks[22,1] + Tasks[23,1] + Tasks[24,1] = 0
Resourcebalane[1,2]: - Resources[1,1] + Resources[1,2] + Tasks[1,2]
+ Tasks[2,2] + Tasks[3,2] + Tasks[4,2] + Tasks[5,2] + Tasks[6,2]
+ Tasks[7,2] + Tasks[8,2] + Tasks[9,2] + Tasks[10,2] + Tasks[11,2]
+ Tasks[12,2] + Tasks[13,2] + Tasks[14,2] + Tasks[15,2] + Tasks[16,2]
+ Tasks[17,2] + Tasks[18,2] + Tasks[19,2] + Tasks[20,2] + Tasks[21,2]
+ Tasks[22,2] + Tasks[23,2] + Tasks[24,2] = 0
Resourcebalane[1,3]: - Resources[1,2] + Resources[1,3] + Tasks[1,3]
+ Tasks[2,3] + Tasks[3,3] + Tasks[4,3] + Tasks[5,3] + Tasks[6,3]
+ Tasks[7,3] + Tasks[8,3] + Tasks[9,3] + Tasks[10,3] + Tasks[11,3]
+ Tasks[12,3] + Tasks[13,3] + Tasks[14,3] + Tasks[15,3] + Tasks[16,3]
+ Tasks[17,3] + Tasks[18,3] + Tasks[19,3] + Tasks[20,3] + Tasks[21,3]
+ Tasks[22,3] + Tasks[23,3] + Tasks[24,3] = 0
Resourcebalane[1,4]: - Resources[1,3] + Resources[1,4] + Tasks[1,4]
+ Tasks[2,4] + Tasks[3,4] + Tasks[4,4] + Tasks[5,4] + Tasks[6,4]
+ Tasks[7,4] + Tasks[8,4] + Tasks[9,4] + Tasks[10,4] + Tasks[11,4]
+ Tasks[12,4] + Tasks[13,4] + Tasks[14,4] + Tasks[15,4] + Tasks[16,4]
+ Tasks[17,4] + Tasks[18,4] + Tasks[19,4] + Tasks[20,4] + Tasks[21,4]
+ Tasks[22,4] + Tasks[23,4] + Tasks[24,4] = 0
Resourcebalane[1,5]: - Resources[1,4] + Resources[1,5] + Tasks[1,5]
+ Tasks[2,5] + Tasks[3,5] + Tasks[4,5] + Tasks[5,5] + Tasks[6,5]
+ Tasks[7,5] + Tasks[8,5] + Tasks[9,5] + Tasks[10,5] + Tasks[11,5]
+ Tasks[12,5] + Tasks[13,5] + Tasks[14,5] + Tasks[15,5] + Tasks[16,5]
+ Tasks[17,5] + Tasks[18,5] + Tasks[19,5] + Tasks[20,5] + Tasks[21,5]
+ Tasks[22,5] + Tasks[23,5] + Tasks[24,5] = 0
Resourcebalane[1,6]: - Resources[1,5] + Resources[1,6] + Tasks[1,6]
+ Tasks[2,6] + Tasks[3,6] + Tasks[4,6] + Tasks[5,6] + Tasks[6,6]
+ Tasks[7,6] + Tasks[8,6] + Tasks[9,6] + Tasks[10,6] + Tasks[11,6]
+ Tasks[12,6] + Tasks[13,6] + Tasks[14,6] + Tasks[15,6] + Tasks[16,6]
+ Tasks[17,6] + Tasks[18,6] + Tasks[19,6] + Tasks[20,6] + Tasks[21,6]
+ Tasks[22,6] + Tasks[23,6] + Tasks[24,6] = 0
Wrong Formulation:
Resourcebalane[1,6]: - Resources[1,5] + Resources[1,6] + Tasks[1,6] -Task[1,0]
+ Tasks[2,6] -Task[2,0]+ Tasks[3,6]-Task[3,0] + Tasks[4,6]-Task[4,0] + Tasks[5,6]-Task[5,0] + Tasks[6,6]-Task[6,0]
+ Tasks[7,6] -Task[7,0]+ Tasks[8,6]-Task[8,0] + Tasks[9,6]-Task[9,0] + Tasks[10,6]-Task[10,0] + Tasks[11,6]-Task[11,0]
+ Tasks[12,6] -Task[12,0]+ Tasks[13,6] -Task[13,0]+ Tasks[14,6]-Task[14,0] + Tasks[15,6]-Task[15,0] + Tasks[16,6]-Task[16,0]
+ Tasks[17,6]-Task[17,0] + Tasks[18,6]-Task[18,0] + Tasks[19,6]-Task[19,0] + Tasks[20,6]-Task[20,0] + Tasks[21,6]-Task[21,0]
+ Tasks[22,6] -Task[22,0]+ Tasks[23,6]-Task[23,0] + Tasks[24,6]-Task[24,0] = 0
Resourcebalane[1,7]: - Resources[1,6] + Resources[1,7] - Tasks[1,1]
+ Tasks[1,7] - Tasks[2,1] + Tasks[2,7] - Tasks[3,1] + Tasks[3,7]
- Tasks[4,1] + Tasks[4,7] - Tasks[5,1] + Tasks[5,7] - Tasks[6,1]
+ Tasks[6,7] - Tasks[7,1] + Tasks[7,7] - Tasks[8,1] + Tasks[8,7]
- Tasks[9,1] + Tasks[9,7] - Tasks[10,1] + Tasks[10,7] - Tasks[11,1]
+ Tasks[11,7] - Tasks[12,1] + Tasks[12,7] - Tasks[13,1] + Tasks[13,7]
- Tasks[14,1] + Tasks[14,7] - Tasks[15,1] + Tasks[15,7] - Tasks[16,1]
+ Tasks[16,7] - Tasks[17,1] + Tasks[17,7] - Tasks[18,1] + Tasks[18,7]
- Tasks[19,1] + Tasks[19,7] - Tasks[20,1] + Tasks[20,7] - Tasks[21,1]
+ Tasks[21,7] - Tasks[22,1] + Tasks[22,7] - Tasks[23,1] + Tasks[23,7]
- Tasks[24,1] + Tasks[24,7] = 0
In the above constraint (Resourcebalane[1,7])- It can take max value 2 or minimum value 0 ,
As no more than 2 task will be executed.
Jaromil I am attaching .sol file of the model which very first went feasible and gave such incorrect values of variables, You will understand what I am trying to say.
https://docs.google.com/document/d/16U4-soyEtV27T9Z7x4vlpeTvc7hhqaer/edit?usp=sharing&ouid=104556000005791842995&rtpof=true&sd=true0 -
Could you tell me whether this works
Resourcebalance = {}
for res in res_list1:
for t in time:
if t == 0 and 1 <= res and res <= 3:
Resourcebalance[res,0] = steel.addConstr(Resources[res,0] == 2, name="Resourcebalance[%s,%d]"%(res,t))
elif t == 0 and 4 <= res and res<=5:
Resourcebalance[res,0] = steel.addConstr(Resources[res,0] == 1, name="Resourcebalance[%s,%d]"%(res,t))
else:
sumexpression = gp.LinExpr(0)
for task in task_list:
if task not in rtn_profile[res]:
continue
duration = len(rtn_profile[res][task]) - 1
for theta in range(0, min(duration, t)+ 1):
if (t-theta) != 0:
sumexpression.add(rtn_profile[res][task][theta]* Tasks[task,t-theta] )
Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == Resources[res,time[time.index(t)-1]] + sumexpression, name="Resourcebalance[%s,%d]"%(res,t))Note that I added the \(\texttt{t == 0}\) check to the \(\texttt{res}\) \(\texttt{if}\)-clause. It might be possible that you might have to remove it, but please check it first.
0 -
Hi Jaromil,
I dont know but it doesnt work , I will share the .sol file in which you can see that Task[1,0]= 1
Do you prefer I should change the time list & run all constraints from time = 1 ?
This is the .sol file,
https://drive.google.com/file/d/168sMIzyxTKtldMyRR5iK9SqvQzI4utan/view?usp=sharing
I think, lets deal with it patiently, We will find the exact reason:
Fundamentally What are we desiring?
- That is: Entire Algorithm should start from T=1,Just for resource balance constraint, as we need to give some initial value? It will take some initial value at 0,
I think there is some problem with the time assignment ? Could you try in my code with some of your logics? I think it will work.
0 -
I dont know but it doesnt work , I will share the .sol file in which you can see that Task[1,0]= 1
Please check the LP file and not the solution file. The values for Task[1,0] can still be set via other constraints such as Taskexecution or Energyusage.
You have to define a time1 as your tried
time1 = list()
for x in range(1,int(num_t + 1)):
time1.append(x)then go through your variable and constraint definitions and check which time list you have to use. For example, if only Resources variables can take a value for t = 0, then you should define your variables as
Resources=steel.addVars(res_list1,time,vtype=GRB.INTEGER,name="Resources")
Tasks=steel.addVars(task_list,time1,vtype= GRB.BINARY,name="Tasks")
EnergyResource=steel.addVars(res_list4,time1,vtype=GRB.CONTINUOUS,name="EnergyResource")You then have to carefully go through all constraints and adjust time to time1 if necessary.
An easy example would be Taskexecution where you can just change time to time1
Taskexecution=steel.addConstrs((gp.quicksum(Tasks[task,t] for t in time1)==1 for task in heat2tasks),name="Taskexecution")
A more complex one where you have to think about it is Transfertime. Here I don't know whether you have to use time or time1. This is something you have to adjust.
Transfertime = {}
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")time would produce constraints Resources[res,0] = 0 for res in y_list, while time1 would not produce them.
From here, you should go through every constraint one by one and adjust time to time1 if necessary. It is possible that you also might have to skip something as you did for Resourcebalance. For example, in the Energyusage constraint, you might have to add something like
for ti in time1:
sumexpression = gp.LinExpr(0)
for task_cat, task_list1 in tasks.items():
if 'TR' in task_cat: # transportation has no energy consumption
continue
for task in task_list1:
duration = task_duration[task]
for theta in range(0, min(duration, ti)+1):
if ti-theta != 0:
sumexpression.add(rtn_profile[res][task][theta]* Tasks[task,ti-theta] )
Energyusage[res,ti] = steel.addConstr(EnergyResource[res,ti] ==sumexpression,name="Energyusage[%s,%d]"%(res,ti))to avoid accesses to undefined variables.
Again, after every change, you should take a look at the model's LP file to see whether the changes are what you expect them to be.
0 -
Hi Jaromil,
I tried doing so.Then there is an infeasibility problem.
I think I need some moral support in form of you.
I will execute each constraint one by one as per my best understanding and see what happens.
0 -
You have managed to solve the infeasibility problem before changing the time step setup so I am sure you will manage it this time as well.
0 -
Hi Jaromil,
Many thanks for motivating me. I have made minor changes in the code related to time step.
I realized one thing, which specifically relates to Resource Balance constraint:
Before that let me share the updated code& also the .sol file, to explain you what I am trying to convey:
Code: https://drive.google.com/file/d/1-6ga6imsAIhCiBExdq6vHlih8UV4Z1ac/view?usp=sharing
Sol file: https://drive.google.com/file/d/1FqNCmVyfKFOr-59kumPJDeL-Dv_y2i-O/view?usp=sharing
If you see, in Optimization, Variables are something whose values we intend to get after optimization.
I intend to get all variables values (Resources, Tasks, Energy Resource) from time step 1.
But as you see, I have defined variable Resource from time step 0, I understand why it is because of Resourcebalance [1,0].
But, due to this in the .sol file I get some values of resources at time step 0 which is not at all intended.
So, my question is,
If you see the equation of Resourcebalance constraint (lp file) :
https://drive.google.com/file/d/1-Zn2R02BMtPwLU2TpfFrognX4TJ8CfH1/view?usp=sharing
It contains initial constant value which is fed in next constraint at time step 1.
i.e R[1,1]= R[1,0]- T[1,1]
We have treated R[1,0] as a constraint ,
But, How to treat such constant variable so that I can define Resource variables also from time step 1?
As that is not a constraint, rather just a constant value.
I searched some related literature of Gurobi, I found some "GRBLinExpr.Constant".
Also some post like, "Constant Variable – Gurobi Help Center"
I think this is the only reason, because if I treat resources from time step 0, Optimizer will give me the values at that time step even though all the constraints are starting from time step 1(Reference code is shared)
How to deal with this issue?
I think this is the last thing needs to be paid attention. All other things I triple checked it. It is correct.
Please Would you mind helping me?
Many thanks Jaromil.
Kind regards,
-Margi
0 -
Hi Margi,
Just for my understanding. The issue is now that you defined variables Resource[res,0] but you don't want to have them as optimization variables, is this correct?
If this is the case, then I think that the issue comes from the fact that you only fix variables Resources[1,0] - Resources[5,0] instead of all variables Resources[res,0]. In your code I see
if t == 0:
if 1 <= res and res <= 3:
Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == 2, name="Resourcebalance[%s,%d]"%(res,t))
elif 4<= res and res<=5:
Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == 1, name="Resourcebalance[%s,%d]"%(res,t))
#else:
# Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == 0, name="Resourcebalane[%s,%d]"%(res,t))So you commented out the part, where you fix all other Resources variables to 0. Is this on purpose?
Best regards,
Jaromił0 -
Hi Jaromil,
1. "The issue is now that you defined variables Resource[res,0] but you don't want to have them as optimization variables, is this correct?"
- Yes, Jaromil, 100 % correct. I do not intend to define Resources[res,0] as the Optimization Variables.
Optimization variables starts from Resources[res,1].
2. "So you commented out the part, where you fix all other Resources variables to 0. Is this on purpose?"
Yes, I commented this on purpose as you can see the end resource constraint, it has to be 1 at last time step. If I keep them, it will create a conflict, so I mandatorily commented the line.
Resources[1,0], Resources[2,0], Resources[3,0], Resources[4,0], Resources[5,0] are only some constant values rather than treating them as a constraint.
Also, if you see in the .sol file, Resources [6,0] has some value. It is because we are treating Resources [res,0] as Optimization variables but Resource variables too start from Resources[res,1].
Jaromil, I hope I made you understand where the problem lies. I think this is the only issue.
Hoping to hear from you.
-Best Regards,
Margi
0 -
Hi Margi,
Also, if you see in the .sol file, Resources [6,0] has some value. It is because we are treating Resources [res,0] as Optimization variables but Resource variables too start from Resources[res,1].
But what is the problem in having Resources[res,0] as optimization variables? You can just ignore them if you are not interested in their final values.
You fix the first 5 Resources[res,0] values, so they will definitely have the expected value in the final solution. The problem with not having those Resources[res,0] variables is that you use them in the t=1 case because you are accessing Resources[res,time[time.index(t)-1]]. Thus, all Resouces[res,0] have to be somehow defined, whether via a fixed value or they have to be a free variable. So you either have to fix all Resources[res,0] to some value, let them just be free variables, or adjust the Resourcebalance constraint to not access Resources[res,0] for res > 5 via Resources[res,time[time.index(t)-1]].
Best regards,
Jaromił0 -
Hi Jaromil,
1."You can just ignore them if you are not interested in their final values".
y={}
for res_cat, resources in res_cat2idx.items():
if 'H_A_S' not in res_cat or 'H_A_S4' in res_cat:
continue
y[res_cat]= list(resources)
Transfertime = {}
for key in y:
y_list = y[key]
Transfertime=steel.addConstrs((Resources[res,t] == 0 for res in y_list for t in time1),name ="Transfertime")As, you can see in this constraint, Resources (6-30) has to be zero at every time step. But in the .sol file, Resources (6,0) has some value. This will cause a problem in Resource balance constraint.
Is there any way Gurobi handles such Constant Varibales?
Resources=steel.addVars(res_list1, time1,vtype=GRB.INTEGER,name="Resources")
Can I use time step (1-96) in variable assignment of resources and use some extra loop to ignore Resources[res,0] in Resource balance constraint?
For those resources for which initial value is not defined i.e.(from Resource 6), I think Python automatically takes it as 0, so no need to define it.
Best Regards,
Margi
0 -
Hi Margi,
You could construct the Resources variable dictionary by hand, i.e., instead of
Resources=steel.addVars(res_list1,time,vtype=GRB.INTEGER,name="Resources")
you could go with
Resources = {}
for res in res_list1:
for t in time:
if t == 0:
if 1 <= res and res <= 3:
Resources[res,t] = steel.addVar(lb=2, ub=2, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 4 <= res and res <= 5:
Resources[res,t] = steel.addVar(lb=1, ub=1, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 6 <= res and res <= 30:
Resources[res,t] = steel.addVar(lb=0, ub=0, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
# variables Resources[31,0] - Resources[96,0] will no be defined
else:
Resources[res,t] = steel.addVar(vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))The above will define the Resources dictionary "by hand" You will have variables
Resouces[i,0] = 2 with 1<= i <= 3
Resouces[i,0] = 1 with 4<= i <= 5
Resouces[i,0] = 0 with 6<= i <= 30All other variables Resources[res,t] with t > 0 are non-negative integer variables. Note that variables Resources[i,0] with 31 <= i <= 96 are not defined which means that you cannot access them.
With this definition, you don't have to check for t=0 in your Resourcebalance constraints
Resourcebalance = {}
for res in res_list1:
for t in time1:
sumexpression = gp.LinExpr(0)
for task in task_list:
if task not in rtn_profile[res]:
continue
duration = len(rtn_profile[res][task]) - 1
for theta in range(0, min(duration, t-1)+1):
sumexpression.add(rtn_profile[res][task][theta]* Tasks[task,t-theta] )
Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == Resources[res,time[time.index(t)-1]] + sumexpression, name="Resourcebalance[%s,%d]"%(res,t))You have to make sure that Resources[res,time[time.index(t)-1]] never accesses values with Resources[res,t] with t=0 and 31 <= res <= 96, because they are not defined. You could use an if-statement for this
if 31 <= res and res <= 96 and time[time.index(t)-1]==0:
continueBest regards,
Jaromił0 -
Hi Jaromil,
I need not need to access any resource value (from 6 to 173) at time step = 0. So, Shall I do this?
Resources = {}
for res in res_list1:
for t in time:
if t == 0:
if 1 <= res and res <= 3:
Resources[res,t] = steel.addVar(lb=2, ub=2, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 4 <= res and res <= 5:
Resources[res,t] = steel.addVar(lb=1, ub=1, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 6 <= res and res <= 173:
Resources[res,t] = steel.addVar(lb=0, ub=0, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
#else:
# Resources[res,t] = steel.addVar(vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))If this is the case, then do I need to do this?
"You have to make sure that Resources[res,time[time.index(t)-1]] never accesses values with Resources[res,t] with t=0 and 31 <= res <= 96, because they are not defined. You could use an if-statement for this"
or
Any other changes in Resourcebalance constraint?
- Best Regards,
Margi
0 -
I need not need to access any resource value (from 6 to 173) at time step = 0. So, Shall I do this?
Yes, this is fine if you don't access those value anywhere in your model. However, you need the #else case which you currently commented out. Otherwise, you won't define any other variables than Resources[res,0].
Any other changes in Resourcebalance constraint?
Only the ones I mentioned in my previous comment. If you are sure that you never access Resources[res,0] for 31 <= res <= 96, then you don't need the additional if - continue block.
Please note that this is quite some change so your model can become infeasible (hopefully not) so you will have to go through the debugging process again.
0 -
Hi Jaromil,
So, the Resource Variable Dictionary will look like:
Resources = {}
for res in res_list1:
for t in time:
if t == 0:
if 1 <= res and res <= 3:
Resources[res,t] = steel.addVar(lb=2, ub=2, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 4 <= res and res <= 5:
Resources[res,t] = steel.addVar(lb=1, ub=1, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 6 <= res and res <= 173:
Resources[res,t] = steel.addVar(lb=0, ub=0, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
else:
Resources[res,t] = steel.addVar(vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))Resource balance constraint will look like:
Resourcebalance = {}
for res in res_list1:
for t in time1:
sumexpression = gp.LinExpr(0)
for task in task_list:
if task not in rtn_profile[res]:
continue
duration = len(rtn_profile[res][task]) - 1
for theta in range(0, min(duration, t-1)+1):
sumexpression.add(rtn_profile[res][task][theta]* Tasks[task,t-theta] )
Resourcebalance[res,t] = steel.addConstr(Resources[res,t] == Resources[res,time[time.index(t)-1]] + sumexpression, name="Resourcebalance[%s,%d]"%(res,t))Is it making sense?
Also,
"Please note that this is quite some change so your model can become infeasible"
May I ask why you feel so?
0 -
Is it making sense?
Yes, this looks good.
May I ask why you feel so?
Just a gut feeling, nothing in particular. Your model changed so much that I cannot tell which change has what effect. This was just a guess so I would not put any weight into it.
0 -
Hi Jaromil,
You are truly an inspiration.
I hope this works, I will implement & let you know.
-Best Regards,
Margi
0 -
Hi Jaromil,
I ran the model, fortunately it was feasible.
But I just have one confusion with one of the constraints named as Transfer task in which we used binary variables to see which task is taking place.
for key in group2tasks:
b = steel.addVar(vtype=GRB.BINARY, name="b[%d]"%key)
Taskexecution1= steel.addConstr((gp.quicksum(Tasks[group2tasks[key][0],t] for t in time1 ) == b),
name="constr1[%d]"%key)
Taskexecution2= steel.addConstr((gp.quicksum(Tasks[group2tasks[key][1],t] for t in time1 ) == 1 - b),
name="constr2[%d]"%key)Either of the two tasks should take place. Means either of the one should be 1.
But in the .sol file,
b[1] 0
b[2] 0
b[3] 1
b[4] 0
b[5] 1
b[6] 1Is this correct?
The code: https://drive.google.com/file/d/1w77ac20tJZx4FZACb9EBrGTt-zvdL4uw/view?usp=sharing
It takes now only fraction of seconds to complete. If you could just run on your device to see if it is correct?
Because now there is no infeasibility problem but just wanted to doublecheck with you if it is correctly executed?
-Kind Regards,
Margi
0 -
Hi Margi,
We discussed this constraint before. If \(b_1=0\) then \(\sum_{t in time1} Tasks_{145,t} = 0\) and \(\sum_{t in time1} Tasks_{151,t} = 1\). You can verify this by checking the solution values of the respective Tasks variables and indeed variable \(\texttt{Tasks[151,82]}\) is 1 (at least for the solution on my machine) so the equality \(\sum_{t in time1} Tasks_{151,t} = 1\) is fulfilled as expected.
It takes now only fraction of seconds to complete. If you could just run on your device to see if it is correct?
Because now there is no infeasibility problem but just wanted to doublecheck with you if it is correctly executed?
Just because it's quick, it does not mean that it's wrong. You should now use the solution point values and check whether they make sense for your application.
You can also now set the MIPGap parameter value to something lower. I would recommend leaving it at its default value, i.e., not setting it at all.
Best regards,
Jaromił0 -
Hi Jaromil,
May I ask how much time it took on your machine?
"You should now use the solution point values and check whether they make sense for your application."
Yes, you are right, I will do that.
Also, I have one question regarding the Log file that Gurobi generates, i.e I am using matplotlib to plot the results suppose,
How do I extract quantities "Obj Function value" i.e here is Elec cost vs "time step" values from this Log file?
This file generally has the iteration values.
-Kind Regards,
Margi
0 -
Hi Margi,
May I ask how much time it took on your machine?
Only a couple of seconds, between 6-8s.
Also, I have one question regarding the Log file that Gurobi generates, i.e I am using matplotlib to plot the results suppose,
How do I extract quantities "Obj Function value" i.e here is Elec cost vs "time step" values from this Log file?
Do you mean that you want to extract the information of each log line? Or do you want to just have the final information about objective value, time needed, etc.?
Best regards,
Jaromił0 -
Hi Jaromil,
Many thanks for informing me.
"Do you mean that you want to extract the information of each log line? Or do you want to just have the final information about objective value, time needed, etc.?"
No, What I mean is,
I want to plot the graph between (Electricity cost- Objective Func value) and (time- which is a instance of gurobi variable object)
i.e:For ex: I am talking about this time values: From 0 to 96
Resources=steel.addVars(res_list1, time,vtype=GRB.INTEGER,name="Resources")
This is the objective function:
obj=gp.quicksum(price_energy[t]*EnergyResource[res,t] for res in reslist2 for t in time)
So, how do I extract these values from Gurobi log file or is there any other way of doing so?
0 -
After the optimization is complete, you can access all attributes listed in the respective documentation. There you can find a list of all values that are accessible after a successful optimization run.
For example, \(\texttt{model.ObjVal}\) gives you the objective value of the final solution. Note that it is a model attribute, cf. table in the attribute documentation, so you have to access this value via the model. You can access the solution point value of some variable via \(\texttt{Resources[1,1].X}\). Note that X is a variable attribute, cf. table in the attribute documentation, so you have to access this value via the respective variable.
0 -
Hi Jaromil,
Thanks for the information. I searched all necessary information from the Gurobi website that what necessary attributes I require.
I am taking this: portfolio.py (gurobi.com) as a reference example on how to use model and variable attributes.
In my case,
1. Variables:
Resources = {}
for res in res_list1:
for t in time:
if t == 0:
if 1 <= res and res <= 3:
Resources[res,t] = steel.addVar(lb=2, ub=2, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 4 <= res and res <= 5:
Resources[res,t] = steel.addVar(lb=1, ub=1, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
if 6 <= res and res <= 173:
Resources[res,t] = steel.addVar(lb=0, ub=0, vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
else:
Resources[res,t] = steel.addVar(vtype=GRB.INTEGER, name="Resources[%d,%d]"%(res,t))
Tasks=steel.addVars(task_list,time1,vtype= GRB.BINARY,name="Tasks")
EnergyResource=steel.addVars(res_list4,time1,vtype=GRB.CONTINUOUS,name="EnergyResource")Objective function:
obj=gp.quicksum(price_energy[t-1]*EnergyResource[res,t] for res in reslist2 for t in time1)
However,
When I am doing this "steel.ObjVal ", I am getting one solution point value.i.e Final objective func value.
But where I am facing problem is , How do I plot Electricity costs(objvalue) at different time slots?
for ex: objvalue at time step 1: price_energy[0]*EnergyResource[res,1]
objvalue at time step 2: price_energy[1]*EnergyResource[res,2]
EnergyResource is variable.
I am trying to get some help from this example of gurobi but unable to get some detail information.
Jaromil, could you throw some light?
Kind Regards,
Margi
0 -
Hi Margi,
You have to access the solution point value via the X attribute, cf. my previous comment.
So
print(price_energy[0]*EnergyResource[1,1].X)
will give you the value of at time step 1 using resource 1. If you want the sum over all resources at time 1 then
print(price_energy[0]* sum(EnergyResource[res,1].X for res in reslist2))
should work.
Best regards,
Jaromił0 -
Hi Jaromil,
Yes , you are right, but that isn't a tedious task? I mean doing this,
print(price_energy[1]*EnergyResource[174,2].X)
print(price_energy[2]*EnergyResource[174,3].X)
print(price_energy[3]*EnergyResource[174,4].X)
print(price_energy[4]*EnergyResource[174,5].X)
print(price_energy[5]*EnergyResource[174,6].X)
print(price_energy[6]*EnergyResource[174,7].X)
print(price_energy[7]*EnergyResource[174,8].X)
print(price_energy[8]*EnergyResource[174,9].X)
print(price_energy[9]*EnergyResource[174,10].X)
print(price_energy[10]*EnergyResource[174,11].X)Then, storing it as a data frame(df) and then plotting, Isn't it not efficient?
Does Gurobi has some other features to handle such values as dataframes?
Also, If i see the above example, (very nice ex), they have used .csv as data file but I dont have that file in the example folder where the Gurobi is installed in my machine. Is it open source?
For ex: It has used this,
Would you mind help me to understand what it is being done here?It is pretty hard to figure it out as I cant run this ex because of unavaibility of .csv file.
ax = plt.gca() ax.scatter(x=stock_volatility, y=stock_return, color='Blue', label='Individual Stocks') for i, stock in enumerate(stocks): ax.annotate(stock, (stock_volatility[i], stock_return[i]))
0 -
Hi Margi,
Yes , you are right, but that isn't a tedious task? I mean doing this,
print(price_energy[1]*EnergyResource[174,2].X)
print(price_energy[2]*EnergyResource[174,3].X)
print(price_energy[3]*EnergyResource[174,4].X)
print(price_energy[4]*EnergyResource[174,5].X)
print(price_energy[5]*EnergyResource[174,6].X)
print(price_energy[6]*EnergyResource[174,7].X)
print(price_energy[7]*EnergyResource[174,8].X)
print(price_energy[8]*EnergyResource[174,9].X)
print(price_energy[9]*EnergyResource[174,10].X)
print(price_energy[10]*EnergyResource[174,11].X)Then, storing it as a data frame(df) and then plotting, Isn't it not efficient?
You are using Python so you shouldn't write it by hand one by one. You can use a for-loop
for t in time1:
print(price_energy[i-1]*EnergyResource[174,t].X)Does Gurobi has some other features to handle such values as dataframes?
No, currently Gurobi does not have such feature.
Also, If i see the above example, (very nice ex), they have used .csv as data file but I dont have that file in the example folder where the Gurobi is installed in my machine. Is it open source?
I guess you installed Gurobi via PIP. This does not include all files. You have to download the full Gurobi Optimizer package to have access to all files.
For ex: It has used this,
Would you mind help me to understand what it is being done here?It is pretty hard to figure it out as I cant run this ex because of unavaibility of .csv file.
ax = plt.gca()ax.scatter(x=stock_volatility, y=stock_return, color='Blue', label='Individual Stocks')for i, stock in enumerate(stocks): ax.annotate(stock, (stock_volatility[i], stock_return[i]))
I don't use plot libraries often so I can only point you to the corresponding documentation matplotlib.pyplot.gca, matplotlib.pyplot.scatter. For best plotting and pandas advice, I would recommend asking in a corresponding Python forum.
Best regards,
Jaromił0 -
Hi Jaromil,
Thanks for the information. I will surely look into it.
0
Please sign in to leave a comment.
Comments
209 comments