bfsearch

Поиск графика в ширину

Синтаксис

v = bfsearch(G,s)
T = bfsearch(G,s,events)
[T,E] = bfsearch(G,s,events)
[___] = bfsearch(___,'Restart',tf)

Описание

пример

v = bfsearch(G,s) применяет поиск в ширину, чтобы изобразить в виде графика G, запускающийся в узле s. Результатом является вектор идентификаторов узла в порядке их открытия.

пример

T = bfsearch(G,s,events) настраивает вывод поиска в ширину путем установки флага одного или нескольких поисковых событий. Например, T = bfsearch(G,s,'allevents') возвращает таблицу, содержащую все отмеченные события, и X = bfsearch(G,s,'edgetonew') возвращает матричный или массив ячеек краев.

[T,E] = bfsearch(G,s,events) дополнительно возвращает вектор граничных индексов E, когда events установлен в 'edgetonew', 'edgetodiscovered' или 'edgetofinished'. Граничные индексы для уникальной идентификации краев в мультиграфе.

пример

[___] = bfsearch(___,'Restart',tf), где tf является true, перезапускает поиск, если никакие новые узлы не достижимы от обнаруженных узлов. Можно использовать любую из комбинаций аргументов ввода или вывода в предыдущих синтаксисах. Эта опция гарантирует, что поиск в ширину достигает всех узлов и краев в графике, даже если они не достижимы от стартового узла, s.

Примеры

свернуть все

Создайте и постройте график.

s = [1 1 1 1 2 2 2 2 2];
t = [3 5 4 2 6 10 7 9 8];
G = graph(s,t);
plot(G)

Выполните поиск в ширину графика, запускающегося в узле 2. Результат указывает на порядок открытия узла.

v = bfsearch(G,2)
v = 10×1

     2
     1
     6
     7
     8
     9
    10
     3
     4
     5

Создайте и постройте график ориентированного графа.

s = [1 1 1 2 3 3 3 4 6];
t = [2 4 5 5 6 7 4 1 4];
G = digraph(s,t);
plot(G)

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

T = bfsearch(G,1,'allevents')
T=14×4 table
         Event          Node       Edge       EdgeIndex
    ________________    ____    __________    _________

    startnode             1     NaN    NaN       NaN   
    discovernode          1     NaN    NaN       NaN   
    edgetonew           NaN       1      2         1   
    discovernode          2     NaN    NaN       NaN   
    edgetonew           NaN       1      4         2   
    discovernode          4     NaN    NaN       NaN   
    edgetonew           NaN       1      5         3   
    discovernode          5     NaN    NaN       NaN   
    finishnode            1     NaN    NaN       NaN   
    edgetodiscovered    NaN       2      5         4   
    finishnode            2     NaN    NaN       NaN   
    edgetofinished      NaN       4      1         8   
    finishnode            4     NaN    NaN       NaN   
    finishnode            5     NaN    NaN       NaN   

Чтобы выполнить шаги в алгоритме, считайте события в таблице сверху донизу. Например:

  1. Алгоритм начинается в узле 1

  2. Край обнаружен между узлом 1 и узлом 2

  3. Узел 2 обнаружен

  4. и так далее...

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

Создайте и постройте график ориентированного графа. Этот график имеет два слабо связанных компонента.

s = [1 1 2 2 2 3 4 7 8 8 8 8];
t = [3 4 7 5 6 2 6 2 9 10 11 12];
G = digraph(s,t);
p = plot(G,'Layout','layered');

c = conncomp(G,'Type','weak')
c = 1×12

     1     1     1     1     1     1     1     2     2     2     2     2

Выполните поиск в ширину графика, запускающегося в узле 2, и отметьте 'edgetonew', 'edgetofinished' и события 'startnode'. Задайте Restart как true, чтобы сделать поисковый перезапуск каждый раз, когда там остаются узлы, которые не могут быть достигнуты.

events = {'edgetonew','edgetofinished','startnode'};
T = bfsearch(G,2,events,'Restart',true)
T=15×4 table
        Event         Node       Edge       EdgeIndex
    ______________    ____    __________    _________
    startnode           2     NaN    NaN       NaN   
    edgetonew         NaN       2      5         3   
    edgetonew         NaN       2      6         4   
    edgetonew         NaN       2      7         5   
    edgetofinished    NaN       7      2         8   
    startnode           1     NaN    NaN       NaN   
    edgetonew         NaN       1      3         1   
    edgetonew         NaN       1      4         2   
    edgetofinished    NaN       3      2         6   
    edgetofinished    NaN       4      6         7   
    startnode           8     NaN    NaN       NaN   
    edgetonew         NaN       8      9         9   
    edgetonew         NaN       8     10        10   
    edgetonew         NaN       8     11        11   
    edgetonew         NaN       8     12        12   

Когда Restart является true, событие 'startnode' возвращает информацию о том, где и когда алгоритм перезапускает поиск.

Подсветите график на основе события:

  • Окрасьте стартовые узлы в красный.

  • Зеленые края для 'edgetonew'

  • Черные края для 'edgetofinished'

highlight(p, 'Edges', T.EdgeIndex(T.Event == 'edgetonew'), 'EdgeColor', 'g')
highlight(p, 'Edges', T.EdgeIndex(T.Event == 'edgetofinished'), 'EdgeColor', 'k') 
highlight(p,T.Node(~isnan(T.Node)),'NodeColor','r')

Используйте поиск в ширину, чтобы решить, что график является двусторонним, и возвратите соответствующие разделы. Биграф является графиком, который имеет узлы, которые можно разделить на два набора, A и B, с каждым краем в графике, соединяющем узел в A к узлу в B.

Создайте и постройте график ориентированного графа.

s = [1 1 1 1 2 2 4 5 6 7 8];
t = [2 3 6 8 5 10 6 6 10 3 10];
g = digraph(s,t);
plot(g);

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

events = {'edgetonew', 'edgetodiscovered', 'edgetofinished'};
T = bfsearch(g, 1, events, 'Restart', true);
partitions = false(1, numnodes(g));
is_bipart = true;
is_edgetonew = T.Event == 'edgetonew';
ed = T.Edge;

for ii=1:size(T, 1)   
    if is_edgetonew(ii)
        partitions(ed(ii, 2)) = ~partitions(ed(ii, 1));
    else
        if partitions(ed(ii, 1)) == partitions(ed(ii, 2))
            is_bipart = false;
            break;
        end
    end
end
is_bipart
is_bipart = logical
   1

Поскольку g является двусторонним, переменная partitions содержит информацию, о котором разделе каждый узел принадлежит.

Постройте график биграфа с размещением 'layered', с помощью переменной partitions, чтобы задать исходные узлы, которые появляются в первом уровне.

partitions
partitions = 1x10 logical array

   0   1   1   0   0   1   0   1   0   0

plot(g, 'Layout', 'layered', 'Source', find(partitions));

Входные параметры

свернуть все

Входной график, заданный как объект граф или диграф. Используйте граф для создания неориентированного графа или диграф для создания ориентированного графа.

Пример: G = график (1,2)

Пример: G = digraph([1 2],[2 3])

Стартовый узел, заданный как одно из значений в этой таблице.

ЗначениеПример
Скалярный индекс узла1
Имя узла вектора символаA
Представьте скалярное имя узла в виде строкиA

Пример: bfsearch (G, 1)

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

  • Чтобы отметить единственные события, используйте имена флага.

  • Чтобы отметить подмножество событий, поставьте два или больше имени флага в массив ячеек или массив строк.

  • Чтобы отметить все события, используйте 'allevents'.

Примечание

В зависимости от значения events отличается вывод bfsearch. См. последний столбец в следующей таблице для получения информации о выводе, возвращенном каждой опцией.

Значение eventsОписаниеВывод
'discovernode' (значение по умолчанию)

Был обнаружен новый узел.

Возвратите вектор идентификаторов узла:

  • Если s является числовым индексом узла, то вектор содержит числовые индексы узла.

  • Если s является именем узла, то вектор является массивом ячеек, содержащим имена узла.

'finishnode'

Посетили все исходящие края от узла.

'startnode'

Этот флаг указывает на стартовый узел в поиске.

Если 'Restart' является true, то 'startnode' отмечает стартовый узел каждый раз поисковые перезапуски.

'edgetonew'

Край соединяется с неоткрытым узлом.

Возвратите матричный или массив ячеек размера N-by-2, который задает конечные узлы краев в графике:

  • Если s является числовым индексом узла, то матрица содержит числовые индексы узла.

  • Если s является именем узла, то матрица является массивом ячеек, содержащим имена узла.

Кроме того, можно задать второй вывод с [T,E] = bfsearch(…), который возвращает вектор граничных индексов E.

'edgetodiscovered'

Край соединяется с ранее обнаруженным узлом.

'edgetofinished'

Край соединяется с законченным узлом.

cellArray

Задайте два или больше флага в массиве ячеек, чтобы только отметить те события во время поиска.

Возвратите таблицу, T, который содержит переменные T.Event, T.Node, T.Edge и T.EdgeIndex:

  • T. Событие является категориальным вектором, содержащим флаги в порядке их возникновения.

  • T. Узел содержит идентификатор узла соответствующего узла для событий 'discovernode', 'finishnode', и 'startnode'.

  • T. Край содержит соответствующий край для событий 'edgetonew', 'edgetodiscovered', и 'edgetofinished'.

  • T. EdgeIndex содержит граничный индекс для событий 'edgetonew', 'edgetodiscovered', и 'edgetofinished'. Граничный индекс для уникальной идентификации повторных краев в мультиграфе.

  • Неиспользованные элементы T.Node и T.Edge установлены в NaN.

  • Если s является числовым индексом узла, то T.Node и T.Edge содержат числовые индексы узла.

  • Если s является именем узла, то T.Node и T.Edge являются массивами ячеек, содержащими имена узла.

'allevents'

Все события отмечаются.

Пример: v = bfsearch (G, 3) начинает поиск в третьем узле и возвращает вектор, v, содержа узлы в порядке открытия. Это совпадает с v = bfsearch (G, 3, 'discovernode').

Пример: X = bfsearch (G, 'edgetonew') начинается в узле под названием и возвращает массив ячеек, X, указывая на каждый из краев, который соединяется с неоткрытым узлом во время поиска.

Пример: T = bfsearch (G, s, {'discovernode', 'finishnode'}) возвращает таблицу, T, но только отмечает, когда новые узлы обнаружены или когда узел отмечен законченный.

Пример: T = bfsearch (G, s, 'allevents') отмечает все поисковые события и возвращает таблицу, T.

Типы данных: char | представляет в виде строки | ячейка

Переключитесь, чтобы перезапустить поиск, заданный как false (значение по умолчанию) или true. Эта опция полезна, если график содержит узлы, которые недостижимы от стартового узла. Если 'Restart' является true, то поиск перезапускает каждый раз, когда неоткрытые узлы остаются, что недостижимы от обнаруженных узлов. Новый узел запуска является узлом с самым маленьким индексом, который является все еще неоткрытым. Повторения процесса перезапуска до bfsearch обнаруживают все узлы.

'Restart' является false по умолчанию, так, чтобы поиск только посетил узлы, которые достижимы от стартового узла.

Когда 'Restart' является true, события 'discovernode' и 'finishnode' имеют место однажды для каждого узла в графике. Кроме того, каждый край в графике отмечается однажды 'edgetonew', 'edgetodiscovered' или 'edgetofinished'. Края, отмеченные 'edgetonew', формируют одно или несколько деревьев.

Пример: T = bfsearch (график ([1 3], [2 4]), 1, 'Перезапуск', верный), ищет оба из связанных компонентов в графике.

Типы данных: логический

Выходные аргументы

свернуть все

Идентификаторы узла, возвращенные в одном из следующих форматов:

  • При использовании числовой идентификатор узла, чтобы задать стартовый узел s, то v является числовым вектором - столбцом индексов узла.

  • Если s является вектором символа или строкой, содержащей имя узла, то v является вектором ячейки, содержащим имена узла.

Идентификаторы узла в v отражают порядок открытия поиском графика в ширину.

Результаты поиска, возвращенные в одном из следующих форматов:

  • Если events не задан или является 'discovernode', 'finishnode' или 'startnode', то T является вектором идентификаторов узла, подобных v.

  • Если events является 'edgetonew', 'edgetodiscovered' или 'edgetofinished', то T является матричным или массивом ячеек размера N-by-2 указание на входные и выходные узлы для каждого соответствующего края.

  • Если events является массивом ячеек поисковых событий или 'allevents', то T является таблицей, содержащей отмеченные поисковые события. Таблица содержит поисковые флаги события в T.Event, соответствующие идентификаторы узла в T.Node и соответствующие края в T.Edge и T.EdgeIndex.

Во всех случаях:

  • Порядок элементов или строки T указывают на их порядок возникновения во время поиска.

  • Если вы задаете s как числовой идентификатор узла, то T также относится к узлам с помощью их числовых идентификаторов.

  • Если вы задаете s как имя узла, то T также относится к узлам с помощью их имен.

Граничные индексы, возвращенные как вектор.

Задайте этот вывод, чтобы получить вектор граничных индексов для событий 'edgetonew', 'edgetodiscovered' или 'edgetofinished'. N-by-1 вектор граничных индексов соответствует T, который является матричным или массивом ячеек размера N-by-2 указание на входные и выходные узлы для каждого соответствующего края.

Пример: [T, E] = bfsearch (G, s, 'edgetonew')

Советы

  • dfsearch и bfsearch обрабатывают неориентированных графов то же самое как ориентированные графы. Неориентированное ребро между узлами s и t обработано как два ориентированных ребра, один от s до t и один от t до s.

Алгоритмы

Алгоритм Поиска в ширину начинается в стартовом узле, s, и осматривает все свои соседние узлы в порядке их индекса узла. Затем для каждого из тех соседей, это посещает их непосещаемых соседей по порядку. Алгоритм продолжается, пока все узлы, которые достижимы от стартового узла, не посетили.

В псевдокоде алгоритм может быть записан как:

Event startnode(S)
Event discovernode(S)
NodeList = {S}

WHILE NodeList is not empty

  C = NodeList{1}
  Remove first element from NodeList
  
  FOR edge E from outgoing edges of node C, connecting to node N
    Event edgetonew(C,E), edgetodiscovered(C,E) or edgetofinished(C,E)
    (depending on the state of node N)
    IF event was edgetonew
      Event discovernode(N)
      Append N to the end of NodeList
    END
  END

  Event finishnode(C)
END

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

Флаг событияОписание события
'discovernode'

Был обнаружен новый узел.

'finishnode'

Посетили все исходящие края от узла.

'startnode'

Этот флаг указывает на стартовый узел в поиске.

'edgetonew'

Край соединяется с неоткрытым узлом

'edgetodiscovered'

Край соединяется с ранее обнаруженным узлом

'edgetofinished'

Край соединяется с законченным узлом

Для получения дополнительной информации см. описание входного параметра для events.

Примечание

В случаях, где входной график содержит узлы, которые недостижимы от стартового узла, опция 'Restart' обеспечивает способ нанести поисковый визит каждый узел в графике. В этом случае событие 'startnode' указывает на стартовый узел каждый раз поисковые перезапуски.

Введенный в R2015b

Была ли эта тема полезной?