使用 Python Pulp 进行多日播放器选择的二进制优化
Using Python Pulp for binary optimization for multi-day player selection
我正在努力解决一个使用 pulp 的整数优化问题。我正在创建一支梦幻运动队 - 每个比赛日我需要 select 11 名球员。 [为简单起见,假设只有 2 个比赛日]。另一个限制是我不能在 2 天内进行超过 3 次更改。换言之,2 天之间需要有 8 名球员相同。我购买的播放器需要在100学分的预算内。
我有 2 个决策变量:即 selected 团队每天 2 天。
prob = LpProblem("Fantasy_Cricket", LpMaximize)
player_names = list(squad.Player)
player_gd1 = LpVariable.dicts("playerChosen1", player_names, 0, 1, cat='Integer')
player_gd2 = LpVariable.dicts("playerChosen2", player_names, 0, 1, cat='Integer')
仅供参考:player_names
指的是所有可用玩家的列表。
objective 函数是最大化这 2 天的预测分数(gd1 和 gd2 指的是比赛日 1 和比赛日 2)。这是球员 selected * 他的 'Value' 以及他的球队是否在某一天比赛的函数。
prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd1'].sum() + player_gd2[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd2'].sum() for p in player_names])
约束设置如下:
prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
prob += lpSum([player_gd2[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
prob += lpSum([player_gd1[p] for p in player_names]) == 11
prob += lpSum([player_gd2[p] for p in player_names]) == 11
prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8
前 4 个约束工作正常。这是导致 'infeasible' 解决方案的第 5 个。基本上,我正在执行一个规则,即在这 2 天内至少有 8 个玩家是共同的。
prob.solve()
print("Status:", LpStatus[prob.status])
Status: Infeasible
我是 Python 和 PuLP 的新手。谁能帮忙?我错过了什么?
在此重申前 4 个约束条件运行良好。引起问题的是第 5 次(这是对多天 selection 的限制)。
提前致谢。
你的最后一个约束:
prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8
在 PuLP 中不是有效约束。我可以看到您要实现的目标,即创建一个中间二进制变量 ((player_gd1[p] + player_gd2[p]) ==2)
,然后将其汇总到所有玩家中。如果你想这样做,你必须显式声明这个二进制变量,并找到一种方法来强制它在(且仅当)满足该条件时取真值。
例如,您可以创建一组新变量:
player_swapped = LpVariable.dicts("player_swapped", player_names, 0, 1, cat='Integer')
然后有一组约束为:
for p in player_names:
player_swapped[p] >= player_gd1[p] - player_gd2[p]
player_swapped[p] >= player_gd2[p] - player_gd1[p]
然后您可以设置游戏之间可以交换多少玩家的限制。
我正在努力解决一个使用 pulp 的整数优化问题。我正在创建一支梦幻运动队 - 每个比赛日我需要 select 11 名球员。 [为简单起见,假设只有 2 个比赛日]。另一个限制是我不能在 2 天内进行超过 3 次更改。换言之,2 天之间需要有 8 名球员相同。我购买的播放器需要在100学分的预算内。
我有 2 个决策变量:即 selected 团队每天 2 天。
prob = LpProblem("Fantasy_Cricket", LpMaximize)
player_names = list(squad.Player)
player_gd1 = LpVariable.dicts("playerChosen1", player_names, 0, 1, cat='Integer')
player_gd2 = LpVariable.dicts("playerChosen2", player_names, 0, 1, cat='Integer')
仅供参考:player_names
指的是所有可用玩家的列表。
objective 函数是最大化这 2 天的预测分数(gd1 和 gd2 指的是比赛日 1 和比赛日 2)。这是球员 selected * 他的 'Value' 以及他的球队是否在某一天比赛的函数。
prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd1'].sum() + player_gd2[p]*squad[squad.Player==p]['Value'].sum()*squad[squad.Player==p]['gd2'].sum() for p in player_names])
约束设置如下:
prob += lpSum([player_gd1[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
prob += lpSum([player_gd2[p]*squad[squad.Player==p]['Points'].sum() for p in player_names]) <=100
prob += lpSum([player_gd1[p] for p in player_names]) == 11
prob += lpSum([player_gd2[p] for p in player_names]) == 11
prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8
前 4 个约束工作正常。这是导致 'infeasible' 解决方案的第 5 个。基本上,我正在执行一个规则,即在这 2 天内至少有 8 个玩家是共同的。
prob.solve()
print("Status:", LpStatus[prob.status])
Status: Infeasible
我是 Python 和 PuLP 的新手。谁能帮忙?我错过了什么?
在此重申前 4 个约束条件运行良好。引起问题的是第 5 次(这是对多天 selection 的限制)。
提前致谢。
你的最后一个约束:
prob += lpSum([((player_gd1[p] + player_gd2[p]) ==2) for p in player_names]) >=8
在 PuLP 中不是有效约束。我可以看到您要实现的目标,即创建一个中间二进制变量 ((player_gd1[p] + player_gd2[p]) ==2)
,然后将其汇总到所有玩家中。如果你想这样做,你必须显式声明这个二进制变量,并找到一种方法来强制它在(且仅当)满足该条件时取真值。
例如,您可以创建一组新变量:
player_swapped = LpVariable.dicts("player_swapped", player_names, 0, 1, cat='Integer')
然后有一组约束为:
for p in player_names:
player_swapped[p] >= player_gd1[p] - player_gd2[p]
player_swapped[p] >= player_gd2[p] - player_gd1[p]
然后您可以设置游戏之间可以交换多少玩家的限制。