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

如何通过JGraphT的KuhnMunkres算法获取按成本排序的多个匹配方案?

获取按成本排序的多组二分图完美匹配方案

针对你用KuhnMunkresMinimalWeightBipartitePerfectMatching类找到最优匹配后,想要获取多个按成本排序的匹配方案的需求,我给你几个实用的思路,适配不同的场景:

1. 基于Kuhn-Munkres算法的迭代修改法

Kuhn-Munkres本身只返回最优解,但我们可以通过“排除已找到的最优匹配”的方式,迭代找出次优、次次优等解:

  • 每次找到当前最小权匹配后,把这个匹配里的所有边的权值设置为一个极大值(比如远大于图中所有边的权值之和),这样下一次运行算法时,就不会再选择这些边的组合。
  • 重复这个过程,直到收集到你需要的匹配数量,或者算法返回不存在完美匹配为止。
  • 注意:如果存在多个成本相同的最优匹配,你需要额外处理——比如只排除当前这一组匹配的边,而不是所有同成本的匹配边,否则会漏掉其他同最优成本的方案。

2. 分支定界法(适合中等规模图)

如果你的图以后可能扩大,分支定界法是更系统的方案:

  • 它会从第一个顶点开始,逐个尝试所有可能的匹配边,计算当前路径的累计成本,同时维护一个“当前已找到的匹配成本列表”。
  • 对于每个分支,如果当前累计成本加上剩余顶点的最小可能权值之和,已经大于列表中最大的成本(当列表已经收集到足够数量时),就直接剪掉这个分支,避免无效计算。
  • 遍历完所有可行分支后,把收集到的匹配按成本排序即可。这种方法比暴力枚举高效得多,尤其是当图的规模超过5x5之后。

3. 暴力枚举+排序(适合你当前的3x3小图)

因为你的二分图是3个顶点对3个顶点,所有可能的完美匹配其实就是Z分区顶点的全排列(总共6种),完全可以直接生成所有可能的匹配,计算成本后排序:

# 示例伪代码,假设你有权值矩阵weight,weight[i][j]代表T_i到Z_j的边权
import itertools

# 替换成你的实际权值
weight = [
    [10, 20, 15],
    [5, 12, 8],
    [7, 18, 11]
]

# 生成Z分区的所有排列,每个排列对应一种完美匹配
all_matches = list(itertools.permutations([0, 1, 2]))
match_with_cost = []

for match in all_matches:
    total_cost = sum(weight[t_idx][z_idx] for t_idx, z_idx in enumerate(match))
    # 把匹配关系和成本存起来,比如match[0]是T0对应的Z顶点索引
    match_with_cost.append( (total_cost, match) )

# 按成本从小到大排序
match_with_cost.sort(key=lambda x: x[0])

# 输出结果
for cost, match in match_with_cost:
    print(f"成本 {cost}: T0→Z{match[0]}, T1→Z{match[1]}, T2→Z{match[2]}")

这种方法最简单直接,完全适配你当前的场景,不需要修改现有的Kuhn-Munkres类代码。

额外提示

  • 如果存在多个成本相同的匹配,上述方法都会把它们放在排序后的同一位置,不会遗漏。
  • 当图的规模超过10x10时,优先考虑分支定界或者优化后的Kuhn-Munkres迭代法,暴力枚举的时间复杂度会指数级上升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:31:05