#python #linked-list #breadth-first-search
#питон #связанный список #широта-первый-поиск
Вопрос:
Я пытаюсь вывести дерево BFS, используя связанный список. Однако у меня возникли проблемы с реализацией алгоритма. Я застрял на том, как внедрить график связанного списка в алгоритм. Я не слишком уверен, как я могу создать матрицу массива false и true, а затем выполнить итерацию по ней, чтобы найти ложные узлы в соответствии с выбранным дочерним узлом. Вывод, который я должен получать, таков
0: 1 3 1: 2 4 3: 4:
Код:
class Node: def __init__(self, value): self.vertex = value self.next = None class AdjGraph: def __init__(self, data): self.data = data self.graph = [None] * self.data # Add edges def addEdge(self, vertice, edge): currNode = self.graph[vertice] newNode = Node(edge) if currNode == None: self.graph[vertice] = newNode return while currNode != None: if currNode.next == None: currNode.next = newNode break currNode = currNode.next # Implement BFS Graph def bfs(self, s): # Set discovered[s] = true, discovered[v] = false for all other v discovered = [False] * self.graph discovered[s] = True # Intialize L[0] to consist of the single element s layer = [] layer.append(s) # Set the counter i = 0 i = 0 # Set the current BFS tree T = None T = None # While L[i] is not empty while layer: # Initialize an empty list L[i 1] empty_list = layer[i 1] print (s, end = " ") # For each node u is an element of L[i] for u in layer[i]: # Consider each edge (u, v) incident to u if discovered[v] == False: # Set discovered[v] = true discovered[v] = True # Add edge (u, v) to the tree T T.append # Add v to the list L[i 1] empty_list.append(v) # Print the graph def printGraph(self): adj_list = "Adjacency List" for i in range(self.data): adj_list = "nnNode " str(i) ": " temp = self.graph[i] while temp: adj_list = str(temp.vertex) " " temp = temp.next print(adj_list) g = AdjGraph(5) g.addEdge(0, 1) g.addEdge(0, 3) g.addEdge(1, 0) g.addEdge(1, 2) g.addEdge(1, 3) g.addEdge(1, 4) g.addEdge(2, 1) g.addEdge(2, 4) g.addEdge(3, 0) g.addEdge(3, 1) g.addEdge(3, 4) g.addEdge(4, 1) g.addEdge(4, 2) g.addEdge(4, 3) g.bfs(0)
Комментарии:
1. Вы можете исправить вмятину? У вас есть неиндентированные функции, которые, возможно, предназначены в качестве методов?
2. Какова цель связанных списков? Я этого не вижу.
3. Извините за то, что я новичок в программировании и на этом сайте. Цель связанного списка-создать список смежности. Связанный список, добавляющий ребро к каждому узлу. Затем создайте дерево BFS из списка смежности.
4. Что такое
v
? Это нигде не определено?5. Существует ли какое-либо требование в порядке , в котором алгоритм BFS посещает узлы? Я имею в виду, важен ли порядок, в котором добавляются ребра
addEdge
, с точки зрения результата?
Ответ №1:
В вашем bfs
коде много проблем. Я не буду перечислять их все, но:
[False] * self.graph
не имеет смысла, так какself.graph
это не числоlayer[i 1]
не существует при первой оценкеfor u in layer[i]
не работает какlayer[i]
номер узла (s
) и не подлежит повторениюempty_list
получает значения, но они никогда не используются.T.append
ничего не делает.- Хотя есть попытка ввести данные
T
, они никогда не используются. - Значение
i
никогда не меняется. bfs
изменяет только локальные переменные и ничего не возвращает. Таким образом, после того, как он был вызван, нет ничего, что отличалось бы от того, что было до его вызова, за исключением номеров узлов, которые печатаются. Но я полагаю, что это было сделано только для целей отладки, так как оно не соответствует формату вывода.
Как я упоминал в комментариях, поскольку ожидаемый результат соответствует дереву поиска, которое формируется с помощью поиска по ширине (BFS), результат может отличаться в зависимости от порядка добавления узлов и порядка посещения узлов.
Пример графика выглядит следующим образом:
0-----1 /| / | 3--4--2
BFS, который начинается в узле 0, может создать любое из этих деревьев поиска:
0-----1 0-----1 | | 3 4 2 3--4 2
Это зависит от порядка, в котором развернуты узлы 1 и 3. Первое дерево является результатом, когда узел 1 расширяется первым, в то время как второе дерево является результатом, когда узел 3 расширяется первым.
Теперь, поскольку вы хотите работать со связанными списками, я должен также упомянуть, что добавление узла в связанный список более эффективно выполняется в начале списка, чем в конце (если вы также не поддерживаете хвостовую ссылку). Поэтому я бы предложил не currNode
использовать цикл, а добавить новый узел в начале списка. Таким образом, петли не будет. Это, конечно, влияет на порядок узлов, которые оказываются в списке.
Следующий код удалит из графика ребра, которые не используются в дереве BFS. Таким образом, вы можете использовать свою printGraph
функцию для вывода результата.
Код:
class Node: def __init__(self, value, nxt=None): self.vertex = value self.next = nxt class AdjGraph: def __init__(self, size): self.size = size self.graph = [None] * self.size def addEdge(self, vertex, edge): # Prepend the new node to the linked list self.graph[vertex] = Node(edge, self.graph[vertex]) def bfs(self, s): discovered = [False] * self.size discovered[s] = True layer = [s] while layer: empty_list = [] for u in layer: keep = None # this will be the new (filtered) list for self.graph[u] v = self.graph[u] while v: nxt = v.next if not discovered[v.vertex]: discovered[v.vertex] = True empty_list.append(v.vertex) # Prepend v to the keep linked list v.next = keep keep = v v = nxt self.graph[u] = keep layer = empty_list # start working with the next layer def printGraph(self): adj_list = "Adjacency List" for i in range(self.size): adj_list = "nNode " str(i) ": " temp = self.graph[i] while temp: adj_list = str(temp.vertex) " " temp = temp.next print(adj_list) g = AdjGraph(5) g.addEdge(0, 1) g.addEdge(0, 3) g.addEdge(1, 0) g.addEdge(1, 2) g.addEdge(1, 3) g.addEdge(1, 4) g.addEdge(2, 1) g.addEdge(2, 4) g.addEdge(3, 0) g.addEdge(3, 1) g.addEdge(3, 4) g.addEdge(4, 1) g.addEdge(4, 2) g.addEdge(4, 3) g.bfs(0) g.printGraph()
Выход:
Adjacency List Node 0: 1 3 Node 1: 2 Node 2: Node 3: 4 Node 4:
Комментарии:
1. Большое вам спасибо за всю информацию. Я многому научился и вижу все свои ошибки.