Дональд Кнут: «Алгоритм Тарьяна — это моя самая большая любовь в программировании»

Stanford Online 31,3 тыс. 1 ч 24 мин 5 мин 07.01.2025
Главное

В Стэнфордском университете прошла лекция легендарного учёного, автора многотомника «Искусство программирования» Дональда Кнута (Donald Knuth). Встреча была посвящена элегантным алгоритмам работы с графами, а также выходу новой части его фундаментального труда — раздела 12a выпуска 7 тома 4C, посвящённого задаче выполнения ограничений (Constraint Satisfaction). Кнут поделился личной историей любви к алгоритму Тарьяна, рассказал о трагических обстоятельствах открытия слабых компонент и объяснил, почему глубокие структуры данных важнее «чистой» математики.

❤️ Алгоритм Тарьяна: любовь с первого взгляда 0:11

В ходе лекции Дональд Кнут признался в любви к алгоритму Роберта Тарьяна (Robert Tarjan) для поиска компонент сильной связности . По словам профессора, когда он впервые изучил эту процедуру в 1973 году, он осознал, что глубокими могут быть не только математические теоремы, но и сами структуры данных.

Особенности «любимого алгоритма» Кнута:

Интересно, что в 1972 году рецензенты математических журналов не оценили гениальность Тарьяна. Кнут продемонстрировал архивный отзыв, где говорилось, что алгоритм «не вызывает удивления» . Однако время доказало обратное: сегодня этот метод считается эталоном в Computer Science.

🕸 Сильные и слабые компоненты: теория 5:38

Кнут подробно разъяснил различие между типами связности в ориентированных графах.

Компоненты сильной связности

Вершины $u$ и $v$ находятся в одной компоненте сильной связности, если существует путь из $u$ в $v$ и обратно из $v$ в $u$ . Если сжать каждую такую компоненту в одну супер-вершину, исходный граф превратится в направленный ациклический граф (DAG) .

Слабые компоненты (Weak Components)

Понятие слабых компонент часто путают с компонентами связности неориентированного графа, что Кнут считает «неудачным» . Математически верное определение слабых компонент связано с порядком:

  1. Если сжать сильные компоненты, мы получим частичный порядок.
  2. Если сжать слабые компоненты (в понимании Кнута и Моцкина), мы получим линейный (полный) порядок .
  3. Две вершины попадают в одну слабую компоненту, если они несравнимы в рамках частичного порядка или связаны цепочкой несравнимых элементов .

🕯 Печальная история Теодора Моцкина 10:29

История открытия слабых компонент омрачена трагедией. Кнут рассказал, что в 1970 году он, Рон Грэм (Ron Graham) и Теодор Моцкин (Theodore Motzkin) вели переписку, работая над одной проблемой с разных сторон. Моцкин предложил концепцию слабых компонент в письме от 28 февраля 1970 года .

В декабре 1970 года Кнут решил, что все трое должны стать соавторами статьи, так как их подходы дополняли друг друга. Однако в то же утро он получил известие о внезапной смерти Моцкина от сердечного приступа . Статья была опубликована в журнале Discrete Mathematics уже посмертно . Долгое время информация об этом открытии в широких источниках (включая Википедию) была скудной, пока ситуацию не исправил профессор Дэвид Эпштейн (David Eppstein) .

🔍 Анатомия поиска в глубину (DFS) 28:56

Для объяснения работы алгоритма Кнут использовал метафору игры в спелеолога: вы исследуете пещеру (граф), оставляя за собой метки . В процессе поиска в глубину (Depth First Search) ребра графа делятся на пять типов :

Кнут продемонстрировал «Тайный соус Тарьяна» — использование стека для хранения активных вершин и специального указателя (Low Point), который позволяет определить, когда мы нашли «сток» (sink) графа . Как только алгоритм находит компоненту-сток, он «закрывает» её и удаляет из рассмотрения, переходя к следующей.

🛠 Оптимизация: когда «трюкачество» оправдано 1:11:11

В последние два года (2022–2024) Кнут и Тарьян снова вернулись к улучшению алгоритма 50-летней давности . Они разработали версию, которая работает еще быстрее, чем оригинал.

Кнут затронул важный этический вопрос программирования:

  1. Преждевременная оптимизация: По его мнению, это корень всех зол.
  2. Постзревшая оптимизация (Postmature optimization): Когда алгоритм уже изучен досконально, можно добавить «хитрости» (trickery), чтобы выжать максимум производительности .

Профессор считает, что если трюк хорошо задокументирован, его не нужно бояться. Компьютер не понимает сложности кода — он просто выполняет инструкции, и если запутанный код работает быстрее, для машины это благо . Кнут также упомянул Эдсгера Дейкстру (Edsger Dijkstra), который пытался решить задачу о компонентах связности независимо. Дейкстра разработал решение с четырьмя дополнительными массивами, но оно оказалось сложнее и медленнее, чем элегантный подход Тарьяна .

🎹 Личные воспоминания о Дейкстре 1:19:11

Отвечая на вопросы из зала, Кнут вспомнил своего коллегу Эдсгера Дейкстру. Он описал его как человека «неспособного на компромисс» и абсолютного перфекциониста .


📦 Где изучить подробнее?

Кнут анонсировал обновление своего сайта, где будут выложены обновленные программы на языке CWEB . Также он порекомендовал свою книгу «Stanford GraphBase», где алгоритм Тарьяна применен к анализу тезауруса Роже (Roget's Thesaurus). В этом примере вершины — это категории слов (например, «Ангел»), а дуги — связи между синонимами .


💬 Цитаты

«Алгоритм Тарьяна для сильных компонент — это, без сомнения, тот алгоритм, который я люблю больше всего.»

Дональд Кнут 03:51

«Преждевременная оптимизация — корень всех зол, но здесь мы занимались постзревшей оптимизацией.»

«Компьютер не идет медленнее, если он встречает часть кода, которую программисту трудно понять.»

👥 Спикер
📚 Упомянутые книги
🔗 Упомянутые сайты и проекты
📖 Термины
Сильная связность
Свойство ориентированного графа, при котором между любыми двумя вершинами в компоненте существует взаимный путь.
Топологическая сортировка
Упорядочивание вершин графа так, что для любого ребра (u, v) вершина u идет перед v.
CWEB
Система грамотного программирования (literate programming), разработанная Кнутом.
DAG (Directed Acyclic Graph)
Ориентированный граф, не содержащий циклов.
📊 Цифры
🗓 Хронология
  1. 28 февраля 1970 Теодор Моцкин описывает концепцию слабых компонент в письме Рону Грэму.
  2. Декабрь 1970 Внезапная смерть Теодора Моцкина от сердечного приступа.
  3. 1972 Публикация оригинального алгоритма Роберта Тарьяна.
  4. 2022 Кнут и Тарьян разрабатывают улучшенную версию алгоритма через 50 лет после оригинала.
  5. 3 февраля 2025 Ожидаемая официальная дата публикации новой книги Кнута.
⚖️ Другая сторона
Наука Donald Knuth Robert Tarjan Strongly Connected Components Graph Theory Edsger Dijkstra