我正在阅读本文(第3页和第8页):http://acl.ldc.upenn.edu/P/P05/P05-1077.pdf,它定义了一个排列函数,用于生成签名的排列。签名是一串像“1001”
的位它定义了排列函数如下:
然而,当我应用它时,它不起作用。假设我有字符串“1001”,其索引为{0,1,2,3}。目的是使指数置换为例如{2,3,0,1}。设p = 7,a = 1,b = 2.现在我需要对索引进行置换:
pi(0)=(0 + 2)mod 7 = 2
pi(1)=(1 + 2)mod 7 = 3
pi(2)=(2 + 2)mod 7 = 4 <&lt;&lt;&lt;&lt;&lt;&lt;这里问题开始,因为它生成一个超出索引空间的错误值
p(pi)=(&lt;&lt;&lt;同样在这里所以我最终得到的新索引为{2,3,4,5},这是无效的,因为我首先没有4和5作为索引。
我的解决方案有什么问题?我做错了吗?
我在stackoverflow上看到了生成字符串所有排列的帖子。但我想使用特定的排列函数生成一个排列。因为我想在多个字符串上使用相同的排列函数。然后我希望能够使用不同的参数创建另一个排列函数,并在同一组字符串/签名上应用新的排列函数。
编辑: 我发现python中的这段代码应用了同样的想法,但不幸的是我之前从未使用过python,所以我希望如果有人能看到不同的东西:
class Permutation(object):
def __init__(self, maximumValue):
if not isPrime(maximumValue): raise Exception('Maximum value should be prime')
self.p, self.a, self.b = maximumValue, random.choice(range(maximumValue)[3::2]), random.choice(range(maximumValue))
def applyFunction(self, x): return (self.a*x+self.b)%self.p
def __eq__(self, other): return self.a==other.a and self.b==other.b and self.p==other.p
def __str__(self): return 'p: %s, a: %s, b: %s'%(self.p, self.a, self.b)
代码来自:https://github.com/kykamath/streaming_lsh/blob/master/streaming_lsh/classes.py
答案 0 :(得分:1)
你需要的是一个字符串的随机排列。而不是使用论文中指定的那个,你可以使用Knuth shuffle。随机排列背后的想法是获得一个应该是概率1 / n!。这就对了。您可以使用任何满足此标准的算法。 http://en.wikipedia.org/wiki/Random_permutation
好的,你的代码正在生成0到P范围内的索引。但你的源数组的长度是&lt; P.因此,它会导致出界。解决此问题的一种方法是使用预先确定的填充字符填充源数组以使长度为P.并在结果排列中删除所有填充字符并缩小。始终确保,P&gt; =源字符串的长度。
答案 1 :(得分:1)
给定的函数本质上是一个随机数生成器http://en.wikipedia.org/wiki/Linear_congruential_generator。要获得置换索引,您需要按数组大小修改结果。因此,对于1001
,您可以使用pi(x) % 4
。
编辑:
考虑到这一点,这个功能不太可能是一对一的,因为你最终会得到像0 mod 4 = 4 mod 4
但0 mod 7 != 4 mod 7
这样的东西。
为了生成范围内的元素,您必须重复应用该函数,直到获得范围内的数字。因此,如果您pi(0) = 6
尝试pi(6)
,而pi(6) = 5
尝试pi(5)
。
在您发布的代码中,作者似乎总是使用素数数组进行排列,因此他没有这个问题。