allcycles

Найти все циклы в графике

Описание

пример

cycles = allcycles(G) возвращает все циклы в заданном графике. Область выхода cycles - массив ячеек, где содержимое каждой камеры cycles{k} приводит список узлов, образующих цикл.

пример

[cycles,edgecycles] = allcycles(G) также возвращает ребра в каждом цикле. Область выхода edgecycles - массив ячеек, где edgecycles{k} приводит ребра в соответствующем цикле, cycles{k}.

пример

[___] = allcycles(G,Name,Value) задает дополнительные опции, используя один или несколько аргументов имя-значение. Можно использовать любой выходной аргумент, комбинации в предыдущих синтаксисах. Для примера можно задать MaxNumCycles и скаляром для ограничения количества возвращаемых циклов.

Примеры

свернуть все

Создайте ориентированный граф с девятью узлами. Постройте график.

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

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

Вычислите все циклы в графике.

cycles = allcycles(G)
cycles=5×1 cell array
    {[    1 2 3 6 5 4]}
    {[1 2 3 6 9 8 5 4]}
    {[1 2 3 6 9 8 7 4]}
    {[        2 3 6 5]}
    {[    2 3 6 9 8 5]}

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

Создайте ориентированный мультиграфик с восемью узлами и 18 ребрами. Задайте имена для узлов. Постройте график с маркированными узлами и ребрами.

s = [1 1 2 2 3 3 2 2 4 6 8 6 6 7 3 3 5 3];
t = [2 3 1 3 2 1 4 4 6 2 6 7 8 8 5 5 7 7];
names = {'A','B','C','D','E','F','G','H'};
G = digraph(s,t,[],names);
p = plot(G,'EdgeLabel',1:numedges(G));

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

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

[cycles,edgecycles] = allcycles(G);

Просмотрите узлы и ребра в пятом цикле.

cycles{5}
ans = 1x7 cell
    {'A'}    {'C'}    {'E'}    {'G'}    {'H'}    {'F'}    {'B'}

edgecycles{5}
ans = 1×7

     2     9    13    17    18    14     3

Выделите узлы и ребра в пятом цикле.

highlight(p,'Edges',edgecycles{5},'EdgeColor','r','LineWidth',1.5,'NodeColor','r','MarkerSize',6)

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

Используйте 'MaxNumCycles', 'MaxCycleLength', и 'MinCycleLength' опции для ограничения количества циклов, возвращаемых allcycles.

Создайте матрицу смежности для полного графика с 20 узлами. Создайте неориентированный граф из матрицы смежности, опуская самоциклы.

A = ones(20);
G = graph(A,'omitselfloops');

Поскольку все узлы в графике связаны со всеми другими узлами, в графике существует большое количество циклов (больше 1.7e17). Поэтому невозможно вычислить все циклы, поскольку результаты не помещаются в памяти. Вместо этого вычислите первые 10 циклов.

cycles1 = allcycles(G,'MaxNumCycles',10)
cycles1=10×1 cell array
    {[                     1 2 3]}
    {[                   1 2 3 4]}
    {[                 1 2 3 4 5]}
    {[               1 2 3 4 5 6]}
    {[             1 2 3 4 5 6 7]}
    {[           1 2 3 4 5 6 7 8]}
    {[         1 2 3 4 5 6 7 8 9]}
    {[      1 2 3 4 5 6 7 8 9 10]}
    {[   1 2 3 4 5 6 7 8 9 10 11]}
    {[1 2 3 4 5 6 7 8 9 10 11 12]}

Теперь вычислите первые 10 циклов, которые имеют длину цикла меньше или равную 3.

cycles2 = allcycles(G,'MaxNumCycles',10,'MaxCycleLength',3)
cycles2=10×1 cell array
    {[ 1 2 3]}
    {[ 1 2 4]}
    {[ 1 2 5]}
    {[ 1 2 6]}
    {[ 1 2 7]}
    {[ 1 2 8]}
    {[ 1 2 9]}
    {[1 2 10]}
    {[1 2 11]}
    {[1 2 12]}

Наконец, вычислите первые 10 циклов, которые имеют длину цикла, большую или равную 4.

cycles3 = allcycles(G,'MaxNumCycles',10,'MinCycleLength',4)
cycles3=10×1 cell array
    {[                      1 2 3 4]}
    {[                    1 2 3 4 5]}
    {[                  1 2 3 4 5 6]}
    {[                1 2 3 4 5 6 7]}
    {[              1 2 3 4 5 6 7 8]}
    {[            1 2 3 4 5 6 7 8 9]}
    {[         1 2 3 4 5 6 7 8 9 10]}
    {[      1 2 3 4 5 6 7 8 9 10 11]}
    {[   1 2 3 4 5 6 7 8 9 10 11 12]}
    {[1 2 3 4 5 6 7 8 9 10 11 12 13]}

Исследуйте, как выходы cyclebasis и allcycles шкалы функций с количеством ребер в графике.

Создайте и постройте график квадратной сетки с тремя узлами на каждой стороне квадрата.

n = 5;
A = delsq(numgrid('S',n));
G = graph(A,'omitselfloops');
plot(G)

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

Вычислите все циклы в графике, используя allcycles. Используйте tiledlayout функция, чтобы создать массив подграфиков и подсветить каждый цикл в подграфике. Результаты показывают, что в графике в общей сложности 13 циклов.

[cycles,edgecycles] = allcycles(G);
tiledlayout flow
for k = 1:length(cycles)
    nexttile
    highlight(plot(G),cycles{k},'Edges',edgecycles{k},'EdgeColor','r','NodeColor','r')
    title("Cycle " + k)
end

Figure contains 13 axes. Axes 1 with title Cycle 1 contains an object of type graphplot. Axes 2 with title Cycle 2 contains an object of type graphplot. Axes 3 with title Cycle 3 contains an object of type graphplot. Axes 4 with title Cycle 4 contains an object of type graphplot. Axes 5 with title Cycle 5 contains an object of type graphplot. Axes 6 with title Cycle 6 contains an object of type graphplot. Axes 7 with title Cycle 7 contains an object of type graphplot. Axes 8 with title Cycle 8 contains an object of type graphplot. Axes 9 with title Cycle 9 contains an object of type graphplot. Axes 10 with title Cycle 10 contains an object of type graphplot. Axes 11 with title Cycle 11 contains an object of type graphplot. Axes 12 with title Cycle 12 contains an object of type graphplot. Axes 13 with title Cycle 13 contains an object of type graphplot.

Некоторые из этих циклов можно рассматривать как комбинации небольших циклов. The cyclebasis функция возвращает подмножество циклов, которые образуют базис для всех других циклов в графике. Использование cyclebasis вычислить базис основного цикла и выделить каждый основной цикл в подграфике. Несмотря на то, что в графике 13 циклов, существует только четыре фундаментальных цикла.

[cycles,edgecycles] = cyclebasis(G);
tiledlayout flow
for k = 1:length(cycles)
    nexttile
    highlight(plot(G),cycles{k},'Edges',edgecycles{k},'EdgeColor','r','NodeColor','r')
    title("Cycle " + k)
end

Figure contains 4 axes. Axes 1 with title Cycle 1 contains an object of type graphplot. Axes 2 with title Cycle 2 contains an object of type graphplot. Axes 3 with title Cycle 3 contains an object of type graphplot. Axes 4 with title Cycle 4 contains an object of type graphplot.

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

n = 6;
A = delsq(numgrid('S',n));
G = graph(A,'omitselfloops');
figure
plot(G)

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

Использование allcycles для вычисления всех циклов в новом графике. Для этого графа существует более 200 циклов, что слишком много, чтобы построить график.

allcycles(G)
ans=213×1 cell array
    {[                       1 2 3 4 8 7 6 5]}
    {[                  1 2 3 4 8 7 6 10 9 5]}
    {[1 2 3 4 8 7 6 10 11 12 16 15 14 13 9 5]}
    {[      1 2 3 4 8 7 6 10 11 15 14 13 9 5]}
    {[            1 2 3 4 8 7 6 10 14 13 9 5]}
    {[                 1 2 3 4 8 7 11 10 6 5]}
    {[                 1 2 3 4 8 7 11 10 9 5]}
    {[           1 2 3 4 8 7 11 10 14 13 9 5]}
    {[     1 2 3 4 8 7 11 12 16 15 14 10 6 5]}
    {[     1 2 3 4 8 7 11 12 16 15 14 10 9 5]}
    {[     1 2 3 4 8 7 11 12 16 15 14 13 9 5]}
    {[1 2 3 4 8 7 11 12 16 15 14 13 9 10 6 5]}
    {[           1 2 3 4 8 7 11 15 14 10 6 5]}
    {[           1 2 3 4 8 7 11 15 14 10 9 5]}
    {[           1 2 3 4 8 7 11 15 14 13 9 5]}
    {[      1 2 3 4 8 7 11 15 14 13 9 10 6 5]}
      ⋮

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

[cycles,edgecycles] = cyclebasis(G);
figure
tiledlayout flow
for k = 1:length(cycles)
    nexttile
    highlight(plot(G),cycles{k},'Edges',edgecycles{k},'EdgeColor','r','NodeColor','r')
    title("Cycle " + k)
end

Figure contains 9 axes. Axes 1 with title Cycle 1 contains an object of type graphplot. Axes 2 with title Cycle 2 contains an object of type graphplot. Axes 3 with title Cycle 3 contains an object of type graphplot. Axes 4 with title Cycle 4 contains an object of type graphplot. Axes 5 with title Cycle 5 contains an object of type graphplot. Axes 6 with title Cycle 6 contains an object of type graphplot. Axes 7 with title Cycle 7 contains an object of type graphplot. Axes 8 with title Cycle 8 contains an object of type graphplot. Axes 9 with title Cycle 9 contains an object of type graphplot.

Большое увеличение количества циклов с лишь небольшим изменением размера графика характерно для некоторых графовых структур. Количество циклов, возвращенных allcycles может расти экспоненциально с количеством ребер в графике. Однако количество циклов, возвращенных cyclebasis может, самое большее, расти линейно с количеством ребер в графике.

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

свернуть все

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

Пример: G = graph(1,2)

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

Аргументы в виде пар имя-значение

Задайте необязательные разделенные разделенными запятой парами Name,Value аргументы. Name - имя аргумента и Value - соответствующее значение. Name должны находиться внутри кавычек. Можно задать несколько аргументов в виде пар имен и значений в любом порядке Name1,Value1,...,NameN,ValueN.

Пример: allcycles(G,'MaxNumCycles',100) возвращает только первые 100 циклов в графике.

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

Пример: allcycles(G,'MaxNumCycles',100)

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

Чтобы найти циклы с областью значений длин, задайте оба 'MaxCycleLength' и 'MinCycleLength'. Чтобы найти циклы с точно определенной длиной, задайте одно и то же значение для обоих 'MaxCycleLength' и 'MinCycleLength'.

Пример: allcycles(G,'MaxCycleLength',4) возвращает циклы, длина которых меньше или равна 4.

Пример: allcycles(G,'MinCycleLength',3,'MaxCycleLength',5) возвращает циклы, которые имеют длину 3, 4 или 5.

Минимальная длина цикла, заданная как разделенная разделенными запятой парами, состоящая из 'MinCycleLength' и положительный целочисленный скаляр. Эта опция фильтрует результаты, возвращенные allcycles так, чтобы никакие циклы с длиной, меньшей заданного предела, не возвращались. Длина цикла измеряется количеством ребер в нем, игнорируя веса ребер.

Чтобы найти циклы с областью значений длин, задайте оба 'MaxCycleLength' и 'MinCycleLength'. Чтобы найти циклы с точно определенной длиной, задайте одно и то же значение для обоих 'MaxCycleLength' и 'MinCycleLength'.

Пример: allcycles(G,'MinCycleLength',2) возвращает циклы, длина которых больше или равна 2.

Пример: allcycles(G,'MinCycleLength',3,'MaxCycleLength',5) возвращает циклы, которые имеют длину 3, 4 или 5.

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

свернуть все

Графовые циклы, возвращенные как массив ячеек. Каждый элемент cycles{k} содержит узлы, которые относятся к одному из циклов в G. Каждый цикл начинается с узла, который имеет наименьший индекс узла, и циклы возвращаются в лексикографическом порядке. Циклы в неориентированных графах возвращаются только один раз, следуя одному направлению. Если G не содержит никаких циклов, тогда cycles пуст.

Тип данных камер в cycles зависит от того, содержит ли входной график имена узлов:

  • Если графиков G не имеет имен узлов, тогда каждый элемент cycles{k} является числовым вектором индексов узлов.

  • Если графиков G имеет имена узлов, затем каждый элемент cycles{k} - массив ячеек с именами узлов векторов символов.

Ребра в каждом цикле, возвращенные как массив ячеек. Каждый элемент edgecycles{k} содержит индексы кромок для ребер в соответствующем цикле, cycles{k}. Если G не содержит никаких циклов, тогда edgecycles пуст.

Подробнее о

свернуть все

Графовые циклы

Цикл существует в график, когда существует непустой путь, в котором повторяются только первый и последний узлы. Примером цикла является: (Node1 - Node2 - Node3 - Node1). По соглашению, allcycles не возвращает последний узел в цикле, так как он совпадает с первым.

Цикл не может пройти одно и то же ребро дважды. Для примера цикл (Node1 - Node2 - Node1) в неориентированном графе существует только, если существует более одного ребра, соединяющего Node1 и Node2. По этому определению самоциклов считаются циклами, хотя они не могут быть частью большого цикла.

Совет

  • Количество циклов в графике в большой степени зависит от структуры графика. Для некоторых графовых структур количество циклов может расти экспоненциально с числом узлов. Для примера - полный график с 12 узлами, заданная G = graph(ones(12)) содержит почти 60 миллионов циклов. Используйте MaxNumCycles, MaxCycleLength, и MinCycleLength опции для управления выходом allcycles в этих случаях.

См. также

| |

Введенный в R2021a