如果我有一些我不想超过的距离。示例= 2。 知道最小允许距离后,我是否可以在完全完成之前打破算法?
也许有类似的算法可以完成。
我有必要减少工作时间。
答案 0 :(得分:4)
是的,你可以,它确实降低了复杂性。
要注意的主要事情是levenstein_distance(a,b) >= |len(a) - len(b)|
即距离不能小于弦长的差异。至少你需要添加字符以使它们具有相同的长度。
了解这一点,您可以忽略|i-j| > max_distance
中原始矩阵中的所有单元格。所以你可以从
for (i in 0 -> len(a))
for (j in 0 -> len(b))
到
for (i in 0-> len(a))
for (j in max(0,i-max_distance) -> min(len(b), i+max_distance))
如果您更容易保留原始矩阵,但您也可以通过使用矩阵(len(a),2 * max_distance)并调整索引来节省空间。
一旦你在最后一行花费了每一笔费用> max_distance你可以停止算法。
这会给你O(N*max_distance)
复杂性。由于你的max_distance为2,因此复杂性几乎是线性的。你也可以在开始时保释|len(a)-len(b)| > max_distance
。
答案 1 :(得分:1)
如果你进行自上而下的动态编程/递归+ memoization,你可以将当前大小作为额外参数传递,如果超过2,则提前返回。但我认为这将是低效的,因为你将重新访问状态。
如果你做自下而上的dp,你将逐行填充(你只需要保留最后一行和当前行)。如果最后一行只有大于2的条目,则可以提前终止。
根据我的评论修改您的源代码:
for (var i = 1; i <= source1Length; i++)
{
for (var j = 1; j <= source2Length; j++)
{
var cost = (source2[j - 1] == source1[i - 1]) ? 0 : 1;
matrix[i, j] = Math.Min(
Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1),
matrix[i - 1, j - 1] + cost);
}
// modify here:
// check here if matrix[i,...] is completely > 2, if yes, break
}