Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Структуры данных.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.58 Mб
Скачать

Неформальное описание[править | править вики-текст]

  1. Поместить узел, с которого начинается поиск, в изначально пустую очередь.

  2. Извлечь из начала очереди узел   и пометить его как развёрнутый.

    • Если узел   является целевым узлом, то завершить поиск с результатом «успех».

    • В противном случае, в конец очереди добавляются все преемники узла  , которые ещё не развёрнуты и не находятся в очереди.

  3. Если очередь пуста, то все узлы связного графа были просмотрены, следовательно, целевой узел недостижим из начального; завершить поиск с результатом «неудача».

  4. Вернуться к п. 2.

Формальное описание[править | править вики-текст]

Ниже приведён псевдокод алгоритма для случая, когда необходимо лишь найти целевой узел. В зависимости от конкретного применения алгоритма, может потребоваться дополнительный код, обеспечивающий сохранение нужной информации (расстояние от начального узла, узел-родитель и т. п.)

Рекурсивная формулировка:

BFS(start_node, goal_node) {

return BFS'({start_node}, ∅, goal_node);

}

BFS'(fringe, visited, goal_node) {

if(fringe == ∅) {

// Целевой узел не найден

return false;

}

if (goal_nodefringe) {

return true;

}

return BFS'({child | xfringe, child ∈ expand(x)} \ visited, visitedfringe, goal_node);

}

Итеративная формулировка:

BFS(start_node, goal_node) {

for(all nodes i) visited[i] = false; // изначально список посещённых узлов пуст

queue.push(start_node); // начиная с узла-источника

visited[start_node] = true;

while(! queue.empty() ) { // пока очередь не пуста

node = queue.pop(); // извлечь первый элемент в очереди

if(node == goal_node) {

return true; // проверить, не является ли текущий узел целевым

}

foreach(child in expand(node)) { // все преемники текущего узла, ...

if(visited[child] == false) { // ... которые ещё не были посещены ...

queue.push(child); // ... добавить в конец очереди...

visited[child] = true; // ... и пометить как посещённые

}

}

}

return false; // Целевой узел недостижим

}

Свойства[править | править вики-текст]

Обозначим число вершин и рёбер в графе как   и   соответственно.

Пространственная сложность[править | править вики-текст]

Так как в памяти хранятся все развёрнутые узлы, пространственная сложность алгоритма составляет  [1].

Алгоритм поиска с итеративным углублением похож на поиск в ширину тем, что при каждой итерации перед переходом на следующий уровень исследуется полный уровень новых узлов, но требует значительно меньше памяти.

Временная сложность[править | править вики-текст]

Так как в худшем случае алгоритм посещает все узлы графа, при хранении графа в виде списков смежностивременная сложность алгоритма составляет  [1][2].

Полнота[править | править вики-текст]

Если у каждого узла имеется конечное число преемников, алгоритм является полным: если решение существует, алгоритм поиска в ширину его находит, независимо от того, является ли граф конечным. Однако если решения не существует, на бесконечном графе поиск не завершается.

Оптимальность[править | править вики-текст]

Если длины рёбер графа равны между собой, поиск в ширину является оптимальным, то есть всегда находит кратчайший путь. В случае взвешенного графа поиск в ширину находит путь, содержащий минимальное количество рёбер, но не обязательно кратчайший.

Поиск по критерию стоимости является обобщением поиска в ширину и оптимален на взвешенном графе с неотрицательными весами рёбер. Алгоритм посещает узлы графа в порядке возрастания стоимости пути из начального узла и обычно использует очередь с приоритетами.

    Поиск в глубину (алгоритм, классификация ребер, поиск циклов, время работы)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]