Подтвердить что ты не робот

Что означает "в постоянное время"?

Я работаю программистом, но у меня нет опыта в области компьютерных наук, поэтому недавно я следил за отличным введением MIT OpenCourseWare в области компьютерных наук и программирования. В ходе которого задается вопрос: "будет ли любая программа, написанная с использованием только определений функций и вызовов, базовых арифметических операторов, присваивания и условных выражений выполняется в постоянное время?"

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

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

Если кто-то может дать мне авторитетное определение "в постоянное время" и последствия этого, я был бы очень благодарен!

4b9b3361

Ответ 1

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

Сравните это, например, с линейным временем (для некоторого ввода n), который часто будет фактически размером входных данных, а не прямым значением), что означает, что верхняя граница времени может быть выражена как mn + k для некоторых значений m и k.

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

int foo(int n)
{
    if (n == 0)
    {
        return 0;
    }
    int j = n + 1;
    int k = j * 2;
    return k;
}

Это делает больше работы в случае, когда n отличен от нуля, чем в случае, когда он равен нулю. Тем не менее, это все еще постоянное время - самое большее, это будет делать одно сравнение, одно добавление и одно умножение.

Сравним это с рекурсивной функцией:

public int foo(int n)
{
    if (n <= 1)
    {
        return 1;
    }
    return n * foo(n - 1);
}

Это будет возвращать n раз - поэтому оно линейно в n. Однако вы можете стать намного хуже линейного. Рассмотрим этот метод вычисления числа Фибоначчи:

public int fib(int n)
{
    if (n == 0)
    {
        return 0;
    }
    if (n == 1)
    {
        return 1;
    }
    return fib(n - 2) + fib(n - 1);
}

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

Ответ 2

"Постоянное время" означает, что операция будет выполняться в течение некоторого времени (или пространства памяти - это часто измеряемая вещь) независимый от размера ввода. Обычно вы выбираете переменную (используйте n), чтобы указать размер ввода.

O(1) - постоянное время - время работы не зависит от n

O(n) - линейное время - время работы линейно пропорционально n

O(n^2) - квадратичное время - время работы пропорционально квадрату n

Это всего лишь несколько примеров; возможности безграничны. См. Статью wiki в complexity

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

int n = // some value
doSomething
doSomething
doSomething

Обратите внимание, что это три значения длины, независимо от того, что n. O(1)

int n = // some value
def f(n):
    if n == 0 return
    doSomething
    f(n-1)
f(n)

Теперь мы запускаем что-то для каждого значения 0..n(линейное время, O(n))

И мы можем немного повеселиться -

int n = //some value
def f(n):
    if n == 0 return
    doSomething
    f(n-1)
    f(n-1)

Какое время работы здесь? (т.е. сколько вещей мы выполняем?):)

Ответ 3

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

Ответ 4

В "постоянном времени" обычно означает, что время, затрачиваемое на вычисление результата, не зависит от размера ввода.

Например. Вычисление длины списка/вектора на большинстве управляемых языков выполняется в постоянное время независимо от того, насколько велик список. Размер сохраняется как отдельное поле и обновляется по мере того, как список растет и сжимается. Но вычисление счета так же просто, как чтение поля.

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

Ответ 5

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

if(ReadInput()) DoSomeThing();
if(ReadInput()) DoSomeThing();
if(ReadInput()) DoSomeThing();
if(ReadInput()) DoSomeThing();

Ответ 6

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

Ответ 7

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

"постоянное время" означает "время, не зависящее от количества ввода".

Ответ 8

"В постоянном времени" означает, что независимо от того, что представляет собой вход, программа не будет работать дольше известного времени.

Рассмотрим факторную функцию как контрпример. Факториал, скажем, 5, вычисляется следующим образом:

5! = 5 * 4 * 3 * 2 * 1 = 120

Это, очевидно, займет меньше времени для вычисления, чем факториал 10, потому что для выполнения последнего программа должна выполнить еще пять умножений:

10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1

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