"KeyError: (0, 'num')" when using List Comprehension to create PuLP LPConstraint
"KeyError: (0, 'num')" when using List Comprehension to create PuLP LPConstraint
我认为我为优化创建的是一个相当简单的问题。我在 csv 文件中有以下数据:
我正在尝试使用 PuLP 包创建“最佳”骑行日,但在创建我的约束之一时不断出现错误。约束简单概括为:每次骑行的时间(#次骑行*骑行时间,加上#次骑行*等待时间),加上两次骑行之间的15分钟,必须等于或小于公园开放时间(减去固定的用餐和洗手间时间)
当我 运行 约束行时,我不断收到 KeyError: (0, 'num') 。 (我可以毫无问题地打印 ride_list.loc[0,'num'] - 解决问题的第一步。)任何提示或想法将不胜感激。
import pandas as pd
import pulp
ride_list = pd.read_csv('RideData.csv')
num_rides = ride_list.shape[0]
rides = list(range(num_rides))
min_times = 0 #minimum # times for each ride
max_times = 2 #maximum # times for each ride
time_between = 0.25 #how long to allow between rides
food_time = 2.5 #how long to allow for meals
hours_open = 12 #how many hours the park is open
# Set default values for testing
for i in rides:
ride_list.loc[i, 'my_min'] = min_times
ride_list.loc[i, 'my_max'] = max_times
ride_list.loc[i, 'my_rating'] = ride_list.loc[i, 'rating']
ride_list.loc[i, 'num'] = 0
# Initialize model
model = pulp.LpProblem('Maximimize ride enjoyment', pulp.LpMaximize)
# Add calculation to be optimized
model += pulp.lpSum([ride_list.loc[i,'ride'] * ride_list.loc[i,'rating'] * ride_list.loc[i,'num'] for i in rides])
# Add constraint to # times for each ride
x = pulp.LpVariable.dicts("times",[ride_list.loc[i, 'num'] for i in rides],
lowBound = min_times,
upBound = max_times,
cat = 'Integer')
# Add constraint for total amount of time
total_rides = pulp.lpSum([ride_list[i,'num'] for i in rides])
model += pulp.LpConstraint('total_ride_time',
(pulp.lpSum([((ride_list.loc[i,'wait'] * ride_list.loc[i,'num']) +
(ride_list.loc[i,'ride'] * ride_list.loc[i,'num'])) for i in rides]) +
((total_rides - 1) * time_between)) <=
(hours_open - food_time))
所以您在索引方面遇到的问题是由于您没有在 pulp
中正确构造变量。当您这样做时:
x = pulp.LpVariable.dicts("times",[ride_list.loc[i, 'num'] for i in rides], ...
您正在传递数据框 values
的列表,这是不正确的。该调用应为要创建的变量提供键集,在本例中为 x
,逻辑索引只是骑行次数的计数。在你的例子中,你提供了一个包含 3 个零的列表,因为你已经用这些值填充了 df。这会折叠成一个其中有一个零的集合。请参阅下面的示例。此外,在你剩下的努力中,你没有使用你创建的变量......??您正在使用 ride_list.loc[i,'num']
这只是数据框中的一些固定值, 而不是 问题中的变量。
这里是一个示例,展示了构建变量等的更好方法。请注意打印 x
[格式不正确] 和 y
的输出结果。还要注意在名义约束中创建的变量的用法。
import pulp
import pandas as pd
data = { 'wait': [1, 5, 10],
'ride_time': [2, 6, 8],
'num' : [0, 0, 0]}
df = pd.DataFrame(data)
print (df)
model = pulp.LpProblem("ride_plan", pulp.LpMaximize)
x = pulp.LpVariable.dicts("rides", [df.loc[i, 'num'] for i in range(len(df))]) # <-- bad
print(x)
y = pulp.LpVariable.dicts("rides", range(len(df)), cat="Integer")
print(y)
# example constraint for notional max wait time of 15 minutes...
model += pulp.LpConstraint(pulp.lpSum(df.loc[i, 'wait'] * y[i] for i in range(len(df)))) <= 15
print(model)
产量:
wait ride_time num
0 1 2 0
1 5 6 0
2 10 8 0
{0: rides_0} # <--- x
{0: rides_0, 1: rides_1, 2: rides_2} # <--- y
ride_plan:
MAXIMIZE
None
SUBJECT TO
_C1: rides_0 + 5 rides_1 + 10 rides_2 <= 15
VARIABLES
rides_0 free Integer
rides_1 free Integer
rides_2 free Integer
[Finished in 220ms]
我认为我为优化创建的是一个相当简单的问题。我在 csv 文件中有以下数据:
我正在尝试使用 PuLP 包创建“最佳”骑行日,但在创建我的约束之一时不断出现错误。约束简单概括为:每次骑行的时间(#次骑行*骑行时间,加上#次骑行*等待时间),加上两次骑行之间的15分钟,必须等于或小于公园开放时间(减去固定的用餐和洗手间时间)
当我 运行 约束行时,我不断收到 KeyError: (0, 'num') 。 (我可以毫无问题地打印 ride_list.loc[0,'num'] - 解决问题的第一步。)任何提示或想法将不胜感激。
import pandas as pd
import pulp
ride_list = pd.read_csv('RideData.csv')
num_rides = ride_list.shape[0]
rides = list(range(num_rides))
min_times = 0 #minimum # times for each ride
max_times = 2 #maximum # times for each ride
time_between = 0.25 #how long to allow between rides
food_time = 2.5 #how long to allow for meals
hours_open = 12 #how many hours the park is open
# Set default values for testing
for i in rides:
ride_list.loc[i, 'my_min'] = min_times
ride_list.loc[i, 'my_max'] = max_times
ride_list.loc[i, 'my_rating'] = ride_list.loc[i, 'rating']
ride_list.loc[i, 'num'] = 0
# Initialize model
model = pulp.LpProblem('Maximimize ride enjoyment', pulp.LpMaximize)
# Add calculation to be optimized
model += pulp.lpSum([ride_list.loc[i,'ride'] * ride_list.loc[i,'rating'] * ride_list.loc[i,'num'] for i in rides])
# Add constraint to # times for each ride
x = pulp.LpVariable.dicts("times",[ride_list.loc[i, 'num'] for i in rides],
lowBound = min_times,
upBound = max_times,
cat = 'Integer')
# Add constraint for total amount of time
total_rides = pulp.lpSum([ride_list[i,'num'] for i in rides])
model += pulp.LpConstraint('total_ride_time',
(pulp.lpSum([((ride_list.loc[i,'wait'] * ride_list.loc[i,'num']) +
(ride_list.loc[i,'ride'] * ride_list.loc[i,'num'])) for i in rides]) +
((total_rides - 1) * time_between)) <=
(hours_open - food_time))
所以您在索引方面遇到的问题是由于您没有在 pulp
中正确构造变量。当您这样做时:
x = pulp.LpVariable.dicts("times",[ride_list.loc[i, 'num'] for i in rides], ...
您正在传递数据框 values
的列表,这是不正确的。该调用应为要创建的变量提供键集,在本例中为 x
,逻辑索引只是骑行次数的计数。在你的例子中,你提供了一个包含 3 个零的列表,因为你已经用这些值填充了 df。这会折叠成一个其中有一个零的集合。请参阅下面的示例。此外,在你剩下的努力中,你没有使用你创建的变量......??您正在使用 ride_list.loc[i,'num']
这只是数据框中的一些固定值, 而不是 问题中的变量。
这里是一个示例,展示了构建变量等的更好方法。请注意打印 x
[格式不正确] 和 y
的输出结果。还要注意在名义约束中创建的变量的用法。
import pulp
import pandas as pd
data = { 'wait': [1, 5, 10],
'ride_time': [2, 6, 8],
'num' : [0, 0, 0]}
df = pd.DataFrame(data)
print (df)
model = pulp.LpProblem("ride_plan", pulp.LpMaximize)
x = pulp.LpVariable.dicts("rides", [df.loc[i, 'num'] for i in range(len(df))]) # <-- bad
print(x)
y = pulp.LpVariable.dicts("rides", range(len(df)), cat="Integer")
print(y)
# example constraint for notional max wait time of 15 minutes...
model += pulp.LpConstraint(pulp.lpSum(df.loc[i, 'wait'] * y[i] for i in range(len(df)))) <= 15
print(model)
产量:
wait ride_time num
0 1 2 0
1 5 6 0
2 10 8 0
{0: rides_0} # <--- x
{0: rides_0, 1: rides_1, 2: rides_2} # <--- y
ride_plan:
MAXIMIZE
None
SUBJECT TO
_C1: rides_0 + 5 rides_1 + 10 rides_2 <= 15
VARIABLES
rides_0 free Integer
rides_1 free Integer
rides_2 free Integer
[Finished in 220ms]