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 have two questions:
1.
x={}
for t in time1:
x[t]=price_energy[t-1]*EnergyResource[174,t].XI have tried to store the value of x as a list. This is Obj value at different time steps? Am I correctly understanding?
2.
y={}
for t in time1:
y[t]=EnergyResource[174,t].Xy is the values of Energy Resource variable at different time steps ? Is it correct?
Can I have both these parameters (Model Attribute) & ( Variable attribute) stored as a list?
0 -
Hi Margi,
1.
x={}
for t in time1:
x[t]=price_energy[t-1]*EnergyResource[174,t].XI have tried to store the value of x as a list. This is Obj value at different time steps? Am I correctly understanding?
Your objective is defined as \(sum_t^{\text{time1}} \sum_{res}^{\text{reslist1}} \text{priceenergy}_{t-1} \cdot \text{EnergyResouce}_{res,t}\) so the \(x\) you compute is only a part of your objective function, namely \(sum_t^{\text{time1}} \text{priceenergy}_{t-1} \cdot \text{EnergyResource}_{174,t}\). So you sum all time steps over \(res=174\). If this is what you want and understand by "Obj value at different time steps" then yes, you understand correctly.
2.
y={}
for t in time1:
y[t]=EnergyResource[174,t].Xy is the values of Energy Resource variable at different time steps ? Is it correct?
\(y\) holds values of the EnergyResource variable for \(res=174\) at different time steps.
Can I have both these parameters (Model Attribute) & ( Variable attribute) stored as a list?
Which parameters do you mean? The \(x,y\) you construct? You can just use a list instead of a dictionary
x=[]
for t in time1:
x.append(price_energy[t-1]*EnergyResource[174,t].X)
y=[]
for t in time1:
y.append(EnergyResource[174,t].X)But note that lists start with index \(0\) and your time1 list starts with \(1\) so I would think that using dictionaries might be more convenient here.
If you mean to get all X attribute values as a list, then yes, this is possible via the Model.getAttr() method. However, you will have to provide the variables as a list to get a list out of this method, which would require an additional step in your current implementation. So it may be better to stick to your current approach.
0 -
Hi Jaromił Najman,
Many thanks for replying to the question. I think I have understood what model attributes are.
Firstly, I am as of now not putting any query, but this post is for the appreciation for the employees like you who are dedicated.
For people like me, who used Gurobi for the very first time, you helped a lot to make this start smooth. I know its lot and lot to learn further but you made sure it was smooth start.
Thanks a lot, Jaromil. I really appreciate it.
Looking forward to more learning.
0 -
Hi Jaromił Najman,
Is there a way to access the number of binary and continuous variables present in the model? I am aware of how I can access the constraints, like below:
x=steel.NumConstrs
I am not sure how to retrieve the binary and continuous variables.
Regards,
Margi
0 -
Hi Margi,
For the total number of variables, you can access the NumVars attribute of the model object. There are also attributes for the number of binary variables (NumBinVars) and the number of integer variables (NumIntVars). To get the number of continuous variables, you can simply subtract the number of binary and integer variables from the number of all variables.
numbinvars = steel.NumBinVars # number of binary vars
numintvars = steel.NumIntVars # number of integer vars
numcontvars = steel.NumVars - numbinvars - numintvars # number of continuous varsBest regards,
Jaromił0 -
Thanks Jaromił Najman :)
0 -
Hi Jaromił Najman,
As per your last comment,
I tried to check the number of constraints and variables:numconstraints = steel.NumConstrs # number of constraints
print(numconstraints)
numbinvars = steel.NumBinVars # number of binary vars
print(numbinvars)
numintvars = steel.NumIntVars # number of integer vars
print(numintvars)
numcontvars = steel.NumVars - numbinvars - numintvars # number of continuous vars
print(numcontvars)Output seems to be:
16800
11520
23451
-11232How does number of continous varibales has negative sign?
Thanks in advance.0 -
Hi Margi,
I just noticed that the parameter for number of integer variables (NumIntVars) counts both binaries and integers. Thus the correct call should be
numintvars = steel.NumIntVars # number of integer and binary vars print(numintvars) numcontvars = steel.NumVars - numintvars # number of continuous vars print(numcontvars)
Sorry for the confusion.
Best regards,
Jaromił0 -
Hi Jaromił Najman,
Thanks for your comment.
I was solving a MILP problem and I see the message below.Does that interpret there is a error in the model?
Set parameter Username
Academic license - for non-commercial use only - expires 2025-01-09
Gurobi Optimizer version 11.0.0 build v11.0.0rc2 (win64 - Windows 11.0 (22621.2))
CPU model: 12th Gen Intel(R) Core(TM) i7-12700, instruction set [SSE2|AVX|AVX2]
Thread count: 12 physical cores, 20 logical processors, using up to 20 threads
Optimize a model with 98592 rows, 140211 columns and 779575 nonzeros
Model fingerprint: 0x9f0c9bc7
Model has 288 general constraints
Variable types: 864 continuous, 139347 integer (69120 binary)
Coefficient statistics:
Matrix range [2e-01, 7e+00]
Objective range [3e+01, 9e+01]
Bounds range [1e+00, 2e+00]
RHS range [1e+00, 5e+01]
Presolve removed 71679 rows and 74765 columns
Presolve time: 2.07s
Presolved: 26913 rows, 65446 columns, 510584 nonzeros
Variable types: 0 continuous, 65446 integer (38980 binary)
Deterministic concurrent LP optimizer: primal simplex, dual simplex, and barrier
Showing barrier log only...
Root barrier log...
Ordering time: 0.19s
Barrier statistics:
AA' NZ : 6.963e+05
Factor NZ : 2.780e+06 (roughly 60 MB of memory)
Factor Ops : 8.332e+08 (less than 1 second per iteration)
Threads : 9
Objective Residual
Iter Primal Dual Primal Dual Compl Time
0 1.60606716e+09 -8.85134680e+08 5.90e+05 0.00e+00 8.56e+05 3s
1 4.83313425e+08 -5.08655091e+08 1.76e+05 1.48e+02 2.59e+05 3s
2 3.47612326e+07 -1.84927426e+08 1.17e+04 6.54e-11 1.84e+04 3s
3 9.72483914e+06 -8.58172782e+07 2.86e+03 5.97e-11 4.68e+03 3s
4 9.00611709e+06 -7.77744736e+07 2.60e+03 6.63e-11 4.21e+03 3s
5 7.36512578e+06 -6.69103310e+07 2.02e+03 1.25e-10 3.31e+03 3s
6 1.95451399e+06 -4.26878556e+07 4.05e+02 8.25e-11 8.48e+02 3s
7 6.94822602e+05 -8.91461349e+06 1.27e+02 7.12e-11 2.07e+02 3s
8 2.53059121e+05 -4.37385742e+06 3.37e+01 7.60e-11 6.81e+01 3s
9 1.58572834e+05 -2.44412900e+06 1.34e+01 6.35e-11 3.16e+01 3s
10 1.52436112e+05 -1.62277799e+06 1.18e+01 8.21e-11 2.27e+01 3s
11 1.30677778e+05 -1.18385144e+06 7.06e+00 9.08e-11 1.51e+01 3s
12 1.15300570e+05 -6.12351449e+05 3.59e+00 7.54e-11 7.61e+00 3s
13 1.05989192e+05 -4.14634307e+05 1.92e+00 5.50e-11 4.93e+00 3s
14 9.96725987e+04 -2.48795783e+05 9.64e-01 6.44e-11 3.06e+00 3s
15 9.84988138e+04 -1.79386295e+05 7.93e-01 7.10e-11 2.40e+00 3s
16 9.66247872e+04 -1.28162154e+05 6.39e-01 7.40e-11 1.92e+00 3s
17 9.39721606e+04 -6.15255350e+04 3.34e-01 6.24e-11 1.27e+00 3s
18 9.20959060e+04 -4.43444144e+04 1.82e-01 5.38e-11 1.08e+00 3s
19 8.98493310e+04 -2.29414822e+03 1.10e-01 5.94e-11 7.22e-01 3s
20 8.87635839e+04 1.95183360e+04 7.93e-02 5.29e-11 5.39e-01 3s
21 8.84540516e+04 2.39727220e+04 7.05e-02 5.26e-11 5.01e-01 3s
22 8.78120292e+04 4.53174903e+04 5.56e-02 4.53e-11 3.30e-01 3s
23 8.75156453e+04 5.68868708e+04 4.77e-02 3.37e-11 2.38e-01 3s
24 8.69889024e+04 6.25361992e+04 3.75e-02 4.61e-11 1.89e-01 3s
25 8.66943307e+04 6.99545536e+04 3.16e-02 4.44e-11 1.30e-01 4s
26 8.62448626e+04 7.39449906e+04 2.05e-02 2.87e-11 9.48e-02 4s
27 8.58815436e+04 7.57373976e+04 1.32e-02 3.12e-11 7.80e-02 4s
28 8.57064836e+04 7.97025751e+04 1.02e-02 3.01e-11 4.62e-02 4s
29 8.55075443e+04 8.15352363e+04 7.77e-03 3.55e-11 3.06e-02 4s
30 8.53856830e+04 8.21181821e+04 6.52e-03 4.04e-11 2.51e-02 4s
31 8.52500771e+04 8.29536725e+04 5.15e-03 3.97e-11 1.77e-02 4s
32 8.51119472e+04 8.33196743e+04 3.75e-03 2.84e-11 1.38e-02 4s
33 8.50243785e+04 8.35818785e+04 2.95e-03 3.32e-11 1.11e-02 4s
34 8.49431437e+04 8.37695504e+04 2.28e-03 4.23e-11 9.02e-03 4s
35 8.49002525e+04 8.39717067e+04 1.91e-03 4.39e-11 7.14e-03 4s
36 8.48346445e+04 8.41384990e+04 1.42e-03 4.50e-11 5.35e-03 4s
37 8.48016230e+04 8.41903466e+04 1.19e-03 4.64e-11 4.70e-03 4s
38 8.47792862e+04 8.42126092e+04 1.03e-03 5.97e-11 4.35e-03 4s
39 8.47418146e+04 8.43274396e+04 7.75e-04 5.23e-11 3.18e-03 4s
40 8.47264439e+04 8.43616733e+04 6.79e-04 6.03e-11 2.80e-03 4s
41 8.46929448e+04 8.44339802e+04 4.75e-04 4.18e-11 1.99e-03 4s
42 8.46724001e+04 8.44743653e+04 3.65e-04 5.06e-11 1.52e-03 4s
43 8.46620288e+04 8.45018676e+04 3.10e-04 5.42e-11 1.23e-03 4s
44 8.46538245e+04 8.45187973e+04 2.69e-04 6.00e-11 1.04e-03 4s
45 8.46336794e+04 8.45375778e+04 1.67e-04 5.18e-11 7.38e-04 4s
46 8.46295046e+04 8.45486523e+04 1.48e-04 5.33e-11 6.21e-04 4s
47 8.46190101e+04 8.45601962e+04 1.03e-04 5.18e-11 4.52e-04 4s
48 8.46096688e+04 8.45689460e+04 6.47e-05 5.31e-11 3.13e-04 4s
49 8.46040765e+04 8.45760993e+04 4.24e-05 4.72e-11 2.15e-04 4s
50 8.46002605e+04 8.45820584e+04 2.79e-05 4.94e-11 1.40e-04 4s
51 8.45977328e+04 8.45860607e+04 1.86e-05 4.79e-11 8.97e-05 4s
52 8.45961081e+04 8.45874891e+04 1.29e-05 4.50e-11 6.62e-05 4s
53 8.45952727e+04 8.45885442e+04 9.98e-06 5.13e-11 5.17e-05 4s
54 8.45943504e+04 8.45894339e+04 6.80e-06 5.45e-11 3.78e-05 4s
55 8.45936911e+04 8.45902599e+04 4.58e-06 8.70e-11 2.63e-05 4s
56 8.45931330e+04 8.45909608e+04 2.74e-06 8.21e-11 1.67e-05 5s
57 8.45929633e+04 8.45915183e+04 2.19e-06 9.69e-11 1.11e-05 5s
58 8.45926389e+04 8.45917617e+04 1.20e-06 1.14e-10 6.74e-06 5s
59 8.45925912e+04 8.45918048e+04 1.06e-06 1.22e-10 6.04e-06 5s
60 8.45924333e+04 8.45919327e+04 5.87e-07 8.39e-11 3.84e-06 5s
61 8.45923244e+04 8.45920622e+04 2.77e-07 9.04e-11 2.01e-06 5s
62 8.45922846e+04 8.45921580e+04 1.73e-07 6.01e-11 9.74e-07 5s
63 8.45922578e+04 8.45921825e+04 1.02e-07 7.30e-11 5.80e-07 5s
64 8.45922307e+04 8.45921903e+04 2.85e-08 8.42e-11 3.09e-07 5s
65 8.45922227e+04 8.45922089e+04 8.83e-09 5.97e-11 1.06e-07 5s
66 8.45922196e+04 8.45922166e+04 2.69e-09 5.73e-11 2.33e-08 5s
67 8.45922189e+04 8.45922173e+04 1.47e-09 7.64e-11 1.26e-08 5s
68 8.45922186e+04 8.45922177e+04 1.79e-09 8.47e-11 6.99e-09 5s
69 8.45922151e+04 8.45922181e+04 5.24e-08 6.55e-11 2.45e-09 5s
Barrier solved model in 69 iterations and 4.91 seconds (9.10 work units)
Optimal objective 8.45922151e+04
Root crossover log...
0 DPushes remaining with DInf 0.0000000e+00 5s
5483 PPushes remaining with PInf 1.3603881e-03 5s
0 PPushes remaining with PInf 0.0000000e+00 5s
Push phase complete: Pinf 0.0000000e+00, Dinf 5.2146768e-02 5s
Root simplex log...
Iteration Objective Primal Inf. Dual Inf. Time
24179 8.4592218e+04 0.000000e+00 5.214676e-02 5s
24185 8.4592218e+04 0.000000e+00 0.000000e+00 5s
Concurrent spin time: 0.00s
Solved with barrier
24185 8.4592218e+04 0.000000e+00 0.000000e+00 5s
Root relaxation: objective 8.459222e+04, 24185 iterations, 3.12 seconds (4.90 work units)
Total elapsed time = 12.11s (DegenMoves)
Total elapsed time = 16.96s (DegenMoves)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 84592.2184 0 3879 - 84592.2184 - - 20s...........
.
.
.
.
.
. .......continuesI haven't seen such a message previously.
Regards,
Margi0 -
Hi Margi,
I haven't seen such a message previously.
Could you please explain which message exactly did you not see previously?
What you currently posted is the normal output for models with discrete variables, see MIP Logging.
Best regards,
Jaromił0 -
Hi Jaromił Najman,
I am trying to reformulate the optimisation problem.
Objective function:for res in res_list4:
for t in time1:
# add constr aux = EnergyResouce - E
steel.addConstr(aux[res,t] == EnergyResource[res,t] + BatteryPower - E_Wind[t-1],name="aux_constr_%s_%d"%(res,t))
# add constr maxaux = max(0, aux)
steel.addGenConstrMax(maxaux[res,t],[aux[res,t]],0.0,name="maxconstr_%s_%d"%(res,t))
obj=gp.quicksum(price_energy[t-1]*maxaux[res,t] for res in res_list4 for t in time1)My question is how do I write the below constraint and define variable:
Constraint:SoC calculation:
if t == 1:
SoC = initial_SoC(at t=0) + (BatteryPower * ch_eff) / e_b_cap
else:
SoC = SoC + (BatteryPower * ch_eff) / e_b_capThe variable BatteryPower can be any number between [-3,-2,-1,0,1,2,3].
My question is, how do I write the variable and the constraint with regards to SoC calculation?
Regards,
Margi0 -
Hi Margi,
You will need to introduce a bounded continuous \(\texttt{SoC_t}\) variable.
# introduce variable SoC for every timestep t
SoC = steel.addVars(time1, lb= SoC_MIN, ub = SoC_MAX, name="SoC")Next, you can add linear constraints by looping over the time index
for t in time1:
if t == 1:
steel.addConstr(SoC[t] == inital_SoC(0) + (BatteryPower * ch_eff) / e_b_cap
else:
steel.addConstr(SoC[t] == (BatteryPower * ch_eff) / e_b_capIn the above I assumed that \(\texttt{intial_SoC}\) is some constant value that you can calculate.
Best regards,
Jaromił0 -
Hi Jaromił Najman,
Actually the variable is the BatteryPower and SoC is calculated from it.SoC calculation:
if t == 1: SoC = initial_SoC(at t=0) + (BatteryPower * ch_eff) / e_b_cap else: SoC = SoC(t-1) + (BatteryPower * ch_eff) / e_b_cap
0 -
Hi Margi,
Actually the variable is the BatteryPower and SoC is calculated from it.
This is correct, but if you want to compute SoC being dependent on an optimization variable, then SoC has to become an optimization variable itself. Otherwise, it cannot be modeled.
Best regards,
Jaromił0 -
Hi Jaromił Najman,
Thats correct. I understand but then how it is possible to calculate BatteryPower necessary for the objective function?
Regards,
Margi0 -
Thats correct. I understand but then how it is possible to calculate BatteryPower necessary for the objective function?
BatteryPower is an optimization variable itself. This means that you can use it in the objective function and the solver will compute an optimal value for it.
0 -
Hi Jaromił Najman,
Does that mean If I define SoC as a variable, I don't require to define BatteryPower as a variable?0 -
Hi Margi,
Does that mean If I define SoC as a variable, I don't require to define BatteryPower as a variable?
No, you still need to keep BatteryPower as a variable, because as you said it can take different values that need to be determined by the solver.
0 -
Hi Jaromił Najman,
Alright, That means I will need to define batterypower like below:# introduce variable BatteryPower for every timestep t
BatteryPower = steel.addVars(time1, lb= -3, ub = 3, name="BatteryPower")But how to make sure that it will take discrete values like -3,-2,-1,0,1,2,3?
Regards,
Margi0 -
Hi Jaromił Najman,
Also I am not sure why I am getting this error:initial_SoC = 0.5
Regards,
Margi0 -
How do you define the optimization variable BatteryPower? Is it only one variable?
0 -
Hi Jaromił Najman,
This is how I define BatteryPower:
What do you mean by 'is it only one variable?'# introduce variable BatteryPower for every timestep t BatteryPower = steel.addVars(time1, lb= -3, ub = 3, name="BatteryPower")
0 -
Hi Jaromił Najman,
Yes correct, I want to access BatteryPower[t].
It can take any discrete value from [-3,-2,-1,0,1,2,3].
How do I write it as variable?0 -
How do I write it as variable?
You already added it as a tupledict of variables by the code
BatteryPower = steel.addVars(time1, lb= -3, ub = 3, name="BatteryPower")
You now just have to access it via \(\texttt{BatteryPower[t]}\) just as you do with SoC and other variables in your model.
0 -
Hi Jaromił Najman,
Thank you for the response.
I ran the optimisation model and when I saw the Battery power, I can see that it is continous variable rather than a discrete variable.
Why so ?
BatteryPower[88] -2.7939182097697230e+00
BatteryPower[89] -6.5532541123029220e-01
BatteryPower[90] 1.0434642353333383e+00
BatteryPower[91] 7.6636275700000844e-01
BatteryPower[92] 1.2850982193333333e+00
BatteryPower[93] 2.475373096
I have defined BatteryPower as:
BatteryPower = steel.addVars(time1, lb= -3, ub = 3, name="BatteryPower")0 -
You have to set the variable's vtype to be integer, see the documentation of addVars.
BatteryPower = steel.addVars(time1, lb= -3, ub = 3, vtype=gp.GRB.INTEGER, name="BatteryPower")
0 -
Hi Jaromił Najman Najman,When I am trying to replace '<=' sign in the below constraint to '<', it shows me this error, why gurobi don't accept '<' sign?
res = res_cat2idx['SP'][0]
Spinningusage = {}
for ti in time1:
sumexpression = gp.LinExpr(0)
for task_cat, task_list1 in tasks.items():
if task_cat == 'EAF':
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)):
sumexpression.add(rtn_profile[res][task][theta] * Tasks[task, ti - theta])
Spinningusage[res, ti] = steel.addConstr(SpinningResource[res, ti] <= sumexpression,name="Spinningusage[%s,%d]" % (res, ti))
Error:0 -
Hi Margi and Happy New Year,
This issue is explained in the Knowledge Base article Why doesn't Gurobi support strict inequality constraints like x < a?
Best regards,
Jaromił0
Please sign in to leave a comment.
Comments
209 comments