You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多位置球员导致的阵容优化器实现问题求助

多位置球员导致的阵容优化器实现问题求助

我完全懂你的痛点——多位置球员的阵容筛选确实比单一位置的麻烦太多了,毕竟不能直接硬套位置匹配规则,还要避免重复选同一个人,同时得盯着总投影最高的组合来选。我给你梳理几个可行的解决思路,从简单暴力到高效建模都有,你可以根据自己的球员数量来挑:

首先,先把你的原始数据转成结构化的格式,方便后续处理,比如用字典列表存储每个球员的信息:

# 先解析你的原始数据成结构化列表
raw_data = """juan-soto 30.3773 ['OF']
kyle-tucker 44.0626 ['OF']
yordan-alvarez 32.510200000000005 ['CI', 'OF']
william-contreras 26.7904 ['CI', 'MI']"""

players = []
for line in raw_data.splitlines():
    name, proj_str, pos_str = line.split(maxsplit=2)
    proj = float(proj_str)
    # 把位置字符串转成列表,比如['CI', 'OF']处理成['CI', 'OF']
    positions = pos_str.strip('[]').replace("'", "").split(', ')
    players.append({
        "name": name,
        "projection": proj,
        "positions": positions
    })

方法一:暴力组合+验证(适合球员少的情况,比如少于20人)

如果你的球员列表不多,直接穷举所有5人组合,然后验证每个组合是否能满足位置要求,最后选总投影最高的就行。

核心是写一个验证函数,判断给定的5人组合是否存在一种位置分配方式,满足1个CI、1个MI、1个OF,剩下2个当FLEX。这里用递归回溯的方式尝试所有可能的分配,确保不会漏掉任何潜在的有效组合:

def can_assign(remaining_players, needed_positions):
    # 递归终止条件:所有需求都满足了
    if all(count == 0 for count in needed_positions.values()):
        return True
    
    # 遍历当前还需要的位置
    for pos, required in needed_positions.items():
        if required <= 0:
            continue
        
        # 找所有能打这个位置且还没被分配的球员
        eligible = [p for p in remaining_players if pos in p["positions"]]
        if not eligible:
            continue
        
        # 尝试用其中一个球员来满足这个位置需求
        for player in eligible:
            # 复制需求字典,避免修改原数据
            new_needed = needed_positions.copy()
            new_needed[pos] -= 1
            
            # 复制球员列表,移除当前选中的球员(不能重复用)
            new_players = remaining_players[:]
            new_players.remove(player)
            
            # 递归验证剩下的需求和球员
            if can_assign(new_players, new_needed):
                return True
    
    return False

def is_valid_lineup(combo):
    # 基础需求:1个CI、1个MI、1个OF,剩下2个FLEX不需要额外限制
    base_needs = {"CI": 1, "MI": 1, "OF": 1}
    return can_assign(list(combo), base_needs)

然后就可以遍历所有5人组合,筛选有效组合并找出最优:

from itertools import combinations

def find_best_bruteforce(players):
    best_total = -1.0
    best_lineup = None
    
    for combo in combinations(players, 5):
        if is_valid_lineup(combo):
            total = sum(p["projection"] for p in combo)
            if total > best_total:
                best_total = total
                best_lineup = combo
    
    return best_lineup, best_total

# 调用测试
lineup, total = find_best_bruteforce(players)
if lineup:
    print(f"最佳总投影: {total:.4f}")
    print("阵容:")
    for p in lineup:
        print(f"- {p['name']} | 投影: {p['projection']:.4f} | 位置: {p['positions']}")
else:
    print("没有符合要求的阵容")

方法二:整数规划(适合球员多的情况,高效不暴力)

如果你的球员数量很多(比如20+),暴力穷举组合会非常慢,这时候可以用线性规划库PuLP来建模求解,效率会高很多。

这个思路是把问题转化为数学规划:每个球员要么选要么不选,目标是总投影最大,约束条件是:

  1. 总共选5个球员
  2. 选中的球员里,至少有1个能打CI
  3. 至少有1个能打MI
  4. 至少有1个能打OF

代码实现如下:

from pulp import LpProblem, LpVariable, LpMaximize, lpSum

# 创建最大化问题
prob = LpProblem("OptimalFantasyLineup", LpMaximize)

# 给每个球员创建0-1变量:1表示选中,0表示不选
player_vars = LpVariable.dicts(
    "Player",
    [p["name"] for p in players],
    lowBound=0,
    upBound=1,
    cat="Integer"
)

# 目标函数:总投影最大化
prob += lpSum([p["projection"] * player_vars[p["name"]] for p in players])

# 约束1:必须选恰好5个球员
prob += lpSum([player_vars[p["name"]] for p in players]) == 5

# 约束2:至少有1个能打CI的球员被选中
prob += lpSum([player_vars[p["name"]] for p in players if "CI" in p["positions"]]) >= 1

# 约束3:至少有1个能打MI的球员被选中
prob += lpSum([player_vars[p["name"]] for p in players if "MI" in p["positions"]]) >= 1

# 约束4:至少有1个能打OF的球员被选中
prob += lpSum([player_vars[p["name"]] for p in players if "OF" in p["positions"]]) >= 1

# 求解问题(PuLP会自动调用合适的求解器)
prob.solve()

# 输出结果
print("最佳阵容(整数规划解法):")
total_proj = 0.0
for p in players:
    if player_vars[p["name"]].varValue == 1:
        print(f"- {p['name']} | 投影: {p['projection']:.4f} | 位置: {p['positions']}")
        total_proj += p["projection"]
print(f"总投影: {total_proj:.4f}")

这个方法不需要穷举所有组合,求解器会直接找到最优解,适合大数量的球员列表。


补充说明

这里的关键是不要纠结球员的“所有位置”,而是关注“是否存在至少一种位置分配方式满足阵容需求”——只要一个球员能覆盖某个位置需求,并且整个组合能通过分配不同球员到对应位置来填满所有配额,同时不重复使用球员,这个组合就是有效的。

备注:内容来源于stack exchange,提问作者markus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 20:00:28