Python约束优化问题



我正在开发一个梦幻足球程序,遇到了一个约束问题。幻想团队由1QB、2RBs、3WR、1TE、1DEF和1FLEX(可以是RB、WR或TE(组成

我的输出是复制播放器。例如,如果John Doe担任RB职位,我需要他不要担任FLEX职位。我不知道如何完成这个限制。也许是为了确保名字不相等而进行的名字比较?

如有任何建议,我们将不胜感激

以下是一些示例数据:

| position | displayName         | Roster   | Position | salary | points |
|----------+---------------------+----------+----------+--------+--------|
| RB       | Christian McCaffrey | 15033483 | RB/FLEX  | 10000  | 30.95  |
| WR       | Michael Thomas      | 15033799 | WR/FLEX  | 9000   | 24.62  |
| QB       | Lamar Jackson       | 15033397 | QB       | 8100   | 29.85  |
| RB       | Dalvin Cook         | 15033485 | RB/FLEX  | 7900   | 21.62  |
# Set constraints
##################################################################
salaries = {}
points = {}
for pos in availables.position.unique():
available_pos = availables[availables.position == pos]
salary = list(available_pos[["displayName","salary"]].set_index("displayName").to_dict().values())[0]
point = list(available_pos[["displayName","points"]].set_index("displayName").to_dict().values())[0]
salaries[pos] = salary
points[pos] = point
pos_num_available = {
"QB": 1,
"RB": 2,
"WR": 3,
"TE": 1,
"FLEX": 1,
"DST": 1
}

pos_flex = {
"QB": 0,
"RB": 1,
"WR": 1,
"TE": 1,
"FLEX": 0,
"DST": 0
}

pos_flex_available = 3
SALARY_CAP = 50000
_vars = {k: LpVariable.dict(k, v, cat="Binary") for k, v in points.items()}
##################################################################
# Problem Definition
##################################################################
prob = LpProblem("Fantasy", LpMaximize)
rewards = []
costs = []
position_constraints = []

for k, v in _vars.items():
costs += lpSum([salaries[k][i] * _vars[k][i] for i in v])
rewards += lpSum([points[k][i] * _vars[k][i] for i in v])
prob += lpSum([_vars[k][i] for i in v]) <= pos_num_available[k]
prob += lpSum([pos_flex[k] * _vars[k][i] for i in v]) <= pos_flex_available
prob += lpSum(rewards)
prob += lpSum(costs) <= SALARY_CAP
prob.solve()

为了可读性,我对您的代码进行了一些清理。结构完全相同,只是一些语法方面的问题。

考虑以下内容:

import pulp as pl
import pandas as pd
availables = pd.DataFrame(
[
["RB", "Christian McCaffrey", 15033483, "RB/FLEX", 10000, 30.95],
["WR", "Michael Thomas", 15033799, "WR/FLEX", 9000, 24.62],
["QB", "Lamar Jackson", 15033397, "QB", 8100, 29.85],
["RB", "Dalvin Cook", 15033485, "RB/FLEX", 7900, 21.62]
],
columns=["position", "displayName", "Roster", "Position", "salary", "points"]
)
##################################################################
# Set constraints
##################################################################
salaries = {}
points = {}
players = {}
for position in availables.position.unique():
available_for_position = availables[availables.position == position]
players[position] = list(available_for_position.Roster.values)
salaries[position] = {
player_roster: salary for player_roster, salary in
zip(players[position], available_for_position.salary.values)
}
points[position] = {
player_roster: _points for player_roster, _points in
zip(players[position], available_for_position.points.values)
}
positions_available = {
"QB": 1,
"RB": 2,
"WR": 3,
"TE": 1,
"FLEX": 1,
"DST": 1
}
flexible_positions = ("RB", "WR", "TE")
SALARY_CAP = 50000
# Player variables['QB'][15033483] denotes whether Lamar Jackson is selected
variables = {position: pl.LpVariable.dict(position, players[position], cat="Binary")
for position in players}
##################################################################
# Problem Definition
##################################################################
prob = pl.LpProblem("Fantasy", pl.LpMaximize)
rewards = []
costs = []
number_of_selected_players = []
for position, players in variables.items():
for player, player_selected in players.items():
# If this player is selected, he will add salaries and points
costs += salaries[position][player] * player_selected
rewards += points[position][player] * player_selected
number_of_selected_players += player_selected
# Of this position, if it does not support FLEX, at most `positions_available`
# are supported. If it does support FLEX, increment that by
# `flexible_positions_available`
if position not in flexible_positions:
prob += pl.lpSum(players.values()) == positions_available[position]
else:
# We need at least `positions_available` players on this position and at
# most`positions_available + flexible_positions_available` players
prob += pl.lpSum(players.values()) >= positions_available[position]
prob += (pl.lpSum(players.values())
<= positions_available[position] + positions_available["FLEX"])
# In total, we need exactly `positions_available` players
prob += pl.lpSum(number_of_selected_players) == sum(positions_available.values())
prob += pl.lpSum(rewards)
prob += pl.lpSum(costs) <= SALARY_CAP
prob.solve()

你跟踪每个球员是否被选中。然后,你最多允许positions_available球员处于该位置,除非是";"柔性";位置,则允许在positions_availablepositions_available + positions_available['FLEX']之间。

因为你总共需要9名玩家,所以问题的唯一自由度是选择一名灵活的玩家来填补最后的灵活位置。

最新更新