python - 在特定条件下生成边的组合

标签 python algorithm combinations combinatorics

<分区>

我将图的边表示为 (node_from, node_to)。

我想有效地生成形式为 (0,x) 的两条边的所有组合,其中 0 是我图中的节点 0 - 结合形式为 (x,n) 的两条边的所有组合,其中 n是我图中的“最终节点”(我知道是任意的)。我已经将所有边放在一个集合中,或者每个节点都包含到每个其他节点的边(例如,您可以直接遍历范围以生成组合)。

一个有效的组合可以是

  • (0,1),(0,5),(7,n),(11,n) 或
  • (0,1),(0,5),(5,n),(11,n) 或
  • (0,1),(0,n),(0,n),(11,n)

并且,为了清楚起见,我想要组合而不是排列。我不想重复使用同一个组。

我通常很擅长解决这些问题,但我在这方面遇到了一些麻烦。

最佳答案

编辑:更新以适应“只有两个开始/结束边缘”的要求

我不确定您想到的接口(interface)是什么,但据我了解,您似乎可以使用 filter() 来选择“从 0 开始”的边缘子集”或“以 n 结尾”。

>>> edges = [(0,1), (0,5), (0,2), (5,3), (2,9), (4,6), (6,9), (3,9), (0,9)]
>>> edges_start = filter(lambda e: e[0] == 0, edges)
>>> edges_end = filter(lambda e: e[1] == 9, edges)
>>> edges_end
[(2, 9), (6, 9), (3, 9), (0, 9)]
>>> edges_start
[(0, 1), (0, 5), (0, 2), (0, 9)]

现在您可以使用 itertools.combinations() 从每个列表中生成所有可能的对。这是一个例子:

>>> import itertools
>>> list(itertools.combinations(edges_start, 2))
[((0, 1), (0, 5)), ((0, 1), (0, 2)), ((0, 1), (0, 9)), ((0, 5), (0, 2)), ((0, 5), (0, 9)), ((0, 2), (0, 9))]

现在您可以插入 itertools.product() 以生成“来自一个列表的对”和“来自其他列表的对”的所有组合:

>>> edges_start_pairs = list(itertools.combinations(edges_start, 2))
>>> edges_end_pairs = list(itertools.combinations(edges_end, 2))
>>> pairs = list(itertools.product(edges_start_pairs, edges_end_pairs))

就是这样!如果愿意,您可以“展平”数据结构,但这是可选的:

>>> flat_pairs = [list(p[0]+p[1]) for p in pairs]

现在让我们漂亮地打印结果:

>>> from pprint import pprint
>>> pprint(flat_pairs)
[[(0, 1), (0, 5), (2, 9), (6, 9)],
 [(0, 1), (0, 5), (2, 9), (3, 9)],
 [(0, 1), (0, 5), (2, 9), (0, 9)],
 [(0, 1), (0, 5), (6, 9), (3, 9)],
 [(0, 1), (0, 5), (6, 9), (0, 9)],
 [(0, 1), (0, 5), (3, 9), (0, 9)],
 [(0, 1), (0, 2), (2, 9), (6, 9)],
 [(0, 1), (0, 2), (2, 9), (3, 9)],
 [(0, 1), (0, 2), (2, 9), (0, 9)],
 [(0, 1), (0, 2), (6, 9), (3, 9)],
 [(0, 1), (0, 2), (6, 9), (0, 9)],
 [(0, 1), (0, 2), (3, 9), (0, 9)],
 [(0, 1), (0, 9), (2, 9), (6, 9)],
 [(0, 1), (0, 9), (2, 9), (3, 9)],
 [(0, 1), (0, 9), (2, 9), (0, 9)],
 [(0, 1), (0, 9), (6, 9), (3, 9)],
 [(0, 1), (0, 9), (6, 9), (0, 9)],
 [(0, 1), (0, 9), (3, 9), (0, 9)],
 [(0, 5), (0, 2), (2, 9), (6, 9)],
 [(0, 5), (0, 2), (2, 9), (3, 9)],
 [(0, 5), (0, 2), (2, 9), (0, 9)],
 [(0, 5), (0, 2), (6, 9), (3, 9)],
 [(0, 5), (0, 2), (6, 9), (0, 9)],
 [(0, 5), (0, 2), (3, 9), (0, 9)],
 [(0, 5), (0, 9), (2, 9), (6, 9)],
 [(0, 5), (0, 9), (2, 9), (3, 9)],
 [(0, 5), (0, 9), (2, 9), (0, 9)],
 [(0, 5), (0, 9), (6, 9), (3, 9)],
 [(0, 5), (0, 9), (6, 9), (0, 9)],
 [(0, 5), (0, 9), (3, 9), (0, 9)],
 [(0, 2), (0, 9), (2, 9), (6, 9)],
 [(0, 2), (0, 9), (2, 9), (3, 9)],
 [(0, 2), (0, 9), (2, 9), (0, 9)],
 [(0, 2), (0, 9), (6, 9), (3, 9)],
 [(0, 2), (0, 9), (6, 9), (0, 9)],
 [(0, 2), (0, 9), (3, 9), (0, 9)]]

关于python - 在特定条件下生成边的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490799/

相关文章:

python - 附加失败时如何有效地重建 pandas hdfstore 表

python - 将 IP 范围转换为 CIDR 表示法的模块、脚本或算法

python - 获取列表列表的 powerset

python - 为什么用于内容更新的 Github API 会抛出 400 错误?

python - 如果在某些时间/值之间, Pandas 累积总和

python - 传递一个由用户设置的变量作为 os.system() 命令的参数

algorithm - 确定流中的所有字节是否相等

java - 数独与 AC3

R:来自具有 2 个可能条件 (+/-) 的元素向量的所有可能组合

postgresql - 具有顺序和限制的排列