2014-10-02 40 views
1

是否有一个生成函数f(i,j,n)在确定性的恒定时间和空间中返回第j个置换的第i个元素(0 < = i < n) 0 < = j < n!)前n个整数?如果是这样,它是如何工作的?如果没有,我可以看到一个disproof?线性时间常数空间置换发生器

这个问题是与此相关的一个:Create a random permutation of 1..N in constant space 然而,在这种情况下,我们希望能够产生排列,这取决于我们的选择j的,不只是一个特定的或任意一个。

它也与此相关:Random access random permutations (事实上,这可能就是这个问题的作者所希望拥有的东西,尽管我不能确定这个问题没有更具体和更具约束性。无论如何,我对并行化并不感兴趣。)

如果可能的话,那么我也想知道如果我们可以消除参数j(因为它的长度是O(n))并且只是产生一个置换无需先将其命名即可随意选择。

如果是不可能的,那么我不知道是否有可能概率(但仍然在确定性线性时间和恒定的空间)产生一个统一选择置换。例如,一种产生均匀选择的序列的方法,该序列恰好也是时间> 1%的置换。

我问这个问题,因为所有的我所知道的方法生成置换或者需要存储的值的范围被明确置换,或者至少存储所有这些迄今已产生的数字。

+0

https://en.wikipedia.org/wiki/Factorial_number_system – phs 2014-10-03 08:16:24

+1

@phs我意识到factoriadics,并已考虑涉及他们的解决方案,但我无法弄清楚如何使用它们作为反演向量来构造一个特定置换而不存储所述排列的所有部分在堆栈上已经产生的,并且这里的目标是能够在置换找到一个元件/无/在置换其它元素 – quintopia 2014-10-03 15:37:00

回答

2

前段时间我为this problem做了类似的事情。

对您的问题稍作修改后,它会直接生成第j个排列,然后选择其第i个元素。

#!/usr/bin/env python3 

from math import factorial 

def getJthPermutation(initList, j): 
    j -= 1 

    result = "" 
    fac = factorial(len(initList) - 1) 
    for div in range(len(initList) - 1, 0, -1): 
     k = j // fac 
     result += initList[k] 
     del initList[k] 

     j %= fac 

     fac //= div 
    result += initList[0] 

    return result 


def fct(i, j, n): 
    list = [str(k) for k in range(n+1)] 

    permutation = getNPermutation(list[:], j) 

    return permutation[i] 


if __name__ == "__main__": 
    print(fct(3,1000000,9)) 
    print(fct(3,1,9)) 
    print(fct(1,factorial(9), 9)) 

(if you don't have python installed)

意愿仍取决于n,但不能在i也不j复杂性(如果我没有记错的话)。

+2

看起来体面的知道任何(或多个),但会为O(n^2),因为计算单因子为O(n),和你做这一个O内部(n)的循环。您可以通过循环之前计算阶乘只有一次,并且将'在每个循环周期结束时通过'div' fac'解决这个问题。 – 2014-10-02 08:21:18

+1

你是完全正确的,我会更新我的答案! – ZomZom 2014-10-02 12:13:47

+1

更大的问题是明确计算n!需要O(n * lg(n))空间来存储结果。我正在寻找一个恒定的空间解决方案。 – quintopia 2014-10-03 05:02:50