【问题标题】:Algorithm for recursive function for permutations with replacement in pythonpython中置换置换的递归函数算法
【发布时间】:2014-02-09 06:40:03
【问题描述】:

因此,使用 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循环。所以如果有人能告诉我如何做到这一点,那也很好,谢谢。

【问题讨论】:

    标签: python algorithm recursion permutation


    【解决方案1】:

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

    我想出了以下几点:

    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$ 
    

    【讨论】:

    • 如果您将k==0 更改为返回[[]],则不需要k==1 的特殊情况。
    • 谢谢!!!实际上,我多年来一直在考虑如何摆脱这种特殊情况:)它一直摆在我面前。但是,有趣的是,发现它需要考虑整个事情是如何以不同的方式工作的……我坚持认为这一切的基础是在 k=1 处生成 n 个 vales!不错!
    【解决方案2】:

    如果您想推出自己的解决方案,我想这无济于事,但使用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)
    

    【讨论】:

    • 如果您阅读了我的帖子的第一行,您会发现我最初是使用 itertools 完成的,另一方面,谢谢您承认我的存在,我很孤独 =(.
    • @pajamas 好吧,是的,我阅读了您帖子的第一行,但是看到您实际上并没有向我们展示您的 itertools 实现,我无法知道您是否知道itertools.product.
    • @seshin 你说得对,我可能也应该把那个实现放在那里。
    猜你喜欢
    • 2013-11-25
    • 1970-01-01
    • 2016-06-05
    • 2019-08-28
    • 2011-02-17
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多