Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.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_Graph Theory_Nodes_Depth First Search_Breadth First Search - Fatal编程技术网

Python 广度优先搜索/深度优先搜索还是有向图?

Python 广度优先搜索/深度优先搜索还是有向图?,python,graph-theory,nodes,depth-first-search,breadth-first-search,Python,Graph Theory,Nodes,Depth First Search,Breadth First Search,我已经为此挣扎了一段时间了。给定一组节点: nodes = { ('A','B'), ('B','C'), ('C','D'), ('C','E'), ('B','E'), ('C','F') } 实现以下目标的最佳方法是什么: A | B

我已经为此挣扎了一段时间了。给定一组节点:

nodes = { ('A','B'),
          ('B','C'),
          ('C','D'),
          ('C','E'),
          ('B','E'),
          ('C','F') }
实现以下目标的最佳方法是什么:

                          A
                          |
                          B
                 _________|_________
                 |                  |
                 C                  E
            _____|_____             |
            |    |     |            C
            D    E     F        ____|____
                                |        |
                                D        F
我可以看到:

the routes from A -> B:
A -> B
the routes from A -> C: 
A -> B -> C
A -> B -> E -> C
the routes from A -> D:
A -> B -> C -> D
A -> B -> E -> C -> D

etc...
我这样做的原因,纯粹是因为我想知道如何去做

我知道bfs可以找到最快的路线(我想我可能在GetChildren函数中使用了类似的功能)

但我不知道循环/递归运行图形的最佳方法。我应该使用字典和键/VAL或列表吗。或设置

def make_graph(nodes):
    d = dict()
    for (x,y,*z) in nodes:
        if x not in d: d[x] = set()
        if y not in d: d[y] = set()
        d[x].add(y)
        d[y].add(x)
    return d
我在这里使用*z,因为元组实际上会包含一个浮点,但目前我正试图保持简单

def display_graph(nodes):
    for (key,val) in make_graph(nodes).items():
        print(key, val)

# A {'B'}
# C {'B', 'E', 'D', 'F'}
# B {'A', 'C', 'E'}
# E {'C', 'B'}
# D {'C'}
# F {'C'}
getchildren函数查找节点根的所有可能端点:

def getchildren(noderoot,graph):
    previousnodes, nextnodes = set(), set()
    currentnode = noderoot
    while True:
        previousnodes.add(currentnode)
        nextnodes.update(graph[currentnode] - previousnodes)
        try:
            currentnode = nextnodes.pop()
        except KeyError: break
    return (noderoot, previousnodes - set(noderoot))
在这种情况下,A:

print(getchildren('A', make_graph(nodes)))

# ('A', {'C', 'B', 'E', 'D', 'F'})

我认为普通的树结构对于表示数据没有意义,因为它是顺序的,但不一定是有序的。使用trytes(前缀树或基数树)或(可能更好)有向图可能更合适。

在使用程序语言编码之前,您需要正确地抽象问题

首先,您需要考虑图形的属性,例如循环/非循环、有向/无向等

然后你需要选择一种相应的方法来解决你的问题。e、 如果它是一个非循环的、无向的、连通的图,那么你可以将该图表示为一个图,并使用BFS或DFS遍历它


最后,在您仔细考虑所有这些之后,您可以更轻松地将其放入代码中。就像您已经在做的一样,您可以给每个节点一个存储所有邻居的列表,并使用遍历树。

我认为您可能使事情变得比需要的更复杂。考虑一下您所表示的数据类型,如xvatar所说

对于基本有向图,字典是有意义的。只需存储父项:子项列表

nodes = [ ('A','B'),
          ('B','C'),
          ('C','D'),
          ('C','E'),
          ('B','E'),
          ('C','F') ]

from collections import defaultdict
d = defaultdict(list)
for node in nodes:
    d[node[0]].append(node[1])
从任何根节点查找所有可访问的子节点非常简单:

def getchildren(root, graph, path=[]):
    path = path + [root]
    for child in graph[root]:
        if child not in path:  #accounts for cycles
            path=getchildren(child, graph, path)
    return path
打电话时:

>>> print getchildren('A',d)
['A', 'B', 'C', 'D', 'E', 'F']
>>> print getchildren('C',d)
['C', 'D', 'E', 'F']

谢谢大家,问题解决了。我需要编写的函数如下

def trace_graph(k, graph):
    """ takes a graph and returns a list of lists showing all possible routes from k """
    paths = [[k,v] for v in graph[k]]
    for path in paths:
        xs = path[:-1]
        x  = path[-1]
        for v in graph[x]:
            if v not in xs and path + [v] not in paths:
                paths.append(path + [v])
    paths.sort()
    return paths


for path in trace_graph('A', make_graph(nodes)):
    print(path)


['A', 'B']
['A', 'B', 'C']
['A', 'B', 'C', 'D']
['A', 'B', 'C', 'E']
['A', 'B', 'C', 'F']
['A', 'B', 'E']
['A', 'B', 'E', 'C']
['A', 'B', 'E', 'C', 'D']
['A', 'B', 'E', 'C', 'F']

可能的副本。不同的语言,但相同的问题为什么
E
不出现在左侧的
C
下?C、D、F各两个?你确定你想要一棵树,而不是一个有向图吗?我想找到任何给定密钥的所有可能路径。我不是在寻找最短的路径。。。我不知道我的“目标”。我不知道我想要的是一棵树还是一张图,大部分这篇文章都是在没有任何关于树和图的知识的情况下写成的work@Eric我不知道你的意思是什么?在我脑子里,我知道怎么做,但当我试着编写代码的时候。。。我感到困惑。@ThemanonthenCelaphammonibus将您的想法转化为自然语言-->将自然语言转化为伪代码-->将伪代码转化为真实代码,但我现在肯定能做到这一点,getchildren函数正是这样做的,它只是使用集合而不是列表。在您的getchildren函数中,为什么C不返回A-as(A,B),(C,B)@ThemanontheClaphamomnibus,我假设是。。。如题名所示。。。您询问了递归运行图形和存储数据的最佳方法,我建议使用defaultdict来轻松创建,并使用一个简单的递归算法来处理遍历时的循环。如果你已经在做你想做的事,你到底在问什么?