目标跟踪中的匈牙利算法

  • 从数学角度来看,线性分配问题(也称为匈牙利算法或指派问题)是一个经典的优化问题,其目的是在两个集合之间找到最佳匹配,使得总成本最小。我们可以将其形式化为一个二分图的最小权匹配问题。

数学背景

假设我们有两个集合 ( A ) 和 ( B ),其中 ( A ) 有 ( m ) 个元素,( B ) 有 ( n ) 个元素。我们有一个 ( m \times n ) 的成本矩阵 ( C ),其中 ( C[i, j] ) 表示将 ( A ) 中的第 ( i ) 个元素分配给 ( B ) 中的第 ( j ) 个元素的成本。

目标是找到一个匹配 ( M ⊆ A × B ) (M \subseteq A \times B ) (MA×B),使得总成本

∑ ( i , j ) ∈ M C [ i , j ] \sum_{(i, j) \in M} C[i, j] (i,j)MC[i,j]

最小,并且每个元素最多匹配一次。

算法解释

1. 空成本矩阵的处理

如果成本矩阵为空(即没有元素),则直接返回空匹配和未匹配的索引。

if cost_matrix.size == 0:
    return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1]))
2. 使用 LAPJV 算法

如果选择使用 LAPJV 算法(来自 lap 库),则执行以下步骤:

_, x, y = lap.lapjv(cost_matrix, extend_cost=True, cost_limit=thresh)
  • lap.lapjv 函数返回三个数组:
    • 第一个数组(未使用)是总成本。
    • x 数组表示每个 ( A ) 中元素的匹配结果,如果未匹配则为 -1。
    • y 数组表示每个 ( B ) 中元素的匹配结果,如果未匹配则为 -1。
matches = [[ix, mx] for ix, mx in enumerate(x) if mx >= 0]
unmatched_a = np.where(x < 0)[0]
unmatched_b = np.where(y < 0)[0]
  • matches 是一个列表,包含所有有效的匹配对。
  • unmatched_aunmatched_b 分别是未匹配的 ( A ) 和 ( B ) 中的索引。
3. 使用 SciPy 的线性和分配算法

如果选择使用 SciPy 的 linear_sum_assignment 算法,则执行以下步骤:

x, y = scipy.optimize.linear_sum_assignment(cost_matrix)
  • scipy.optimize.linear_sum_assignment 返回两个数组:
    • x 表示 ( A ) 中元素的匹配索引。
    • y 表示 ( B ) 中元素的匹配索引。
matches = np.asarray([[x[i], y[i]] for i in range(len(x)) if cost_matrix[x[i], y[i]] <= thresh])
  • 这行代码筛选出所有匹配成本不超过阈值的匹配对。
if len(matches) == 0:
    unmatched_a = list(np.arange(cost_matrix.shape[0]))
    unmatched_b = list(np.arange(cost_matrix.shape[1]))
else:
    unmatched_a = list(set(np.arange(cost_matrix.shape[0])) - set(matches[:, 0]))
    unmatched_b = list(set(np.arange(cost_matrix.shape[1])) - 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值