Algos — греческое слово, означающее боль. Algor — латинское слово, означающее холод. Но ни то, ни другое не является корнем слова «алгоритм», которое происходит от имени Аль-Хорезми – арабского ученого девятого века – чья книга «al-jabr wa’l muqabalah» (Китаб аль-джебр ва-ль-мукабала) переросла современные учебники по алгебре для средней школы. Аль-Хорезми подчеркивал важность методических процедур для решения задач. Будь он сегодня здесь, то, несомненно, был бы впечатлен вершинами математического метода, названного в его честь.
Часть из лучших алгоритмов компьютерной эры были освещены в январско-февральском выпуске 2000 года журнала Computing in Science & Engineering — совместном издании Американского института физики и Компьютерного общества IEEE. Приглашенные редакторы Jack Dongarra (Джек Донгарра) из Университета Теннесси и Francis Sullivan (Фрэнсис Салливан) из Института оборонного анализа составили список из 10 алгоритмов, который они назвали «Top Ten Algorithms of the Century».
«Мы попытались собрать 10 алгоритмов, оказавших наибольшее влияние на развитие и практику науки и техники в 20 веке», — пишут Донгарра и Салливан. По признанию авторов, как и в любом рейтинге, их выборы неизбежно будут спорными. Когда дело доходит до выбора лучшего алгоритма, кажется, что он и вовсе не существует.
Итак, вот список 10 лучших алгоритмов в хронологическом порядке. (Все даты и имена стоит воспринимать как аппроксимацию первого порядка. Большинство алгоритмов формируются в течение времени при участии многих ученых).
1946. Метод Монте-Карло
Джон фон Нейман, Станислав Улам и Николас Метрополис, работая в Лос-Аламосской научной лаборатории, разработали алгоритм Метрополиса, также известный как метод Монте-Карло.
Алгоритм Метрополиса предназначен для получения приближенных решений численных задач с неуправляемым числом степеней свободы и комбинаторных задач факториального размера путем имитации случайного процесса. Учитывая репутацию цифрового компьютера как детерминированного устройства, вполне уместно считать, что одним из самых ранних его применений была генерация случайных чисел.
1947. Симплекс-метод
Джордж Данциг, работавший в корпорации RAND, создал симплекс-метод для линейного программирования. С точки зрения широты применения алгоритм Данцига является одним из самых успешных за все время: линейное программирование доминирует в мире промышленности, где экономическое выживание зависит от способности к оптимизации в рамках бюджета и других ограничений. (Конечно, «реальные» проблемы промышленности зачастую нелинейны; использование линейного программирования иногда диктуется computational budget). Симплекс-метод — это элегантный способ решения оптимизационных задач. Хотя в теории алгоритм и подвержен экспоненциальным задержкам, на практике он очень эффективен, что само по себе говорит кое-что интересное о природе вычислений.
1950. Подпространство Крылова
Магнус Хестенес, Эдуард Штифель и Корнелий Ланцош, все из Института численного анализа при Национальном бюро стандартов, начали разработку итерационных алгоритмов подпространства Крылова.
Эти алгоритмы решают, казалось бы, простую задачу — решение уравнений вида Ax = b. Загвоздка заключалась в том, что A — это огромная матрица n * n, так что алгебраический ответ x = b/A не так-то просто вычислить. (И действительно, «деление» матрицы не является особенно полезным понятием.) Итерационные методы, например решение уравнений такого вида:
с более простой матрицей K, которая идеально «близка» к матрице A, привели к изучению подпространств Крылова. Ланцош нашел отличный способ сгенерировать ортогональный базис для такого подпространства, когда матрица является симметричной. Хестенес и Штифель предложили еще более хитрый метод, известный как метод сопряженного градиента, для систем, которые являются симметричными и положительно определенными. За последние 50 лет большое количество исследователей внесли свой вклад в развитие этих алгоритмов, улучшив и расширив их.
Современный набор алгоритмов включает методы для несимметричных систем с такие, как GMRES и Bi-CGSTAB. (GMRES и Bi-CGSTAB были впервые опубликованы в журнале SIAM Journal on Scientific and Statistical Computing в 1986 и 1992 гг, соответственно).
1951. Матричные вычисления
Элстон Хаусхолдер из Окриджской национальной лаборатории формализовал декомпозиционный подход к матричным вычислениям.
Возможность разложения матриц на треугольные, диагональные, ортогональные и другие специальные формы оказалась чрезвычайно полезной. Декомпозиционный подход позволил разработчикам программного обеспечения создавать гибкие и эффективные матричные пакеты. Также такой подход облегчил анализ ошибок округления, одной из главных проблем численной линейной алгебры. (В 1961 году Джеймс Уилкинсон из Национальной физической лаборатории в Лондоне опубликовал в журнале ACM основополагающую работу под названием «Анализ ошибок прямых методов инверсии матриц», основанный на LU-разложении матрицы как произведения нижнего и верхнего треугольных коэффициентов).
1957. Fortran
Джон Бэкус возглавлял группу в IBM по разработке оптимизирующего компилятора Fortran.
Создание Fortran может считаться одним из самых важных событий в истории компьютерного программирования: наконец-то ученые (и другие пользователи) могли сообщить компьютеру, чего они хотят без необходимости погружаться в мир машинного кода.
Хотя, конечно, по современным стандартам компиляторы были скромными — Фортран I состоял всего из 23 500 инструкций на языке ассемблера. Но, тем не менее, «ранний» компилятор был способен на удивительно сложные вычисления. По воспоминания самого Джона Бэкуса (в опубликованной в 1998 году статье) компилятор создавал невероятно эффективный код, поражавший программистов.
1959-1961. QR-алгоритм
Джон Фрэнсис из компании Ferranti Ltd. нашел устойчивый метод вычисления собственных значений, известный как QR-алгоритм.
Собственные значения — это, пожалуй, самые важные числа, связанные с матрицами, и порой их очень сложно вычислить. Относительно легко преобразовать квадратную матрицу в «почти» верхнетреугольную матрицу с дополнительным набором ненулевых записей чуть ниже главной диагонали. Но убрать эти ненулевые значения, не допустив лавины из ошибок — нетривиальная задача. Алгоритм QR — это как раз то, что нужно для решения этой задачи. На основе QR-разложения, которое записывает матрицу A как произведение ортогональной матрицы Q и верхнетреугольной матрицы R, этот подход итеративно меняет на , с несколькими дополнениями для ускорения сходимости к верхнетреугольной форме. К середине 1960-х годов алгоритм QR превратил некогда серьезные проблемы собственных значений в рутинные вычисления.
1962. Quicksort
Тони Хоар из компании Elliott Brothers, Ltd., Лондон разработал алгоритм Quicksort.
Расположить N предметов в числовом или алфавитном порядке — это скучная рутина. Интеллектуальный вызов заключается в том, чтобы сделать это быстро. Алгоритм Хоара использует вековую рекурсивную стратегию «разделяй и властвуй» для решения проблемы: необходимо выбрать один элемент в качестве «стержня», разделить остальные на кучи «больших» и «маленьких» элементов (по сравнению со стержнем), а затем повторить процедуру с каждой кучей. Хотя можно и встрять, выполнив все N(N — 1)/2 итераций (особенно выбрать в качестве стержня первый элемент отсортированного списка), средняя сложность Quicksort составляет O(N log N). Элегантная простота сделала Quicksort образцом вычислительной сложности
1965. Быстрые преобразования Фурье
Джеймс Кули из Исследовательского центра IBM и Джон Тьюки из Принстонского Университета разработали быстрые преобразования Фурье.
Несомненно, как самый масштабный алгоритм в прикладной математике, БПФ произвели революцию в области обработке сигналов. Основополагающая идея восходит к Гауссу (которому когда-то нужно было вычислить орбиты астероидов), но именно из работы Кули-Тьюки стало ясно, насколько легко могут вычисляться преобразования Фурье.
Подобно Quicksort, БПФ опирается на стратегию «разделяй и властвуй», чтобы сократить якобы квадратичную сложность до O(N log N). Но в отличие от Quicksort, реализация БПФ (на первый взгляд) нетривиальна и не интуитивна. Это дало толчок к исследованию сложности, присущей вычислительным задачам и алгоритмам.
1977. Поиск целочисленных соотношений
Хеламан Фергюсон и Родни Форкейд из Университета Бригама Янга разработали алгоритм обнаружения целочисленных отношений.
Формулировка проблемы такая: пусть — набор вещественных чисел. Существует ли набор целых числа (хотя бы одно из которых не равно нулю), для которых ? При n = 2 с этой задачей справляется старый добрый алгоритм Евклида, работающий на дробном разложении x1/x2. Если x1/x2 рационально, то разложение, в конечном счете, завершится и, при правильном подходе, даст наименьшие целые a1 и a2.
Если алгоритм Евклида не завершается (или если вы просто устали его вычислять), то алгоритм, по крайней мере, даёт нижнюю границу наименьшего целочисленного отношения. Обобщение Фергюсона и Форкейда, которое гораздо сложнее реализовать и понять, является более мощным. Их алгоритм обнаружения, например, был использован для нахождения точные коэффициенты полиномов, которым удовлетворяют третья и четвертая точки бифуркации: B3 = 3,544090 и B4 = 3,564407, логистической карты. (Последний полином имел степень 120; его наибольший коэффициент равен 25730). Этот подход также оказался полезным для упрощения вычислений с диаграммами Фейнмана в квантовой теории поля.
1987. Мультиполя
Лесли Грингард и Владимир Рохлин из Йельского университета изобретают метод быстрого мультиполя.
Этот алгоритм преодолевает одну из самых больших головных болей при моделировании системы из N тел: точные расчеты движения N частиц, взаимодействующих посредством гравитационных или электростатических силы (вспомните звезды в галактике или атомы в белке), казалось бы, требуют O(N2) вычислений — по одному для каждой пары частиц. Но сложность быстрого метода мультиполя равна O(N). Это достигается путем использования мультипольных разложения (чистый заряд или масса, дипольный момент, квадруполь и т.д.) для аппроксимации влияния удаленной группы частиц на локальную группу. Иерархическая декомпозиция пространства используется для определения всё более крупных групп по мере увеличения расстояния.
Одно из явных преимуществ быстрого мультипольного алгоритма заключается в том, что он оснащен строгими оценками ошибок, чего не хватает многим другим методам.
Какие новые идеи и алгоритмы принесет 21 век? Полный ответ на этот вопрос, очевидно, будет известен лишь через сто лет. Одно кажется несомненным. Как пишет Салливан во введении «новый век не будет для нас очень спокойным, но и скучным он тоже не будет!»
Комментарии (38)
EvilMan
17.05.2022 13:17+10Предлагайте свои варианты значимых алгоритмов. Начну с себя:
алгоритм сортировочной станции (преобразование инфиксной нотации в обратную польскую нотацию)
алгоритм Дейкстры (поиск кратчайшего пути в графах)
алгоритм Ахо-Корасик (поиск множества совпадений в строке за один проход)
Krasnoarmeec
17.05.2022 18:45+5Алгоритм MP3. Всунуть психоакустику в алгоритм это вообще гениально!
domix32
18.05.2022 15:12Так там же и есть FFT из статьи
Krasnoarmeec
18.05.2022 19:36FFT это не самая главная особенность MP3 алгоритма. Дело в том, что MP3 использует психоакустическую модель, в частности, эффект маскирования. Грубо говоря, алгоритм отсекает все частоты, которые слушатель не услышит по той причине, что соседняя частота имеет большую интенсивность.
domix32
18.05.2022 19:56Это опять же тонкий тюнинг FFT. Сложно назвать расчёт некоторого трешхолда для фреймов спектра каким-то отдельным алгоритмом, главным образом потому что это нечто не универсальное, в отличие от FFT или того же поиска пути Дийкстры. JPEG тоже использовал похожий подход, но уже для кодирования цветов, такой же тонкий тюнинг под восприятие глаза.
arheops
19.05.2022 01:28Это не более чем пред-тюнинг/шумокорекция FFT. Впричем вполне очевидный.
Как и использование апроксимации при низких битрейтах ДО самого FFT
Balling
19.05.2022 01:01Алгоритм Риша для нахождения первообразной в символьном виде. И все его расширения.
Алгорим Грунца для нахождения пределов любой сложности.
Первый вообще еще никто полностью не запилил в коде.
flamehj
19.05.2022 10:28На фоне алгоритма QR-алгоритма разложения матриц не упомянули не менее именитое SVD-разложение (которое делается на QR-разложениях).
randomsimplenumber
17.05.2022 22:58SHA256, пожалуй, самый часто используемый алгоритм.
LordDarklight
18.05.2022 09:40+1SHA-2 - это уже 2002 год, т.е. XXI век, а в статье алгоритмы XX века - но да, в XX была разработана основа в виде MD2 (1989), MD4, MD5 и SHA-1 - которые были широко применимы на рубеже веков, да и сейчас тоже - но уже в меньшей степени!
funny_falcon
19.05.2022 00:20Я бы назвал гениальным RC4. Такой простой код, и продержался 20 лет до значительного скачка вычислительной мощности. И то до сих пор требуются десятки часов, куча железа и большой объём known plaintext.
mbait
18.05.2022 01:44+1Marching cubes для создания полигональной сетки из произвольно заданного скалярного поля. Позволяет легко создавать 3D модели аналитических функций, в том числе заданных неявно (f(x,y,z) = 0).
Алгоритм Вагнера-Фишера для вычисления редакционного расстояния (расстояние Левенштейна), который часто ошибочно называют алгоритмом Левенштейна. Параллельно был изобретён Нидлманом и Вуншом, но уже применительно к биоинформатике.
domix32
18.05.2022 20:10А есть какое-то широкое применение марширующих n-гонов? Для всяких игр понятно, но использующих этот подход не так много. Вики подсказывает, что построение моделей из МРТ. А больше сходу ничего и не придумать.
0serg
18.05.2022 22:45Очень широко используется в 3D сканерах и вообще любом коде где требуется сформировать полигональную поверхность.
Germanjon
18.05.2022 09:13+1Как так вышло, что в статье перемешаны и алгоритмы и язык программирования
LordDarklight
18.05.2022 09:37Только ЯП Fortran затесался - ему действительно тут не место
В остальном - по большей части одна сплошная математика - да - понятно - что это всё автоматизируется на вычислительных системах - но то о чём идёт речь (более чем 60% "алгоритмов") приводится именно как описание математических методов - причём в виде очень бестолковых описаний, чисто для "тех кто в танке". Спорить не буду - что большинство математических методов ещё до нашей эры по сути можно считать алгоритмами, созданными для вычислительной биосистемы - человеческий мозг - алгоритм вообще понятие уж очень обобщённое, и да - спорить не буду - что приведённые здесь алгоритмы в XX веке по больше части были автоматизированы уже на вычислительных системах. Но всё таки - статья как-то не оправдала ожидания - ожидал увидеть именно алгоритмы в программном коде (хоть на псевдоязыке) именно из мира цифровых систем, а не для решения математических задач (что не спорю - тоже очень важно и применимо в цифровых системах)
ShashkovS
18.05.2022 11:09+4Мне кажется, что чтобы алгоритм можно было признать «лучшим алгоритмом 20-го века», у него в 20-м веке не должно быть альтернатив.
Скажем ни одна сортировка не подходит: их есть куча «эффективных»: Хоара, слиянием, пирамидальная и т.д.
То же самое с хешированием. Adler-32, FNV-1, PJW-32, MD4, MD5, SHA-1 — их много.
Вот симплекс метод, матричные вычисления, быстрое преобразование Фурье, коды Рида-Соломона, обход в ширину + в глубину, Диффи-Хеллман — в рамках 20-го века (некоторые из них даже и в рамках 21-го) совершенно безальтернативны.funny_falcon
19.05.2022 08:52Ну, не соглашусь в некоторых моментах.
Безальтернативность - не показатель. Например, quicksort: да, ему есть альтернативы. Но сам по себе он гениален, и служит базой для многих. Изучая его и его вариации (introsort) программист понимает несколько вещей: алгоритм может и не иметь гарантированного времени работы, но оставаться хорошим в большинстве случаев; рандом и/или небольшой пред-анализ на каждом шаге может значительно увеличить стабильность времени выполнения; можно обнаружить «плохой случай» и переключиться на алгоритм с гарантией по времени; в вычислительной сложность алгоритма на маленьких объёмах уже нельзя игнорировать константу, и иногда выгоднее переключиться на квадратичный алгоритм с меньшей константой.
Вот сколько всего можно подчерпнуть, изучая историю quicksort.
А приведённые вами алгоритмы тоже не все безальтернативны. Например, код Рида-Соломона лишь один из многих кодов восстановления.
T968
Без Канторовича, Карацубы, RSA совсем список не смотрится.
Tiriet
Диффи-Хеллмана еще и Рида-Соломона- они гораздо чаще Карацубы и Канторовича используются, да и мультиполя или Монте-Карло тоже не такие чтоб прямо часто встречающиеся алгоритмы. И Диффи-Хеллмана наверное надо вперед РСА ставить. Канторович и Карацуба- это сильно нишевые какие-то алгоритмы (особенно Карацуба- хоть раз кто-то его использовал из здесь присутствующих?). хотя, если уж тут мультиполе включили в список- то наверно тогда Канторович тоже подходит.
T968
Каждый раз при использовании openssl
Куда уж чаще))
Tiriet
Однако, не знал. С универа запомнилось, что Карацуба начинает заметно выигрывать перед обычным длинным умножением только на очень больших числах- в тысячи знаков, удивлен, что его засунули в SSL- там числа не такие жирные. Сравнение скоростей было на хабре, кстати: https://habr.com/ru/post/262705/
funny_falcon
1024 бита - не такие жирные? Причём вроде же в степень возводятся, а не просто умножаются
Tiriet
1024 бита это 128 байт или 16 целых чисел. это короткие числа с точки зрения арифметики длинных чисел (где нередки числа на десятки-сотни тысяч знаков), кроме того, возведения в степень используются там в рамках модульной арифметики- поэтому сильно длинных чисел не возникает.
Balling
GMP/gcc давно перешли на Schönhage–Strassen алгоритм (для чисел от 33000 цифр) для умножения и собственный алгоритм для деления, причем некоторые уже умудрились написать в коде еще более сложный алгоритм Фюрера, созданный в 2007. https://en.wikipedia.org/wiki/Fürer's_algorithm
saipr
Уж если упомянули openssl, то и NSS (Network Security Services)
Вот теперь будет совсем часто.
Krasnoarmeec
Вы не поверите, но я пользовался методом Карацубы. Времени правда утекло с тех пор порядочно, так что подробности надо поднимать из бэкапов. Кстати, до того момента о нём не знал.
Deosis
Алгоритм Карацубы ещё важен тем, что показал, насколько глубока кроличья нора.
До него предполагали, что если за несколько сотен лет не нашли способ перемножать длинные числа эффективнее, чем столбиком, то такого способа не существует.
domix32
Тут недавно дожали таки алгоритм до доказанного минимума, правда имплементаций так и не показали.
Balling
Сам минимум не доказан.
domix32
Было доказано, что должен существовать алгоритм с определённой асимптотики, которая является минимальным на текущий момент. Собственно, к этому минимуму и был доделан алгоритм. Могут ли существовать ещё асимптотики меньше или нет - не доказано. Это я и имел ввиду.
omxela
Вы несколько подменяете понятия. В оригинале статья называется "The Best of the 20th Century: Editors Name Top 10 Algorithms". Можно сколько угодно дискутировать на тему, что значит "лучший", но это точно не "чаще", или не столько "чаще". Тем более, что дальше стоИт "по мнению редакции".
Tiriet
если стоит пометка "по мнению редакции"- то тогда обсуждать и уж тем более критиковать предмет статьи или ее выводы нельзя? а зачем же тогда ее опубликовали?