Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
nestudent.ru_46905.doc
Скачиваний:
22
Добавлен:
12.09.2019
Размер:
2.07 Mб
Скачать

Наименьшие остовные деревья

Если задана сеть с ценой связей, то наименьшим остовным деревом (minimal spanning tree) называется остовное дерево, в котором суммарная цена всех связей в дереве будет наименьшей. Наименьшее остовное дерево можно использовать, чтобы связать все узлы в сети путем с наименьшей ценой.

Например, предположим, что требуется разработать телефонную сеть, которая должна соединить шесть городов. Можно проложить магистральный кабель между всеми парами городов, но это будет неоправданно дорого. Меньшую стоимость будет иметь решение, при котором города будут соединены связями, которые содержатся в наименьшем остовном дереве. На рис. 12.5 показаны шесть городов, каждые два из которых соединены магистральным кабелем. Жирными линиями нарисовано наименьшее остовное дерево.

Заметьте, что сеть может иметь несколько наименьших остовных деревьев. На рис. 12.6 показаны два изображения сети с двумя различными наименьшими остовными деревьями, которые нарисованы жирными линиями. Полная цена обоих деревьев равна 32.

@Рис. 12.5. Магистральные телефонные кабели, связывающие шесть городов

========320

@Рис. 12.6. Два различных наименьших остовных дерева для одной сети

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

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

Подобные алгоритмы, которые находят глобальный оптимум, при помощи серии локально оптимальных приближений называются поглощающими алгоритмами(greedy algorithms). Можно представлять себе поглощающие алгоритмы как алгоритмы типа восхождения на холм, не являющиеся при этом эвристиками — они гарантированно находят наилучшее возможное решение.

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

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

Алгоритм использует флаг Used в классе link, чтобы определить, попадала ли эта связь ранее в список возможных связей. Если да, то она не заносится в этот список снова.

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

=========321

Private Sub FindSpanningTree(root As SpanNode)

Dim candidates As New Collection

Dim to_node As SpanNode

Dim link As SpanLink

Dim i As Integer

Dim best_i As Integer

Dim best_cost As Integer

Dim best_to_node As SpanNode

If root Is Nothing Then Exit Sub

' Сбросить флаг Marked для всех узлов и флаги

' Used и InSpanningTree для всех связей.

ResetSpanningTree

' Начать с корня остовного дерева.

root.Marked = True

Set best_to_node = root

Do

' Добавить связи последнего узла в список

' возможных связей.

For Each link In best_to_node.Links

If Not link.Used Then

candidates.Add link

link.Used = True

End If

Next link

' Найти самую короткую связь в списке возможных

' связей, которая ведет к узлу, которого еще нет

' в дереве.

best_i = 0

best_cost = INFINITY

i = 1

Do While i <= candidates.Count

Set link = candidates(i)

If link.Node1.Marked Then

Set to_node = link.Node2

Else

Set to_node = link.Node1

End If

If to_node.Marked Then

' Связь соединяет два узла, которые

' оба находятся в дереве.

' Удалить ее из списка возможных связей.

candidates.Remove i

Else

If link.Cost < best_cost Then

best_i = i

best_cost = link.Cost

Set best_to_node = to_node

End If

i = i + 1

End If

Loop

' Если больше не осталось связей, которые можно

' было бы добавить, то мы сделали все, что могли.

If best_i < 1 Then Exit Do

' Добавить наилучшую связь и узел на ее конце в дерево.

Set link = candidates(best_i)

link.InSpanningTree = True

candidates.Remove best_i

best_to_node.Marked = True

Loop

GotSpanningTree = True

' Перерисовать сеть.

DrawNetwork

End Sub

Этот алгоритм проверяет каждую связь не более одного раза. При проверке каждой связи, она добавляется в список возможных связей, а затем удаляется из него. Если этот список находится в приоритетной очереди на основе пирамид, то для вставки или удаления элемента из очереди потребуется время порядка O(log(N)), где — число связей в сети. В этом случае полное время выполнения алгоритма будет порядка O(N * log(N)).

Если список возможных связей находится в коллекции, как в вышеприведенном коде, то для поиска в списке связи с наименьшей ценой потребуется время порядка O(N), при этом полное время выполнения алгоритма будет порядка O(N2). Для малых N производительность будет приемлемой. Если же число связей в сети достаточно велико, то список возможных связей следует хранить в приоритетной очереди, а не в коллекции.

Программа Span использует этот алгоритм для поиска наименьшего остовного дерева. Эта программа аналогична программе NetEdit. Она позволяет загружать, редактировать и сохранять на диске файлы, представляющие сеть. Если выбрать какой‑либо узел в программе двойным щелчком мыши, то программа найдет и выведет на экран наименьшее остовное дерево с корнем в этом узле. На рис. 12.7 показано окно программы Span, в котором показано наименьшее остовное дерево с корнем в узле 9.

======322-323

@Рис. 12.7. Программа Span

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