Python 组合数学,第 2 部分

标签 python combinatorics

这是 Combinatorics in Python 的后续问题

我有一个树或有向无环图,如果你愿意的话,结构如下:

alt text

其中 r 是根节点,p 是父节点,c 是子节点,b 是假设分支。根节点与父节点没有直接联系,只是一个引用。

我很想找到约束条件下的所有分支组合:

  1. 子节点可以由任意数量的父节点共享,前提是这些父节点不共享根节点。
  2. 有效组合不应是另一个组合的子集

在这个例子中,在约束下只有两个有效组合是可能的:

combo[0] = [b[0], b[1], b[2], b[3]]
combo[1] = [b[0], b[1], b[2], b[4]]

数据结构如b是分支对象的列表,具有属性r、c和p,例如:

b[3].r = 1
b[3].p = 3
b[3].c = 2

最佳答案

这个问题在 Python 中可以轻松优雅地解决,因为有一个名为“itertools”的模块。

假设我们有 HypotheticalBranch 类型的对象,它们具有属性 r、p 和 c。就像您在帖子中描述的那样:

class HypotheticalBranch(object):
  def __init__(self, r, p, c):
    self.r=r
    self.p=p
    self.c=c
  def __repr__(self):
    return "HypotheticalBranch(%d,%d,%d)" % (self.r,self.p,self.c)

因此你的一组假设分支是

b=[ HypotheticalBranch(0,0,0),
  HypotheticalBranch(0,1,1),
  HypotheticalBranch(1,2,1),
  HypotheticalBranch(1,3,2),
  HypotheticalBranch(1,4,2) ]

返回所有可能分支组合列表的神奇函数可以这样写:

import collections, itertools

def get_combos(branches):
  rc=collections.defaultdict(list)
  for b in branches:
    rc[b.r,b.c].append(b)
  return itertools.product(*rc.values())

准确地说,这个函数返回一个迭代器。通过迭代获取列表。这四行代码将打印出所有可能的组合:

for combo in get_combos(b):
  print "Combo:"
  for branch in combo:
    print "  %r" % (branch,)

这个程序的输出是:

Combo:
  HypotheticalBranch(0,1,1)
  HypotheticalBranch(1,3,2)
  HypotheticalBranch(0,0,0)
  HypotheticalBranch(1,2,1)
Combo:
  HypotheticalBranch(0,1,1)
  HypotheticalBranch(1,4,2)
  HypotheticalBranch(0,0,0)
  HypotheticalBranch(1,2,1)

...这正是您想要的。

那么脚本是做什么的呢?它为每个组合(根节点、子节点)创建一个所有假设分支的列表。然后它会生成这些列表的乘积,即每个列表中一项的所有可能组合。

我希望我得到了你真正想要的。

关于Python 组合数学,第 2 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4145873/

相关文章:

matlab - 将参数(即笛卡尔积)排列成多维数组

r - 查找分布在 data.frame 的 2 列中的成对重复项

javascript - Django/Python/toDataURL 返回带有来自 toDataURL 的字符串的响应

python - PyTorch 加载 "\lib\site-packages\torch\lib\shm.dll"或其依赖项之一时出错

python - 这种转置矩阵的方法有什么问题

Python-为每个唯一单词显示一行

python - 在 Python 中遍历列表列表中的列

algorithm - Grundy 的游戏扩展到两个以上的堆

string - 快速生成字符串组合的方法

algorithm - 如何以随机顺序生成所有集合组合