今天大年初一,哪里也没去,在家里重新看了下IOA的NP问题。感觉看明白了。

首先定义下:

所谓P问题是指所有能在多项式复杂度解决的问题,比如排序算法,n*n复杂度解决问题。

有些问题目前没有多项式复杂度的解决方案,但是如果你给我一个解决方案,我可以在多项式时间内验证该算法是否正确。比如说bool表达式的可满足性问题,给我一个表达式,虽然我不能在多项式时间内判断它是否可满足,但是如果你给我一个答案,我能判断这个答案的正确性。这类问题就是NP问题。

P属于NP。这是很明显的。

那么P是否等于NP呢?目前看,不等于。因为存在一类NP完全的问题。

NP完全问题是NP中的一类问题,如果满足以下两个条件,那么我们说L是NP完全的:L是NP问题;所有的NP问题都可以“多项式归结”为L。

----------------------------------------------------

先定义什么是问题?问题就是一个映射,把“instance”(输入)映射到“solution”(输出)。

各种问题的输出千差万别,不便于讨论,统一下,都输出true和false。这就是判定型问题,decision problem。其他那些寻找最优解的叫优化类问题。所有优化类问题都可以转变成判定型问题。

接着是语言。既然一个问题P输出都是true或者false,如果集合L中的所有instance都让P输出true,那么我们说P 接受L。这里有一个很重要的转变,就是把一个抽象的问题,变成了一个instance的集合。两个问题是难以相等或者转换的,但是两个集合是可以的,mapping。基于这个mapping就可以定义多项式归结。

----------------------------------------------------

什么是多项式归结?也有两层含义:

给定两个算法,A和B。x是A输入,f是一个映射函数,能把x映射成B的输入。含义1:A(x)==B(f(x));含义2:f(x)是多项式复杂度。

-------------------------------------------------------------

然后我们要寻找一个NP完全问题,这个问题就是Circuit-SAT。它的意思是给任意一个集成电路,判断该电路是否会输出1.我们知道集成电路都是有若干管脚作为输入,几个管家作为输出的。这里简单起见,只有一个输出。如果我们发现一个电路只能输出0,那么我们可能发现了一个bug,或者简单的把它替换成常数。

怎么证明呢,从定义出发,先证明它是NP的,再证明所有的NP问题都可以归结到它(任意一个算法的输入实例都可以在多项式时间里变成一个集成电路)。

-------------

它是NP的,就是要证明存在算法A,给输入x(某个集成电路),y(某种输入方式),可以判断y是否满足x。这个复杂度是线性的,满足多项式复杂度的要求。

-----------

所有的NP问题都能归结到Circuit-SAT的问题吗?这又要解决两个问题:

1. 是否存在一个映射函数F,使得任意算法的输入x都能变成等价的一个集成电路C;

2.F是否是多项式的复杂度;

先看第一个问题,能否找到这样的F呢。下面的描述就是为了构造这个F。假定我们要把算法W归结到Circuit-SAT。W算法的验证算法是A,给定x和y,可以判断输入为x时,y是否是一个正确的答案。举个例子,W是要判断图中是否存在长度为K的路径,x代表图的数据结果,y代表最长路径的各条边,那么A是验证的算法。

如果我们把系统内存当成一个变量,那么每条指令的执行都会将一个内存快照(conf)变成另外一个(conf),我们可以认为这个映射是一个circuit完成的。

由于A(x,y)是多项式复杂度,所以conf的个数是多项式个。我们把这所有的集成电路组合起来,形成一个新的集成电路C。这样我们就把x变成了C。

也就是说,对于W而言,验证算法A(x,y)=1,当且仅当B(C,y)=1.其中B是验证集成电路的可满足性算法。

-------------

F已经找到了,那么F是否是多项式复杂度的呢?首先x是多项式的,内存大小是多项式的,集成电路个数等于执行的指令数,也是多项式的,多项式组合在一起,还是多项式的。

--------------

这就证明了所有NP问题都能归结到circuit-sat问题。

其实这里还有一个language的问题,我貌似还没看懂。

------------------------------------------------------------

如何判断一个问题是NP-hard的呢,如果一个NP完全的问题能够归结到该问题,(不管他是不是NP问题),它都是NP-hard。

由于我们已经找到了一个NP完全问题circuit-sat,对于目标问题W,只需要把circuit-sat问题归结到W的输入即可证明W是NP-hard的问题。这就很容易证明很多算法都是NP的。比如说Boolean表达式的可满足性。后续将会继续讨论。

 

首先

NP-Completeness理解的更多相关文章

  1. 怎么理解np.random.seed()?

    在使用numpy时,难免会用到随机数生成器.我一直对np.random.seed(),随机数种子搞不懂.很多博客也就粗略的说,利用随机数种子,每次生成的随机数相同. 我有两个疑惑:1, 利用随机数种子 ...

  2. np.stack() 与 tf.stack() 的简单理解

    说明:np ----> numpy       tf ----> tensorflownp.stack(arrays, axis=0) np.stack(arrays, axis=0) - ...

  3. python指定概率随机取值 理解np.random.seed()

    python指定概率随机取值参考如下: 下面是利用 np.random.choice()指定概率取样的例子: np.random.seed(0) p = np.array([0.1, 0.0, 0.7 ...

  4. Numpy中np.random.randn与np.random.rand的区别,及np.mgrid与np.ogrid的理解

    np.random.randn是基于标准正态分布产生的随机数,np.random.rand是基于均匀分布产生的随机数,其值在[0,1). np.mgrid 与np.ogrid的理解及区别:np.mgr ...

  5. 简单理解 NP, P, NP-complete和NP-Hard

    P是一类可以通过确定性图灵机(以下简称 图灵机)在多项式时间(Polynomial time)内解决的问题集合. NP是一类可以通过非确定性图灵机( Non-deterministic Turing ...

  6. 理解np.nonzero()函数

    举三个例子,就能清楚的看到 np.nonzero() 这个函数返回值的意义 一. #例1 一维数组 import numpy as np a = [0,1,2,0,3,0] b = np.nonzer ...

  7. 理解Docker(3):Docker 使用 Linux namespace 隔离容器的运行环境

    本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  8. 深入理解numpy

    一.为啥需要numpy python虽然说注重优雅简洁,但它终究是需要考虑效率的.别说运行速度不是瓶颈,在科学计算中运行速度就是瓶颈. python的列表,跟java一样,其实只是一维列表.一维列表相 ...

  9. 转载 什么是P问题、NP问题和NPC问题

    原文地址http://www.matrix67.com/blog/archives/105 这或许是众多OIer最大的误区之一.    你会经常看到网上出现“这怎么做,这不是NP问题吗”.“这个只有搜 ...

  10. 理解记忆三种常见字符编码:ASCII, Unicode,UTF-8

    理解什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是25 ...

随机推荐

  1. codeblocks 配置 opengl 编程宝典 的 gltools 环境

    懒得多说,亲测,这个问题,csdn 和 cnblog 上的博客真的没有一个能解决的. 这个帖子2L的答案则完美解决了问题,虽然步骤有些繁琐,过程还是英文,但考虑到了可能出现的各种问题,跟着走一遍就完美 ...

  2. OpenStack基础组件安装keystone身份认证服务

    域名解析 vim /etc/hosts 192.168.245.172 controller01 192.168.245.171 controller02 192.168.245.173 contro ...

  3. Python学习笔记十一

    1. 协程 并发的解决方案: 多进程      多线程      什么叫并发:看起来同时进行 如何实现并发:切换+保存状态 进程线程都是由操作系统调度的 协程:单线程下实现的并发,应用程序级别的切换, ...

  4. python-循环&运算符

    一.while 循环语句 while 循环语句的基本用法如下: while 条件表达式: 循环体 当条件表达式的返回值为真时,则执行循环体中的语句,执行完毕后,重新判断条件表达式的返回值,直到表达式的 ...

  5. Flume-ng高可用集群负载安装与配置

    1. 写在前面 flume-ng高可用长在大数据处理环节第一个出现,对于处理日志文件有很好的作用,本篇博客将详细介绍flume-ng的高可用负载均衡搭建 2. flume-ng高可用负载均衡描述 在一 ...

  6. urls控制器

    路由分发include('blog.urls')): 将以指定名称开头的url分发到指定app中去匹配 urlpatterns = [ url(r'^admin/', admin.site.urls) ...

  7. Selenium之Selenium IDE

    官方文档:https://www.seleniumhq.org/docs/02_selenium_ide.jsp 1.       Selenium IDE介绍 Selenium IED (Integ ...

  8. vue v-if 和 v-show 的知识点

    1.v-if 的特点: 实现方式:根据后面数据的真假判断是否重新删除或创建元素. 性能消耗:有较高的切换性能消耗. 编译过程:v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的 ...

  9. 适用于 Android 的 Visual Studio 模拟器

    适用于 Android 的 Visual Studio 模拟器 https://visualstudio.microsoft.com/zh-hans/vs/msft-android-emulator/ ...

  10. 福州大学软件工程1916|W班 第6次作业成绩排名

    作业链接 团队第三次-项目原型设计 评分细则 博客评分标准 在随笔开头,备注小组同学的学号.(1') 文字准确.样式清晰.图文并茂.字数在1000字左右.(10') 原型模型必须采用专用的原型模型设计 ...