在计算理论领域中,若一个数值算法的实践复杂度可以表示为输入数值N的多项式,则称其时间复杂度为伪多项式时间。由于N的值是N的位数的幂,故该算法的时间复杂度实际上应视为输入数值N的位数的幂。
伪多项式(时间)算法是一组特定算法的名称,这些算法的运行时间都是指数级的,但往往“看上去像”一个多项式时间的算法,甚至其在具体实践中的行为也像多项式级算法。比如,当我们要检查或回答“某个数是不是质数”这类问题时,通常会认为其解决方案应该是多项式级的,但其实问题远没有那么想当然......而且事实上,这种想当然的方式所产生的将是一个非多项式级的解决方案。
下面我们来看一个相对直接的解决方案:
def is_prime(n):
for i in range(2,n):
if n % i == 0:
return False
return True
该算法其实就是从2开始,逐步遍历所有小于n的正整数,并检查它们是否能整除n。只要它们有一个能整除,n就不是质数,否则就是质数。看上去这的确像是一个多项式级算法,运行时间应该为Θ(n)。但关键是,这里的n根本不是该问题的准确规模值!
当然,将其运行时间描述成n的线性关系,甚至说成是n的一个多项式也是有用的。但这并不等于说这就是一个多项式级算法。一个问题的规模值包含n,并不等于就是n,而是我们用来编码n所需要的比特数。例如,如果n等于2的某次方,那么其需要的比特数大约等于lgn+1。对于一个任意的正整数,实际则需要floor(log(n,2))+1个比特位。
假设我们将问题规模(比特数)设为k,那么(大致上)n=2^k-1。如此一来,我们的运行时间Θ(n)就在其实际问题规模函数重写下变成了Θ(2^k),这显然是一个指数级算法。像这样的其他算法还有不少,它们的运行时间可以被解释为某个输入数值的某个多项式函数。(背包问题,子集就是其中的例子)它们统称为伪多项式级算法。