【伪多项式时间】

Stack Overflow 上有人关于这个概念(Pseudo-polynomial time)进行过详细解释。
原答案:
algorithm - What is pseudopolynomial time? How does it differ from polynomial time?

我大概翻译一下:
想要理解“伪多项式时间”,我们需要先给出“多项式时间”的一个清楚的定义。

对于“多项式时间”,我们的直观概念是时间复杂度 O(n^{k} ),其中 k是一常数。比如,选择排序的时间复杂度是 O(n^{2} ),是多项式时间;暴力解决TSP问题的时间复杂度是 O(n\cdot n!),不是多项式时间。我们称这种时间复杂度为“传统时间复杂度”。

我们通常认为传统时间复杂度中的变量 n表示数据的输入规模。比如,选择排序中, n指待排序数组中元素的个数;TSP问题中 n表示图中节点的数量。但是,这些所谓的输入规模,仅仅是直观的定义,并不足够严谨。为了标准化这些 n,在计算标准时间复杂度时,我们给出了输入规模的标准定义:
一个问题的输入规模是保存输入数据所需要的bit位数。

比如,如果排序算法的输入是一个32-bit整数 数组,那么输入规模就是 32nn是指数组中元素的个数。对于一个带有 n个节点、 m条边的图,需要的bit位数就是 \Omega (n+m)

了解了输入规模的定义,我们来看“多项式时间”的标准定义:
对于一个问题,在输入规模为x的情况下,如果一个算法能够在O(x^{k} )时间内解决此问题,则我们称此算法是多项式时间的,其中k为一常数。

当我们处理一些图论、链表、数组、树等问题时,这个标准定义下的多项式时间和我们传统的多项式时间相差无几。比如,用选择排序对元素个数为 n的数组进行排序时,传统时间复杂度为 O(n^{2} )。输入规模 x=32n,因此,得到的标准时间复杂度是 O(x^{2} ),仍然是多项式时间。

类似的,假设在带有 n个节点、 m条边的图中做DFS(深度优先搜索),传统时间复杂度为 O(n+m)。数据规模 x=\Omega (n+m),因此,标准时间复杂度是 O(x ),仍是多项式时间的。

然而,当我们处理一些与数论有关的问题时,事情就不太乐观了。现在我们来讨论判断一个整数是否为素数的算法,下面是一个简单的算法:
function isPrime(n):
    for i from 2 to n - 1:
        if (n mod i) = 0, return false
    return true
显然,这个算法在传统时间复杂度计算方法中是多项式时间的。我们不妨认为它的传统时间复杂度是 O(n^{4} )。然后我们再来分析这个问题的输入规模,可能有的同学会说,对于32-bit整数,这个输入规模不就是32吗?这话虽然没错,但是因为在这个问题中,输入规模完全依赖于 n的大小,所以 n的范围不再限制在32-bit整数的范围内,而是要探讨当 n更大时对数据规模的影响。我们知道,保存一个整数所需要的bit位数 x=logn,因此,在标准的时间复杂度中,此算法的复杂度变为了 O(2^{4x} )!这已经不再是多项式时间,而是一个指数时间。

我们可以从下面这个例子中直观感受一下这种指数时间的增长速度:
对于一个二进制串:
10001010101011
我们记指数时间复杂度算法运行时间为T。
然后,我们在二进制串后面 仅仅增加一位
100010101010111
这时,算法运行时间会变为2T(至少)!因此,我们仅仅增加几个bit 就会使得算法运行时间成倍成倍的增长。

... ...

最后我们来说 伪多项式时间的定义:
如果一个算法的传统时间复杂度是多项式时间的,而标准时间复杂度不是多项式时间的,则我们称这个算法是伪多项式时间的。

除此之外,原回答者还提到了伪多项式时间算法在加密中的应用,多项式时间的素数判断算法等,有兴趣的同学请移步原答案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值