这是基于之前的问题Solve a simple packing combination with dependencies,虽然没有必要检查这个问题以理解这个问题。
这个问题询问了计算部分有序集的线性扩展数的最快方法。
在给定对象的任意排序的情况下,可以将这种部分有序列表可视化为包装配置的可行性。问题是,如果一旦放置了块就不能移动,那么为了达到所示的包装配置,所有块的可能顺序都是相同的。
在此示例中,需要规划所有块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
我的问题是,如果有任何方法可以进一步优化גלעדברקן的算法而不失一般性?如果依赖项很少,我可以使它更快,列表可以进一步细分为独立的子列表,但对于这个特定的例子情况并非如此。