繁体   English   中英

python中置换置换的递归函数算法

[英]Algorithm for recursive function for permutations with replacement in python

因此,使用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用作示例,因为我必须初始化置换列表,并在函数内部对其进行初始化,导致递归操作变得混乱。 我还为该范围而不是n ^ k输入了27,因为n ^ k在递归时也会被搞砸。 如何使它干净地工作?

我真正想做的是做一个递归,该递归基本上用替换替换了产生所有排列的嵌套for循环方法,我的理解是,递归解决了嵌套for循环方法需要知道嵌套深度的问题。 -循环先验。 因此,如果有人可以向我展示如何使用该方法,那也很好,谢谢。

我认为您的方法的问题在于您在精神上没有致力于递归。 警告标志必须在开始之前创建整个大小的数组,并发现您需要知道整个事情在例程递归例程的主体中有多大。

我想到了以下几点:

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

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

在意识到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$ 

我想这对您想推出自己的解决方案没有帮助,但是有一种非常干净的方法可以使用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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM