篮球CBA球队轮换阵容优化(CBA球队轮换与阵容配置优化)
添加时间:2026-01-25
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)}")
如何继续把它变强
给我这些信息,我能把模型替你具体化并输出可直接用的轮换表:
需要的话,我也可以把上面的脚本改成读取CSV/Excel并生成一张“每分钟阵容表”和“每节用人统计”的报告。