使用列表推导创建PuLP LPConstraint时报KeyError: (0, 'num')如何处理
问题原因
- 直接触发
KeyError: (0, 'num')的原因:
计算total_rides的代码行中使用了ride_list[i,'num']的索引写法,pandas原生的[]索引不支持直接传入(行序号, 列名)格式的元组,只有.loc/.iloc索引器支持该格式。你单独测试时用了ride_list.loc[0,'num']所以可以正常输出,这行漏写.loc就会把(i, 'num')当成整体的键去匹配DataFrame的列名,自然找不到对应键。 - 隐藏的模型逻辑错误:
你对PuLP决策变量的定义和使用完全不符合要求:- 定义
pulp.LpVariable.dicts时,第二个参数应该是变量的索引列表(也就是所有游乐项目的序号列表rides),但你传的是提前写死为0的ride_list.loc[i, 'num'],会导致所有变量的索引重合,无法对应到每个游乐项目 - 目标函数、时间约束的代码中,全部使用了固定为0的
ride_list.loc[i,'num']常量,完全没有用到你定义的决策变量,模型根本无法求解出最优的游玩次数
- 定义
- 约束定义语法错误:
pulp.LpConstraint的参数顺序错误,第一个参数应为约束表达式,第二个才是约束名称,你把两者顺序写反了。
修复后的完整代码
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 # 每个项目最低游玩次数 max_times = 2 # 每个项目最高游玩次数 time_between = 0.25 # 项目间转场耗时,单位小时 food_time = 2.5 # 用餐休息总耗时,单位小时 hours_open = 12 # 乐园总开放时长,单位小时 # 初始化模型 model = pulp.LpProblem('Maximimize ride enjoyment', pulp.LpMaximize) # 定义决策变量:x[i]代表第i个项目的游玩次数 x = pulp.LpVariable.dicts("times", rides, lowBound=min_times, upBound=max_times, cat='Integer') # 设置目标函数:最大化总评分 model += pulp.lpSum([ride_list.loc[i,'ride'] * ride_list.loc[i,'rating'] * x[i] for i in rides]) # 设置总时间约束 total_rides = pulp.lpSum([x[i] for i in rides]) # 总耗时 = 所有项目的等待+乘坐总时长 + 转场总时长,不超过可用时长 model += (pulp.lpSum([((ride_list.loc[i,'wait'] * x[i]) + (ride_list.loc[i,'ride'] * x[i])) for i in rides]) + ((total_rides - 1) * time_between)) <= (hours_open - food_time), "total_ride_time" # 求解模型 model.solve() # 输出结果 for i in rides: print(f"项目{ride_list.loc[i, 'name']}游玩次数:{x[i].value()}") print(f"总评分:{pulp.value(model.objective)}")
内容的提问来源于stack exchange,提问作者dhunton
相关产品推荐
相关产品推荐

