Каковы причины для изучения различных алгоритмов / структур данных, служащих одной и той же цели?


92

Я задавался вопросом об этом вопросе, так как я был студентом. Это общий вопрос, но я приведу примеры ниже.

Я видел много алгоритмов - например, для задач с максимальным потоком я знаю около 3 алгоритмов, которые могут решить эту проблему: Ford-Fulkerson, Edmonds-Karp & Dinic, причем Dinic имеет лучшую сложность.

Для структур данных - например, куч - есть двоичные кучи, биномиальные кучи и кучи Фибоначчи, причем куча Фибоначчи имеет лучшую общую сложность.

Что меня смущает: есть ли причины, по которым мы должны знать их всех? Почему бы просто не изучить и познакомиться с лучшим из них?

Я знаю, что лучше всего, если мы знаем их всех, я просто хочу знать, есть ли какие-либо «более веские» причины, например, некоторые проблемы / алгоритмы могут быть решены только с помощью A, но не B и т. Д.


17
Как я всегда говорю: эти (обычно) не «лучшие». Как только вы четко определите, что вы подразумеваете под «лучше», ответ становится очевидным.
Рафаэль

2
Это хороший вопрос, но он говорит о том, что я считаю дырой в вашем образовании, которую вы могли бы исправить. Это практический опыт: если вы на самом деле не писали эти алгоритмы во время обучения, вы могли бы написать их сейчас, я подозреваю, что ответ на этот вопрос станет быстро очевидным, если вы попытаетесь найти их применение.
Сэм

@Sam Из моего опыта я подумал, что в лекциях или в некоторых учебниках они информативны, содержат много алгоритмов, анализ и т. Д., Но не так много практических случаев или примеров сценариев, в которых A будет переигрывать B. Они могут охватывать жанр алгоритмов от А до Я, и некоторые домашние задания, но для меня все они могут быть решены только А или только Z и т. д., таким образом, вопрос задан.
Shole

5
Если вы настаиваете на том, чтобы оставить академический интерес в стороне, лучшим практическим поводом для изучения неоптимальных алгоритмов является то, чтобы вы могли распознать их такими, какие они есть, и оптимизировать их путем рефакторинга до оптимальных. Вы не можете улучшить лук и стрелу до оружия, если не знаете, для чего предназначены лук и стрела.
candied_orange

1
На самом деле мы предложили сайт StackExchange, чтобы конкретно помочь с такими вопросами CS образования, как этот. Приходите поддержать нас здесь: area51.stackexchange.com/proposals/92460/…
vk2015

Ответы:


121

В какой-то момент есть учебник с рабочим названием Структуры данных, Алгоритмы и Компромиссы . Почти каждый алгоритм или структура данных, которые вы, вероятно, изучите на уровне бакалавриата, имеет некоторые особенности, которые делают его лучше для некоторых приложений, чем для других.

Давайте рассмотрим сортировку в качестве примера, поскольку все знакомы со стандартными алгоритмами сортировки.

Во-первых, сложность не единственная проблема. На практике постоянные факторы имеют значение, поэтому, скажем, быстрая сортировка имеет тенденцию использоваться больше, чем сортировка в куче, даже если быстрая сортировка имела ужасную сложность в худшем случае.

Во-вторых, всегда есть вероятность, что вы окажетесь в ситуации, когда вы программируете в странных условиях. Мне когда-то приходилось делать квантильное извлечение из выборки небольшого размера (1000 или около того) как можно быстрее, но это было на небольшом микроконтроллере, у которого было очень мало свободной памяти для чтения и записи, так что исключалось большинство сортировать алгоритмы. Сортировка оболочки была лучшим компромиссом, поскольку она была субквадратичной и не требовала дополнительной памяти.O(nlogn)

В других случаях идеи из алгоритма или структуры данных могут быть применимы к задаче специального назначения. Bubble sort, кажется, всегда медленнее, чем сортировка с вставкой на реальном оборудовании, но идея выполнения Bubble Pass иногда именно то, что вам нужно.

Рассмотрим, например, какую-то 3D-визуализацию или видеоигру на современной видеокарте, где вы хотите рисовать объекты в порядке от ближайшего к камере до самого дальнего от камеры по соображениям производительности, но если вы не получите точный заказ, оборудование позаботится об этом. Если вы перемещаетесь по трехмерной среде, относительный порядок объектов не сильно меняется между кадрами, поэтому выполнение одного прохода пузыря на каждый кадр может быть разумным компромиссом. (Механизм Source от Valve делает это для эффектов частиц.)

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

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


7
Отличный ответ с отличными примерами! Не знал, что даже пузырьковый проход имеет свое практическое применение в реальном мире ...
Shole

1
@shole У меня нет большого опыта в игровом бизнесе, но все вышеперечисленное важно в разной степени. (Очевидно, что алгоритмы, структуры данных и математика, которые вам нужны для игр, вероятно, отличаются от тех, которые требуются для баз данных, биоинформатики или чего-то еще.) Если бы я был вами, я бы пошел сюда и начал смотреть: handmadehero. org Также стоит потаскать
Псевдоним

1
Эффективность кеширования является важным фактором, который недостаточно изучен (Google «стена памяти»).
Рафаэль

6
Осторожно, Quicksort в среднем намного быстрее, чем Heapsort, но Heapsort более последовательный (разница во времени выполнения меньше, а в худшем случае гораздо лучше). И скачки Heapsort в массиве по сравнению с линейным сканированием Quicksort слева и справа имеют огромное значение, когда кэш / пейджинг вступает в игру.
vonbrand

1
@shole Какая разработка игр вас интересует? Есть как минимум два совершенно разных подполя, 3D-графика и геймплей (включая AI). У меня есть только опыт работы с графикой, но я могу сказать, что структуры данных и математика чрезвычайно важны в графике, а также в меньшей степени в алгоритмах. Если вы используете движок, большинство этих вещей, конечно же, позаботятся, но вы все равно должны понимать основную математику трехмерной геометрии.
садовник

51

Помимо того, что на множестве моделей машин (TM, RAM, PRAM, ...) существует множество способов измерения затрат (время выполнения, использование памяти, ошибки в кэше, неправильные прогнозы веток, сложность реализации, возможность проверки ...) При рассмотрении среднего по сравнению с наихудшим случаем, а также соображений амортизации для сопоставления друг с другом, часто существуют также функциональные различия, выходящие за рамки базовой спецификации учебника.

Некоторые примеры:

  • Mergesort стабилен там, где Quicksort нет.
  • Деревья бинарного поиска дают вам итерации по порядку, хеш-таблицы - нет.
  • Беллман-Форд может справиться с отрицательными весами, Дейкстра - нет.

Есть также дидактические соображения :

  • Насколько легко понять более сложное решение перед более простыми? (Деревья AVL (и их анализ) без BST; Dinic без Ford-Fulkerson; ...)
  • Видите ли вы те же принципы и закономерности, когда вы сталкиваетесь с одним решением на одну проблему по сравнению со многими решениями?
  • Достаточно ли обучения (к овладению) дает экспозиция только по одному решению проблемы?
  • Должны ли вы знать, какие решения были найдены (чтобы не изобретать колесо снова и снова?)?
  • Когда вы столкнетесь с одним решением для каждой проблемы, поймете ли вы другие решения, которые вы найдете в дикой природе (скажем, в реальной библиотеке программирования)?

  1. Это то , что мы видим много из типов программаторов , которые не имеют богатый CS набора инструментов в их распоряжении.

4
+1 за включение дидактических обоснований! Относительно нескольких обоснований (особенно второго и третьего), понимание того, как алгоритмы и структуры данных разрабатываются и оптимизируются, учит методам разработки и оптимизации и пониманию компромиссов (обучение не только «что», но также «как» и «почему»). ).
Пол А. Клейтон,

2
Еще одно соображение заключается в том, что анализ различных альтернатив предлагает примеры полезных инструментов для анализа новых алгоритмов для, возможно, необычных настроек.
vonbrand

1
Хороший вопрос, @vonbrand. Амортизированный анализ сложности был изобретен, чтобы понять поведение splay-деревьев, но splay-деревья редко используются на практике. Ну, во всяком случае, не расклеивать деревья. Ядро Windows NT, как известно, использует splay-деревья для реализации карт виртуальной памяти, но не меняет порядок при каждом поиске.
псевдоним

1
@ vonbrand Да. Однако я бы понял, как кто-то, кто больше всего интересуется размером набора инструментов в классе алгоритмов, посмеялся бы над этой причиной.
Рафаэль

7

В реальном мире в какой-то момент вы, вероятно, будете работать над программным обеспечением, написанным группой других людей. Некоторые из этих программ будут написаны еще до вашего рождения!

Чтобы понять используемые алгоритмы / структуры данных, очень полезно знать большое количество алгоритмов / структур данных, включая параметры, которые больше не рассматриваются как «современные».

Вам также придется работать над алгоритмами, которые не являются стандартными и используются только в приложении, над которым вы работаете. Когда вам нужно улучшить эти алгоритмы, вы обнаружите, что ваш мозг наполнился полезными методами для улучшения алгоритмов, так как вы изучили, как другие люди улучшили алгоритмы.

Это то, что отличает того, кто изучал информатику, от человека, который только что научился программировать. В большинстве работ, в которых я работал, было время, когда, изучая информатику, я мог решить проблему, которую не мог «программист из книг», но в 95% случаев я обнаружил, что изучение информатики не дает мне никаких преимуществ. над другими опытными программистами .


если 95% вещей, которые вы пытаетесь решить, не связаны с машинным обучением. Я не понимаю, как нормальный программист может даже иметь правильный шанс попробовать любую из проблем, с которыми сталкиваются настоящие проблемы ОД.
Буратино

3
Цель: получить работу с лучшей ставкой, чем 5%.
Рафаэль

Помните, что изучение CS было отличным способом сбора знаний об алгоритмах и структурах данных. Кодирование - лучшее занятие для программистов.
седобородый

5

Многие справедливо отмечают, что зачастую нет одного лучшего алгоритма - это зависит от ситуации.

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


5
Этот ответ только повторяет очки от старых.
Рафаэль

1

Множество хороших ответов, просто, я думаю, чего-то не хватает, хотя в ответе Рафаэля это несколько упоминается.

Простота реализации также является чем-то, что необходимо учитывать.
Обычно это не проблема с алгоритмами сортировки, потому что большинство платформ / языков уже имеют один реализованный (и часто лучше, чем то, что вы могли бы сделать), но более необычные алгоритмы могут быть недоступны.
В зависимости от вашей проблемы, вам может не потребоваться абсолютный наилучший алгоритм, если время внедрения составляет 1 день против 2 недель.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.