python - 基于一些数据使用节点和顶点构建图

标签 python python-3.x algorithm dictionary graph

我正在处理由邻接表示给出的有向图。换句话说,图 G 将由一个字典表示,其键是顶点,其值是字典,其键是顶点的邻居,其值可以分配给 1。给定一个有向的两个顶点 u,v图 G 可能存在从 u 到 v 的边,但反之则不然。然而,可能在两个方向上都有边缘。

我创建了一个名为 reachable_vertices 的函数,它将图 G 和顶点 v 作为输入,并返回 G 中可以从 v 到达的所有顶点的列表。如果顶点 w 可以通过 v 到达,这意味着存在一条链 v → v1 → v2... → w 链中的每个顶点到紧随其后的顶点都有一条边。顶点 v 不必具有特定类型,例如 int 或 string,它可以是其中之一,它只需要是表示图 G 的字典中的键。

我定义了一个名为 cfb_graph 的函数,它不带任何参数。我通过将团队视为顶点并仅当 team1 击败 team2 时在 team1 和 team2 之间创建一条边,从文件 cfb2010.csv(下面的链接)形成了一个有向图。 数据集链接 = https://drive.google.com/open?id=1ZgNjH_QE7if1xHMfRU2-ebd9bNpL2E3d

cfb_graph 将返回给出此表示的字典。

我能够找到以下问题,我在下面附上了我的代码: 我。奥本无法联系到哪些团队。将它们存储在列表中。 二.从巴黎圣母院可以联系到哪些团队。将它们存储在列表中。 三.从阿拉巴马州无法到达哪些团队。将它们存储在列表中。

我正在编写以下代码:

def reachable(G, v, setA): # This function checks if it's possible to reach w from v
    setA|={v}
    try:
        for w in set(G[v])-setA:reachable(G,w,setA)
    except KeyError:
        donothing = 0   
    return setA    
##   2a ##
def reachable_vertices(G, v):
    setA=set()
    setA|={v}
    try:
        for n in set(G[v])-setA:reachable(G,n,setA)
    except KeyError:
        donothing = 0    
    return setA    

def cfb_graph():
    svertex = []
    evertex = []
    count= 0
    file = open("cfb2010.csv","r")
    for line in file:  
        fields = line.split(",")
        if fields[5].replace("\n", "") == 'W':
            svertex.append(fields[1])
            evertex.append(fields[2])
        if count == 0:
            count = count +1


    graph = {}
    for i in range(len(svertex)):
        v = svertex[i]
        if v in graph:
            graph[v] |= set([evertex[i]])
        else:
            graph[v] = set([evertex[i]])    

    for key, value in graph.items():
          graph[key] =  dict.fromkeys(value,1) 
    return(graph)


######Part 2 c############
auburn_answer = list(set(cfb_graph().keys()).difference(set(reachable_vertices(cfb_graph(), "Auburn"))))
notre_dame_answer = reachable_vertices(cfb_graph(), "Notre Dame")
alabama_answer = list(set(cfb_graph().keys()).difference(set(reachable_vertices(cfb_graph(), "Alabama"))))

特别是对于每个顶点,我想返回一个字典,其中键是可到达的顶点,值是现在将要描述的。如果顶点 w 可以从顶点 v 到达,则存在从 v 到 w 的路径。返回字典中与 w 对应的值将是从 v 到 w 的某些路径中紧接在它之前的顶点。如果我使用队列方法,那么 w 的值将是 while 循环中的第一个顶点 u,其中 w 是 u 的邻居。

此外,我想定义一个名为 path 的函数,它将以图 G 和两个顶点 v 和 w 作为输入。如果 w 从 v 是可达的,它将返回一个顶点列表,其第一个元素是 v,最后一个元素是 w,其他顶点是从 v 到 w 的路径上的顶点,按照它们被遍历的顺序。如果没有路径,我应该返回 None。我可能想要使用上面定义的函数。

最佳答案

我想快速而强大的图形处理库 networkx会对你有很大帮助。它具有大量的各种算法,因此您无法手动实现它,而只需在代码中使用函数调用即可。

我构建了一个小型工作流来复制您的所有功能并解决您的问题:

# Imports
import networkx as nx
import csv

# Load CSV file and construct the directed graph
G = nx.DiGraph()
with open('cfb2010.csv', 'r') as f:
    sreader = csv.reader(f, delimiter=',')
    for line in sreader:
        if line[-1] != 'W':
            continue
        G.add_node(line[1])
        G.add_node(line[2])
        G.add_edge(line[1], line[2])

# Get all nodes
all_nodes = set(G.nodes())

# Get nodes that can be reached from the particular node
notredame_nodes = set(nx.bfs_tree(G, 'Notre Dame').nodes())
alabama_nodes = set(nx.bfs_tree(G, 'Alabama').nodes())
auburn_nodes = set(nx.bfs_tree(G, 'Auburn').nodes())

# Construct lists of nodes you need
print(all_nodes - alabama_nodes)
print(all_nodes - auburn_nodes)
print(notredame_nodes)

Networkx 还有一个函数等同于您的名为路径 的函数:

print(nx.shortest_path(G, 'Florida', 'Illinois'))

['Florida', 'Penn St', 'Michigan', 'Illinois']

附言可达节点构造使用BFS algorithm .

关于python - 基于一些数据使用节点和顶点构建图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53670463/

相关文章:

performance - 邻接矩阵的速度提升

python - 计算总和可被 k 整除的所有子数组

python - 密码/解密 Python 初学者程序

python - 防止为特定的 save() 调用发送信号

python - 有没有办法用 Pillow 仅反转特定像素?

python - 面临属性错误: for 'tag_' using Spacy in Python

arrays - 异或交换可以扩展到两个以上的变量吗?

python - 如何在AWS lambda上导入opencv模块

python - 如何获取用户接触的所有项目?

python-3.x - python的新手,我需要从输出中绘制一个条形图,以百分比表示