3212

Creating a rotation template

I’m considering providing a rotation template heuristic for those who might not want to delve into math programming. For example, I could break down units like having a starter time of 7-8 minutes, with a rest period at 5 minutes, ensuring the lineup maintains a mix of a creator and a rim protector throughout.

I also wonder if a compact 10-man rotation table could work, but I need to avoid heavy formatting. Since rules vary by season, I should clarify which season the user is interested in before finalizing the example.

要做“轮换阵容优化”,建议把规则、球员能力、体能与比赛情境都量化,然后用一个简单的优化器先产出赛前基准轮换,再结合临场信息微调。下面给你一套落地框架+可直接改的优化代码样例。

目标和输入

硬性约束(常见且实用)

策略要点(赛前模板)

可执行的优化模型(Python+PuLP,40分钟FIBA计时)

示例代码(最小可用骨架,先跑通再加特性)

# requirements: pulp (pip install pulp)

import pulp as pl

# 配置
T = 40  # CBA/FIBA: 4*10 分钟
players = [
    # name, position, is_import, base_value, max_minutes, min_minutes
    ("PG_A", "G", 0, 1.2, 32, 12),
    ("SG_B", "G", 0, 0.9, 28, 8),
    ("SF_C", "W", 0, 0.8, 26, 6),
    ("PF_D", "F", 0, 0.7, 26, 6),
    ("C_E",  "C", 0, 1.0, 30, 10),
    ("G_F",  "G", 1, 1.5, 24, 0),  # 外援示例
    ("F_G",  "F", 1, 1.3, 20, 0),  # 外援示例
    ("W_H",  "W", 0, 0.6, 18, 0),
    ("C_I",  "C", 0, 0.5, 16, 0),
    ("G_J",  "G", 0, 0.4, 14, 0),
]

name_idx = {p[0]: i for i, p in enumerate(players)}
P = range(len(players))
quarters = [(0,9), (10,19), (20,29), (30,39)]  # 四节

钟是

# 参数化外援规则(按赛季调整) max_import_on_court_per_min = {0: 1, 1: 2, 2: 2, 3: 1} # 例:第4节最多1人 total_import_minutes_cap = None # 可选:总外援分钟上限;None表示不限制 # 体能惩罚:连续上场第c分钟的边际价值衰减 fatigue_penalty_per_cont_min = 0.04 # 可调;值越大越鼓励休息 # 位置覆盖参数 min_ball_handlers = 1 min_bigs = 1 pos_map = {"G": "G", "W": "W", "F": "F", "C": "C"} is_guard = [1 if players[i][1] == "G" else 0 for i in P] is_big = [1 if players[i][1] in ("F","C") else 0 for i in P] is_import= [players[i][2] for i in P] base_val = [players[i][3] for i in P] max_min = [players[i][4] for i in P] min_min = [players[i][5] for i in P] # 模型 m = pl.LpProblem("CBA_Rotation", pl.LpMaximize) # 变量:是否在场 x = pl.LpVariable.dicts("x", (P, range(T)), lowBound=0, upBound=1, cat="Binary") # 连续上场计数辅助变量:c[p,t] = 从t往前连续在场的长度(上界近似) c = pl.LpVariable.dicts("c", (P, range(T)), lowBound=0, upBound=40, cat="Integer") # 目标:阵容价值 - 疲劳惩罚 lineup_value = pl.lpSum(base_val[p] * x[p][t] for p in P for t in range(T)) fatigue_pen = pl.lpSum(fatigue_penalty_per_cont_min * c[p][t] for p in P for t in range(T)) m += lineup_value - fatigue_pen # 约束:每分钟5人 for t in range(T): m += pl.lpSum(x[p][t] for p in P) == 5 # 每人全场分钟上下限 for p in P: m += pl.lpSum(x[p][t] for t in range(T)) <= max_min[p] m += pl.lpSum(x[p][t] for t in range(T)) >= min_min[p] # 连续上场计数递推和上限(可调上限K) K = 10 for p in P: # t=0 m += c[p][0] >= x[p][0] # 在场 -> 至少1 m += c[p][0] <= x[p][0]*K # 不在场 -> 0 的松弛 # t>0 for t in range(1, T): # 若本分钟在场,则连续计数 >= 上分钟计数+1;否则=0(用两个不等式近似) m += c[p][t] >= c[p][t-1] + x[p][t] - (1 - x[p][t]) * K m += c[p][t] <= x[p][t] * K # 连续上场K上限 m += c[p][t] <= K # 位置覆盖:每分钟至少1名控卫、1名内线 for t in range(T): m += pl.lpSum(is_guard[p] * x[p][t] for p in P) >= min_ball_handlers m += pl.lpSum(is_big[p] * x[p][t] for p in P) >= min_bigs # 外援规则:每节同时在场人数上限 for qi, (s, e) in enumerate(quarters): cap = max_import_on_court_per_min.get(qi, 2) for t in range(s, e + 1): m += pl.lpSum(is_import[p] * x[p][t] for p in P) <= cap # 可选:外援总分钟上限 if total_import_minutes_cap is not None: m += pl.lpSum(is_import[p] * x[p][t] for p in P for t in range(T)) <= total_import_minutes_cap # 求解 m.solve(pl.PULP_CBC_CMD(msg=False)) # 导出结果:每分钟阵容 rotation = [] for t in range(T): lineup = [players[p][0] for p in P if pl.value(x[p][t]) > 0.5] rotation.append((t, lineup)) # 打印简表 for t, lineup in rotation: print(f"Min {t:02d}: {', '.join(lineup)}")

如何继续把它变强

给我这些信息,我能把模型替你具体化并输出可直接用的轮换表:

  1. 本赛季外援规则(按你们赛季为准),以及是否有亚洲外援特殊条款
  2. 每名球员:位置、是否外援、健康/分钟上限、主观攻防评分或数据、犯规/体能特征
  3. 必须/禁止同场的搭配、关键时刻的偏好
  4. 赛程强度与目标(赢当下 vs 练新人)
  5. mp

需要的话,我也可以把上面的脚本改成读取CSV/Excel并生成一张“每分钟阵容表”和“每节用人统计”的报告。