我需要在一个有向图中找到一条路径(具体要求见下文),图中的节点可以分层分类。这些层对于图的结构非常重要(详见图的属性)。
上下文:这个图论问题是我正在尝试解决的另一个更复杂问题的(希望有用的)抽象。
编辑1:
以下是使用python+networkx建议的实现。请注意,图是以这样的方式构建的,即如果存在反向边e=(u,v),则始终适用于u>v。用户数据文件太大无法发布(>17000行)。
这是一个分层有向图的示例
需要找到的路径要求:
- 路径必须从第一层开始,结束于最后一层。
- 路径上不能有任何节点u、v,它们之间存在反向边e=(u,v), 即路径上不能存在任何形成环的节点。
允许路径的示例
允许路径:p=(1,2,5,6,8,9),因为这些节点之间没有反向边,即图中不存在仅由p中节点组成的环。
禁止路径的示例
禁止路径: p=(1,2,4,6,8,9),因为存在反向边e=(4,1),即存在一个环 c=(1,2,4,1),其中所有节点都是p的一部分。
限制有向图的属性:
- 每个层至少包含一个节点。
- 只有当layer(v) = layer(u) + 1(即到下一层)时,才可以存在有向边e=(u,v)
- 只有当layer(u) >= layer(v) + 2(即至少两个层之前)时,才可以存在反向边e=(u,v)
- 始终至少存在一条“正常”路径从第一个节点到最后一个节点。
- 虽然可能不存在特殊路径(如上所述)。
上下文:这个图论问题是我正在尝试解决的另一个更复杂问题的(希望有用的)抽象。
编辑1:
以下是使用python+networkx建议的实现。请注意,图是以这样的方式构建的,即如果存在反向边e=(u,v),则始终适用于u>v。用户数据文件太大无法发布(>17000行)。
def is_result(path, forbidden_pairs):
for (u,v) in forbidden_pairs:
if u in path and v in path:
return False;
return True;
def find_path(G, s, e):
forbidden_pairs = set()
for (u,v) in G.edges:
if (u > v):
forbidden_pairs.add((u,v))
for (u,v) in forbidden_pairs:
G.remove_edge(u,v)
for path in nx.all_shortest_paths(G, s, e):
if is_result(path, forbidden_pairs):
return(path)