简体   繁体   English

如何为无环有向图的顶点分配“层”?

[英]How to assign “levels” to vertices of an acyclic directed graph?

I have an acyclic directed graph. 我有一个无环有向图。 I would like to assign levels to each vertex in a manner that guarantees that if the edge (v1,v2) is in the graph, then level(v1) > level(v2). 我想为每个顶点分配级别,以确保如果边(v1,v2)在图中,则level(v1)> level(v2)。 I would also like it if level(v1) = level(v3) whenever (v1,v2) and (v3,v2) are in the graph. 每当(v1,v2)和(v3,v2)在图中时,如果level(v1)= level(v3),我也希望它。 Also, the possible levels are discrete (might as well take them to be the natural numbers). 同样,可能的级别是离散的(也可以将它们取为自然数)。 The ideal case would be that level(v1) = level(v2) + 1 whenever (v1,v2) is in the graph and there is no other path from v1 to v2, but sometimes that isn't possible with the other constraints - eg, consider a graph on five vertices with the edges (a,b) (b,d) (d,e) (a,c) (c,e). 理想的情况是,每当(v1,v2)在图中并且没有从v1到v2的其他路径时,level(v1)= level(v2)+1,但是有时在其他约束条件下是不可能的-例如,考虑在五个顶点为边(a,b)(b,d)(d,e)(a,c)(c,e)的图中。
Does anyone know a decent algorithm to solve this? 有谁知道一个体面的算法来解决这个问题? My graphs are fairly small (|V| <= 25 or so), so I don't need something blazing fast - simplicity is more important. 我的图相当小(| V | <= 25左右),因此我不需要快速进行操作-简单性更为重要。

My thinking so far is to just find a least element, assign it level 0, find all parents, assign them level 1, and resolve contradictions by adding +0.5 to the appropriate vertices, but this seems pretty awful. 到目前为止,我的想法是只找到一个最小元素,将其分配为0级,找到所有父级,将它们分配为1级,并通过在适当的顶点上添加+0.5来解决矛盾,但这似乎很糟糕。

Also, I get the feeling that it might be helpful to remove all "implicit" edges (ie, remove (v1,v3) if the graph contains both (v1,v2) and (v2,v3). 另外,我感觉删除所有“隐式”边缘可能会有所帮助(即,如果图形同时包含(v1,v2)和(v2,v3),则删除(v1,v3)。

I think letting the level of v be the length of the longest directed path from v might work well for you. 我认为让v的水平为v的最长有向路径的长度可能对您来说很好。 In Python: 在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

Output: 输出:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM