Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Существуют ли реальные алгоритмы со сложностью O(1/n)?


Существуют ли реальные алгоритмы со сложностью O(1/n)? В голову лезет только ерунда по типу:

function test(n) {
  for (i=1; i<100000/n; i++) {
    dosomething();
  }
}

    


Ответы

Ответ 1



Их даже в теории не существует. Потому что это ограничение сверху. O(C + 1/n) = O(C) = O(1) Где C - некоторая константа, отличная от 0. А 0 она не может быть равна, поскольку у нас в любом случае есть накладные расходы хотя бы на получение самого n и какое-то его использование. Потому что если мы не используем n вообще, то сложность, очевидно, от него не зависи и не может быть O(1/n). А если используем, то мы хоть раз к нему обратимся и константа будет ненулевой. Альтернативное обоснование: представим, что такой алгоритм есть, но тогда при удвоени n время его исполнения уменьшается вдвое и при достаточно большом n должно будет стать менее одной процессорной инструкции, что невозможно. Даже в коде из вопроса for (i=1; i<100000/n; i++) { что произойдёт, когда n превысит 100000? У нас будет ровно 4 операции: присваивание, деление, сравнение и выход из функции. Это O(1) - оно уже неспособно уменьшиться с ростом n.

Ответ 2



Нет, не существует. Сначала вспомним, что такое асимптота: Пусть у нас есть некая кривая y = A(x). Тогда асимптота y = B(x) — это такая кривая, к которой A как бы «прижимается» при движении в бесконечность вдоль оси x. Графически это выглядит так: Источник: https://en.wikipedia.org/wiki/File:1-over-x-plus-x.svg В данном примере прямая y = x является асимптотой для y = 1 / x + x, так как пр достаточно больших x обе линии практически сливаются. Асимптотатическая сложность ведёт себя аналогичным образом, только вместо графиков у нас зависимость вычислительной сложности от количества элементов. Соответственно, чтобы утверждать, что алгоритм имеет сложность O(1 / N), надо, чтоб график сложности алгоритма совпадал с графиком 1 / n при очень больших n. Но в этом случае 1 / n вырождается в константу ноль. А раз у нас константа, значит и алгоритм имеет константную сложность, обозначаемую как O(1).

Ответ 3



А вообще, есть интересный случай. В большинстве случаев говоря об асимптотике м предполагаем возрастание аргумента. Но, строго говоря, это может быть не так. Например, если мы знаем, что область определения некоторой функции ограничена. Возьмём и реализуем деление int(1/x) через вычитание: function f(x) { for (var i=0, v=1; v>0; ++i, v-=x); return i; } console.log(f(1)); console.log(f(.5)); console.log(f(.25)); console.log(f(.125)); console.log(f(.0625)); console.log(f(.0000001)); В принципе можно сказать, что у этой функции асимптотика O(1/x), т. е. при маленьки значениях x она будет работать очень медленно (кстати, ещё и неточно из-за накопления погрешноти). Разумеется, в случае с целым аргументом такой вариант будет невозможен.

Комментариев нет:

Отправить комментарий