exponenta event banner

dfsearch

Поиск по графу с первой глубиной

Описание

пример

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

пример

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

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

пример

[___] = dfsearch(___,'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.

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

v = dfsearch(G,7)
v = 10×1

     7
     2
     1
     3
     4
     5
     6
     8
     9
    10

Создание и печать направленного графика.

A = [0 1 0 1 1 0 0; 
     0 0 0 0 0 0 0; 
     0 0 0 1 0 1 1;
     0 0 0 0 0 1 0; 
     0 0 0 0 0 0 0; 
     0 0 0 0 0 0 0; 
     0 0 0 0 0 0 0];
G = digraph(A);
plot(G)

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

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

T = dfsearch(G,3,'allevents')
T=13×4 table
        Event         Node       Edge       EdgeIndex
    ______________    ____    __________    _________

    startnode           3     NaN    NaN       NaN   
    discovernode        3     NaN    NaN       NaN   
    edgetonew         NaN       3      4         4   
    discovernode        4     NaN    NaN       NaN   
    edgetonew         NaN       4      6         7   
    discovernode        6     NaN    NaN       NaN   
    finishnode          6     NaN    NaN       NaN   
    finishnode          4     NaN    NaN       NaN   
    edgetofinished    NaN       3      6         5   
    edgetonew         NaN       3      7         6   
    discovernode        7     NaN    NaN       NaN   
    finishnode          7     NaN    NaN       NaN   
    finishnode          3     NaN    NaN       NaN   

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

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

  2. Обнаружен край между узлом 3 и узлом 4

  3. Обнаружен узел 4

  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

Выполните поиск по глубине графика, начиная с узла 4, и отметьте 'edgetonew', 'edgetodiscovered', 'edgetofinished', и 'startnode' события. Определить Restart как true для перезапуска поиска при наличии оставшихся узлов, доступ к которым невозможен.

events = {'edgetonew','edgetodiscovered','edgetofinished','startnode'};
T = dfsearch(G,4,events,'Restart',true)
T=15×4 table
         Event          Node       Edge       EdgeIndex
    ________________    ____    __________    _________

    startnode             4     NaN    NaN       NaN   
    edgetonew           NaN       4      6         7   
    startnode             1     NaN    NaN       NaN   
    edgetonew           NaN       1      3         1   
    edgetonew           NaN       3      2         6   
    edgetonew           NaN       2      5         3   
    edgetofinished      NaN       2      6         4   
    edgetonew           NaN       2      7         5   
    edgetodiscovered    NaN       7      2         8   
    edgetofinished      NaN       1      4         2   
    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'

  • Пурпурные кромки предназначены для 'edgetodiscovered'

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

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

Сделайте направленный граф ациклическим, обратив некоторые его рёбра.

Создание и печать направленного графика.

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

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

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

[e,edge_indices] = dfsearch(g, 1, 'edgetodiscovered', 'Restart', true)
e = 3×2

     3     1
     6     4
     8     7

edge_indices = 3×1

     3
     9
    11

Использовать flipedge чтобы изменить направление помеченных кромок на противоположное, чтобы они больше не завершали цикл. Это удаляет все циклы из графика. Использовать isdag чтобы подтвердить, что граф является ациклическим.

gnew = flipedge(g, edge_indices);
isdag(gnew)
ans = logical
   1

Постройте график и выделите перевернутые кромки.

p = plot(gnew, 'Layout', 'force');
highlight(p,'Edges',findedge(gnew,e(:,2),e(:,1)),'EdgeColor','r')

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"

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

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

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

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

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

Примечание

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

Значение eventsОписаниеПродукция
'discovernode' (по умолчанию)

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

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

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

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

'finishnode'

Все исходящие границы узла посещены.

'startnode'

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

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

'edgetonew'

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

Возврат матрицы или массива ячеек размером Nоколо-2 задающий конечные узлы рёбер на графике:

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

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

Кроме того, можно указать второй вывод с помощью [T,E] = dfsearch(…) который возвращает вектор граничных индексов 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 = dfsearch(G,3) начинает поиск в третьем узле и возвращает вектор, v, содержащий узлы в порядке обнаружения. Это то же самое, что и v = dfsearch(G,3,'discovernode').

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

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

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

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

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

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

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

Пример: T = dfsearch(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] = dfsearch(G,s,'edgetonew')

Совет

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

Алгоритмы

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

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

Event startnode(S)
Call DFS(S)

function DFS(C)

  Event discovernode(C)
  
  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
      Call DFS(N)
    END
  END

Event finishnode(C)  

END

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

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

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

'finishnode'

Все исходящие границы узла посещены.

'startnode'

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

'edgetonew'

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

'edgetodiscovered'

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

'edgetofinished'

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

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

Примечание

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

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