Любой пример алгоритмов, когда мы предпочитаем временную сложность Big O (n ^ 2) O (n logn)? Я где-то видел этот вопрос, но не нашел ответа.
Большой O (n logn) не предпочтительнее, чем O (n ^ 2)
Ответы (4)
Есть несколько причин для выбора алгоритма с более высокой временной сложностью:
- Скорость: асимптотическая сложность применяется только к значениям n больше некоторого n_0. Кроме того, предполагается, что под ним находится некая машина, которая лишь частично соответствует реальным машинам с несколькими уровнями кеша и ограниченной памятью.
- Пространство: некоторые алгоритмы требуют больше места, чем другие, и поэтому их невозможно реализовать. Кроме того, это может просто повлиять на скорость на реальной машине. Например, локальность ссылок влияет на попадание или промах в кэш, поэтому быстрая сортировка работает лучше, чем сортировка слиянием.
- Сложность реализации: в некоторых случаях потеря производительности просто незначительна, но время разработки — нет.
Для большой проблемы O (n log n) всегда будет лучше O (n ^ 2). Для небольшой задачи постоянные факторы, скрытые за нотацией большого O, могут заставить вас предпочесть алгоритм O (n ^ 2). Например, быстрая сортировка O(n log n) быстрее, чем сортировка вставками O(n^2), но некоторые реализации быстрой сортировки переключаются на сортировку вставками, когда разделы становятся маленькими (менее десяти элементов).
n0
, так что для всех n > n0
... Кроме того, это n0
может быть на удивление большим.
- person Ulrich Eckhardt; 05.02.2016
Многие наивные алгоритмы O(n^2) работают быстрее на небольших входных данных, чем их более сложные O(n log(n)) собратья.
Например, библиотека GNU MP Bignum имеет очень оптимизированную реализацию умножения. Но для чисел, состоящих из пары десятков слов, используется просто умножение из школьного учебника (наилучший порог сильно зависит от машина). На самом деле GMP проходит через целую последовательность самых быстрых алгоритмов X-размера а>.
Одна возможность - алгоритм O (n logn) является рекурсивным, но вы можете программировать O (n ^ 2) итеративно, а ваш язык программирования, который вы должны использовать, не поддерживает рекурсию.
«Предпочтительный» здесь относителен, кстати. Если набор данных был достаточно большим, вы МОГЛИ эмулировать рекурсию, используя свою собственную переменную стека, которой вы манипулируете в версии «рекурсивного» алгоритма, которая была реализована итеративно (мы должны были сделать это упражнение в классе сравнительного программирования Гая Стила в CMU). в старые времена).