Heap's Algorithm - Python 中用于生成排列的非递归方法

Posted

技术标签:

【中文标题】Heap\'s Algorithm - Python 中用于生成排列的非递归方法【英文标题】:Heap's Algorithm - Non Recursive Method in Python to generate permutationsHeap's Algorithm - Python 中用于生成排列的非递归方法 【发布时间】:2020-11-18 13:02:20 【问题描述】:

我是编程新手。我正在研究堆算法,特别是非递归方法。互联网上没有太多关于算法如何工作的解释。我从Bernardo Sulzbach 找到了这篇作品,但他没有解释他的算法是如何工作的。几天以来我一直坚持下去,尝试了一切都无法弄清楚。我在每行之后添加了 cmets 以使自己理解 - 这里发生了什么?但我仍然无法让它工作。难道我做错了什么?请帮忙。

# Heap's Algorithm (Non Recursive)

# function to swap values in python
def swap(elements, i, j):
    elements[i], elements[j] = elements[j], elements[i]

# function to generate permutation
def generate_permutations(elements, n): 
    # Passing two parameters of elements and n to function "generate_permutations".
    c = [0] * n 
    # c is a new list and its value set to an array literal with value 0, n times.
    # Example - [a] * 3 ==> ['a', 'a', 'a', 'a']
    yield elements 
    # "yield" statement is used to define generators, while "return" statement causes a function to exit.
    # "yield" replacing the return of a function to provide a result to its caller without destroying
    # local variables. Unlike a function, where on each call it starts with new sets of variables, a generator
    # will resume the execution where it left off.
    i = 0
    # i is a new variable and its value is set to 0. It can also be used to count the number of loop runs.
    while i < n:
    # while loop ==> while i is less than n, do following:
        if c[i] < i:
        # if statement ==> while i is less than n and if any element from 'c' list is less than i, 
        # then do following:
            if i % 2 == 0:
            # if statement ==> while i is less than n, and if any element in 'c' list is less than i, and
            # i is an even number, then do following:
                swap(elements, 0, i)
                # calling swap function and passing following arguments: elements, '0' and 'i'
            else:
            # else, if all three conditions above are not true then do following:
                swap(elements, c[i], i)
                # calling swap funtions and passing following arguments: elements, an item from 'c' list and 'i'
            yield elements
            # ??? yield elements
            c[i] += 1
            # after that, increment c[i] by 1.
            i = 0
            # set the value of i to 0
        else:
            # else, if c[i] < i is not true the do the following.
            c[i] = 0
            # set the value of c[i] to 0
            i += 1
            # and increment i by 1

def permutations(elements):
    return generate_permutations(elements, len(elements))

# Driver Code
# c = ?
# n = ?
# i = ?
print(permutations(['abc']))

【问题讨论】:

欢迎来到 Stack Overflow。不要忘记接受(勾选答案旁边的复选标记)并可能在回答您的问题时对其进行投票,这样您的问题就不会在搜索中显示为未回答。 目前您正在要求这里有人解释您找到的完整算法 - 这可能仍然过于宽泛。如果您可以将问题集中在Heap algorithm 的迭代实现的某个特定部分,那么这将是一个更好的问题。例如,如果您的问题是您不了解在此实现中如何使用 c 数组,那么这将是一个更具体的问题。 此外,有时它还可以通过在纸上手动“执行”实现/算法来帮助增加理解;) @IvoMori 非常感谢您的友好反馈。我是 Stack Overflow 和编程的新手。下次我会尽量让我的问题具体而简短。 【参考方案1】:

只是清理你的代码(太多 cmets):

# Heap's Algorithm (Non Recursive)
# https://en.wikipedia.org/wiki/Heap%27s_algorithm

def swap(seq, i, j):
  seq[i], seq[j] = seq[j], seq[i]

def generate_permutations(seq, seqLen, resLen): 
  c = [0] * seqLen
  yield seq[:resLen]
  
  i = 0
  while i < seqLen:
    if c[i] < i:
      if i % 2 == 0:
        swap(seq, 0, i)
      else:
        swap(seq, c[i], i)
      yield seq[:resLen]
      c[i] += 1
      i = 0
    else:
      c[i] = 0
      i += 1

def permutations(seq, resLen=None):
  if not resLen: resLen = len(seq)
  return generate_permutations(seq, len(seq), resLen)

for p in permutations([1,2,3]): print(p)
for p in permutations([1,2,3],2): print(p)

【讨论】:

它只适用于数字: – 怎么样?如果您传入['a', 'b', 'c'] 而不是[1, 2, 3],那么您将获得预期的排列。 @IvoMori,它也适用于字符串。你可以试试看。我试过了,它一开始就对我有用。 @IvoMori 是的,我把c 和别的东西混在一起了。感谢您指出这一点。 @volothud 只是一个简单的问题?有没有办法设置生成的排列的长度。假设我输入了一个列表 [1, 2, 3],它输出 [1, 2], [1, 3], [2, 1] .... 等等。 @Avy 我会尝试调查它,但我认为您现在要求的是组合,而不是排列。有关它们的差异,请参阅 en.wikipedia.org/wiki/Permutation 和 en.wikipedia.org/wiki/Combination。您可能想查看 itertools:docs.python.org/3.6/library/itertools.html(permutations()、combinations() 函数)。

以上是关于Heap's Algorithm - Python 中用于生成排列的非递归方法的主要内容,如果未能解决你的问题,请参考以下文章

python 缩短搜索Algorithm.py

python 用Python编写的循环算法实现。 #round-robin #scheduling #algorithm #python

190218-Python(str) Algorithm(Red-black tree update)

Python--K-mean-algorithm进行样本点的分类

networkx图论最短路径Dijkstra Algorithm,Python

算法(algorithm) Python技能树的「使用体验」「改进建议」