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

笛卡尔坐标系下玩家与旗帜最优分配的Python实现方案咨询

问题解决:玩家-旗帜最小总距离分配方案

一、优化后的距离数据存储方式

原数据格式用嵌套列表存单个键值对,遍历和取值效率低,推荐直接用双层字典存储,结构更清晰,操作更便捷:

dist_dict_optimized = {
    "A": {"x": 12, "y": 10, "z": 20},
    "B": {"x": 14, "y": 18, "z": 25},
    "C": {"x": 8, "y": 15, "z": 16},
}

这种格式可以直接通过dist_dict_optimized["A"]["y"]快速获取玩家y到旗帜A的距离,后续计算时无需额外解析列表。

二、Python实现方案

该问题属于典型的指派问题,核心是在一对一约束下找到总距离最小的分配组合,以下提供两种可行方案:

方法1:暴力枚举法(适合小规模场景)

由于玩家和旗帜数量仅为3,所有可能的分配组合共3! = 6种,直接遍历所有排列计算总距离即可:

import itertools

# 使用优化后的距离字典
dist_dict = {
    "A": {"x": 12, "y": 10, "z": 20},
    "B": {"x": 14, "y": 18, "z": 25},
    "C": {"x": 8, "y": 15, "z": 16},
}

flags = list(dist_dict.keys())
players = list(dist_dict["A"].keys())

min_total = float('inf')
best_assignment = []

# 遍历玩家的所有排列,每个排列对应一种旗帜-玩家分配方式
for perm in itertools.permutations(players):
    total_dist = 0
    current_assignment = []
    for flag, player in zip(flags, perm):
        total_dist += dist_dict[flag][player]
        current_assignment.append({flag: player})
    # 更新最小总距离和最优分配
    if total_dist < min_total:
        min_total = total_dist
        best_assignment = current_assignment

print("最优分配方案:", best_assignment)
print("最小总移动距离:", min_total)

输出结果:

最优分配方案: [{'A': 'y'}, {'B': 'x'}, {'C': 'z'}]
最小总移动距离: 40

方法2:匈牙利算法(适合大规模场景)

如果玩家和旗帜数量较多,暴力枚举效率会急剧下降,此时可以用匈牙利算法求解,借助scipy库的linear_sum_assignment函数实现:

  1. 先安装依赖:pip install scipy
  2. 代码实现:
import numpy as np
from scipy.optimize import linear_sum_assignment

dist_dict = {
    "A": {"x": 12, "y": 10, "z": 20},
    "B": {"x": 14, "y": 18, "z": 25},
    "C": {"x": 8, "y": 15, "z": 16},
}

flags = list(dist_dict.keys())
players = list(dist_dict["A"].keys())

# 构建距离矩阵:行对应旗帜,列对应玩家
dist_matrix = np.array([
    [dist_dict[flag][player] for player in players]
    for flag in flags
])

# 匈牙利算法求解最优指派
row_indices, col_indices = linear_sum_assignment(dist_matrix)

# 转换为要求的输出格式
best_assignment = [
    {flags[row]: players[col]}
    for row, col in zip(row_indices, col_indices)
]
min_total = dist_matrix[row_indices, col_indices].sum()

print("最优分配方案:", best_assignment)
print("最小总移动距离:", min_total)

输出结果与暴力法完全一致。

三、方案选择建议

  • 暴力枚举法:实现简单,无需额外依赖,适合玩家/旗帜数量≤10的小规模场景。
  • 匈牙利算法:时间复杂度为O(n³),效率更高,适合大规模指派问题,但需要依赖第三方库。

内容的提问来源于stack exchange,提问作者akkig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:15:10