如何将“级别”分配给非循环有向图的顶点?

时间:2010-08-06 02:44:42

标签: java algorithm graph directed-acyclic-graphs

我有一个非循环有向图。我想以保证如果边(v1,v2)在图中,然后是水平(v1)>的方式为每个顶点分配水平。级(V2)。如果等级(v1)=等级(v3),只要(v1,v2)和(v3,v2)在图中,我也会喜欢它。此外,可能的级别是离散的(也可能将它们视为自然数)。理想情况是级别(v1)=级别(v2)+ 1只要(v1,v2)在图表中并且没有其他路径从v1到v2,但有时这对于其他约束是不可能的 - 例如,考虑带有边(a,b)(b,d)(d,e)(a,c)(c,e)的五个顶点上的图形。
有谁知道一个不错的算法来解决这个问题?我的图表相当小(| V | <= 25左右),所以我不需要快速的东西 - 简单性更重要。

到目前为止,我的想法是找到一个最小元素,将它指定为0级,找到所有父级,将它们指定为级别1,并通过将+0.5添加到适当的顶点来解决矛盾,但这看起来非常糟糕。

另外,我觉得删除所有“隐含”边缘可能会有所帮助(例如,如果图形同时包含(v1,v2)和(v2,v3),则删除(v1,v3)。

2 个答案:

答案 0 :(得分:4)

我认为让v的级别成为v中最长的定向路径的长度可能对你有用。在Python中:

# the level of v is the length of the longest directed path from v
def assignlevel(graph, v, level):
    if v not in level:
        if v not in graph or not graph[v]:
            level[v] = 0
        else:
            level[v] = max(assignlevel(graph, w, level) + 1 for w in graph[v])
    return level[v]

g = {'a': ['b', 'c'], 'b': ['d'], 'd': ['e'], 'c': ['e']}
l = {}
for v in g:
    assignlevel(g, v, l)
print l

输出:

{'a': 3, 'c': 1, 'b': 2, 'e': 0, 'd': 1}

答案 1 :(得分:2)

您可以使用拓扑排序为每个顶点分配一个具有所需属性的唯一编号 类似地,您可以按拓扑顺序浏览节点并分配max(parents)+ 1