2 回答
TA贡献1864条经验 获得超2个赞
我将遵循您的要求,并提供一种非编程方法,但仅是我认为的逻辑(半数学)方法。
算法步骤:
让我们将阈值定义为
T
用无关值填充较小的列表(例如无) - 只是为了确保尺寸一致
通过取一个列表中每个元素与另一个列表中元素的绝对值来创建相似度矩阵,我们将矩阵定义为 S。
澄清:S[i,j]指的是列表A中的第i个元素与列表B中的第j个元素之间的差异
创建二进制矩阵 B,其中满足阈值 Critirea 的每个元素为 1,否则为 0 (MATLAB-> B=S<L)
例如:
0 0 0 B = 0 1 1 1 0 0
假设 X 维度代表列表 A,Y 维度代表列表 B,则:
B[2] === A[2] B[2] === A[3] B[3] === A[1] (=== means that two elements satisfy the criteria of similarity)
现在 - 问题变得更加数学化,为了找到最佳匹配,您可以使用以下建议之一:
蛮力(我认为不太优雅的方法):
选择为 1 的元素(在未标记的行和列中)
将他的整个列和行标记为已标记
继续选择另外1个,直到没有合法位置为止,求和为
score
对所有选项迭代执行此操作并选择最高的选项
score
更优雅的方法:
迭代所有列的排列(对于 B 矩阵)
如果 Trace 或对角线等于 len(A) 则完成(找到所有元素的匹配)
选择具有最高 TRACE(或相反对角线)的排列 最坏情况下的排列数量当然是 N!(其中N是B的维度)
正如文档所述 - 该算法试图找到所有可能的矩阵排列的最小跟踪 - 因此只需将其-B
作为参数即可。
总体示例(最后一步采用更优雅的方法):
A = [1,5,7]
B = [6,6,2]
T = 2
S =
5 5 1
1 1 3
1 1 5
B =
0 0 1
1 1 0
1 1 0
permutations of columns:
1-
0 0 1
1 1 0
1 1 0
Trace = 1
other-diagonal = 3
Done -- > no need for more permutations because len(other-diagonal) == 3
A[1] =1 === B[3] =2
A[2] =5 === B[2] =6
A[3] =7 === B[1] =6
请随意询问,或提供您可能有的任何见解
TA贡献1827条经验 获得超7个赞
我刚刚发现 scipy python 包中“匈牙利算法”(赋值问题)有很好的实现:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linear_sum_assignment.html
示例(对于expected, detected,metric请参阅问题的示例代码):
from scipy.optimize import linear_sum_assignment
...
def match_events(expected, detected, metric, tolerance=5):
# some arbitrary large value used to prevent impossible matches
dont_match = 1000 * tolerance
def modified_metric(e, d):
dt = metric(e, d)
return dt if dt <= tolerance else dont_match
cost_matrix = [
[
modified_metric(exp, det)
for det in detected
]
for exp in expected
]
row_idx, col_idx = linear_sum_assignment(cost_matrix)
for e_idx, d_idx in zip(row_idx, col_idx):
dt = cost_matrix[e_idx][d_idx]
if dt <= time_tolerance:
yield (expected[e_idx], detected[d_idx], dt)
它不是很优雅,因为我必须以某种方式将匹配限制为tolerance,但匈牙利算法仅适用于所有可能组合的矩阵,因此我使用dont_matchvalue 来标记这些情况。
添加回答
举报