exponenta event banner

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'

Edge подключается к ранее обнаруженному узлу.

'edgetofinished'

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

массив ячеек

Укажите два или более флага в массиве ячеек, чтобы отмечать только эти события во время поиска.

Возврат таблицы, 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) выполняет поиск обоих связанных компонентов на графике.

Типы данных: logical

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

свернуть все

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

  • Если для указания начального узла используется числовой идентификатор узла 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'. Nоколо-1 вектор граничных индексов соответствует T, который является матрицей или массивом ячеек размера Nоколо-2 указание исходного и целевого узлов для каждого соответствующего края.

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

Совет

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

Алгоритмы

Алгоритм поиска Breadth-First начинается с начального узла, 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'

Edge подключается к ранее обнаруженному узлу

'edgetofinished'

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

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

Примечание

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

Представлен в R2015b