Академический Документы
Профессиональный Документы
Культура Документы
12 декабря 2022 г.
Содержание
1 Задача о порядке умножения матриц 1
Пример 1. Для произведения трёх матриц размера 100 × 2, 2 × 100 и 100 × 3, если до-
гадаться сперва перемножить две последних матрицы, то получится матрица 2 × 3,
которую легко будет перемножить с матрицей 100 × 2 — всего потребуется выполнить
2 · 100 · 3 + 100 · 2 · 3 = 1200 умножений и примерно столько же сложений. Если же начать
с умножения двух первых матриц, получится неудобоумножаемая промежуточная мат-
рица размера 100×100, и общее число умножений составит 100·2·100+100·100·3 = 50000.
∗
Краткое содержание лекций, прочитанных студентам 1-го курса факульте-
та МКН СПбГУ в осеннем семестре 2022–2023 учебного года. Страница курса:
http://users.math-cs.spbu.ru/~okhotin/teaching/algorithms1_2022/.
1
Конечно, можно просто перебрать все возможные порядки — их ровно число Каталана
𝐶𝑛 — для каждого определить общее число операций, и найти среди этих чисел наимень-
шее. Но не исключено, что чем за такое браться, быстрее будет перемножить матрицы как
придётся!
Задача решается методом динамического программирования. Сперва ставится цель: по-
строить верхнедиагональную числовую матрицу 𝑇 размера 𝑛 × 𝑛, где 𝑇𝑖,𝑗 — наименьшее
число действий, необходимых для вычисления 𝑀𝑖+1 × . . . × 𝑀𝑗 .
Внешний цикл по длине куска ℓ = 𝑗 − 𝑖, второй — по 𝑖, во внутреннем перебираются все
разбиения 𝑀𝑖+1 × . . . × 𝑀𝑗 = (𝑀𝑖+1 × . . . × 𝑀𝑘 ) × (𝑀𝑘+1 × . . . × 𝑀𝑗 ) и для каждого такого раз-
биения вычисляется время вычисления произведения 𝑀𝑖+1 × . . . × 𝑀𝑗 при таком разбиении,
которое составит 𝑇𝑖,𝑘 + 𝑇𝑘,𝑗 + 𝑚𝑖 𝑚𝑘 𝑚𝑗 . Из всех таких значений берётся минимальное.
𝑗−1 (︀ )︀
𝑇𝑖,𝑗 = min 𝑇𝑖,𝑘 + 𝑇𝑘,𝑗 + 𝑚𝑖 𝑚𝑘 𝑚𝑗
𝑘=𝑖+1
2
Ww дубль-вэ
Ww дубль-вэ (курсив)
Ωω омега
2.1 Строки
Сперва задаётся конечное множество символов Σ, называемое алфавитом. В абстрактных
примерах элементы Σ обозначаются строчными латинскими буквами из начала алфавита
(𝑎, 𝑏, . . . ).
3
b1 bj–1 bj b1 bj–1 bj
a1 a1
ai–1 +1 ai–1
ai ai
max
1: for 𝑗 = 0 to 𝑛 do
2: 𝑇0,𝑗 = 0
3: for 𝑖 = 1 to 𝑚 do
4: 𝑇𝑖,0 = 0
5: for 𝑗 = 1 to 𝑛 do
6: if 𝑎𝑖 = 𝑏𝑗 then
7: 𝑇𝑖,𝑗 = 𝑇𝑖−1,𝑗−1 + 1
8: else
9: 𝑇𝑖,𝑗 = max(𝑇𝑖−1,𝑗 , 𝑇𝑖,𝑗−1 )
10: return 𝑇𝑚,𝑛
4
Рис. 3: Дэниэл Хиршберг (род. 1949).
b1 bj–1 bj bj+1 bn
a1
u' T u',v
u''
~
T u'',v
am
5
ся максимум — это и будет искомое разбиение 𝑣 = 𝑣 ′ 𝑣 ′′ . Для этого вычисления алгоритм
использовал 𝑂(|𝑣|) ячеек памяти, которые теперь можно освободить.
Далее алгоритм дважды рекурсивно вызывает сам себя, чтобы вычислить наилучшее
совмещение 𝑢′ и 𝑣 ′ , и 𝑢′′ и 𝑣 ′′ . Полученные совмещения последовательно приписываются
друг к другу.
𝑓 (𝑚, 𝑛) = 2 · 12 𝑚𝑛 + max 𝑓 ( 𝑚 𝑚
(︀ )︀
𝑘 2 , 𝑘) + 𝑓 ( 2 , 𝑛 − 𝑘) ⩽ 𝑚𝑛 + max(𝑚𝑘 + 𝑚(𝑛 − 𝑘)) = 2𝑚𝑛
𝑘
2
Их иногда называют «белыми», «серыми» и «чёрными», соответственно.
6
Алгоритм 3 Поиск в ширину
Структуры данных: очередь вершин для обработки, множество всех встреченных вершин
(можно хранить вместе с вершинами как пометки, а если граф задан неявно, то в отдельной
структуре данных).
1: пометить 𝑠
2: поместить 𝑠 в конец очереди
3: while очередь непуста do
4: извлечь из очереди первый элемент, 𝑢
5: for all 𝑣: (𝑢, 𝑣) ∈ 𝐸 do
6: if 𝑣 не помечена then
7: пометить 𝑣
8: поместить 𝑣 в конец очереди
9: теперь 𝑢 обработана
Утверждение 2. (I) алгоритм помечает вершину 𝑣 тогда и только тогда, когда есть
путь из 𝑠 в 𝑣; (II) если алгоритм находит 𝑣 по дуге (𝑢, 𝑣), то один из кратчайших путей
из 𝑠 в 𝑣 идёт через 𝑢; (III) все пройденные дуги (𝑢, 𝑣) образуют дерево.
Доказательство. (I)
(обходит ⇒ есть путь) индукция по длине вычисления. Базис: помечена в этой строке
— тогда это 𝑠. Переход: когда 𝑣 помечается, есть ранее помеченная вершина 𝑢 и дуга (𝑢, 𝑣).
Путь из 𝑠 в 𝑢 есть по предположению индукции, он продолжается дугой до искомого.
(есть путь ⇒ обходит) индукция по длине пути. Базис: 0, помечается в первой строке.
Переход: пусть 𝑢 — предпоследняя вершина на пути из 𝑠 в 𝑣. Тогда путь в неё короче, и
по предположению индукции 𝑢 когда-то помечается. Одновременно 𝑢 заносится в очередь,
откуда она рано или поздно будет извлечена, и тогда при рассмотрении дуги (𝑢, 𝑣) будет
обнаружена вершина 𝑣.
(II) Из утверждения 1.
(III) Всякий раз, когда алгоритм переходит по дуге, он переходит в ранее не рассмат-
ривавшуюся вершину. Поэтому все рассмотренные дуги образуют ориентированный граф,
в котором у одной вершины степень захода 0, а у остальных — 1. В таком графе не может
быть циклов, в том числе неориентированных.
7
тельное действие — например, записывать куда-нибудь это остовное дерево или вычислять
кратчайшее расстояние от 𝑠 до очередной вершины.
Если нужно обойти не только вершины, достижимые из данной, а вообще все вершины,
то надо перезапускать 𝐵𝐹 𝑆(𝑠) на непомеченных вершинах, пока таковые будут оставаться.
Если записать все дуги, по которым делаются рекурсивные вызовы, то получится лес.
Кроме того, алгоритм часто используется, чтобы поставить каждой вершине в соответ-
ствие два числа, соответствующие времени её обхода, измеряемому в шагах работы алго-
8
ритма. В момент перекраски в серый вершине назначается время обнаружения, а в момент
перекраски в чёрный — время окончания.
Время работы: 𝑂(|𝑉 | + |𝐸|); написать просто |𝐸| нельзя, потому что может быть много
изолированных вершин.
Лемма 2. Граф ациклический тогда и только тогда, когда при поиске в глубину никогда
не рассматривается дуга, ведущая в вершину, находящуюся в стеке возврата (дуга из
«серой» вершины в «серую»).
Лемма 3. Если в ациклическом графе есть дуга (𝑢, 𝑣), то время завершения 𝑣 меньше,
чем время завершения 𝑢.
Доказательство. Эта дуга однажды будет рассматриваться. В этот момент 𝑣 нет в стеке
возврата. Если 𝑣 помечена, то у неё уже есть время завершения, а у 𝑢 ещё только будет
(позднее). Если же 𝑣 ранее не рассматривалась, то в неё спустится рекурсия, и по воз-
вращении из рекурсии 𝑣 будет уже обработана — а 𝑢 только предстоит получить время
завершения.
9
Рис. 5: Рао Косараджу (род. 1943), Миха Шарир (род. 1950).
Лемма 4. Пусть в графе 𝐺 есть сильно связные компоненты 𝐶 и 𝐷, и есть дуга (𝑢, 𝑣) ∈ 𝐸
из 𝐶 в 𝐷, как показано на рис. 6(левом). Тогда при поиске в глубину в графе 𝐺 самое позднее
время завершения вершины в 𝐶 превосходит таковое в 𝐷.
Стало быть, все вершины из 𝐷 будут закончены раньше, чем вершина из 𝐶, законченная
последней. Поэтому когда поиск в глубину будет запущен в графе 𝐺𝑅 , и первой будет
рассмотрена позже всех законченная вершина из 𝐶, из неё не удастся придти в 𝐷, поскольку
в графе 𝐺𝑅 есть только дуга (𝑣, 𝑢), а будь в нём какие-то дуги из 𝐶 в 𝐷, это был бы один
компонент связности. Позднее, когда будут рассмотрены вершины из 𝐷, переходить из них
в 𝐶 будет уже поздно, поскольку все вершины из 𝐶 к тому времени будут уже рассмотрены.
3
Стоит упомянуть, что у графов 𝐺 и 𝐺𝑅 одни и те же компоненты сильной связности.
10
C D C D
G: GR:
u v u v
11
Рис. 7: Ричард Беллман (1920–1984), Лестер Форд мл. (1927–2017).
Алгоритм постепенно находит пути меньшего веса в другие вершины, запоминая веса
лучших из найденных путей в этих переменных. Значения уменьшаются с помощью эле-
ментарной операции улучшения пути, используя некоторую дугу (𝑢, 𝑣) ∈ 𝐸.
1: 𝑑𝑠 = 0
2: 𝑑𝑣 = ∞ для всех 𝑣 ̸= 𝑠
3: for 𝑖 = 1 to |𝑉 | − 1 do
4: for all (𝑢, 𝑣) ∈ 𝐸 do
5: if 𝑑𝑢 + 𝑤𝑢,𝑣 < 𝑑𝑣 then /* если путь из 𝑠 в 𝑣 можно улучшить этой дугой */
6: 𝑑𝑣 = 𝑑𝑢 + 𝑤𝑢,𝑣
7: 𝜋𝑣 = 𝑢
8: for all (𝑢, 𝑣) ∈ 𝐸 do
9: if 𝑑𝑢 + 𝑤𝑢,𝑣 < 𝑑𝑣 then
10: return есть достижимый цикл отрицательного веса
11: return достижимых циклов отрицательного веса нет
Лемма 5. После 𝑖-й итерации внешнего цикла алгоритм Беллмана–Форда находит все
пути наименьшего веса длины не более чем 𝑖.
Доказательство. Индукция по 𝑖.
Индукционный переход. Пусть верно для 𝑖-го прохода. Всякий путь наименьшего веса
длины 𝑖 + 1 в вершину 𝑣 на предыдущем шаге проходит через некоторую вершину 𝑢,
и потому содержит путь наименьшего веса длины 𝑖 в 𝑢. Тогда на (𝑖 + 1)-м проходе
искомый путь в вершину 𝑣 будет найден при рассмотрении вершины 𝑢.
12
Теорема 2. Алгоритм Беллмана–Форда за |𝑉 | · |𝐸| шагов или правильно вычисляет пути
наименьшего веса из вершины 𝑠 во все вершины, или сообщает о наличии достижимого
цикла отрицательного веса.
Доказательство. После |𝑉 |−1 итераций, согласно лемме 5, найдены все пути наименьшего
веса, состоящие не более чем из |𝑉 | − 1 дуг. Время работы — поскольку на каждой итерации
рассматриваются все дуги.
Если после |𝑉 | − 1 итераций первого цикла оказывается, что какие-то пути можно ещё
улучшить, это значит, что есть путь длины |𝑉 | в какую-то вершину 𝑣, вес которого меньше,
чем у всех путей длины не более чем |𝑉 | − 1, идущих в 𝑣. Какая-то вершина 𝑥 на этом
пути повторяется дважды. При удалении фрагмента пути между двумя вхождениями 𝑥
+получается путь длины не более чем |𝑉 | − 1, который, по предположению, имеет больший
вес, чем исходный путь длины |𝑉 |. Стало быть, вес удалённого цикла отрицательный, о чём
и сообщит алгоритм.
Пусть после |𝑉 | − 1 итераций никакие пути улучшить уже нельзя. Утверждается, что
всякий цикл 𝑣0 , 𝑣1 , . . . , 𝑣𝑘−1 , 𝑣0 , достижимый из 𝑠, будет иметь неотрицательный вес. Дей-
ствительно, для каждой дуги (𝑣𝑖 , 𝑣𝑖+1 ) этого цикла условие улучшения пути не выполняется.
Список литературы
[1975] D. S. Hirschberg, “A linear space algorithm for computing maximal common
subsequences”, Communications of the ACM, 18:6 (1975), 341–343.
[1981] M. Sharir, “A strong connectivity algorithm and its applications to data flow analysis”,
Computers and Mathematics with Applications, 7:1 (1981), 67–72.
13