Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 检查DI图中是否存在任何路径_Python_Graph_Graph Theory - Fatal编程技术网

Python 检查DI图中是否存在任何路径

Python 检查DI图中是否存在任何路径,python,graph,graph-theory,Python,Graph,Graph Theory,如果我有一个Di图,如何检查是否所有的节点对(a,b)都创建了一条路径 例如: 输入: v1 v2 v5 v6 v2 v3 v3 v4 v4 v5 v0 v1 我需要检查是否至少存在一条通过该图的路径,而不必访问每个节点一次 我已经试过回溯,但要想获得最大的投入,需要几个小时 具体示例: 输入时,我有边: {m,a}, {a,c}, {a,m} 我必须检查,如果有路径,在这种情况下它将返回True,因为存在 {a,m} -> {m, a} -> {a,c} 一种相对简单的二

如果我有一个Di图,如何检查是否所有的节点对(a,b)都创建了一条路径

例如:

输入:

v1 v2
v5 v6
v2 v3
v3 v4
v4 v5
v0 v1
我需要检查是否至少存在一条通过该图的路径,而不必访问每个节点一次

我已经试过回溯,但要想获得最大的投入,需要几个小时

具体示例:

输入时,我有边:

{m,a}, {a,c}, {a,m} 
我必须检查,如果有路径,在这种情况下它将返回True,因为存在

{a,m} -> {m, a} -> {a,c}
一种相对简单的二次算法 从路径列表中弹出一个路径。在列表中弹出另一个路径以将其连接。将连接的路径推回到列表中。如果在任何时候我们都找不到另一条路径来连接它,这意味着答案是否定的,所有节点对都不会合并成一条路径,因此我们返回
None

def将_组合成一条路径(路径列表):
path=路径列表。pop()
当列出\u路径时:
路径2=弹出相邻路径(路径列表,路径[0],路径[-1])
如果路径2为无:
一无所获
elif路径[-1]==路径2[0]:
路径=路径[:-1]+路径2
elif路径2[-1]==路径[0]:
路径=路径2[:-1]+路径
其他:
断言(假)
返回路径
def pop_相邻_路径(路径列表a、b):
对于枚举中的i,p(路径列表):
如果(a,b)中的p[0]或(a,b)中的p[-1]:
返回路径列表\u.pop(i)
一无所获
打印(将_合并到一个_路径([[1,2]、[5,6]、[2,3]、[3,4]、[4,5]、[0,1]]))
# [0, 1, 2, 3, 4, 5, 6]
打印(将_合并到一个_路径([[1,2]、[5,6]、[2,3]、[3,7]、[4,5]、[0,1]]))
#没有
该算法在路径数量上是二次的,因为
中的
while
-循环将路径组合成一条路径
在列表中的每条路径都有一次迭代,并且函数
pop\u相邻路径
也会在列表中迭代

请注意,此代码不会检查节点是否唯一;例如,
[v1,v2,v3,v2,v4,v1,v5]
将被视为有效路径。您可以在
combine\u to\u one\u path
中的最终返回之前添加一个检查,以确保路径中的每个元素都是唯一的

线性化 降低算法速度的是必须遍历整个列表,以找到一对节点来组合当前路径。避免这种情况的一种方法是将成对数据存储在字典中,这样我们就可以在固定时间内回答“成对数据是否以
a
结尾?”和“成对数据是否以
b
开头”的问题

def combine_into_one_path(list_of_paths):
  path = list_of_paths.pop()
  forwards = {p[0]:p for p in list_of_paths}
  backwards = {p[-1]:p for p in list_of_paths}
  while forwards:
    if path[-1] in forwards:
      p2 = forwards[path[-1]]
      del forwards[path[-1]]
      del backwards[p2[-1]]
      path = path[:-1] + p2
    elif path[0] in backwards:
      p2 = backwards[path[0]]
      del backwards[path[0]]
      del forwards[p2[0]]
      path = p2[:-1] + path
    else:
      return None
    print('\npath     =', path)
    print('forwards =', forwards)
    print('backwards=', backwards)
  return path

print(combine_into_one_path(['manta', 'alcats', 'random']))
# randomantalcats
这几乎是相同的算法,但我们用字典检查取代了函数
pop_nexture_path
,这是恒定时间而不是线性时间

为了了解算法的工作原理:

list_of_paths = [[1, 2], [5, 6], [3, 4], [4, 5], [0, 1], [2, 3]]

path     = [2, 3]
forwards = {1: [1, 2], 5: [5, 6], 3: [3, 4], 4: [4, 5], 0: [0, 1]}
backwards= {2: [1, 2], 6: [5, 6], 4: [3, 4], 5: [4, 5], 1: [0, 1]}

path     = [2, 3, 4]
forwards = {1: [1, 2], 5: [5, 6], 4: [4, 5], 0: [0, 1]}
backwards= {2: [1, 2], 6: [5, 6], 5: [4, 5], 1: [0, 1]}

path     = [2, 3, 4, 5]
forwards = {1: [1, 2], 5: [5, 6], 0: [0, 1]}
backwards= {2: [1, 2], 6: [5, 6], 1: [0, 1]}

path     = [2, 3, 4, 5, 6]
forwards = {1: [1, 2], 0: [0, 1]}
backwards= {2: [1, 2], 1: [0, 1]}

path     = [1, 2, 3, 4, 5, 6]
forwards = {0: [0, 1]}
backwards= {1: [0, 1]}

path     = [0, 1, 2, 3, 4, 5, 6]
forwards = {}
backwards= {}

你的问题模棱两可。你能澄清一下你想做什么吗?输入时我有边:{m,a},{a,c},{a,m},我必须检查,如果有路径,在这种情况下它将返回True,因为存在{a,m}->{m,a}->{a,c}从列表中选择一对;寻找另一对你可以连接它;如果存在这样一对,则弹出两对,推送它们的串联;如果不存在这样的对,但至少还有两个不同的对,则不存在路径。您是否已从
networkx
中签出函数?您的示例不满足每个节点只访问一次的要求:
a
访问两次。它返回:
del backwardwards[p2[-1]]KeyError:100
@MartinPoláček哪个输入?@MartinPoláček此单词列表中有多个单词以相同字母开头或以相同字母结尾!!这与你的问题完全不同,这将是一个更难的问题