Я читал статью о сравнении двух алгоритмов, сначала проанализировав их.

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

Для бывших:

algo printArray(arr[n]){
    for(int i=0;i<n;i++){
    write arr[i];
    }
}

Будет иметь сложность O(N), где N - размер массива. и он повторяет цикл for N раз.

Пока

algo printMatrix(arr,m,n){
    for(i=0;i<m;i++){
        for(j=0;j<n;j++){
        write arr[i][j];
        }
    }
}

Будет иметь сложность O(MXN) ~ O(N^2), когда M=N. операторы внутри for выполняются MXN раз.

Аналогично O(log N). если он делит ввод на 2 равные части. и так далее.

Но согласно этой статье:

Меры Execution Time, Number of statements не подходят для анализа алгоритма.

Так как:

Execution Time будет зависеть от системы и,

Number of statements зависит от используемого языка программирования.

И в нем говорится, что

Идеальное решение - выразить время работы алгоритма как функцию от размера ввода N, то есть f(n).

Это меня немного смутило. Как можно рассчитать время выполнения, если вы считаете время выполнения не лучшим показателем?

Не могли бы эксперты уточнить это?

Заранее спасибо.

1
Vedant Terkar 13 Авг 2014 в 17:53

5 ответов

Лучший ответ

Когда вы говорили «сложность O (N)», это называется «нотацией Big-O», что совпадает с «идеальным решением», которое вы упомянули в своем сообщении. Это способ выражения времени выполнения как функции размера ввода.

Я думаю, вы запутались, когда было сказано «выразить время выполнения» - это не означало выразить его в числовом значении (что такое время выполнения), это означало выразить его в нотации Big-O. Я думаю, вы просто запутались в терминологии.

3
Andrew_CS 13 Авг 2014 в 14:10

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

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

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

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

2
webuster 13 Авг 2014 в 14:10

Обозначение Big-O устраняет константы (как фиксированные затраты, так и постоянные множители). Таким образом, любая функция, выполняющая операции kn+c, является (по определению!) O(n), независимо от k и c. Вот почему часто лучше проводить реальные измерения (профилирование) ваших алгоритмов в действии с реальными данными, чтобы увидеть, насколько они эффективны.

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

Обозначение Big-O становится более ценным по мере перехода к большим наборам данных. Это дает вам приблизительное представление о производительности алгоритма, принимая разумные значения для k и c . Если у вас есть миллион чисел, которые вы хотите отсортировать, то можно с уверенностью сказать, что вы не хотите использовать какой-либо алгоритм O(n^2) и попытаетесь найти лучший алгоритм O(n lg n). Если вы сортируете три числа, теоретическая граница сложности больше не имеет значения, потому что константы доминируют над потребляемыми ресурсами.

Также обратите внимание, что хотя количество операторов, в которых может быть выражен данный алгоритм, сильно различается между языками программирования, количество шагов с постоянным временем, которые необходимо выполнить (на машинном уровне для вашей целевой архитектуры, которая обычно является той, где целочисленная арифметика а доступ к памяти занимает фиксированное время или, точнее, ограничен фиксированным промежутком времени). Это ограничение на максимальное количество шагов с фиксированной стоимостью, требуемое для алгоритма, который измеряет big-O, который не имеет прямого отношения к фактическому времени выполнения для данного ввода, но все же приблизительно описывает, сколько работы должно выполняться для данного набора данных по мере увеличения размера набора.

2
Cameron 13 Авг 2014 в 14:11

При сравнении алгоритмов важна скорость выполнения, о которой говорили другие, но другие факторы, такие как объем памяти, также имеют решающее значение.

Пространство памяти также использует обозначение порядка сложности.

Код может отсортировать массив на месте, используя пузырьковую сортировку, требуя лишь небольшого количества дополнительной памяти O (1). Другие методы, хотя и более быстрые, могут потребовать памяти O (ln N).

Другие более эзотерические меры включают сложность кода, например цикломатическую сложность и Читаемость

2
chux - Reinstate Monica 13 Авг 2014 в 16:29

Традиционно информатика измеряет эффективность (скорость) алгоритма по количеству сравнений или иногда обращений к данным, используя «нотацию Big O». Это так, потому что количество сравнений (и / или доступов к данным) является хорошей математической моделью для описания эффективности определенных алгоритмов, в частности алгоритмов поиска и сортировки, где O (log n) теоретически считается самым быстрым из возможных.

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

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

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

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

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

1
Lundin 13 Авг 2014 в 14:33