allcycles

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

Описание

пример

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

пример

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

пример

[___] = allcycles(G,Name,Value) задает дополнительные опции с помощью одних или нескольких аргументов 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 object. The axes object 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 object. The axes object 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 object. The axes object 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 object. The axes object 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 objects. Axes object 1 with title Cycle 1 contains an object of type graphplot. Axes object 2 with title Cycle 2 contains an object of type graphplot. Axes object 3 with title Cycle 3 contains an object of type graphplot. Axes object 4 with title Cycle 4 contains an object of type graphplot. Axes object 5 with title Cycle 5 contains an object of type graphplot. Axes object 6 with title Cycle 6 contains an object of type graphplot. Axes object 7 with title Cycle 7 contains an object of type graphplot. Axes object 8 with title Cycle 8 contains an object of type graphplot. Axes object 9 with title Cycle 9 contains an object of type graphplot. Axes object 10 with title Cycle 10 contains an object of type graphplot. Axes object 11 with title Cycle 11 contains an object of type graphplot. Axes object 12 with title Cycle 12 contains an object of type graphplot. Axes object 13 with title Cycle 13 contains an object of type graphplot.

Некоторые из этих циклов могут рассматриваться как комбинации меньших циклов. 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 objects. Axes object 1 with title Cycle 1 contains an object of type graphplot. Axes object 2 with title Cycle 2 contains an object of type graphplot. Axes object 3 with title Cycle 3 contains an object of type graphplot. Axes object 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 object. The axes object 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 objects. Axes object 1 with title Cycle 1 contains an object of type graphplot. Axes object 2 with title Cycle 2 contains an object of type graphplot. Axes object 3 with title Cycle 3 contains an object of type graphplot. Axes object 4 with title Cycle 4 contains an object of type graphplot. Axes object 5 with title Cycle 5 contains an object of type graphplot. Axes object 6 with title Cycle 6 contains an object of type graphplot. Axes object 7 with title Cycle 7 contains an object of type graphplot. Axes object 8 with title Cycle 8 contains an object of type graphplot. Axes object 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 имя аргумента и 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 isempty.

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

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

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

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

Больше о

свернуть все

Циклы графика

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

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

Советы

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

Смотрите также

| |

Введенный в R2021a