Я копирую этот ответ и добавляю также добавление моего доказательства правильности алгоритма:
Я бы использовал какой-нибудь вариант Дейкстры . Я взял псевдокод ниже прямо из Википедии и изменил только 5 маленьких вещей:
- Переименовано
dist
в width
(со строки 3 на)
- Инициализируется каждый
width
до -infinity
(строка 3)
- Инициализировал ширину источника как
infinity
(строка 8)
- Установите критерий финиша на
-infinity
(строка 14)
- Изменена функция обновления и подпись (строка 20 + 21)
1 function Dijkstra(Graph, source):
2 for each vertex v in Graph: // Initializations
3 width[v] := -infinity ; // Unknown width function from
4 // source to v
5 previous[v] := undefined ; // Previous node in optimal path
6 end for // from source
7
8 width[source] := infinity ; // Width from source to source
9 Q := the set of all nodes in Graph ; // All nodes in the graph are
10 // unoptimized – thus are in Q
11 while Q is not empty: // The main loop
12 u := vertex in Q with largest width in width[] ; // Source node in first case
13 remove u from Q ;
14 if width[u] = -infinity:
15 break ; // all remaining vertices are
16 end if // inaccessible from source
17
18 for each neighbor v of u: // where v has not yet been
19 // removed from Q.
20 alt := max(width[v], min(width[u], width_between(u, v))) ;
21 if alt > width[v]: // Relax (u,v,a)
22 width[v] := alt ;
23 previous[v] := u ;
24 decrease-key v in Q; // Reorder v in the Queue
25 end if
26 end for
27 end while
28 return width;
29 endfunction
Несколько (ручных) объяснений, почему это работает: вы начинаете с источника. Оттуда у вас есть бесконечная способность к себе. Теперь вы проверяете всех соседей по источнику. Предположим, что края не имеют одинаковую емкость (в вашем примере, скажем, (s, a) = 300
). Тогда нет лучшего способа достичь b
, чем через (s, b)
, так что вы знаете наилучшую вместимость b
. Вы продолжаете идти к лучшим соседям из известного набора вершин, пока не достигнете всех вершин.
Подтверждение правильности алгоритма:
В любой точке алгоритма будет 2 набора вершин A и B . Вершины в A будут вершинами, к которым был найден правильный путь максимальной минимальной емкости. И множество B имеет вершины, на которые мы не нашли ответа.
Индуктивная гипотеза : На любом этапе все вершины в наборе A имеют правильные значения максимального минимального пути к ним. т.е. все предыдущие итерации верны.
Корректность базового случая : Когда множество A имеет только вершину S. Тогда значение S равно бесконечности, что является правильным.
В текущей итерации мы устанавливаем
val [W] = max (val [W], min (val [V], width_between (V-W)))
Индуктивный шаг : Предположим, W - вершина в множестве B с наибольшим значением [W]. И W исключается из очереди, и W был установлен ответ val [W].
Теперь нам нужно показать, что каждый другой путь S-W имеет ширину <= val [W]. Это будет всегда верно, потому что все другие способы достижения W пройдут через какую-то другую вершину (назовите это X) в множестве B. </p>
И для всех других вершин X в множестве B val [X] <= val [W] </p>
Таким образом, любой другой путь к W будет ограничен val [X], который никогда не превышает val [W].
Таким образом, текущая оценка val [W] является оптимальной, и, следовательно, алгоритм вычисляет правильные значения для всех вершин.