【发布时间】:2018-01-19 03:59:33
【问题描述】:
我有一个简单的递归函数,它提供对选项列表的每个可能组合的深度优先搜索:
def twoCharacters_dfs(options, used):
for i in range(len(options)):
used.append(options.pop(0))
print("used=", used)
twoCharacters_dfs(options, used)
if len(used) == 0:
return
options.append(used.pop())
twoCharacters_dfs(['q', 'w', 'e', 'r'], [])
输出(由于长度而缩短)如下所示:
used= ['q']
used= ['q', 'w']
used= ['q', 'w', 'e']
used= ['q', 'w', 'e', 'r']
used= ['q', 'w', 'r']
used= ['q', 'w', 'r', 'e']
used= ['q', 'e']
used= ['q', 'e', 'r']
used= ['q', 'e', 'r', 'w']
used= ['q', 'e', 'w']
used= ['q', 'e', 'w', 'r']
....
used= ['w']
....
used= ['e']
....
used= ['r']
....
这一切都很好,可以按我的意愿工作。但我有兴趣将其从深度优先转换为广度优先,因此输出看起来更像:
used= ['q']
used= ['w']
used= ['e']
used= ['r']
used= ['q', 'w']
used= ['q', 'e']
used= ['q', 'r']
used= ['w', 'q']
used= ['w', 'e']
used= ['w', 'r']
....
我已经能够(只有一个硬编码的固定长度列表)迭代地完成它,但需要一个递归解决方案,以便它可以适用于任何长度的选项。我也故意避免提供我所寻求的功能的 python 库,因为我想了解事物是如何工作的,并构建自己的东西作为学习练习。
我觉得有一个简单的解决方案,但我无法将广度优先算法概念化到我的代码中。
更新
在尝试递归 BFS 解决方案之前,我想创建一个迭代 BFS 解决方案,因为它似乎更容易实现。事实证明,我也很难做到这一点。
def twoCharacters_bfs_iterative(options, used):
for option in options:
print("using option = ", option)
for option1 in options:
list2 = options[:]
list2.remove(option1)
for option2 in list2:
print("using option = ", option1, option2)
for option1 in options:
list2 = options[:]
list2.remove(option1)
for option2 in list2:
list3 = list2[:]
list3.remove(option2)
for option3 in list3:
print("using option = ", option1, option2, option3)
这实现了我想要的输出(如上所列),但仅适用于我知道长度的集合。我想将其扩展为任意长度的列表,但在这样做时遇到了麻烦。我想如果我能让迭代解决方案发挥作用,递归解决方案也不会落后。
【问题讨论】:
-
我不知道 BFS 作为递归函数是否有意义。 DFS 和 BFS 的基本区别在于 DFS 使用堆栈来跟踪未访问的节点,而 BFS 使用队列。递归 DFS 实现基本上只是将调用堆栈用作该堆栈。尝试编写一个非递归 DFS(提示:python 列表可以被视为堆栈),然后尝试用队列替换该实现中的堆栈(您可以使用
queue.Queue作为 FIFO 队列) -
@PatrickHaugh 这是一个很好的提示。想锻炼我的递归肌肉,但是转到非递归 DFS 然后从那里转到非递归 BFS 对我来说是一个很好的学习过程
-
100% 同意@PatrickHaugh,将 BFS 实现为递归函数需要跳过一些复杂的环节。 BFS 使用循环更自然地实现。
-
关于 DFS “使用调用堆栈”作为数据结构本身的见解很棒。
-
@Turksarama:这不是很复杂的篮球;有些语言中递归是唯一可用的循环结构,它们显然仍然可以实现 BFS。问题更多的是 Python 不 (and never will) 支持尾调用优化,所以你不能在不浪费大量内存的情况下做到这一点。
标签: python combinations depth-first-search breadth-first-search