遍历 Class 对象列表属性

时间:2021-03-10 17:47:02

标签: python oop kosaraju-algorithm

希望有人在这里有一些见解。 带有图和节点类的 Kosaraju 算法实现的前半部分。 我正在遍历一个节点列表,每个节点都有一个头部列表和一个尾部列表,以允许向前或向后移动。 当您在图形中移动时,新探索的顶点是 explored,然后您访问 head_list

    for j in i.head_list:
        DFS(my_graph, j, T, S)

有趣的是,i.head_list 有时是一个空列表,尽管在图表测试数据中,每个节点都至少有一个头和一个尾。

示例(来自下面的测试数据):第一次调用应为“9”,head_list 为 [6],但返回 [] 且 tail_list 为 [ 3, 7]。在调试深入到变量 3 作为 th tail_list 的一部分时,head_list 填充有 [9] 但 tail_list 是 []。填充头部和尾部列表之间的某种翻转。

我以为有一些全局变量混淆,但我还没有找到。我想也许 copy.deepcopy 可能已经修复了它,但事实并非如此。这似乎是非常不寻常的行为。更有趣的是,当节点已经包含在 head_list 中时,它似乎只生成一个空列表。例如:节点 4 是第一个失败并且

我希望能够无限期地连续钻取节点和 head_listtail_list,但迭代中列表的存在会前后变化。任何见解将不胜感激。

测试数据

<头>
节点 尾巴
1 4
2 8
3 6
4 7
5 2
6 9
7 1
8 5
8 6
9 3
9 7
class Graph():

    def __init__(self, graph):
        self.graph = graph
        self.node_list = []
    def add_node(self, node):
        self.node_list.append(node)


    def __repr__(self):
        return (f'_{self.graph} + {[node for node in self.node_list]} + {[node.head_list for node in self.node_list]}')

class Node():

    def __init__(self, head):
        self.head = head
        self.explored = False
        self.head_list = []
        self.tail_list = []
        self.leader = None
        self.finish_time = 0
    def __repr__(self):
        return f'{self.head}'
    def add_node_edge(self, Node, lst):
        if lst == 'head':
            self.head_list.extend([Node])
        else: 
            self.tail_list.extend([Node])

def DFS_loop(my_graph):
    global T
    global S
    T = 0 # number of nodes processed so far
    S = None # current source vertex

    for node in my_graph.node_list[::-1]:
        if node.explored == False:
            S = node
            DFS(my_graph, node, T, S)

def DFS(my_graph, i, T, S):

    i.explored = True
    i.leader = S.head

    for j in i.head_list:
        DFS(my_graph, j, T, S)
    T += 1
    i.finish_time = T

file1 = open('C:/Downloads/test_Data.txt', 'r')
Lines = file1.readlines()

my_graph = Graph('A')

default_node = Node(0)
my_graph.node_list = [default_node]*9
unexplored_queue = []

for line in Lines:
    h, t = line.strip().split()
    h = int(h)
    t = int(t)
    new_node = Node(h)
    new_head_node = Node(h)
    new_tail_node = Node(t)

    new_node.add_node_edge(new_tail_node, 'tail')
    new_tail_node.add_node_edge(new_node, 'head')

    if my_graph.node_list[h-1].head == 0:
        my_graph.node_list[h-1] = new_node
    else:
        my_graph.node_list[h-1].add_node_edge(new_tail_node, 'tail')

    if my_graph.node_list[t-1].head == 0:
        my_graph.node_list[t-1] = new_tail_node
    else:
        my_graph.node_list[t-1].add_node_edge(new_node, 'head')

DFS_loop(my_graph)
for node in my_graph.node_list:
    print(node, node.finish_time)```

2 个答案:

答案 0 :(得分:0)

在这段代码中:

new_node = Node(h)
new_head_node = Node(h)
new_tail_node = Node(t)

您假设图中不存在尾节点。这不是一个安全的假设。如果尾节点已经存在,则需要调整其链接,而不是分配新链接。

答案 1 :(得分:0)

感谢蒂姆让我更清楚地思考这个问题。在我的原始代码中,头和尾列表是节点对象的列表。但是如果你没有使用图中已有的节点,那么你就没有正确地包含所有的尾节点和头节点,更新节点的头和尾列表是一场噩梦。

我更新了代码以索引头部或尾部现在所指的图表中的位置。 node.head_listnode.tail_list 成为您使用 my_graph.node_list[node.head_list[0]]

调用的整数列表
    new_node = Node(h)
    new_tail_node = Node(t)

    if my_graph.node_list[h-1].head == 0:
        my_graph.node_list[h-1] = new_node
        my_graph.node_list[h-1].tail_list.append(t)
    else:
        my_graph.node_list[h-1].tail_list.append(t)

    if my_graph.node_list[t-1].head == 0:
        my_graph.node_list[t-1] = new_tail_node
        my_graph.node_list[t-1].head_list.append(h)
    else:
        my_graph.node_list[t-1].head_list.append(h)
相关问题