在 PuLP 优化解决方案中仅包含唯一值
Include Only Unique Values in a PuLP Optimization Solution
这个 post 是从
衍生出来的一个相关问题
我的目标是在给定一组约束的情况下生成最佳梦幻足球阵容。由于梦幻足球联赛的性质,我的清单中可能会多次出现同一名球员,尽管我只能在我的阵容中扮演该球员的一个实例。我已经使用 PuLP 创建了一个优化问题来生成阵容,但我需要添加一个约束以确保一名球员不会多次出现在该阵容中。
下面是我现在的模型。任何有关如何确保我的解决方案中没有重复播放器的建议都将受到赞赏!
import pandas as pd
import pulp
print('--- (1/4) Defining the problem ---')
# Read csv
raw_data = pd.read_csv('./csv/fantasypros.csv')
# create new columns that has binary numbers if player == a specific position
encoded = pd.get_dummies(raw_data['Pos. Parent']) # <-- One-Hote Encoding
raw_data = raw_data.join(encoded) # <-- joining it to the raw_data table
raw_data["salary"] = raw_data["Point Cost"].astype(float)
model = pulp.LpProblem("NFTdraft", pulp.LpMaximize)
total_points = {}
cost = {}
qb = {}
rb = {}
wr = {}
te = {}
k = {}
dst = {}
dk = {}
num_players = {}
vars_list = []
# i = row index, player = player attributes
for i, player in raw_data.iterrows():
var_name = 'x' + str(i) # Create variable name
decision_var = pulp.LpVariable(var_name, cat='Binary') # Initialize Variables
total_points[decision_var] = player["FPTS"] # Create FPTS Dictionary
cost[decision_var] = player["salary"] # Create Cost Dictionary
# Create Dictionary for Player Types
qb[decision_var] = player["QB"]
rb[decision_var] = player["RB"]
wr[decision_var] = player["WR"]
te[decision_var] = player["TE"]
k[decision_var] = player["K"]
dst[decision_var] = player["DST"]
dk[decision_var] = player["DK"]
num_players[decision_var] = 1.0
objective_function = pulp.LpAffineExpression(total_points)
model += objective_function
total_cost = pulp.LpAffineExpression(cost)
model += (total_cost <= 135)
print('--- (2/4) Defining the constraints ---')
QB_constraint = pulp.LpAffineExpression(qb)
RB_constraint = pulp.LpAffineExpression(rb)
WR_constraint = pulp.LpAffineExpression(wr)
TE_constraint = pulp.LpAffineExpression(te)
K_constraint = pulp.LpAffineExpression(k)
DST_constraint = pulp.LpAffineExpression(dst)
DK_constraint = pulp.LpAffineExpression(dk)
total_players = pulp.LpAffineExpression(num_players)
model += (QB_constraint >= 1)
model += (QB_constraint <= 2)
model += (RB_constraint <= 8)
model += (WR_constraint <= 8)
model += (TE_constraint <= 8)
model += (K_constraint <= 1)
model += (DST_constraint <= 1)
model += (DK_constraint <= 2)
model += (total_players == 10)
print('--- (3/4) Solving the problem ---')
model.solve()
print('--- (4/4) Formatting the results ---')
raw_data["is_drafted"] = 0.0
for var in model.variables():
raw_data.loc[int(var.name[1:]), 'is_drafted'] = var.varValue # <--- CHANGED HERE
my_team = raw_data[raw_data["is_drafted"] == 1.0]
my_team = my_team[["Asset Name", "Player", "Pos. Parent", "Rarity", "Point Cost", "FPTS"]]
print(my_team)
print("Total used amount of salary cap: {}".format(my_team["Point Cost"].sum()))
print("Projected points: {}".format(my_team["FPTS"].sum().round(1)))
print('--- Completed ---')
要将限制设置为仅允许单人游戏(从重复玩家的数据框中),您需要设置类似于其他限制的内容)。在这里,我们将只对 "Player"
进行单热编码,然后遍历它以创建限制,即每个 "Player"
名称必须有 1 个或更少。
import pandas as pd
import pulp
print('--- (1/4) Defining the problem ---')
# Read csv
raw_data = pd.read_csv('./csv/fantasypros.csv').drop_duplicates().reset_index(drop=True)
# create new columns that has binary numbers if player == a specific position
encoded = pd.get_dummies(raw_data['Pos. Parent']) #<-- One-Hote Encoding
raw_data = raw_data.join(encoded) #<-- joining it to the raw_data table
# Will be used to create the constraint of not using same player name in lineup
encoded = pd.get_dummies(raw_data['Player']) #<-- One-Hote Encoding
raw_data = raw_data.join(encoded) #<-- joining it to the raw_data table
raw_data["salary"] = raw_data["Point Cost"].astype(float)
model = pulp.LpProblem("NFTdraft", pulp.LpMaximize)
total_points = {}
cost = {}
qb = {}
rb = {}
wr = {}
te = {}
k = {}
dst = {}
dk = {}
num_players = {}
# Here I created a list of all the possible players in the dataframe
# This is used later to construct the dictionary of players, then
# to add each of those into the model
players_list = list(raw_data['Player'].unique())
players_list.sort()
pLAYER_dict = {}
for player in players_list:
pLAYER_dict[player] ={}
vars_list = []
# i = row index, player = player attributes
for i, player in raw_data.iterrows():
#print('Processing row: %s of %s' %((i+1),len(raw_data)))
var_name = 'x' + str(i) # Create variable name
decision_var = pulp.LpVariable(var_name, cat='Binary') # Initialize Variables
total_points[decision_var] = player["FPTS"] # Create FPTS Dictionary
cost[decision_var] = player["salary"] # Create Cost Dictionary
# Create Dictionary for Player Types
qb[decision_var] = player["QB"]
rb[decision_var] = player["RB"]
wr[decision_var] = player["WR"]
te[decision_var] = player["TE"]
k[decision_var] = player["K"]
dst[decision_var] = player["DST"]
dk[decision_var] = player["DK"]
num_players[decision_var] = 1.0
# Here is where I store each value for each player name for the player
for key, v in PLAYER_dict.items():
PLAYER_dict[key].update({decision_var:player[key]})
objective_function = pulp.LpAffineExpression(total_points)
model += objective_function
total_cost = pulp.LpAffineExpression(cost)
model += (total_cost <= 135)
print('--- (2/4) Defining the constraints ---')
QB_constraint = pulp.LpAffineExpression(qb)
RB_constraint = pulp.LpAffineExpression(rb)
WR_constraint = pulp.LpAffineExpression(wr)
TE_constraint = pulp.LpAffineExpression(te)
K_constraint = pulp.LpAffineExpression(k)
DST_constraint = pulp.LpAffineExpression(dst)
DK_constraint = pulp.LpAffineExpression(dk)
total_players = pulp.LpAffineExpression(num_players)
model += (QB_constraint >= 1)
model += (QB_constraint <= 2)
model += (RB_constraint <= 8)
model += (WR_constraint <= 8)
model += (TE_constraint <= 8)
model += (K_constraint <= 1)
model += (DST_constraint <= 1)
model += (DK_constraint <= 2)
model += (total_players == 10)
for k1, v1 in PLAYER_dict.items():
player_constraint = pulp.LpAffineExpression(v1)
model += (player_constraint <= 1)
print('--- (3/4) Solving the problem ---')
model.solve()
print('--- (4/4) Formatting the results ---')
raw_data["is_drafted"] = 0.0
for var in model.variables():
raw_data.loc[int(var.name[1:]), 'is_drafted'] = var.varValue # <--- CHANGED HERE
my_team = raw_data[raw_data["is_drafted"] == 1.0]
my_team = my_team[["Asset Name", "Player", "Pos. Parent", "Rarity", "Point Cost", "FPTS"]]
print(my_team)
print("Total used amount of salary cap: {}".format(my_team["Point Cost"].sum()))
print("Projected points: {}".format(my_team["FPTS"].sum().round(1)))
print('--- Completed ---')
输出:
Asset Name Player ... Point Cost FPTS
59 Arizona WR #1 DeAndre Hopkins ... 19 20.301
375 Carolina RB #1 Christian McCaffrey ... 20 26.500
582 Cincinnati WR #3 Tyler Boyd ... 10 13.000
803 Denver RB #2 Javonte Williams ... 8 11.100
1011 Green Bay WR #4 Randall Cobb ... 5 8.800
1170 Indianapolis QB #2 Jacob Eason ... 5 11.400
1301 Kansas City QB #1 Patrick Mahomes II ... 20 23.900
1349 Kansas City WR #1 Tyreek Hill ... 20 21.100
1658 Minnesota RB #1 Dalvin Cook ... 20 22.500
2729 Washington WR #2 Curtis Samuel ... 8 11.700
[10 rows x 6 columns]
Total used amount of salary cap: 135
Projected points: 170.3
--- Completed ---
这个 post 是从
我的目标是在给定一组约束的情况下生成最佳梦幻足球阵容。由于梦幻足球联赛的性质,我的清单中可能会多次出现同一名球员,尽管我只能在我的阵容中扮演该球员的一个实例。我已经使用 PuLP 创建了一个优化问题来生成阵容,但我需要添加一个约束以确保一名球员不会多次出现在该阵容中。
下面是我现在的模型。任何有关如何确保我的解决方案中没有重复播放器的建议都将受到赞赏!
import pandas as pd
import pulp
print('--- (1/4) Defining the problem ---')
# Read csv
raw_data = pd.read_csv('./csv/fantasypros.csv')
# create new columns that has binary numbers if player == a specific position
encoded = pd.get_dummies(raw_data['Pos. Parent']) # <-- One-Hote Encoding
raw_data = raw_data.join(encoded) # <-- joining it to the raw_data table
raw_data["salary"] = raw_data["Point Cost"].astype(float)
model = pulp.LpProblem("NFTdraft", pulp.LpMaximize)
total_points = {}
cost = {}
qb = {}
rb = {}
wr = {}
te = {}
k = {}
dst = {}
dk = {}
num_players = {}
vars_list = []
# i = row index, player = player attributes
for i, player in raw_data.iterrows():
var_name = 'x' + str(i) # Create variable name
decision_var = pulp.LpVariable(var_name, cat='Binary') # Initialize Variables
total_points[decision_var] = player["FPTS"] # Create FPTS Dictionary
cost[decision_var] = player["salary"] # Create Cost Dictionary
# Create Dictionary for Player Types
qb[decision_var] = player["QB"]
rb[decision_var] = player["RB"]
wr[decision_var] = player["WR"]
te[decision_var] = player["TE"]
k[decision_var] = player["K"]
dst[decision_var] = player["DST"]
dk[decision_var] = player["DK"]
num_players[decision_var] = 1.0
objective_function = pulp.LpAffineExpression(total_points)
model += objective_function
total_cost = pulp.LpAffineExpression(cost)
model += (total_cost <= 135)
print('--- (2/4) Defining the constraints ---')
QB_constraint = pulp.LpAffineExpression(qb)
RB_constraint = pulp.LpAffineExpression(rb)
WR_constraint = pulp.LpAffineExpression(wr)
TE_constraint = pulp.LpAffineExpression(te)
K_constraint = pulp.LpAffineExpression(k)
DST_constraint = pulp.LpAffineExpression(dst)
DK_constraint = pulp.LpAffineExpression(dk)
total_players = pulp.LpAffineExpression(num_players)
model += (QB_constraint >= 1)
model += (QB_constraint <= 2)
model += (RB_constraint <= 8)
model += (WR_constraint <= 8)
model += (TE_constraint <= 8)
model += (K_constraint <= 1)
model += (DST_constraint <= 1)
model += (DK_constraint <= 2)
model += (total_players == 10)
print('--- (3/4) Solving the problem ---')
model.solve()
print('--- (4/4) Formatting the results ---')
raw_data["is_drafted"] = 0.0
for var in model.variables():
raw_data.loc[int(var.name[1:]), 'is_drafted'] = var.varValue # <--- CHANGED HERE
my_team = raw_data[raw_data["is_drafted"] == 1.0]
my_team = my_team[["Asset Name", "Player", "Pos. Parent", "Rarity", "Point Cost", "FPTS"]]
print(my_team)
print("Total used amount of salary cap: {}".format(my_team["Point Cost"].sum()))
print("Projected points: {}".format(my_team["FPTS"].sum().round(1)))
print('--- Completed ---')
要将限制设置为仅允许单人游戏(从重复玩家的数据框中),您需要设置类似于其他限制的内容)。在这里,我们将只对 "Player"
进行单热编码,然后遍历它以创建限制,即每个 "Player"
名称必须有 1 个或更少。
import pandas as pd
import pulp
print('--- (1/4) Defining the problem ---')
# Read csv
raw_data = pd.read_csv('./csv/fantasypros.csv').drop_duplicates().reset_index(drop=True)
# create new columns that has binary numbers if player == a specific position
encoded = pd.get_dummies(raw_data['Pos. Parent']) #<-- One-Hote Encoding
raw_data = raw_data.join(encoded) #<-- joining it to the raw_data table
# Will be used to create the constraint of not using same player name in lineup
encoded = pd.get_dummies(raw_data['Player']) #<-- One-Hote Encoding
raw_data = raw_data.join(encoded) #<-- joining it to the raw_data table
raw_data["salary"] = raw_data["Point Cost"].astype(float)
model = pulp.LpProblem("NFTdraft", pulp.LpMaximize)
total_points = {}
cost = {}
qb = {}
rb = {}
wr = {}
te = {}
k = {}
dst = {}
dk = {}
num_players = {}
# Here I created a list of all the possible players in the dataframe
# This is used later to construct the dictionary of players, then
# to add each of those into the model
players_list = list(raw_data['Player'].unique())
players_list.sort()
pLAYER_dict = {}
for player in players_list:
pLAYER_dict[player] ={}
vars_list = []
# i = row index, player = player attributes
for i, player in raw_data.iterrows():
#print('Processing row: %s of %s' %((i+1),len(raw_data)))
var_name = 'x' + str(i) # Create variable name
decision_var = pulp.LpVariable(var_name, cat='Binary') # Initialize Variables
total_points[decision_var] = player["FPTS"] # Create FPTS Dictionary
cost[decision_var] = player["salary"] # Create Cost Dictionary
# Create Dictionary for Player Types
qb[decision_var] = player["QB"]
rb[decision_var] = player["RB"]
wr[decision_var] = player["WR"]
te[decision_var] = player["TE"]
k[decision_var] = player["K"]
dst[decision_var] = player["DST"]
dk[decision_var] = player["DK"]
num_players[decision_var] = 1.0
# Here is where I store each value for each player name for the player
for key, v in PLAYER_dict.items():
PLAYER_dict[key].update({decision_var:player[key]})
objective_function = pulp.LpAffineExpression(total_points)
model += objective_function
total_cost = pulp.LpAffineExpression(cost)
model += (total_cost <= 135)
print('--- (2/4) Defining the constraints ---')
QB_constraint = pulp.LpAffineExpression(qb)
RB_constraint = pulp.LpAffineExpression(rb)
WR_constraint = pulp.LpAffineExpression(wr)
TE_constraint = pulp.LpAffineExpression(te)
K_constraint = pulp.LpAffineExpression(k)
DST_constraint = pulp.LpAffineExpression(dst)
DK_constraint = pulp.LpAffineExpression(dk)
total_players = pulp.LpAffineExpression(num_players)
model += (QB_constraint >= 1)
model += (QB_constraint <= 2)
model += (RB_constraint <= 8)
model += (WR_constraint <= 8)
model += (TE_constraint <= 8)
model += (K_constraint <= 1)
model += (DST_constraint <= 1)
model += (DK_constraint <= 2)
model += (total_players == 10)
for k1, v1 in PLAYER_dict.items():
player_constraint = pulp.LpAffineExpression(v1)
model += (player_constraint <= 1)
print('--- (3/4) Solving the problem ---')
model.solve()
print('--- (4/4) Formatting the results ---')
raw_data["is_drafted"] = 0.0
for var in model.variables():
raw_data.loc[int(var.name[1:]), 'is_drafted'] = var.varValue # <--- CHANGED HERE
my_team = raw_data[raw_data["is_drafted"] == 1.0]
my_team = my_team[["Asset Name", "Player", "Pos. Parent", "Rarity", "Point Cost", "FPTS"]]
print(my_team)
print("Total used amount of salary cap: {}".format(my_team["Point Cost"].sum()))
print("Projected points: {}".format(my_team["FPTS"].sum().round(1)))
print('--- Completed ---')
输出:
Asset Name Player ... Point Cost FPTS
59 Arizona WR #1 DeAndre Hopkins ... 19 20.301
375 Carolina RB #1 Christian McCaffrey ... 20 26.500
582 Cincinnati WR #3 Tyler Boyd ... 10 13.000
803 Denver RB #2 Javonte Williams ... 8 11.100
1011 Green Bay WR #4 Randall Cobb ... 5 8.800
1170 Indianapolis QB #2 Jacob Eason ... 5 11.400
1301 Kansas City QB #1 Patrick Mahomes II ... 20 23.900
1349 Kansas City WR #1 Tyreek Hill ... 20 21.100
1658 Minnesota RB #1 Dalvin Cook ... 20 22.500
2729 Washington WR #2 Curtis Samuel ... 8 11.700
[10 rows x 6 columns]
Total used amount of salary cap: 135
Projected points: 170.3
--- Completed ---