exponenta event banner

shortestpath

Кратчайший путь между двумя одиночными узлами

Описание

пример

P = shortestpath(G,s,t) вычисляет кратчайший путь, начинающийся с исходного узла s и заканчивается в целевом узле t. Если график взвешен (то есть G.Edges содержит переменную Weight), то эти веса используются как расстояния вдоль рёбер на графике. В противном случае все расстояния кромок принимаются равными 1.

пример

P = shortestpath(G,s,t,'Method',algorithm) дополнительно задает алгоритм, используемый при вычислении кратчайшего пути. Например, если G является взвешенным графиком, то shortestpath(G,s,t,'Method','unweighted') игнорирует веса кромок в G и вместо этого рассматривает все веса кромок как 1.

пример

[P,d] = shortestpath(___) дополнительно возвращает длину кратчайшего пути, d, используя любой из входных аргументов в предыдущих синтаксисах.

пример

[P,d,edgepath] = shortestpath(___) дополнительно возвращает индексы границ edgepath всех ребер на кратчайшем пути от s кому t.

Примеры

свернуть все

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

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

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

Вычислите кратчайший путь между узлами 7 и 8.

P = shortestpath(G,7,8)
P = 1×5

     7     1     3     5     8

Создайте и постройте график с взвешенными кромками.

s = [1 1 1 2 2 6 6 7 7 3 3 9 9 4 4 11 11 8];
t = [2 3 4 5 6 7 8 5 8 9 10 5 10 11 12 10 12 12];
weights = [10 10 10 10 10 1 1 1 1 1 1 1 1 1 1 1 1 1];
G = graph(s,t,weights);
plot(G,'EdgeLabel',G.Edges.Weight)

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

Найдите кратчайший путь между узлами 3 и 8 и укажите два выхода, чтобы также вернуть длину пути.

[P,d] = shortestpath(G,3,8)
P = 1×5

     3     9     5     7     8

d = 4

Поскольку рёбра в центре графа имеют большие веса, кратчайший путь между узлами 3 и 8 проходит вокруг границы графа, где рёберные веса наименьшие. Этот путь имеет общую длину 4.

Создание и печать графика с взвешенными кромками с использованием пользовательских координат узла.

s = [1 1 1 1 1 2 2 7 7 9 3 3 1 4 10 8 4 5 6 8];
t = [2 3 4 5 7 6 7 5 9 6 6 10 10 10 11 11 8 8 11 9];
weights = [1 1 1 1 3 3 2 4 1 6 2 8 8 9 3 2 10 12 15 16];
G = graph(s,t,weights);

x = [0 0.5 -0.5 -0.5 0.5 0 1.5 0 2 -1.5 -2];
y = [0 0.5 0.5 -0.5 -0.5 2 0 -2 0 0 0];
p = plot(G,'XData',x,'YData',y,'EdgeLabel',G.Edges.Weight);

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

Найдите кратчайший путь между узлами 6 и 8 на основе весов рёбер графика. Выделите этот путь зеленым цветом.

[path1,d] = shortestpath(G,6,8)
path1 = 1×5

     6     3     1     4     8

d = 14
highlight(p,path1,'EdgeColor','g')

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

Определить Method как unweighted игнорировать веса кромок, вместо этого обрабатывая все кромки так, как если бы они имели вес 1. Этот способ создает другой путь между узлами, который ранее имел слишком большую длину пути, чтобы быть самым коротким путем. Выделите этот контур красным цветом.

[path2,d] = shortestpath(G,6,8,'Method','unweighted')
path2 = 1×3

     6     9     8

d = 2
highlight(p,path2,'EdgeColor','r')

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

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

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

G = graph([1 1 1 1 1 2 2 3 3 3 4 4],[2 2 2 2 2 3 4 4 5 5 5 2],[2 4 6 8 10 5 3 1 5 6 8 9]);
p = plot(G,'EdgeLabel',G.Edges.Weight);

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

Найдите кратчайший путь между узлом 1 и узлом 5. Поскольку несколько пар узлов имеют более одного края между ними, укажите три выхода для shortestpath для возврата определенных кромок, через которые проходит кратчайший путь.

[P,d,edgepath] = shortestpath(G,1,5)
P = 1×5

     1     2     4     3     5

d = 11
edgepath = 1×4

     1     7     9    10

Результаты показывают, что кратчайший путь имеет общую длину 11 и следует за краями, заданными G.Edges(edgepath,:).

G.Edges(edgepath,:)
ans=4×2 table
    EndNodes    Weight
    ________    ______

     1    2       2   
     2    4       3   
     3    4       1   
     3    5       5   

Выделите этот контур кромки с помощью highlight функции с помощью 'Edges' пара «имя-значение» для указания индексов пересекаемых кромок.

highlight(p,'Edges',edgepath)

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

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

Создайте график с 10 узлами.

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

Создайте координаты x и y для узлов графика. Затем постройте график, используя координаты узла, указав 'XData' и 'YData' пары имя-значение.

x = [1 2 3 2 2.5 4 3 5 3 5];
y = [1 3 4 -1 2 3.5 1 3 0 1.5];
plot(G,'XData',x,'YData',y)

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

Добавьте веса рёбер к графу, вычисляя евклидовы расстояния между узлами графа. Расстояние вычисляется по координатам узла (xi, yi) как:

d = | Δx | 2 + | Δy | 2 = | xs-xt | 2 + | ys-yt | 2.

Для вычисления Δx и Δy сначала используйте findedges для получения векторов sn и tn описание исходного и целевого узлов каждого ребра в графе. Затем использовать sn и tn для индексирования в векторы координат x и y и вычисления Δx = xs-xt и Δy = ys-yt. hypot функция вычисляет квадрат суммы квадратов, поэтому задайте Δx и Δy в качестве входных аргументов для вычисления длины каждого ребра.

[sn,tn] = findedge(G);
dx = x(sn) - x(tn);
dy = y(sn) - y(tn);
D = hypot(dx,dy);

Добавьте расстояния к графу в качестве весов ребер и повторите график с ребрами.

G.Edges.Weight = D';
p = plot(G,'XData',x,'YData',y,'EdgeLabel',G.Edges.Weight);

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

Вычислите кратчайший путь между узлом 1 и узлом 10 и задайте два выхода, чтобы также вернуть длину пути. Для взвешенных графиков shortestpath автоматически использует 'positive' способ, учитывающий веса кромок.

[path,len] = shortestpath(G,1,10)
path = 1×4

     1     4     9    10

len = 6.1503

Используйте highlight для отображения траектории на графике.

highlight(p,path,'EdgeColor','r','LineWidth',2)

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"

Пример: shortestpath(G,2,5) вычисляет кратчайший путь между узлом 2 и узлом 5.

Пример: shortestpath(G,'node1','node2') вычисляет кратчайший путь между названными узлами node1 и node2.

Алгоритм кратчайшего пути, указанный как один из параметров в таблице.

ВыборОписание
'auto' (по умолчанию)

'auto' опция автоматически выбирает алгоритм:

  • 'unweighted' используется для graph и digraph входы без веса кромок.

  • 'positive' используется для всех graph входные данные, имеющие веса кромок и требующие, чтобы веса были неотрицательными. Эта опция также используется для digraph входы с неотрицательными кромочными весами.

  • 'mixed' используется для digraph входные данные, веса кромок которых содержат некоторые отрицательные значения. График не может иметь отрицательные циклы.

'unweighted'

Ширина (Breadth) - первый расчет, который рассматривает все веса кромок как 1.

'positive'

Алгоритм Dijkstra, который требует, чтобы все веса ребер были неотрицательными.

'mixed' (только для digraph)

Алгоритм Беллмана - Форда для направленных графов, который требует, чтобы граф не имел отрицательных циклов.

В то время как 'mixed' медленнее, чем 'positive' для той же проблемы, 'mixed' является более универсальным, поскольку позволяет некоторым весам края быть отрицательными.

'acyclic' (только для digraph)

Алгоритм, предназначенный для повышения производительности направленных ациклических графов (DAG) с взвешенными рёбрами.

Использовать isdag для подтверждения, является ли направленный граф ациклическим.

Примечание

Для большинства графиков: 'unweighted' является самым быстрым алгоритмом, за которым следует 'acyclic', 'positive', и 'mixed'.

Пример: shortestpath(G,s,t,'Method','acyclic')

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

свернуть все

Кратчайший путь между узлами, возвращаемый как вектор индексов узлов или массив имен узлов. P пуст, {}, если между узлами нет пути.

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

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

Если существует несколько кратчайших путей между s и t, то P содержит только один из путей. Возвращаемый путь может изменяться в зависимости от алгоритма Method указывает.

Кратчайшее расстояние пути, возвращаемое как числовой скаляр. d - суммирование весов кромок между последовательными узлами в P. Если между узлами нет пути, то d является Inf.

Рёбра на кратчайшем пути, возвращаемые как вектор индексов рёбер. Для мультиграфов этот вывод указывает, какой край между двумя узлами находится на пути. Эти выходные данные совместимы с 'Edges' пара имя-значение highlight, например: highlight(p,'Edges',edgepath).

Совет

  • shortestpath, shortestpathtree, и distances функции не поддерживают неориентированные графы с отрицательными весами рёбер или, в более общем случае, любой граф, содержащий отрицательный цикл, по следующим причинам:

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

    • Единственный отрицательный вес ребра в неориентированном графике создает отрицательный цикл.

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