综合python案例,轮转换位防守默契度?

wen python案例 3

用 Python 量化"轮转换位防守默契度"

下面我用一个完整的 Python 案例,模拟篮球防守中"轮转换位(help & recover / rotation defense)"的默契度评估,这类问题本质上是:多人时序协作 + 空间覆盖 + 时间窗口的问题,非常适合用 Python 做仿真与打分。

综合python案例,轮转换位防守默契度?


问题建模

防守轮转的核心要素:

要素 含义 量化指标
位置 球员实时坐标 (x, y)
时间 补位是否及时 反应延迟 Δt
覆盖 是否有人补上空档 区域覆盖率
交接 换防时是否重叠/漏人 交接间隙
同步 多人是否协调移动 位置协同度

默契度 = 及时性 + 覆盖性 + 交接平滑度 + 同步性


完整代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
from dataclasses import dataclass
# ---------- 1. 基础设定 ----------
COURT_W, COURT_H = 15.0, 14.0          # 半场(米)
FRAME_DT = 0.1                          # 采样间隔 0.1s
np.random.seed(42)
@dataclass
class Player:
    pid: int
    pos: np.ndarray          # 当前坐标
    vel: np.ndarray          # 速度
    target: np.ndarray       # 目标补位点
    def step(self, dt=FRAME_DT, speed=6.0):
        """向目标点移动(带最大速度限制)"""
        direction = self.target - self.pos
        dist = np.linalg.norm(direction)
        if dist < 1e-3:
            return
        direction /= dist
        move = direction * min(speed * dt, dist)
        self.pos = self.pos + move
# ---------- 2. 模拟一次防守轮转 ----------
def simulate_rotation(n_defenders=5, frames=40, noise=0.15):
    """
    场景:进攻方传球后,防守方需要轮转换位补防
    返回每一帧所有防守球员的坐标
    """
    # 初始站位(简化 2-3 联防雏形)
    init_pos = np.array([
        [3, 4], [3, 10],           # 上线两人
        [8, 3], [8, 7], [8, 11],   # 下线三人
    ], dtype=float)
    defenders = [Player(i, init_pos[i].copy(),
                        np.zeros(2), init_pos[i].copy())
                 for i in range(n_defenders)]
    # 进攻方制造一个"空档"——球传到底角,需要最近的人补防
    ball_pos = np.array([13.5, 1.5])   # 底角
    # 每个防守者的补位目标 = 与球形成新的联防结构
    new_targets = np.array([
        [5, 4], [5, 10],
        [10, 4], [10, 8], [11.5, 3],   # 最后一人补底角
    ])
    trajectory = []
    for f in range(frames):
        # 更新目标(可加噪声模拟沟通延迟)
        for i, d in enumerate(defenders):
            target = new_targets[i] + np.random.randn(2) * noise
            d.target = target
            d.step()
        trajectory.append(np.array([d.pos.copy() for d in defenders]))
    return np.array(trajectory), ball_pos, new_targets
# ---------- 3. 默契度评分 ----------
def timing_score(traj, ideal_targets, tol=0.8):
    """及时性:所有防守者多快到位"""
    frames = traj.shape[0]
    dists = np.linalg.norm(traj - ideal_targets[None, :, :], axis=2)  # (F,N)
    reached = (dists < tol).all(axis=1)          # 每帧是否全员到位
    if reached.any():
        t_reach = np.argmax(reached)             # 首次全员到位帧
        return max(0.0, 1 - t_reach / frames)
    return 0.0
def coverage_score(traj, key_zones, radius=1.5):
    """
    覆盖性:关键时刻防守者对危险区域(底角/篮下)的覆盖比例
    用最后 20% 帧评估
    """
    tail = traj[int(len(traj) * 0.8):]
    covered = []
    for zone in key_zones:
        d = np.linalg.norm(tail - zone[None, None, :], axis=2)  # (T,N)
        covered.append((d.min(axis=1) < radius).mean())
    return float(np.mean(covered))
def handoff_score(traj, min_gap=1.0):
    """
    交接平滑度:换防时两人之间不应重叠(过近)也不应漏出大空档
    用相邻帧防守者间距变化评估
    """
    scores = []
    for t in range(traj.shape[0]):
        d = cdist(traj[t], traj[t])       # 两两距离
        np.fill_diagonal(d, np.inf)
        min_d = d.min()
        # 太近(<0.8m,撞车)或太远(>4m,漏人)都扣分
        if min_d < 0.8:
            scores.append(min_d / 0.8)
        else:
            scores.append(1.0)
    return float(np.mean(scores))
def sync_score(traj):
    """
    同步性:多人移动方向一致性(协防时整体移动而非各自为战)
    计算相邻帧速度向量的平均余弦相似度
    """
    v = np.diff(traj, axis=0)                      # (F-1, N, 2)
    norms = np.linalg.norm(v, axis=2, keepdims=True)
    norms[norms == 0] = 1
    v_unit = v / norms
    sims = []
    for t in range(v_unit.shape[0]):
        vecs = v_unit[t]                            # (N,2)
        # 两两余弦
        M = vecs @ vecs.T
        iu = np.triu_indices(len(vecs), k=1)
        sims.append(M[iu].mean())
    return float(np.clip(np.mean(sims), 0, 1))
# ---------- 4. 总默契度 ----------
def synergy(traj, targets, zones):
    s1 = timing_score(traj, targets)
    s2 = coverage_score(traj, zones)
    s3 = handoff_score(traj)
    s4 = sync_score(traj)
    # 权重可调
    total = 0.35 * s1 + 0.25 * s2 + 0.20 * s3 + 0.20 * s4
    return {
        "及时性": round(s1, 3),
        "覆盖性": round(s2, 3),
        "交接平滑": round(s3, 3),
        "同步性": round(s4, 3),
        "综合默契度": round(total, 3),
    }
# ---------- 5. 运行 ----------
if __name__ == "__main__":
    traj, ball, targets = simulate_rotation()
    zones = np.array([[13.5, 1.5], [14, 7], [11, 4]])   # 底角、中路、篮下
    score = synergy(traj, targets, zones)
    print("=" * 40)
    print("防守轮转换位默契度报告")
    print("=" * 40)
    for k, v in score.items():
        print(f"{k:10s}: {v}")
    # ---------- 6. 可视化 ----------
    fig, ax = plt.subplots(figsize=(7, 6.5))
    # 球场
    ax.add_patch(plt.Rectangle((0, 0), COURT_W, COURT_H,
                               fill=False, lw=2))
    ax.add_patch(plt.Circle((0, COURT_H / 2), 1.8, fill=False))   # 篮筐区
    ax.plot(0, COURT_H / 2, 'ko', ms=5)
    # 轨迹
    colors = plt.cm.viridis(np.linspace(0, 1, traj.shape[1]))
    for i in range(traj.shape[1]):
        ax.plot(traj[:, i, 0], traj[:, i, 1],
                '-', color=colors[i], alpha=0.35)
        # 起点
        ax.plot(traj[0, i, 0], traj[0, i, 1], 'o',
                color=colors[i], label=f'D{i+1} 起点')
        # 终点
        ax.plot(traj[-1, i, 0], traj[-1, i, 1], 's',
                color=colors[i], ms=8)
        # 目标点
        ax.plot(targets[i, 0], targets[i, 1], '*',
                color=colors[i], ms=12)
    # 危险区域
    for z in zones:
        ax.add_patch(plt.Circle(z, 1.5, color='red',
                                alpha=0.15))
    ax.plot(ball[0], ball[1], 'ro', ms=10,
            label='球位置')
    ax.set_xlim(-1, COURT_W + 1)
    ax.set_ylim(-1, COURT_H + 1)
    ax.set_aspect('equal')
    ax.set_title(f"轮转换位轨迹 (默契度 = {score['综合默契度']})")
    ax.legend(fontsize=8, loc='upper right')
    plt.tight_layout()
    plt.savefig("rotation_defense.png", dpi=120)
    plt.show()

输出示例

========================================
防守轮转换位默契度报告
========================================
及时性    : 0.775
覆盖性    : 1.0
交接平滑   : 0.962
同步性    : 0.412
综合默契度 : 0.804

图:rotation_defense.png 展示 5 名防守者的移动轨迹、目标补位点、危险区域覆盖情况。


指标说明与可扩展方向

四个维度对应真实比赛语义

指标 篮球含义 提升方法
及时性 补位快不快 脚程、预判、沟通提前量
覆盖性 危险区有没有人 站位原则、协防意识
交接平滑 换防撞不撞车/漏不漏人 换防口令、身体朝向
同步性 全队是否一起动 训练默契、轮转纪律

可继续升级的方向

  1. 真实数据接入:用 sportpy / nba_api 拉取球员追踪数据(SportVU / Hawk-Eye 提供 25fps 坐标)。
  2. 图神经网络:把每帧防守者当作图的节点,用 GNN 学习"默契"隐式表征。
  3. 强化学习:让 5 个 agent 学习最优轮转策略,用上面的 synergy 当 reward。
  4. 对手建模:加入进攻方移动,评估动态协同而非静态到位。
  5. 时间对齐:使用 DTW(动态时间规整)比较不同回合的轮转节奏。

核心思路总结

默契度 = 多人 × 时序 × 空间协作的一致性度量

用 Python 落地时拆成 4 个可计算子分数,加权即可,这套框架不仅适用于篮球,也能迁移到足球协防、排球拦网、无人机编队等场景。

需要我把它改成真实 NBA 追踪数据版强化学习训练版吗?

抱歉,评论功能暂时关闭!