简体   繁体   English

在 Python 中使用邻接表构造节点图

[英]Construct a graph of nodes using adjacency list in Python

I have a Node class as below我有一个Node类如下

class Node:

    def __init__(self, val = 0, neighbors = None):

        self.val = val
        self.neighbors = neighbors if neighbors is not None else []
    
    def __eq__(self, other) -> bool:
        
        if isinstance(other, self.__class__):
            return all([other.val == self.val, self.neighbors == other.neighbors])
        
        return False
    
    def __repr__(self):
        return f"Node(val: {self.val}, neighbors: {self.neighbors})"
    
    def __str__(self):
        return self.__repr__()

I am trying to construct a Graph using an adjacency list as below:我正在尝试使用如下邻接列表构建一个图形:

[
 [2,4],
 [1,3],
 [2,4],
 [1,3]
]

In the above adjacency list that is indexed from 1 , the index is the Node value ie Node.val and the list at that index are the neighbors ie Node.neighbors在上述从1开始索引的邻接列表中,索引是Node值,即Node.val ,该索引处的列表是邻居,即Node.neighbors

For eg, for index 1:例如,对于索引 1:

Node.val = 1
Node.neighbors = [Node(2), Node(4)]

For index 2:对于索引 2:

Node.val = 2
Node.neighbors = [Node(1), Node(3)]

and so on ...等等 ...

How can I construct the Graph using python, where I want to consider the Node represented by index=1 in the adjacency list to be it's entry point ie the root.如何使用 python 构造图形,我想将邻接列表中由 index=1 表示的Node视为它的入口点,即根。

Basically a function that returns the root of the Graph:基本上是一个返回图根的函数:

def make_graph(adj_list: List) -> Node:
    ...

I have tried iterative approach, resulting in infinite loops or wrong output.我尝试过迭代方法,导致无限循环或错误输出。

One of my attempts that resulted in wrong output:我导致错误输出的尝试之一:

def make_graph(adj_list: List) -> Node:
        
        if not adj_list:
            return []
        
        root = Node(1)
        node_dict = {}
        
        for i in adj_list[0]:
            neighbor = Node(i)
            root.neighbors.append(neighbor)
            node_dict[i] = neighbor
        
        node_dict[1] = root
        
        for i in range(1, len(adj_list)):
            
            node = Node(i) if i not in node_dict else node_dict[i]
            
            for neighbor in adj_list[i]:
                
                if neighbor not in node_dict:
                    neighbor_node = Node(neighbor)
                    node_dict[neighbor] = neighbor_node
                else:
                    neighbor_node = node_dict[neighbor]
                
                node.neighbors.append(neighbor_node)
                
            if i not in node_dict:
                node_dict[i] = node
                
        return root

Which gives the output:这给出了输出:

Node(
    val: 1, 
    neighbors: [
        Node(
            val: 2,
            neighbors: [
                Node(
                    val: 2,
                    neighbors: [...]
                ),
                Node(
                    val: 4,
                    neighbors: []
                )
            ]
        ),
        Node(
            val: 4,
            neighbors: []
        ),
        Node(
            val: 1,
            neighbors: [...]
        ),
        Node(
            val: 3,
            neighbors: [
                Node(
                    val: 1,
                    neighbors: [...]
                ), 
                Node(val: 3,
                     neighbors: [...]
                )
            ]
        )
    ]
)

Any kind of help or pointing in the right direction is immensely appreciated.非常感谢任何形式的帮助或指出正确的方向。

It will be easier if you first create all the node instances, and then populate the neighbors, by mapping those neighbor numbers to the nodes you will then have at your disposal.如果您首先创建所有节点实例,然后通过将这些邻居编号映射到您将拥有的节点来填充邻居,将会更容易。

Here is a function you could use:这是您可以使用的功能:

def make_graph(adj_list: List) -> Node:
    nodes = [Node(i + 1) for i in range(len(adj_list))]
    for i, neighbors in enumerate(adj_list):
        nodes[i].neighbors = [nodes[j-1] for j in neighbors]
    return nodes[0]

Code to test this with the example input:使用示例输入进行测试的代码:

from typing import List

class Node:
    def __init__(self, val = 0, neighbors = None):
        self.val = val
        self.neighbors = neighbors if neighbors is not None else []

    def __repr__(self):
        return f"Node(val: {self.val}, neighbors: {self.neighbors})"

def make_graph(adj_list: List) -> Node:
    nodes = [Node(i + 1) for i in range(len(adj_list))]
    for i, neighbors in enumerate(adj_list):
        nodes[i].neighbors = [nodes[j-1] for j in neighbors]
    return nodes[0]

adj_list = [[2,4],[1,3],[2,4],[1,3]]
node = make_graph(adj_list)

print(node)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM