МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования

    Это представление достаточно наглядно, поэтому оно используется далее в

    этой главе.

    =======315

    Используя это представление, программа NetEdit позволяет оперировать

    неориентированными сетями с ценой связей. Меню File (Файл) позволяет

    загружать и сохранять сети в файлах. Команды в меню Edit (Правка) позволяют

    вам вставлять и удалять узлы и связи. На рис. 12.3 показано окно программы

    NetEdit.

    Директория OldSrc\Ch12 содержит программы, которые используют представление

    нумерацией связей. Эти программы немного сложнее понять, но они обычно

    работают быстрее. Они не описаны в тексте, но использованные в них методы

    похожи на те, которые применялись в программах, написанных для 4 версии

    Visual Basic. Например, обе программы Src\Ch12\Paths и OldSrc\Ch12\Paths

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

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

    использует коллекции и классы, а вторая — псевдоуказатели и представление

    нумерацией связей.

    Оперирование узлами и связями

    Корень дерева — это единственный узел, не имеющий родителя. Можно найти

    любой узел в сети, начав от корня и следуя по указателям на дочерние узлы.

    Таким образом, узел представляет основание дерева. Если ввести переменную,

    которая будет содержать указатель на корневой узел, то впоследствии можно

    будет получить доступ ко всем узлам в дереве.

    Сети не всегда содержат узел, который занимает такое особое положение. В

    несвязной сети может не существовать способа обойти все узлы по связям,

    начав с одного узла.

    Поэтому программы, работающие с сетями, обычно содержат полный список всех

    узлов в сети. Программа также может хранить полный список всех связей. При

    помощи этих списков можно легко выполнить какие-либо действия над всеми

    узлами или связями в сети. Например, если программа хранит указатели на

    узлы и связи в коллекциях Nodes и Links, она может вывести сеть на экран

    при помощи следующего метода:

    @Рис. 12.3. Программа NetEdit

    =======316

    Dim node As NetworkNode

    dim link As NetworkLink

    For Each link in links

    ' Нарисовать связь.

    :

    Next link

    For Each node in nodes

    ' Нарисовать узел.

    :

    Next node

    Программа NetEdit использует коллекции Nodes и Links для вывода сетей на

    экран.

    Обходы сети

    Обход сети выполняется аналогично обходу дерева. Можно обходить сеть,

    используя либо обход в глубину, либо обход в ширину. Обход в ширину обычно

    похож на прямой обход дерева, хотя для сетей можно определить также

    обратный и даже симметричный обход.

    Алгоритм для выполнения прямого обхода двоичного дерева, описанный в 6

    главе, формулируется так:

    Обратиться к узлу.

    Выполнить рекурсивный прямой обход левого поддерева.

    Выполнить рекурсивный прямой обход правого поддерева.

    В дереве между связанными между собой узлами существует отношение родитель-

    потомок. Так как алгоритм начинается с корневого узла и всегда выполняется

    сверху вниз, он не обращается дважды ни к одному узлу.

    В сети узлы не обязательно связаны в направлении сверху вниз. Если

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

    бесконечный цикл.

    Чтобы избежать этого, алгоритм должен помечать узел после обращения к нему,

    при этом при поиске в соседних узлах, обращение происходит только к узлам,

    которые еще не были помечены. После того, как алгоритм завершит работу, все

    узлы в сети будут помечены (если сеть является связной). Алгоритм прямого

    обхода сети формулируется так:

    Пометить узел.

    Обратиться к узлу.

    3. Выполнить рекурсивный обход не помеченных соседних узлов.

    ========317

    В Visual Basic можно добавить флаг Marked к классу NetworkNode.

    Public Id As Long

    Public Marked As Boolean

    Public Links As Collection

    Класс NetworkNode может включать открытую процедуру для обхода сети,

    начиная с этого узла. Процедура узла PreorderPrint обращается ко всем

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

    связной, то при таком обходе произойдет обращение ко всем узлам сети.

    Public Sub PreorderPrint()

    Dim link As NoworkLink

    Dim node As NetworkNode

    ' Пометить узел.

    Marked = True

    ' Обратиться к непомеченным узлам.

    For Each link In Links

    ' Найти соседний узел.

    If link.Node1 Is Me Then

    Set node = link.Node2

    Else

    Set node = link.Node1

    End If

    ' Определить, требуется ли обращение к соседнему узлу.

    If Not node.Marked Then node.PreorderPrint

    Next link

    End Sub

    Так как эта процедура не обращается ни к одному узлу дважды, то коллекция

    обходимых связей не содержит циклов и образует дерево.

    Если сеть является связной, то дерево будет обходить все узлы сети. Так как

    это дерево охватывает все узлы сети, то оно называется остовным деревом

    (spanning tree). На рис. 12.4 показана небольшая сеть с остовным деревом с

    корнем в узле A, которое изображено жирными линиями.

    Можно использовать похожий подход с пометкой узлов для преобразования

    обхода дерева в ширину в сетевой алгоритм. Алгоритм обхода дерева

    начинается с помещения корневого узла в очередь. Затем первый узел

    удаляется из очереди, происходит обращение к узлу, и затем в конце очереди

    помещаются его дочерние узлы. Затем этот процесс повторяется до тех пор,

    пока очередь не опустеет.

    ======318

    @Рис. 12.4. Остовное дерево

    В алгоритме обхода сети нужно вначале убедиться, что узел не проверялся

    раньше или он уже не находится в очереди. Для этого мы помечаем каждый

    узел, который помещается в очередь. Сетевая версия этого алгоритма выглядит

    так:

    1. Пометить первый узел (который будет корнем остовного дерева) и добавить

    его в конец очереди.

    2. Повторять следующие шаги до тех пор, пока очередь не опустеет:

    a) Удалить из очереди первый узел и обратиться к нему.

    b) Для каждого из непомеченных соседних узлов, пометить его и добавить в

    конец очереди.

    Следующая процедура печатает список узлов сети в порядке обхода в ширину:

    Public Sub BreadthFirstPrint(root As NetworkNode)

    Dim queue As New Collection

    Dim node As NetworkNode

    Dim neighbor As NetworkNode

    Dim link As NetworkLink

    ' Поместить корень в очередь.

    root.Marked = True

    queue.Add root

    ' Многократно помещать верхний элемент в очередь

    ' пока очередь не опустеет.

    Do While queue.Count > 0

    ' Выбрать следующий узел из очереди.

    Set node = queue.Item(1)

    queue.Remove 1

    ' Обратиться к узлу.

    Print node.Id

    ' Добавить в очередь все непомеченные соседние узлы.

    For Each link In node.Links

    ' Найти соседний узел.

    If link.Node1 Is Me Then

    Set neighbor = link.Node2

    Else

    Set neighbor = link.Node1

    End If

    ' Проверить, нужно ли обращение к соседнему узлу.

    If Not neighbor.Marked Then queue.Add neighbor

    Next link

    Loop

    End Sub

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

    Если задана сеть с ценой связей, то наименьшим остовным деревом (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 0

    ' Найти ближайший к корню узел-кандидат.

    best_dist = INFINITY

    For i = 1 To candidates.Count

    new_dist = candidates(i).Dist

    If new_dist < best_dist Then

    best_i = i

    best_dist = new_dist

    End If

    Next i

    ' Добавить узел к дерева кратчайшего маршрута.

    Set node = candidates(best_i)

    candidates.Remove best_i

    node.NodeStatus = WAS_IN_LIST

    ' Проверить соседние узлы.

    For Each link In node.Links

    If node Is link.Node1 Then

    Set to_node = link.Node2

    Else

    Set to_node = link.Node1

    End If

    If to_node.NodeStatus = NOT_IN_LIST Then

    ' Узел раньше не был в списке возможных

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

    candidates.Add to_node

    to_node.NodeStatus = NOW_IN_LIST

    to_node.Dist = best_dist + link.Cost

    Set to_node.InLink = link

    ElseIf to_node.NodeStatus = NOW_IN_LIST Then

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

    ' Обновить значения его полей Dist и inlink,

    ' если это необходимо.

    new_dist = best_dist + link.Cost

    If new_dist < to_node.Dist Then

    to_node.Dist = new_dist

    Set to_node.InLink = link

    End If

    End If

    Next link

    Loop

    GotPathTree = True

    ' Пометить входящие узлы, чтобы их было проще вывести на экран.

    For Each node In Nodes

    If Not (node.InLink Is Nothing) Then _

    node.InLink.InPathTree = True

    Next node

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

    DrawNetwork

    End Sub

    Важно, чтобы алгоритм обновлял поля InLink и Dist только для узлов, в

    которых поле NodeStatus равно NOW_IN_LIST. Для большинства сетей нельзя

    получить более короткий путь, добавляя узлы, которые не находятся в списке

    возможных узлов. Тем не менее, если сеть содержит цикл, полная длина

    которого отрицательна, алгоритм может обнаружить, что можно уменьшить

    расстояние до некоторых узлов, которые уже находятся в дереве кратчайшего

    маршрута, при этом две ветви дерева кратчайшего маршрута окажутся

    связанными друг с другом, так что оно перестанет быть деревом.

    На рис. 12.10 показана сеть с циклом отрицательной цены и «дерево»

    кратчайшего маршрута, которое получилось бы, если бы алгоритм обновлял цену

    узлов, которые уже находятся в дереве.

    =======329

    @Рис. 12.10. Неправильное «дерево» кратчайшего маршрута для сети с циклом

    отрицательной цены

    Программа PathS использует этот алгоритм установки меток для вычисления

    кратчайшего маршрута. Она аналогична программам NetEdit и Span. Если вы не

    вставляете или не удаляете узел или связь, то можно выбрать узел при помощи

    мыши и программа при этом найдет и выведет на экран дерево кратчайшего

    маршрута с корнем в этом узле. На рис. 12.11 показано окно программы PathS

    с деревом кратчайшего маршрута с корнем в узле 3.

    @Рис. 12.11. Дерево кратчайшего маршрута с корнем в узле 3

    =======330

    Варианты метода установки меток

    Узкое место этого алгоритма заключается в поиске узла с наименьшим

    значением поля Dist в списке возможных узлов. Некоторые варианты этого

    алгоритма используют другие структуры данных для хранения списка возможных

    узлов. Например, можно было бы использовать упорядоченный связный список.

    При использовании этого метода потребуется только один шаг для того, чтобы

    найти следующий узел, который будет добавлен к дереву кратчайшего маршрута.

    Этот список будет всегда упорядоченным, поэтому узел на вершине списка

    всегда будет искомым узлом.

    Это облегчит поиск нужного узла в списке, но усложнит добавление узла в

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

    поместить в нужную позицию.

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

    добавления узла в дерево кратчайшего маршрута уменьшилось кратчайшее

    расстояние до другого узла, который уже был в списке, то нужно переместить

    этот элемент ближе к вершине списка.

    Предыдущий алгоритм и этот его новый вариант представляют собой два крайних

    случая управления списком возможных узлов. Первый алгоритм совсем не

    упорядочивает список и тратит достаточно много времени на поиск узлов в

    сети. Второй тратит много времени на поддержание упорядоченности списка, но

    может очень быстро выбирать из него узлы. Другие варианты используют

    промежуточные стратегии.

    Например, можно использовать для хранения списка возможных узлов

    приоритетную очередь на основе пирамид, тогда можно будет просто выбрать

    следующий узел с вершины пирамиды. Вставка нового узла в пирамиду и ее

    переупорядочение будет выполняться быстрее, чем аналогичные операции для

    упорядоченного связного списка. Другие стратегии используют сложные схемы

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

    Некоторые из этих вариантов достаточно сложны. Из-за этой их сложности эти

    алгоритмы для небольших сетей часто выполняются медленнее, чем более

    простые алгоритмы. Тем не менее, для очень больших сетей или сетей, в

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

    этих алгоритмов может стоить дополнительного усложнения.

    Коррекция меток

    Как и алгоритм установки меток, этот алгоритм начинает с обнуления значения

    поля Dist корневого узла и помещает корневой узел в список возможных узлов.

    При этом значения полей Dist остальных узлов устанавливаются равными

    бесконечности. Затем для вставки в дерево кратчайшего маршрута выбирается

    Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.