【问题标题】:Algorithm to determine which lists satisfy requirement确定哪些列表满足要求的算法
【发布时间】:2021-12-15 21:47:33
【问题描述】:

我在想出一个算法时遇到了困难,我现在不知道该怎么办。

我需要从ad,但只能通过滚动这些列表:

[e, d]
[a, b, c]
[d, a]
[a, b]
[a, e, b]

这当然是一个简单的例子,解决方法是:

[a → d]         // 3rd line
[a → e → d]     // 5th line + 1st line
[a → b → e → d] // 2nd + 5th + 1st line

但我必须在 Python 中解决它。 我想出了两种方法来解决这个问题,第一种是使用 for 循环,但循环开始重复并且非常耗时,所以我选择了想法 2。 我正在考虑创建一个以a 开头并以d 结尾的所有可能变体的列表。然后在我们指定的列表中检查这是否可行。

from itertools import permutations
 
lst = ['a', 'b', 'c', 'd', 'e']

x = 'a'
y = 'd'

for i in range(1, len(lst)):
    perm = permutations(lst, i+1)

    for j in list(perm):
        if (j[0] == x) and (j[-1] == y):
            print(j)

但后来不知何故我被卡住了,我不知道现在该怎么办。有人可以给我一个提示吗?还是我做错了?

编辑:

我正在尝试查找所有路径并打印出来。

【问题讨论】:

  • 你不能只检查每个排列的第一个和最后一个成员吗?
  • 你为什么不创建一个邻接表并遍历图来找到你的解决方案?路径上是否有任何要求(例如确实需要最短)。如果没有,您可以执行 bfs 或 dfs。最后你需要展示什么作为结果?通往目标的路径?
  • 您想要ad 的所有排列吗?
  • 如果您尝试列出所有可能的路径,循环的预期行为是什么?例如使用您的示例,[a → b → e → a → d] 使用第 2、5、5、3 行或类似的,[a → b → e → a → b → e → d][a → b → e → a → b → e → a → b → e → d] 等。
  • @Oli 理想情况下没有周期

标签: python algorithm combinations


【解决方案1】:

这是一个图问题,其中列表是节点之间的无向边。例如:

[a, b, c]

表示从abc,从bac,以及从cab有无向边。当然a——b,也表示b——a。为了清楚起见,我重复了上面的边缘。

因此,您要做的是创建一个表示所有这些边的邻接列表并应用回溯,因为您想要从源到目标的所有可能路径。

这里有一些代码向你展示了这个想法:

adj_list = collections.defaultdict(set)
for row in rows:
  for i, el in enumerate(row):
    for j in range(i+1, len(row):
        adj_list[el].add(row[j])
        adj_list[row[j]].add(el)

def backtrack(node, adj_list, seen, partial_res, res):
  if node == target:
    res.append(partial_res[:])
  
  for neighbor in adj_list[node]:
    if neighbor in seen: continue
    seen.add(neighbor)
    partial_res.append(neighbor)
    backtrack(neighbor, adj_list, seen, partial_res, res)
    partial_res.pop()
    seen.remove(neighbor)

res = []
backtrack(start, adj_list, set(), [], res)
print(res)

我没有运行这个。但是代码应该让我们了解回溯是如何工作的。这是一个 dfs,您可以在其中检查每条可能的路径并跟踪您经过的边缘。如果它通向目的地,则将其副本保存在最终结果中。

请注意,此算法在每条路径中只访问每个节点一次。

【讨论】:

  • 非常感谢您的帮助。我找到了networkx 库,它可以使用list(nx.all_simple_paths(G, x, y)) 命令完成我想要的操作。
  • 不客气。谢谢你的分享。我不知道networkx
猜你喜欢
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 2017-09-04
  • 2019-09-15
相关资源
最近更新 更多