Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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 查找两个节点之间路径数的快速算法_Python_Algorithm_Python 2.7_Nodes_Graph Theory - Fatal编程技术网

Python 查找两个节点之间路径数的快速算法

Python 查找两个节点之间路径数的快速算法,python,algorithm,python-2.7,nodes,graph-theory,Python,Algorithm,Python 2.7,Nodes,Graph Theory,我试图用Python回答一个在线法官的问题,但我已经超过了时间限制和内存限制。问题几乎是询问从开始节点到结束节点的所有路径的数量。可以查看完整的问题规格 这是我的代码: import sys lines = sys.stdin.read().strip().split('\n') n = int(lines[0]) dict1 = {} for i in xrange(1, n+1): dict1[i] = [] for i in xrange(1, len(lines) - 1):

我试图用Python回答一个在线法官的问题,但我已经超过了时间限制和内存限制。问题几乎是询问从开始节点到结束节点的所有路径的数量。可以查看完整的问题规格

这是我的代码:

import sys
lines = sys.stdin.read().strip().split('\n')
n = int(lines[0])
dict1 = {}

for i in xrange(1, n+1):
    dict1[i] = []

for i in xrange(1, len(lines) - 1):
    numbers = map(int, lines[i].split())
    num1 = numbers[0]
    num2 = numbers[1]
    dict1[num2].append(num1)

def pathfinder(start, graph, count):
    new = []
    if start == []:
        return count
    for i in start:
        numList = graph[i]
        for j in numList:
            if j == 1:
                count += 1
            else:
                new.append(j)

    return pathfinder(new, graph, count)   

print pathfinder([n], dict1, 0)

代码所做的是,它从结束节点开始,通过探索所有相邻节点,一直到顶部。我基本上做了一个广度优先的搜索算法,但它占用了太多的空间和时间。如何改进此代码以提高效率?我的方法错了吗?我应该如何修复它?

在代码中,您所做的是DFS(而不是BFS)

这里有一个链接到一个好的解决方案。。。 编辑: 改用这种方法


由于图是非循环的,因此存在一个拓扑顺序,我们可以立即看到它是
1,2,…,n
。所以我们可以用动态规划的方法来解决这个问题。在列表
paths
中,元素
paths[i]
存储从
1
i
的路径数。更新将很简单-对于每个边
(i,j)
,其中
i
来自我们的拓扑顺序,我们执行
路径[j]+=path[i]

from collections import defaultdict

graph = defaultdict(list)
n = int(input())
while True:
    tokens = input().split()
    a, b = int(tokens[0]), int(tokens[1])
    if a == 0:
        break
    graph[a].append(b)

paths = [0] * (n+1)
paths[1] = 1
for i in range(1, n+1):
    for j in graph[i]:
        paths[j] += paths[i]
print(paths[n])
请注意,您正在实现的实际上并不是
BFS
,因为您没有标记您访问过的顶点,从而使
开始
变得不相称

测试图表

for i in range(1, n+1):
    dict1[i] = list(range(i-1, 0, -1))

如果打印
start
的大小,您可以看到它为给定
n
获得的最大值与~4^n/sqrt(n)的大小完全相同。还要注意的是,
BFS
不是您想要的,因为无法以这种方式计算路径数。

代码可以工作,但我只想确保我正确理解这一点。对于每个节点,计数等于父节点访问它的次数,每个父节点访问它的次数,一直到1?这将在O(顶点+边)时间内完成?@BobMarshall完全正确!因此,他们倾向于选择可以独立于外部资源进行评估的未删节答案。
import sys
from collections import defaultdict

def build_matrix(filename, x):
    # A[i] stores number of paths from node x to node i.

    # O(n) to build parents_of_node
    parents_of_node = defaultdict(list)
    with open(filename) as infile:
        num_nodes = int(infile.readline())
        A = [0] * (num_nodes + 1)  # A[0] is dummy variable. Not used.
        for line in infile:
            if line == "0 0":
                break

            u, v = map(int, line.strip().split())
            parents_of_node[v].append(u)

            # Initialize all direct descendants of x to 1
            if u == x:
                A[v] = 1

    # Number of paths from x to i = sum(number of paths from x to parent of i)
    for i in xrange(1, num_nodes + 1):  # O(n)
        A[i] += sum(A[p] for p in parents_of_node[i])  # O(max fan-in of graph), assuming O(1) for accessing dict.

    # Total time complexity to build A is O(n * (max_fan-in of graph))
    return A


def main():
    filename = sys.argv[1]

    x = 1  # Find number of paths from x
    y = 4  # to y

    A = build_matrix(filename, x)
    print(A[y])