kzhereb / kpi-acts-ta2019

Materials for "Algorithm Theory" course
3 stars 0 forks source link

Q02.7. Comparison of theoretical complexity (big-O) with practical measurements #15

Open vldnik opened 5 years ago

vldnik commented 5 years ago

Comparison of theoretical complexity (big-O) with practical measurements Сравнение теоретической сложности (big-O) с практическими измерениями Порівняння теоретичної складності (big-O) з практичними вимірами

Resources that compare theoretical estimates of the complexity of algorithms with practical measurements Measurement details should be provided Availability of the benchmark code (to run and compare with published results) -Extra points for actually running them and comparing with published results

Ресурсы, где сравнивают теоретические оценки сложности алгоритмов с конкретными измерениями Желательно, чтобы были детали измерений И код benchmarks, который можно запустить и сравнить -Дополнительные баллы тем, кто запустит код у себя и сравнит результаты с опубликованными

Ресурси, де порівнюють теоретичні оцінки складності алгоритмів з конкретними вимірами Бажано, щоб були деталі вимірів Та код benchmarks, який можна запустити та порівняти -Додаткові бали тим, хто запустить на своїх пристроях та порівняє результати з опублікованими

alex-rogov commented 5 years ago

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

O(1) показывает то, что алгоритм выполняется за линейный промежуток времени, при этом не зависит от количества или размеров начальных данных. Это демонстрирует код ниже.

private static bool IsFirstElementNullOrEmpty(List elems)
{
    if (elems.Count > 0)
    {
        return string.IsNullOrEmpty(elems[0]));
    }

    return false;
}

O(N) При O(N) производительность алгоритма растет пропорционально размеру заданных данных. Код ниже показывает худший случай выполнения программы. Big O notation всегда будет принимать верхний лимит где алгоритм демонстрирует максимальное количество итераций.

private static bool ContainsValue(List elems, string missingElement)
{
    if (elems.Count > 0)
    {
        for (int i = 0; i< elems.Count; i++)
        {
            if (elems[i].Equals(missingElement))
            {
                return true;
            }
        }
    }
    return false;
}

Классическим примером O(N 2) сложности является Bubble Sort. Алгоритм сравнивает каждый элемент со следующим в списке и меняет их местами, если нужно. В конечном итоге, самый большой элемент будет лидирующим в списке. Худший сценарий O(N 2).

private static int[] BubbleSort(int[] array)
{
    for (int i = array.Length - 1; i >= 0; i--)
    {
        for (int j = 1; j<= i; j++)
        {
            if (array[j- 1] > array[j])
            {
                int temp = array[j- 1];
                array[j - 1] = array[j];
                array[j] = temp;
            }
        }
    }
    return array;
}

Вот визуальное представление о том, как формируется сложность алгоритма сортировки Bubble Sort.

image

vkrasiy commented 5 years ago

https://habr.com/ru/post/188010/ Определение сложности

Наиболее сложными частями программы обычно является выполнение циклов и вызов процедур. В предыдущем примере весь алгоритм выполнен с помощью двух циклов. Если одна процедура вызывает другую, то необходимо более тщательно оценить сложность последней. Если в ней выполняется определённое число инструкций (например, вывод на печать), то на оценку сложности это практически не влияет. Если же в вызываемой процедуре выполняется O(N) шагов, то функция может значительно усложнить алгоритм. Если же процедура вызывается внутри цикла, то влияние может быть намного больше. В качестве примера рассмотрим две процедуры: Slow со сложностью O(N^3) и Fast со сложностью O(N^2). procedure Slow; var i,j,k: integer; begin for i:=1 to N do for j:=1 to N do for k:=1 to N do {какое-то действие} end; procedure Fast; var i,j: integer; begin for i:=1 to N do for j:=1 to N do Slow; end; procedure Both; begin Fast; end;

Простая рекурсия

Напомним, что рекурсивными процедурами называются процедуры, которые вызывают сами себя. Их сложность определить довольно тяжело. Сложность этих алгоритмов зависит не только от сложности внутренних циклов, но и от количества итераций рекурсии. Рекурсивная процедура может выглядеть достаточно простой, но она может серьёзно усложнить программу, многократно вызывая себя. Рассмотрим рекурсивную реализацию вычисления факториала: function Factorial(n: Word): integer; begin if n > 1 then Factorial:=n*Factorial(n-1) else Factorial:=1; end; Эта процедура выполняется N раз, таким образом, вычислительная сложность этого алгоритма равна O(N).

alexzhyshko commented 5 years ago

BigO notation используется для универсального оценивания быстродействия алгоритмов, их оптимальності выполнения и дальшего их улучшения. Есть три вида быстродействия, как их различают: константа, линейная и квадратическая. Следовательно О(1), О(N), O(n^2). Нотация О это свое родное отношение увеличения времени работы при увеличении размера входных данных функции. Чем больше это число при больших N, тем хуже

Ссылка на ресурс информации https://youtu.be/ZRdOb4yR0kk

FairyFox5700 commented 5 years ago

В цій статтті порівнюються практичні виміри з big O нотацією. Описано як працює логарифмчна складність та наскільки впливають показники складності алгориму на реальних даних. Доступ до ресурсу : https://www.freecodecamp.org/news/big-o-notation-simply-explained-with-illustrations-and-video-87d5a71c0174/ Також про це детально описує А. Бхаргава в книзі «Грокаем алгоритмы» сторінки 18 - 36. Тут на простих приклад показано як поводить себе складність на рельних замірах часу. До того ж мітиться багато зображень де все детально проілюстровано.

WalrusPUNCH commented 5 years ago

У статті нижче викладено опис big O нотації, як визначається big O нотація алгоритму та для чого її потрібно використовувати. Приклади доступні на 11 мовах програмування. https://www.interviewcake.com/article/java/big-o-notation-time-and-space-complexity

Також, у пригоді може стати наступне посилання на статтю, у якій вказані основні значення big O нотації для основних алгоритмів сортування, алгоритмів обходу графів та для функцій запису, читання, видалення у різних структурах даних. https://cooervo.github.io/Algorithms-DataStructures-BigONotation/index.html

IlliaKov commented 5 years ago

The Big O notation defines an upper bound of an algorithm, it bounds a function only from above. For example, consider the case of Insertion Sort. It takes linear time in best case and quadratic time in worst case. We can safely say that the time complexity of Insertion sort is O(n^2). Note that O(n^2) also covers linear time.

NikitaViktorov commented 5 years ago

https://www.interviewcake.com/article/java/big-o-notation-time-and-space-complexity

crowl1 commented 5 years ago

Big O - теоретична математична нотація, яка вживається в теорії складності обчислень, інформатиці та математиці. Тому на практиці вона не завжди співпадає з реальністю. Ось статья про використання Big O на практиці https://medium.com/@FelixIT/big-o-notation-%D0%B8-%D0%BF%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%BA%D0%B0-5ed26cabf126

AleksAndriushyn commented 5 years ago

Here's the example of practical use of Big O notation: https://www.baeldung.com/java-algorithm-complexity

galaxyair commented 5 years ago

Теоритичиская сложность отличается от физической(практичной). И этого явления никак не избежать. Зачастую это происходит из-за не учёта низкоуровневых проблем

BogdanDudnik commented 5 years ago

The Big O notation defines an upper bound of an algorithm, it bounds a function only from above. For example, consider the case of Insertion Sort. It takes linear time in best case and quadratic time in worst case. We can safely say that the time complexity of Insertion sort is O(n^2). Note that O(n^2) also covers linear time.