通过部分有序集合的方式数量

时间:2018-05-02 02:10:11

标签: python algorithm graph combinations poset

这是基于之前的问题Solve a simple packing combination with dependencies,虽然没有必要检查这个问题以理解这个问题。

这个问题询问了计算部分有序集的线性扩展数的最快方法。

在给定对象的任意排序的情况下,可以将这种部分有序列表可视化为包装配置的可行性。问题是,如果一旦放置了块就不能移动,那么为了达到所示的包装配置,所有块的可能顺序都是相同的。

enter image description here

在此示例中,需要规划所有块ABCDEFG,A,B,C,D的依赖关系:set {},E:set {A,B},F:set {B,C} G:set {C,d}。

通过检查7个块的所有排列并计算满足依赖性的数量,您可以获得完成部分有序集的所有可能性。上一篇文章中的גלעדברקן提​​供了一个更快的替代方案,如果在已探索的节点中不满足依赖关系,则使用图形结构终止进一步搜索到分支。

nodes = {
  'A': {
    'neighbours': ['B','C','D','E','F','G'], 'dependency': set()},
  'B': {
    'neighbours': ['A','C','D','E','F','G'], 'dependency': set()},
  'C': {
    'neighbours': ['A','B','D','E','F','G'], 'dependency': set()},
  'D': {
    'neighbours': ['A','B','C','E','F','G'], 'dependency': set()},
  'E': {
    'neighbours': ['C','D','F','G'], 'dependency': set(['A','B'])},
  'F': {
    'neighbours': ['A','D','E','G'], 'dependency': set(['B','C'])},
  'G': {
    'neighbours': ['A','D','E','G'], 'dependency': set(['C','D'])},

}

def f(key, visited):
  if len(visited) + 1 == len(nodes):
    return 1

  if nodes[key]['dependency'] and not nodes[key]['dependency'].issubset(visited):
    return 0

  result = 0

  for neighbour in nodes[key]['neighbours']:
    if neighbour not in visited:
      _visited = visited.copy()
      _visited.add(key)
      result += f(neighbour, _visited)

  return result

print 2 * f('A', set()) + 2 * f('B', set()) # exploiting symmetry

我的问题是,如果有任何方法可以进一步优化גלעדברקן的算法而不失一般性?如果依赖项很少,我可以使它更快,列表可以进一步细分为独立的子列表,但对于这个特定的例子情况并非如此。

0 个答案:

没有答案
相关问题