我对与多项式时间相比的假多项式时间感到困惑
input(n);
for (int i=0; i<n;i++){
doStuff; }
运行时为O(n)
,但写出数字n需要x=O(log n)
位。
因此,如果我们让x是写出输入n所需的位数,则该算法的运行时实际上是O(2^x)
,这不是x中的多项式。
这个结论是否正确?
编辑:看看简单的最优秀。
function isPrime(n):
for i from 2 to n - 1:
if (n mod i) = 0, return false
return true
运行时为O(n)
。但请记住,时间复杂度的形式定义将算法的复杂性作为输入位数的函数。
因此,如果我们让x是写出输入n所需的位数,则该算法的运行时实际上是O(2 ^ x),这不是x中的多项式。
EDIT2:我得到了你所有的观点,但看看背包问题。 //输入:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)
for j from 0 to W do:
m[0, j] := 0
for i from 1 to n do:
for j from 0 to W do:
if w[i] > j then:
m[i, j] := m[i-1, j]
else m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
如果你们是对的,那就意味着背包问题有运行时o(n*W)
,因此它有多项式时间!
答案 0 :(得分:1)
Alex每天都会64
俯卧撑。
和
Alex每天2^6
俯卧撑。
如果以上两行对您来说意味着相同,那么O(n)
和O(2^x)
并不重要:)
O(2^x)
=> O(2^log_2(n))
=> n [as we know x^log_x(y) = y]
时间复杂性的正式定义谈到了复杂性 算法作为输入位数的函数。
是的,你是对的。但是,Big-O分析的思想是关于输入增长的算法的增长率,而不是精确计算我的循环迭代的次数。
例如,当n = 32
时,算法复杂度为O(2^5)
,但增长为n
,例如n = 1048576
时,复杂度为{{1} }}。因此,随着输入的增加,复杂性也会增加。
O(2^20)
或n
都是以不同的方式呈现相同的数字量。只要算法的增长率与输入的增长率成线性比例,算法就是线性的 - 无论我们将输入2^(log_2(n))
表示为n
还是e^x
。< / p>
引自维基百科
log(y)
复杂性与背包的事实并不矛盾 问题是NP完全的,因为与O(nW)
不同,W
不是多项式的 问题输入的长度。n
输入的长度 问题与W
,W
中的位数成正比,而不是 到log W
本身。
你前两个片段即将W
明显多项式增长。
答案 1 :(得分:0)
由于,
x = ceil(log_2(n))
,2^x
变为2^log_2(n)
,这只是n
(使用a^log_a(b) = b
)。
请记住仅在输入变量的条款中分析算法的运行时间,而不是像计算它需要的位那样花哨的东西,因为(例如,在这种情况下)比特数本身就是对数号码!