这是我需要解决的问题:
给出2个城市(c1,c2),2个焚化炉(I1和I2)和2个垃圾填埋场(L1和L2)。每个城市都会产生一定数量的垃圾,必须将其送至焚化炉(i1或i2),然后必须将垃圾带入垃圾填埋场(L1或L2)。我需要最小化成本,这基本上是距离(例如1美元/英里)加上使用每个焚化炉的成本。
这是我到目前为止所拥有的。我得到的错误是:“ TypeError:列表索引必须是整数或切片,而不是str”
from pulp import *
cities = ["c1","c2"]
incinerators = ["i1","i2"]
landfills = ["L1","L2"]
#Distances between cities and incinerators are given
distCI = [ #cities
#c1, c2
[30, 5], #i1
[36, 42],#i2 incinerators
]
#Distances between incinerators and landfills are given
distIL = [ #incinerators
#i1, i2
[5, 8], #L1 landfills
[9, 6], #L2
]
# creates a dictionary of the garbage produced by each city
demand = {
"c1": [500], # amount of waste produced by c1
"c2": [400] # amount of waste produced by c2
}
# created a dictionary with the capacity of each incinerator and its usage cost (per ton)
incidata = {# Incinerator, capacity, cost
"i1": [500, 40],
"i2": [500, 30]
}
landdata = {# landfill maxcapacity
"L1": [200],
"L2": [200]
}
# creates a tuple with all the possible routes
route1 = [(c,i) for c in cities for i in incinerators]
route2 = [(i,l) for i in incinerators for l in landfills]
flow1 = LpVariable.dicts("route1",(cities,incinerators),0,None,LpInteger)
flow2 = LpVariable.dicts("route2",(incinerators,landfills),0,None,LpInteger)
prob = LpProblem("GarbageProblem",LpMinimize)
# The objective function is :
# sum of the flow from cities to incinerators multiplied by their respective distances, plus
# sum of the flow from incinerators to landfills multiplied by their respective distances
prob += lpSum([flow1[c][i] * distCI[c][i] for (c,i) in route1] + [flow2[i][l] * distIL[i][l] for (i,l) in route2] )
# Creates all problem constraints - this ensures the amount going into each node is at least equal to the amount leaving
prob+= lpSum([flow1[c,i] for (c,i) in route1 if c==1] )<=500 #garbage produced by city 1
prob+= lpSum([flow1[c,i] for (c,i) in route1 if c==2] )<=400 #gargabe produced by city 2
prob+= lpSum([flow1[c,i] for (c,i) in route1 if i==1] )<=500 #max capacity of incinerator 2
prob+= lpSum([flow1[c,i] for (c,i) in route1 if i==2] )<=500 #max capacity of incinerator 2
prob+= lpSum([flow2[i,l] for (i,l) in route2 if l==1] )<=200 #max capacity of landfill 1
prob+= lpSum([flow2[i,l] for (i,l) in route2 if l==2] )<=200 #max capacity of landfill 2
prob.solve() #solve using PulP's choice
# The status of the solution is printed to the screen
print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen
print("Total Cost = ", value(prob.objective))
distCI
是列表的列表,因此您必须使用整数访问元素,例如distCI[0][0]
。
错误源于目标函数,因为城市和焚化炉中的每个元素都是字符串,所以您无法访问distCI[c][I]
您可以通过使distCI
成为字典并将键作为(c,i)的元组来解决此问题。
谢谢你,埃里克。通过将distCI和distIL更改为包含节点之间距离的字典,我摆脱了错误。现在,我得到了一个不可行的解决方案,但是我已经知道该解决方案应该是什么,也不是不可行的。
from pulp import *
cities = ["c1","c2"]
incinerators = ["i1","i2"]
landfills = ["L1","L2"]
#Distances between cities and incinerators are given
distCI = { #cities, incinerators, distances
"c1": {"i1": 30, "i2": 5},
"c2": {"i1": 36, "i2": 42}
}
distIL = { #incinerators, landfills distances
"i1": {"L1": 5, "L2": 8},
"i2": {"L1": 9, "L2": 6}
}
# creates a dictionary of the garbage produced by each city
demand = {
"c1": [500], # amount of waste produced by c1
"c2": [400] # amount of waste produced by c2
}
# created a dictionary with the capacity of each incinerator and its usage cost (per ton)
incidata = {# Incinerator, capacity, cost
"i1": [500, 40],
"i2": [500, 30]
}
landdata = {# landfill maxcapacity
"L1": 200,
"L2": 200
}
# creates tuples of the possible routes
route1 = [(c,i) for c in cities for i in incinerators]
route2 = [(i,l) for i in incinerators for l in landfills]
flow1 = LpVariable.dicts("route1",(cities,incinerators),0,None,LpInteger)
flow2 = LpVariable.dicts("route2",(incinerators,landfills),0,None,LpInteger)
prob = LpProblem("GarbageProblem",LpMinimize)
# The objective function is :
# sum of the flow from cities to incinerators multiplied by their respective distances, plus
# sum of the flow from incinerators to landfills multiplied by their respective distances
prob += lpSum([flow1[c][i] * distCI[c][i] for (c,i) in route1] + [flow2[i][l] * distIL[i][l] for (i,l) in route2] )
# Creates all problem constraints - this ensures the amount going into each node is at least equal to the amount leaving
prob+= lpSum([flow1[c,i] for (c,i) in route1 if c==1] )==500 #garbage produced by city 1
prob+= lpSum([flow1[c,i] for (c,i) in route1 if c==2] )==400 #gargabe produced by city 2
prob+= lpSum([flow1[c,i] for (c,i) in route1 if i==1] )<=500 #max capacity of incinerator 2
prob+= lpSum([flow1[c,i] for (c,i) in route1 if i==2] )<=500 #max capacity of incinerator 2
prob+= lpSum([flow2[i,l] for (i,l) in route2 if l==1] )<=200 #max capacity of landfill 1
prob+= lpSum([flow2[i,l] for (i,l) in route2 if l==2] )<=200 #max capacity of landfill 2
prob.solve() #solve using PulP's choice
# The status of the solution is printed to the screen
print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen
print("Total Cost = ", value(prob.objective))