What does "x[i,j].x" means?
AnsweredI'm still a beginner in Python & Gurobi, I started with a simple (Capacitated facility planning location problem).. I understood all the code terms except for a line in printing out the solution (I've marked this line by making it bold and italic) ... I don't know why we add (.x) after x[i,j].....and if I tried to remove it and write only if x[i,j] !=0 the model couldn't be optimized and the following error appears
File "E:/Gurobi/My models ;)/Capacitated facility location problem.py", line 63, in <module>
if x[i,j] !=0:
File "var.pxi", line 263, in gurobipy.Var.__ne__
GurobiError: Inequality constraints not supported
from gurobipy import*
#Model parameters
J=[1,2,3,4,5] #Customers
I=[1,2,3] #Facilities
D={1:80, 2:270, 3:250, 4:160, 5:180} #Demand for each customer
M={1:500, 2:500, 3:500} #Production Capacity of each facility
F={1:1000, 2:1000, 3:1000}
c={(1,1):4, (1,2):5, (1,3):6, (1,4):8, (1,5):10,
(2,1):6, (2,2):4, (2,3):3, (2,4):5, (2,5):8,
(3,1):9, (3,2):7, (3,3):4, (3,4):3, (3,5):4} #Transportation cost for faicility i to customer j
m=Model("Capacitated facility location problem")
#Decision variables
x={} #Dictionary contains the amount served from facility i to customer j
for i in I:
for j in J:
x[i,j]=m.addVar(vtype="C", name="x(%s,%s)"%(i,j))
y={} #Dictionary with binary values if facility established at location i or not
for i in I:
y[i]=m.addVar(vtype="B", name="y(%s)"%(i))
#Objective function
m.setObjective((quicksum(F[i]*y[i] for i in I )+ quicksum(c[i,j]*x[i,j] for i in I for j in J)),GRB.MINIMIZE)
#Constriants
#Demand must be satisfied
for j in J:
m.addConstr(quicksum(x[i,j] for i in I)==D[j], name="Demand(%s)"%j)
#All sent products for facility i is smaller than or equal to its capacity if the facility is opened
for i in I:
m.addConstr(quicksum(x[i,j] for j in J)<=M[i]*y[i], name="Capacity(%s)"%i)
#sent items from facility i to customer j is smaller than or equal to the customer's demand if the facility was opened
for i in I:
for j in J:
m.addConstr(x[i,j] <= D[j]*y[i], name="C3(%s,%s)"%(i,j))
m.optimize()
#print("transported quantities", x)
#print("facilities opened", y)
edges={}
for i in I:
for j in J:
if x[i,j].x !=0: #.........................Why do they wirte (.x) here???
keys= ((i,j) for (i,j) in x )
edges[keys]=x[i,j]
facilities=[i for i in y if y[i]==1 ]
print (facilities)
print(edges)
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Welcome to Gurobi!
With the X attribute, you access the variable's value in the current solution. Note that the code first does
m.optimize()
to find the optimal solution. The /(x[i,j].x/) is then part of the code that prints the solution to the screen.
You should actually add the same to y[i] in this line:
facilities=[i for i in y if y[i]==1 ]
Also, it is recommended to allow for some tolerances when comparing the values of variables with other numbers (because some small deviations are unavoidable in computations with floating-point numbers). E.g. instead of \(x[i,j].x \neq 0\) you should check for \(x[i,j].X > \epsilon\) or \(x[i,j].X < -\epsilon\) for some appropriate \(\epsilon\) (e.g. 1e-6). Since y is binary, you could instead of \(y[i].X == 1\) simply check for \(y[i].X > 0.5\).
A few more remarks on your code: The line
keys= ((i,j) for (i,j) in x )
building the same object for each i in I and j in J and could be moved outside the loop. (The variables i and j in this line are not the ones your looping over with "for i in I" and "for j in J".)
The line
edges[keys]=x[i,j]
also does not really make sense it keeps overwriting edges[keys] in each iteration of the loop.
0 -
Thank you very much, your support is greatly appreciated :)
0
Post is closed for comments.
Comments
3 comments