python中替换排列的递归函数算法

时间:2014-01-20 07:13:59

标签: python algorithm recursion permutation

因此,使用itertools模块,我能够编写一个非常灵活的代码来生成替换的所有排列,但我想要做的是使用递归的东西。

以下是我提出的建议:

def permutations_with_replacement(n,k,permutations):
    m = 0
    if k < 1:
        return permutations

    for i in range(27):                    
        permutations[i].append(m % n)
        if (i % n**(k-1)) == n**(k-1) - 1:
            m = m + 1

    return permutations_with_replacement(n,k-1,permutations)


n = 3
k = 3
permutations = [[] for i in range(n**k)]
print permutations_with_replacement(n,k,permutations)

基本上它排列每个排列的第一层(条目),然后在每次后续迭代时,它会更快更快地运行0 ... n-1以获得所有组合。我输入一个n = k = 3的例子,因为我必须初始化排列列表并在函数内部初始化它会导致在递归时搞砸了。我也把27放在范围而不是n ^ k,因为n ^ k在递归时也会被搞砸。怎么能干净利落地工作呢?

我真正想做的是做一个递归,它基本上取代了使用替换生成所有排列的嵌套for循环方法,我的理解是递归解决了嵌套for循环方法需要知道深度的问题嵌套的for循环先验。所以,如果有人能告诉我如何这样做,那也会很棒,谢谢。

2 个答案:

答案 0 :(得分:2)

我认为你的方法存在的问题是你没有在心理上提交递归。警告标志必须在开始之前创建整个大小的数组,并发现你需要知道整个事物在常规递归例程体内有多大。

我想到了以下几点:

1)对于k = 1和任何n,p_w_r的答案是什么?我在纸上试验了n = 2

2)鉴于我认为这是1的答案,我如何为k = 2开始做出答案    从k = 1的输出。

在我意识到k = 1的答案必须是单个元素列表本身的列表(当然,当你看到它时很明显)之前,我不得不在概念上陷入困境。从那里,我可以看到我需要“将这个列表”粘贴到k + 1案例中的每个元素上。

       def permutations_with_replacement(k,n):
         # special case (not part of recursion)
         if k == 0:
            return []

         if k == 1
            return [[i] for i in range(n)]
         else:
            # Make the list by sticking the k-1 permutations onto each number 
            # we can select here at level k    
            result = []
            # Only call the k-1 case once, though we need it's output n times.
            k_take_one_permutations = permutations_with_replacement(k-1,n)  

            for i in range(n):
                for permutation in k_take_one_permutations:
                    result.append([i]+permutation)   
            return result

         print permutations_with_replacement(3,2)



momerath:~ mgregory$ python foo.py
[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
momerath:~ mgregory$ 

答案 1 :(得分:1)

我想如果您想推出自己的解决方案,这无济于事,但使用itertools.product有一种非常简洁的方法,基本上相当于笛卡尔积。

import itertools

def permutations_with_replacement(n, k):
    # if you're on Python 2.x, use xrange(n) instead of range(n)
    return itertools.product(range(n), repeat=k)

n, k = 3, 3
for permutation in permutations_with_replacement(n, k):
    print(permutation)

输出:

(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
# some omitted
(2, 1, 1)
(2, 1, 2)
(2, 2, 0)
(2, 2, 1)
(2, 2, 2)