伪多项式时间和多项式时间

时间:2016-11-13 13:15:31

标签: algorithm

我对与多项式时间相比的假多项式时间感到困惑

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),因此它有多项式时间!

2 个答案:

答案 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输入的长度   问题与WW中的位数成正比,而不是   到log W本身。

你前两个片段即将W明显多项式增长。

答案 1 :(得分:0)

由于,
x = ceil(log_2(n))2^x变为2^log_2(n),这只是n(使用a^log_a(b) = b)。

请记住仅在输入变量的条款中分析算法的运行时间,而不是像计算它需要的位那样花哨的东西,因为(例如,在这种情况下)比特数本身就是对数号码!