首先要了解的是,P和NP对语言进行分类,而不是问题。要理解这意味着什么,我们首先需要一些其他定义。
一个字母是一个非空符号的有限集合。
{ 0
,1
}和ASCII字符集一样都是字母。{}不是字母,因为它为空。N(整数)不是字母,因为它不是有限的。
令Σ为字母。数量有限,从符号的有序级联Σ被称为字在Σ。
该字符串101
是字母{ 0
,1
}上的一个单词。该空字(通常写为ε)是在任何字母词。字符串penguin
是包含ASCII字符的字母上的单词。数π的小数点符号不超过拼音一个字{ .
,0
,1
,2
,3
,4
,5
,6
,7
,8
,9
},因为它不是有限的。
单词w的长度,写为| w |,是其中的符号数。
例如,| hello
| = 5和| ε | =0。对于任何单词w,| |。w | ∈ Ñ因此有限。
令Σ为字母。集合Σ *包含了所有单词Σ,包括ε。集合Σ +包含了所有单词Σ,不含ε。对于Ñ ∈ Ñ,Σ Ñ是设定长度的字的Ñ。
对于每个字母Σ,Σ *和Σ +是无限可数的集合。对于ASCII字符集Σ ASCII,正则表达式.*
,并.+
分别表示Σ ASCII *和Σ ASCII +分别。
{ 0
,1
} 7是该组的7位ASCII码{ 0000000
,0000001
,...,1111111
}。{ 0
,1
} 32是32位整数值的集合。
设Σ是字母和大号⊆ Σ *。L被称为Σ之上的语言。
对于字母Σ,空集和Σ *是Σ之上的平凡语言。前者通常被称为空语言。空语言{}和仅包含空词{ ε } 的语言是不同的。
与非NaN IEEE 754浮点值相对应的{ 0
,1
} 32子集是一种有限语言。
语言可以有无限多个单词,但是每种语言都是可数的。一组琴弦{ 1
,2
,...}表示整数十进制是在字母表无限语言{ 0
,1
,2
,3
,4
,5
,6
,7
,8
,9
}。无穷集合字符串{ 2
,3
,5
,7
,11
,13
,...}十进制表示素数是其子集。包含与正则表达式匹配的所有单词[+-]?\d+\.\d*([eE][+-]?\d+)?
的语言是ASCII字符集上的一种语言(表示由C编程语言定义的有效浮点表达式的子集)。
没有一种语言包含所有实数(以任何符号),因为实数集不可计数。
设Σ是字母和大号⊆ Σ *。一种机器d 决定 大号如果对于每个输入瓦特∈ Σ *它计算特性函数 χ 大号(瓦特在有限时间内)。特征函数定义为
χ 大号:Σ * →{0,1}
瓦特 ↦1, 瓦特 ∈ 大号
0,否则。
这种机器被称为判定为大号。我们写“ d(瓦特)= X ”,“给予瓦特,d输出X ”。
机器型号很多。今天最实用的一种是图灵机的模型。图灵机具有无限的线性存储,它们聚集在单元中。每个单元在任何时间点都可以恰好容纳一个字母符号。图灵机按照一系列计算步骤执行其计算。在每一步中,它都可以读取一个单元格,可能会覆盖其值,并将读/写头向左或右单元格移动一个位置。机器将执行的操作由有限状态自动机控制。
具有有限指令集和无限存储空间的随机访问计算机是另一种与图灵计算机模型一样强大的计算机模型。
为了便于讨论,我们不会打扰我们使用的精确机器模型,而足以说这台机器具有有限的确定性控制单元,无限的存储空间,并按照一系列可以计算的步骤进行计算。
既然您在问题中使用过它,我假设您已经熟悉“ big-O”表示法,因此这里只是快速复习。
令f:N →为一个函数。该组Ô(˚F)包含的所有功能克:Ñ → Ñ为其存在常数Ñ 0 ∈ Ñ和Ç ∈ Ñ使得对于每Ñ ∈ Ñ与Ñ > Ñ 0这是事实,克(Ñ)≤ Ç ˚F(n)。
现在,我们准备解决真正的问题。
类P包含所有语言大号存在用于其图灵机d,其判定大号和恒定ķ ∈ Ñ使得对于每个输入瓦特,d至多后暂停Ť(| 瓦特 |)为函数的步骤Ť ∈ Ô(ñ ↦ ñ ķ)。
由于Ø(ñ ↦ ñ ķ),而数学是正确的,是不方便的写入和读取,大多数人-说实话,每个人除了我自己-平时写简单Ø(ñ ķ)。
请注意,边界取决于w的长度。因此,您为质数语言所做的论点仅适用于无格式编码中的数字,其中对于数字n的w,编码的长度| w | 与n成正比。实际上,没有人会使用这种编码。但是,使用比尝试所有可能的因素更高级的算法,可以证明,如果输入以二进制(或其他基数)编码,质数的语言将保留在P中。(尽管有很大的兴趣,但这只能由Manindra Agrawal,Neeraj Kayal和Nitin Saxena证明。 在2004年的获奖论文中,您可以猜测该算法不是非常简单。)
平凡的语言{}和Σ *和非平凡的语言{ ε }显然在P中(对于任何字母Σ)。您是否可以使用自己喜欢的编程语言编写函数,这些函数将字符串作为输入并返回一个布尔值,以说明字符串是否是每种语言所用语言中的单词,并证明您的函数具有多项式运行时复杂性?
每种正则语言(由正则表达式描述的语言)都以P表示。
设Σ是字母和大号⊆ Σ *。一种机器V,它利用两个词的编码元组瓦特,Ç∈ Σ *并输出0或1的有限数量的步骤之后是验证对大号如果它具有下列性质。
- 给定(瓦特,Ç),V输出1仅当瓦特 ∈ 大号。
- 对于每瓦特 ∈ 大号,存在ç ∈ Σ *,使得V(瓦特,Ç)= 1。
上面定义中的c称为见证人(或证书)。
即使w实际上在L中,也允许验证者为错误的证人提供假阴性。但是,不允许其提供误报。还要求该语言中的每个单词至少要有一个见证人。
对于语言组合,包含为整数的十进制编码不是黄金,证人可能是一个因式分解。例如,(659, 709)
是467231
∈COMPOSITE 的见证人。在没有证人的情况下,您可以轻松地在纸上验证,如果不使用计算机,很难证明467231不是主要的。
我们没有说如何找到合适的证人。这是不确定的部分。
类NP包含所有语言大号存在用于其图灵机V,用于验证大号和恒定ķ ∈ Ñ使得对于每个输入(瓦特,Ç),V暂停后至多Ť(| 瓦特 |)为函数的步骤Ť ∈ ø(ñ ↦ ñ ķ)。
注意上面的定义意味着每个w ^ ∈ 大号存在证人Ç与| c | ≤ 牛逼(| W ^ |)。(图灵机可能无法查看证人的更多符号。)
NP是P的超集(为什么?)。不知道是否存在NP中的语言,但不存在P中的语言。
整数分解本身不是一种语言。但是,我们可以构建一种语言来表示与之相关的决策问题。也就是说,它包含了所有元组语言(Ñ,米),使得Ñ具有因子d与d ≤ 米。让我们将此语言称为FACTOR。如果您有确定FACTOR的算法,则可以通过对每个素因数执行递归二进制搜索,将其用于仅使用多项式开销来计算完全因式分解。
容易证明FACTOR在NP中。适当的见证人,简直是因子d本身和所有验证程序将要做的就是核实d ≤ 米和ñ国防部d = 0。所有这一切都可以在多项式时间内完成。(请再次记住,编码的长度很重要,并且在n中是对数的。)
如果您可以证明FACTOR也在P中,那么您可以肯定会获得很多炫目的奖项。(而且您已经破坏了当今加密技术的很大一部分。)
对于NP中的每种语言,都有一种蛮力算法可以确定性地决定它。它只是对所有证人进行详尽的搜索。(请注意,证人的最大长度受多项式的限制。)因此,您决定PRIMES的算法实际上是决定COMPOSITE的蛮力算法。
为了解决您的最后一个问题,我们需要引入减少。归约是理论计算机科学的一个非常强大的概念。将一个问题简化为另一个问题基本上意味着通过解决另一个问题来解决一个问题。
设Σ为字母,A和B为Σ上的语言。阿是多项式时间许多酮还原至乙如果存在函数˚F:Σ * →交通Σ *具有以下属性。
- 瓦特 ∈ 甲 ⇔ ˚F(瓦特)∈ 乙 所有瓦特 ∈ Σ *。
- 图灵机可以针对每个输入w,以由|的多项式为边界的多个步长来计算函数f。w |。
在这种情况下,我们写一个 ≤ p 乙。
例如,设A为包含所有包含三角形的图形(编码为邻接矩阵)的语言。(一个三角形是一个长度为3的循环。)进一步,B是包含所有非零轨迹矩阵的语言。(矩阵的迹线是其主对角线元素的总和)。然后阿是多项式时间许多酮还原为乙。为了证明这一点,我们需要找到合适的变换函数f。在这种情况下,我们可以设置f来计算邻接矩阵的3 次幂。这需要两个矩阵矩阵乘积,每个矩阵乘积都具有多项式复杂度。
这是平凡真实的大号 ≤ p 大号。(您能正式证明吗?)
我们现在将其应用于NP。
语言大号是NP难的当且仅当大号 “≤ p 大号每种语言大号 ”∈ NP。
一个NP难的语言可能会或可能不会在NP本身。
语言大号是NP -完全当且仅当
NP最著名的完整语言是SAT。它包含所有可以满足的布尔公式。例如,(一个 ∨ b)∧(¬ 一个 ∨¬ b)∈周六 有效证人为{ a = 1,b = 0}。式(一个 ∨ b)∧(¬ 一个 ∨ b)∧¬ b ∉周六 (您将如何证明?)
不难证明SAT∈NP。证明SAT 的NP硬度是一项工作,但它是1971年由Stephen Cook完成的。
一旦知道一种NP完全语言,通过还原来显示其他语言的NP完全相对简单。如果语言甲已知是NP -hard,然后示出了一个 ≤ p 乙表明,乙是NP -hard,太(经由“≤的传递p ”)。1972年,理查德·卡普公布的21种语言,他可以表现出人的名单NP-通过(传递)降低SAT完成。(这是我实际上建议您阅读的该答案中的唯一论文。与其他论文不同,它不难理解,并且很好地说明了如何通过还原证明NP-完整性。)
最后,简短总结。我们将使用符号NPH和NPC分别表示NP-硬语言和NP-完整语言的类别。
- P ⊆ NP
- NPC ⊂ NP和NPC ⊂ NPH,实际上NPC = NP ∩ NPH定义
- (甲 ∈ NP)∧(乙 ∈ NPH)⇒ 甲 ≤ p 乙
请注意,列入全国人大 ⊂ NP是正确的,即使在该情况下P = NP。要看到这一点,请使自己清楚,不能将非平凡的语言简化为平凡的语言,并且P中存在平凡的语言,而NP中存在非平凡的语言。但是,这是一个(不太有趣的)极端情况。
附录
您的主要困惑的来源似乎是自己所想的“的ñ ”在“ Ø(ñ ↦ ˚F(ñ))”作为解释的算法的输入时,它实际上指的是长度的输入。这是一个重要的区别,因为这意味着算法的渐近复杂度取决于用于输入的编码。
本周,已知最大的梅森素数达到了新记录。当前已知的最大质数是2 74 207 281 −1。这个数字太大,令人头疼,因此在以下示例中使用较小的素数:2 31 – 1 = 2 147 483 647。以不同的方式进行编码。
- 通过其梅森指数作为十进制数字:
31
(2个字节)
- 作为十进制数字:
2147483647
(10个字节)
- 作为一元数:
11111…11
其中将…
被2147483640多1
秒(几乎2 GiB)代替
所有这些字符串都编码相同的数字,并且只要给出其中任何一个,我们就可以轻松构造相同数字的任何其他编码。(如果需要,可以将十进制编码替换为二进制,八进制或十六进制。它只会将长度更改为常数。)
用于测试素数的幼稚算法仅适用于一元编码的多项式。所述AKS素性测试是多项式为小数(或任何其他碱b ≥2)。的卢卡斯-莱默检验法是最好的已知算法梅森素数中号p与p为奇素数,但它仍然是在梅森指数的二进制编码的长度的指数p(在多项式p)。
如果我们想谈一谈算法的复杂性,那么非常清楚我们使用什么表示就非常重要。通常,可以假定使用了最有效的编码。也就是说,二进制为整数。(请注意,并非每个素数都是梅森素数,因此使用梅森指数不是一般的编码方案。)
在理论密码学中,许多算法都正式传递了一个完全无用的k 1
s 字符串作为第一个参数。该算法从不考虑此参数,但允许它形式上是k的多项式,k是用于调整过程安全性的安全性参数。
对于二进制编码的决策语言为NP -complete的某些问题,如果将嵌入数字的编码切换为一元,则决策语言将不再是NP -complete。即使到那时,其他问题的决策语言仍然是NP-完整的。后者称为强NP- complete。最著名的例子是装箱。
观察(如果可能)输入压缩后算法的复杂度如何变化,这也可能(或者可能更有趣)。对于Mersenne素数的示例,我们已经看到了三种编码,每种编码的对数压缩程度都比其前身更高。
1983年,Hana Galperin和Avi Wigderson撰写了一篇有趣的文章,介绍了当图形的输入编码被对数压缩时常见图形算法的复杂性。对于这些输入,从上方包含三角形的图形的语言(明显在P中)突然变为NP-完全的。
那是因为像P和NP这样的语言类是为语言而不是问题定义的。