bfsearch

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

Описание

пример

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)

Figure contains an axes. The axes contains an object of type graphplot.

Выполните поиск в ширину графика, запускающегося в узле 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)

Figure contains an axes. The axes contains an object of type graphplot.

Выполните поиск в ширину на графике, запускающемся в узле 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');

Figure contains an axes. The axes contains an object of type graphplot.

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')

Figure contains an axes. The axes contains an object of type graphplot.

Используйте поиск в ширину, чтобы решить, что график является двусторонним, и возвратите соответствующие разделы. Биграф является графиком, который имеет узлы, которые можно разделить на два набора, 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);

Figure contains an axes. The axes contains an object of type graphplot.

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

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));

Figure contains an axes. The axes contains an object of type graphplot.

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

свернуть все

Введите график в виде любого graph или digraph объект. Используйте graph создать неориентированного графа или digraph создать ориентированного графа.

Пример: G = graph(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- 2 это задает конечные узлы ребер в графике:

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

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

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

'edgetodiscovered'

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

'edgetofinished'

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

cellArray

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

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

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

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

  • T.Edge содержит соответствующее ребро для событий '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,'A','edgetonew') начинается в узле под названием 'A' и возвращает массив ячеек, X, указание на каждое из ребер, которое соединяется с неоткрытым узлом во время поиска.

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

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

Типы данных: char | string | cell

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

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

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

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

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

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

свернуть все

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

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

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

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

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

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

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

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

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

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

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

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

Индексы ребра, возвращенные как вектор.

Задайте этот выход, чтобы получить вектор из индексов ребра для событий 'edgetonew', 'edgetodiscovered', или 'edgetofinished'то- 1 вектор из индексов ребра соответствует T, который является матричным или массивом ячеек размера N- 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
Для просмотра документации необходимо авторизоваться на сайте