Algorithm Levenstein与特定数组的距离

Algorithm Levenstein与特定数组的距离,algorithm,Algorithm,我的输入是三个数字-一个数字s,一个范围的开始b和结束e,这是加速计算的第一个想法(如果|e-b |不太大,则有效): 问题:当我们将s与n进行比较,然后与n+1进行比较时,水平距离会发生多大变化 回答:不要太多 让我们看一下s=12007和两个连续n n = 12296 0 1 2 3 4 5 1 0 1 2 3 4 2 1 0 1 2 3 3 2 1 1 2 3 4 3 2 2 2 3 5 4 3 3 3 3 及 如您所见,只有最后一列更改,因为除了最后一列之外,n和n+

我的输入是三个数字-一个数字
s
,一个范围的开始
b
和结束
e
,这是加速计算的第一个想法(如果
|e-b |
不太大,则有效):

  • 问题:当我们将
    s
    n
    进行比较,然后与
    n+1
    进行比较时,水平距离会发生多大变化

  • 回答:不要太多

让我们看一下
s=12007
和两个连续
n

n = 12296

0 1 2 3 4 5 
1 0 1 2 3 4 
2 1 0 1 2 3 
3 2 1 1 2 3 
4 3 2 2 2 3 
5 4 3 3 3 3 

如您所见,只有最后一列更改,因为除了最后一列之外,
n
n+1
具有相同的数字

如果您有编辑距离为
s=12001
n=12296
的动态规划表,您已经有了
n=12297
的表,您只需要更新最后一列

显然,如果
n=12299
,则
n+1=12300
需要更新上一个表的最后3列。。但这种情况每100次迭代只发生一次

一般来说,你必须

  • 在每次迭代中更新最后一列(因此,单元格的长度)
  • 每10次迭代更新一次第二次到最后一次
  • 每100次迭代更新一次第三个到最后一个
因此,让
L=length(s)
D=e-b
。首先计算
s
b
之间的编辑距离。然后您可以找到间隔中每个整数上循环的
[b,e]
上的最小Levenstein距离。其中有
D
,因此执行时间约为:

从现在起

我们有一个算法


[2013年8月10日编辑:DP算法中考虑的某些情况实际上不需要考虑,尽管考虑它们不会导致不正确:)]

在下文中,我描述了一个需要O(N^2)时间的算法,其中N是b、e或s中的最大位数。由于所有这些数字都限制在1000位以内,这意味着在任何现代CPU上最多只能执行几百万次基本操作,这将需要毫秒

假设s有n个数字。在下文中,“中间”表示“包含”;如果我的意思是“排除其端点”,我会说“严格介于两者之间”。指数以1为基础。x[i]表示x的第i位,例如x[1]是其第一位

分解问题 首先要做的是将问题分解为一系列子问题,其中每个b和e具有相同的位数。假设e比s多k>=0位:将问题分解为k+1个子问题。例如,如果b=5和E=14032,则创建以下子问题:

  • b=5,e=9
  • b=10,e=99
  • b=100,e=999
  • b=1000,e=9999
  • b=10000,e=14032
我们可以解决这些子问题中的每一个,并采取最小的解决方案

最简单的例子:中间 简单的例子是中间的例子。当e的位数比b多k>=1时,就会出现k-1子问题(如上面的3),其中b是10的幂,e是10的下一次幂,减去1。假设b是10^m。请注意,选择1到9之间的任意数字,然后选择0到9之间的任意m个数字,将生成一个范围为bu的数字x,否则为0

困难案例:结束 困难的情况是当b和e不限于分别具有形式b=10^m和e=10^(m+1)-1时。任何主问题最多可以生成两个子问题:要么是两个“端点”(由b和e具有不同位数的主问题产生,如顶部的示例)要么是一个子问题(即主问题本身,根本不需要细分,因为b和e已经有相同的位数)。请注意,由于前面对问题的拆分,我们可以假设子问题的b和e有相同的位数,我们称之为m

超级列文斯坦!
我们将要做的是设计一个Levenshtein DP矩阵的变体,该矩阵计算给定数字字符串与范围b中任何数字x之间的最小Levenshtein距离。重写:您正在查找与指定整数范围内的指定值
s
最近的数字的距离
[b,E]
,距离是10进制中的列文斯坦距离(编辑距离)?这不容易。你可能会得到更多答案,是的,这就是我的意思,只是我的英语不太好-被动知识:)你想要最接近的元素,还是它与
s
的距离?@JanDvorak和其他人:这不是NP难的,请看我的算法:)对不起,我差点忘了我问过这个问题。我使用您的提示,它通过了所有测试用例。
n = 12297

0 1 2 3 4 5 
1 0 1 2 3 4 
2 1 0 1 2 3 
3 2 1 1 2 3 
4 3 2 2 2 3 
5 4 3 3 3 2 
# The best Lev distance overall between s[1..i] and x[1..j]
v(i, j) = min(hb(i, j), he(i, j))

# The best Lev distance between s[1..i] and x[1..j] obtainable by
# continuing to hug the lower bound
hb(i, j) = min(hb(i-1, j)+1, hb(i, j-1)+1, hb(i-1, j-1)+diff(s[i], b[j]))

# The best Lev distance between s[1..i] and x[1..j] obtainable by
# continuing to hug the upper bound
he(i, j) = min(he(i-1, j)+1, he(i, j-1)+1, he(i-1, j-1)+diff(s[i], e[j]))
# The best Lev distance possible between the ENTIRE STRINGS s and x, given that
# we choose to stop hugging at the jth digit of x, and have optimally aligned
# the first i digits of s to these j digits
sh(i, j) = if j >= q then shc(i, j)+abs(n-i-m+j)
           else infinity

shc(i, j) = if j == q then
              min(hb(i, j-1)+1, hb(i-1, j-1)+inrange(s[i], (b[j]+1)..(e[j]-1)))
            else
              min(hb(i, j-1)+1, hb(i-1, j-1)+inrange(s[i], (b[j]+1)..9),
                  he(i, j-1)+1, he(i-1, j-1)+inrange(s[i], (0..(e[j]-1)))