Принятые в настоящее время не дадут вам никакой теоретической оценки, если вы каким-то образом не сможете согласовать экспериментально измеренные времена с функцией, которая приближает их. Этот ответ дает вам ручную технику для этого и заполняет этот пробел.
Вы начинаете с угадывания теоретической функции сложности алгоритма. Вы также экспериментально измеряете фактическую сложность (количество операций, время или все, что вы считаете целесообразным) для все более серьезных проблем.
Например, скажем, вы предполагаете, что алгоритм является квадратичным. Измерьте (скажем) время и вычислите отношение времени к вашей предполагаемой функции (n ^ 2):
for n = 5 to 10000 //n: problem size
long start = System.time()
executeAlgorithm(n)
long end = System.time()
long totalTime = end - start
double ratio = (double) time / (n * n)
end
. Когда n
движется к бесконечности, это соотношение ...
- сходится к нулю? Тогда ваше предположение слишком низкое . Повторите с чем-то большим (например, n ^ 3)
- расходится до бесконечности? Тогда ваше предположение слишком высоко . Повторите с чем-то меньшим (например, nlogn)
- сходится к положительной постоянной? Бинго! Ваше предположение на деньги (по крайней мере, приближается к теоретической сложности для столь больших
n
значений, как вы пытались)
В основном используется определение большой O-нотации, что f(x) = O(g(x)) <=> f(x) < c * g(x)
- f(x)
- это фактическая стоимость вашего алгоритма, g(x)
- это предполагаемое вами предположение, а c
- константа. Таким образом, вы пытаетесь экспериментально найти предел f(x)/g(x)
; если ваша догадка достигнет реальной сложности, это соотношение будет оценивать константу c
.