簡體   English   中英

使用 PulP 的優化問題 - 目標 function 中的錯誤

[英]Optimization problem using PulP - error in objective function

這是我需要解決的問題:

給定 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]

錯誤源於目標 function 因為城市和焚化爐中的每個元素都是字符串,因此您無法訪問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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM