科学网

 找回密码
  注册

tag 标签: NP问题

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

NP是可计算的吗?- 常量与变量关系中的认知层次问题
热度 3 liuyu2205 2015-1-9 14:14
网友姜咏江的博文“美国克雷数学研究所会不会颁奖? http://blog.sciencenet.cn/home.php?mod=spaceuid=340399do=blogid=849311 ”,通过辨析常量与变量不同,说明NP问题定义的流行观念中可能存在着的悖论。 此文涉及到二个常见的算法问题: 1,搜索问题( http://zh.wikipedia.org/zh/計算複雜性理論 ):任给一个集合A,和一个数a,问a是否在A中? 2,子集元素和问题( http://zh.wikipedia.org/wiki/子集合加總問題 ):任给一个整数集合,问是否存在某个非空子集,使得子集元素和为0?例:给定集合{−7, −3, −2, 5, 8},答案是yes,因为子集{−3, −2, 5}的数字和是0。 “搜索问题”是常见的P问题,任给一个元素个数为n的集合A,及一个数a,最多比较n次,即可判定a是否在A中。故“搜索问题”存在着多项式时间复杂度O(n)的算法。 “子集元素和问题”是常见NP问题,任给一个k个整数的集合,至今未找到多项式时间复杂度算法,只有基于枚举的指数时间算法。 网友姜咏江视角独特,从“搜索问题”的角度,追究“子集元素和问题”:“给定k个数组成的集合,求其全部非空子集。我们都知道子集数应为2 k -1。子集元素和最多有多少?最多也就是这2 k -1个。现在我们要给出一个数a,问a是否在这2 k -1个和数当中,验证的时间复杂度是多少?是O(2 k )还是O(n)?在这个问题中,k是一个常量,莫要将其当成变量来看。用变量表达式来研究程序执行时间复杂度,必须要加以严格区分变量和常量。问题的正确答案应该说是O(n)。” 网友姜咏江的文章正确地指出,将常量2 k 一般化为变量2 k ,是问题的关键。我们认为,这是流行的NP问题理论中一个最常见、最隐蔽、最顽固的认知错误。在认识论上,是“个别问题”与“一般问题”的混淆,在哲学上有深远的根源。 流行NP问题定义,是基于指数时间的枚举算法来定义的(对此话题,大家还可参见“未來數學家的挑戰 http://episte.math.ntu.edu.tw/articles/mm/mm_10_2_04/index.html )”,然而,此枚举算法针对的却是“搜索问题”,“搜索问题”实际上又是多项式时间复杂度O(n)可求解的P问题!也就是说,流行的NP问题的定义,暗中将NP问题定义成了P问题,从而混淆了NP问题与P问题的层次,使真正的NP——不确定性消失了。“不确定性的消失”,正是我们长时期通过对库克的原初论文深入研究,所得到的一般性结论,现在贴出另一篇论文“What is Cook's theorem?”
个人分类: 不确定性问题和算法讨论|3418 次阅读|6 个评论
[转载]算法问题:什么是P问题、NP问题和NPC问题
silent1982 2013-1-13 04:46
这或许是众多OIer最大的误区之一。 你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题并不是那种“只有搜才行”的问题,NPC问题才是。好,行了,基本上这个误解已经被澄清了。下面的内容都是在讲什么是P问题,什么是NP问题,什么是NPC问题,你如果不是很感兴趣就可以不看了。接下来你可以看到,把NP问题当成是 NPC问题是一个多大的错误。 还是先用几句话简单说明一下时间复杂度。时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还是一样,或者也跟着慢了数百倍,或者变慢了数万倍。不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有O(1)的时间复杂度,也称常数级复杂度;数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是O(n),比如找n个数中的最大值;而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于O(n^2)的复杂度。还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是O(a^n)的指数级复杂度,甚至O(n!)的阶乘级复杂度。不会存在O(2*n^2)的复杂度,因为前面的那个“2”是系数,根本不会影响到整个程序的时间增长。同样地,O (n^3+n^2)的复杂度也就是O(n^3)的复杂度。因此,我们会说,一个O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,尽管在n很小的时候,前者优于后者,但后者时间随数据规模增长得慢,最终O(n^3)的复杂度将远远超过O(n^2)。我们也说,O(n^100)的复杂度小于O(1.01^n)的复杂度。 容易看出,前面的几类复杂度被分为两种级别,其中后者的复杂度无论如何都远远大于前者:一种是O(1),O(log(n)),O(n^a)等,我们把它叫做多项式级的复杂度,因为它的规模n出现在底数的位置;另一种是O(a^n)和O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。 自然地,人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾,答案是否定的。有些问题甚至根本不可能找到一个正确的算法来,这称之为“不可解问题”(Undecidable Decision Problem)。 The Halting Problem就是一个著名的不可解问题 ,在我的Blog上有过专门的介绍和证明。再比如,输出从1到n这n个数的全排列。不管你用什么方法,你的复杂度都是阶乘级,因为你总得用阶乘级的时间打印出结果来。有人说,这样的“问题”不是一个“正规”的问题,正规的问题是让程序解决一个问题,输出一个“YES”或“NO”(这被称为判定性问题),或者一个什么什么的最优值(这被称为最优化问题)。那么,根据这个定义,我也能举出一个不大可能会有多项式级算法的问题来:Hamilton回路。问题是这样的:给你一个图,问你能否找到一条经过每个顶点一次且恰好一次(不遗漏也不重复)最后又走回来的路(满足这个条件的路径叫做Hamilton回路)。这个问题现在还没有找到多项式级的算法。事实上,这个问题就是我们后面要说的NPC问题。 下面引入P类问题的概念:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。P是英文单词多项式的第一个字母。哪些问题是P类问题呢?通常NOI和NOIP不会出不属于P类问题的题目。我们常见到的一些信息奥赛的题目都是P问题。道理很简单,一个用穷举换来的非多项式级时间的超时程序不会涵盖任何有价值的算法。 接下来引入NP问题的概念。这个就有点难理解了,或者说容易理解错误。在这里强调(回到我竭力想澄清的误区上),NP问题不是非P类问题。NP问题是指可以在多项式的时间里验证一个解的问题。NP问题的另一个定义是,可以在多项式的时间里猜出一个解的问题。比方说,我RP很好,在程序中需要枚举时,我可以一猜一个准。现在某人拿到了一个求最短路径的问题,问从起点到终点是否有一条小于100个单位长度的路线。它根据数据画好了图,但怎么也算不出来,于是来问我:你看怎么选条路走得最少?我说,我RP很好,肯定能随便给你指条很短的路出来。然后我就胡乱画了几条线,说就这条吧。那人按我指的这条把权值加起来一看,嘿,神了,路径长度98,比100小。于是答案出来了,存在比100小的路径。别人会问他这题怎么做出来的,他就可以说,因为我找到了一个比100 小的解。在这个题中,找一个解很困难,但验证一个解很容易。验证一个解只需要O(n)的时间复杂度,也就是说我可以花O(n)的时间把我猜的路径的长度加出来。那么,只要我RP好,猜得准,我一定能在多项式的时间里解决这个问题。我猜到的方案总是最优的,不满足题意的方案也不会来骗我去选它。这就是NP问题。当然有不是NP问题的问题,即你猜到了解但是没用,因为你不能在多项式的时间里去验证它。下面我要举的例子是一个经典的例子,它指出了一个目前还没有办法在多项式的时间里验证一个解的问题。很显然,前面所说的Hamilton回路是NP问题,因为验证一条路是否恰好经过了每一个顶点非常容易。但我要把问题换成这样:试问一个图中是否不存在Hamilton回路。这样问题就没法在多项式的时间里进行验证了,因为除非你试过所有的路,否则你不敢断定它“没有Hamilton回路”。 之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法。相信读者很快明白,信息学中的号称最困难的问题——“NP问题”,实际上是在探讨NP问题与P类问题的关系。 很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中,把所有 NP问题划进另一个集合NP中,那么,显然有P属于NP。现在,所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP。 NP问题一直都是信息学的巅峰。巅峰,意即很引人注目但难以解决。在信息学研究中,这是一个耗费了很多时间和精力也没有解决的终极问题,好比物理学中的大统一和数学中的歌德巴赫猜想等。 目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-完全问题,也即所谓的 NPC问题。C是英文单词“完全”的第一个字母。正是NPC问题的存在,使人们相信P≠NP。下文将花大量篇幅介绍NPC问题,你从中可以体会到NPC问题使P=NP变得多么不可思议。 为了说明NPC问题,我们先引入一个概念——约化(Reducibility,有的资料上叫“归约”)。 简单地说,一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。《算法导论》上举了这么一个例子。比如说,现在有两个问题:求解一个一元一次方程和求解一个一元二次方程。那么我们说,前者可以约化为后者,意即知道如何解一个一元二次方程那么一定能解出一元一次方程。我们可以写出两个程序分别对应两个问题,那么我们能找到一个“规则”,按照这个规则把解一元一次方程程序的输入数据变一下,用在解一元二次方程的程序上,两个程序总能得到一样的结果。这个规则即是:两个方程的对应项系数不变,一元二次方程的二次项系数为0。按照这个规则把前一个问题转换成后一个问题,两个问题就等价了。同样地,我们可以说,Hamilton回路可以约化为TSP问题(Travelling Salesman Problem,旅行商问题):在Hamilton回路问题中,两点相连即这两点距离为0,两点不直接相连则令其距离为1,于是问题转化为在TSP问题中,是否存在一条长为0的路径。Hamilton回路存在当且仅当TSP问题中存在长为0的回路。 “问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。这很容易理解。既然问题A能用问题B来解决,倘若B的时间复杂度比A的时间复杂度还低了,那A的算法就可以改进为B的算法,两者的时间复杂度还是相同。正如解一元二次方程比解一元一次方程难,因为解决前者的方法可以用来解决后者。 很显然,约化具有一项重要的性质:约化具有传递性。如果问题A可约化为问题B,问题B可约化为问题C,则问题A一定可约化为问题C。这个道理非常简单,就不必阐述了。 现在再来说一下约化的标准概念就不难理解了:如果能找到这样一个变化法则,对任意一个程序A的输入,都能按这个法则变换成程序B的输入,使两程序的输出相同,那么我们说,问题A可约化为问题B。 当然,我们所说的“可约化”是指的可“多项式地”约化(Polynomial-time Reducible),即变换输入的方法是能在多项式的时间里完成的。约化的过程只有用多项式的时间完成才有意义。 好了,从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。再回想前面讲的P和NP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 NP问题的这样一个超级NP问题?答案居然是肯定的。也就是说,存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC 问题,也就是NP-完全问题。NPC问题的出现使整个NP问题的研究得到了飞跃式的发展。我们有理由相信,NPC问题是最复杂的问题。再次回到全文开头,我们可以看到,人们想表达一个问题不存在多项式的高效算法时应该说它“属于NPC问题”。此时,我的目的终于达到了,我已经把NP问题和NPC问题区别开了。到此为止,本文已经写了近5000字了,我佩服你还能看到这里来,同时也佩服一下自己能写到这里来。 NPC问题的定义非常简单。同时满足下面两个条件的问题就是NPC问题。首先,它得是一个NP问题;然后,所有的NP问题都可以约化到它。证明一个问题是 NPC问题也很简单。先证明它至少是一个NP问题,再证明其中一个已知的NPC问题能约化到它(由约化的传递性,则NPC问题定义的第二条也得以满足;至于第一个NPC问题是怎么来的,下文将介绍),这样就可以说它是NPC问题了。 既然所有的NP问题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法,那么所有的NP问题都能用这个算法解决了,NP也就等于P 了。因此,给NPC找一个多项式算法太不可思议了。因此,前文才说,“正是NPC问题的存在,使人们相信P≠NP”。我们可以就此直观地理解,NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。 顺便讲一下NP-Hard问题。NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条但不一定要满足第一条(就是说,NP-Hard问题要比 NPC问题的范围广)。NP-Hard问题同样难以找到多项式的算法,但它不列入我们的研究范围,因为它不一定是NP问题。即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法。事实上,由于NP-Hard放宽了限定条件,它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。 不要以为NPC问题是一纸空谈。NPC问题是存在的。确实有这么一个非常具体的问题属于NPC问题。下文即将介绍它。 下文即将介绍逻辑电路问题。这是第一个NPC问题。其它的NPC问题都是由这个问题约化而来的。因此,逻辑电路问题是NPC类问题的“鼻祖”。 逻辑电路问题是指的这样一个问题:给定一个逻辑电路,问是否存在一种输入使输出为True。 什么叫做逻辑电路呢?一个逻辑电路由若干个输入,一个输出,若干“逻辑门”和密密麻麻的线组成。看下面一例,不需要解释你马上就明白了。 ┌───┐ │ 输入1├─→┐┌──┐ └───┘└─→┤│ │ or ├→─┐ ┌───┐┌─→┤││┌──┐ │ 输入2├─→┤└──┘└─→┤│ └───┘│┌─→┤AND ├──→输出 └────────┘┌→┤│ ┌───┐┌──┐│└──┘ │ 输入3├─→┤ NOT├─→────┘ └───┘└──┘ 这是个较简单的逻辑电路,当输入1、输入2、输入3分别为True、True、False或False、True、False时,输出为True。 有输出无论如何都不可能为True的逻辑电路吗?有。下面就是一个简单的例子。 ┌───┐ │输入1 ├→─┐┌──┐ └───┘└─→┤│ │AND ├─→┐ ┌─→┤││ │└──┘│┌──┐ │└→┤│ ┌───┐││AND ├─→输出 │输入2 ├→─┤┌──┐┌→┤│ └───┘└→┤NOT ├→──┘└──┘ └──┘ 上面这个逻辑电路中,无论输入是什么,输出都是False。我们就说,这个逻辑电路不存在使输出为True的一组输入。 回到上文,给定一个逻辑电路,问是否存在一种输入使输出为True,这即逻辑电路问题。 逻辑电路问题属于NPC问题。这是有严格证明的。它显然属于NP问题,并且可以直接证明所有的NP问题都可以约化到它(不要以为NP问题有无穷多个将给证明造成不可逾越的困难)。证明过程相当复杂,其大概意思是说任意一个NP问题的输入和输出都可以转换成逻辑电路的输入和输出(想想计算机内部也不过是一些 0和1的运算),因此对于一个NP问题来说,问题转化为了求出满足结果为True的一个输入(即一个可行解)。 有了第一个NPC问题后,一大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了。后来,Hamilton 回路成了NPC问题,TSP问题也成了NPC问题。现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。P=NP问题还有许多有趣的东西,有待大家自己进一步的挖掘。攀登这个信息学的巅峰是我们这一代的终极目标。现在我们需要做的,至少是不要把概念弄混淆了。 来自: http://www.matrix67.com/blog/archives/548
2479 次阅读|0 个评论
Hamilton 环多项式算法、时间复杂度及其详细证明
热度 9 dulizhi95 2012-8-17 07:03
Hamilton 环多项式算法、 时间复杂度及其详细证明 本文已在 arxiv 上公布。相对于以前,本次算法略有调整,但证明方法是全新的。以前的证明方法当然是逻辑严密的高超的和有效的,但需要 ”combine and split” ,这个非常难理解,也非常难实现,所以这次我换了一种全新的方法,实现起来要容易得多。当然,还是属相当难看懂的。能透彻看懂本算法及其证明的人,绝对在计算机专业算法方向实力极其强大!总之,本次的证明比我以前的 ”combine and split” 方法要容易理解得多。 说明: 1, 本文的一些表达,是直接借用了某审稿专家的表达方式,这是一个非常不错的审稿专家,在此表示由衷的感谢!明显看出了英语非我的母语,我英语不行,他将我文中许多不规范的英文表达,重新帮我表达了一次。当然,他说他还是有不理解的地方,并详细指出了哪些地方的意思他不理解,当然,我据此作了根本性修改。 2, 本文希望同行高人给予批评指导,交流合作。 3, 希望有专长的博主给予英语表达和 SCI 写作方面的纠正指点或合作。 Algorithm Definitions: For an undirected graph G with n vertices, let x_1, x_2, ... ,x_n denote the n vertices. A broad cycle is defined as a cyclic sequence x_1, x_2, ... ,x_n, x_1 of the vertices of G where every pair x_i, x_{i+1} may or may not be adjacent in G. We call a pair (x_i, x_{i+1}) (including (x_n, x_1)) of non-adjacent vertices a break point. So the number of break points is between 0 and n for a broad cycle. Apparently, a break point is constituted by two vertices(say vertex a and b). We use a*b to denote this break point. If two consecutive vertices a and b are adjacent, we call them “connecting point”, we use ab to denote this connecting point. We use a…b to denote that there are some vertices between a and b. For an undirected graph with n vertices, the number of all break points and connecting points is n(n-1)/2. A connecting point or a break point is also called “a general point”. A general point(a break point or a connecting point) is constituted by two vertices, we say that the general point contains these two vertices. A segment: any number of vertices sit side by side to shape a sequence, we call this sequence a “segment”. So, for a broad cycle, any part between two general points is a segment, and there are n(n-1) different segments for this broad cycle. For each general point, we construct a broad cycle which contains this general point. We call the broad cycle is the general point’s broad cycle, and the general point is the broad cycle’s general point. Because for an n vertices graph, there are n(n-1)/2 general points, we must construct n(n-1)/2 broad cycles(some of them may repeat). For a broad cycle, cut a segment at any place of this broad cycle, insert the segment between two consecutive vertices in some other place of the broad cycle. Before inserting, we may do the rotation and extension on the segment and then insert it. Note: for this rotation or extension, it is not necessary that the two end vertices are adjacent. We call this operation a “cut and insert” . The main operation in our algorithm is the “cut and insert”, now we explain it: Let x_1, ... ,x_n, x_1 denote a broad cycle, let s = x_i, x_{i+1}, ... ,x_{i+r} be a subsequence of this broad cycle(i.e., a segment), and let j be an index such that x_j and x_{j+1} are not in s. A broad cycle C is obtained by cutting s and inserting it into x_j and x_{j+1} if either C = x_j, x_i, x_{i+1}, ... ,x_{i+r}, x_{j+1}, x_{j+2}, ... ,x_n, x_1, ... ,x_{j-1}, x_{j}, or C = x_{j}, x_{i+r}, x_{i+r-1}, ... ,x_{i}, x_{j+1}, x_{j+2}, ..., x_n, x_1, ... ,x_{j-1}, x_{j} (addition is meant modulo n). Also, before inserting, we may do the rotation and extension on the segment and then insert it. Algorithm FindHCycle: For an undirected graph with n vertices and m edges, we first delete all the edges, then we get a graph with n vertices and no edges. This graph has n(n-1)/2 break points. For each break point(or connecting point), we construct a broad cycle which contains this break point(or connecting point). So, we construct n(n-1)/2 broad cycles(some of them may repeat). For each broad cycle, we try to get the least number of break points under the current edges. Apparently, at first, when no edges, all our n(n-1)/2 broad cycles fulfil the condition(least number of break points). Then, our algorithm includes m steps, we call each of the m steps “a big step”. At each big step, we add one edge. We call it “the current added edg e ”. Note, before adding this edge, all broad cycles are with the least number of break points, but after adding the edge, some broad cycles may not. If so, we try all the broad cycles for all possible one “cut and insert”, at least one “cut and insert” can get a new broad cycle which has the least number of break points(its old one does not, i.e., its break points number minus one). Apparently, this new broad cycle contains the new added edge. We let the new broad cycle replace its old broad cycle whose general point is the same as the new broad cycle’s. We call this a “little step”, each little step contains a successful cut and insert and a replacement. At each big step, we call all the broad cycles before adding the edge “old broad cycles”. If after the added edge, some general point’s broad cycle’s break points should minus one, if we can get this broad cycle with the least number of break points, we call it this general point’s “new broad cycle”. If a general point’s broad cycle, no matter how to arrange it, can always get a new broad cycle by a cut and insert, we call this general point “key general point”, call this broad cycle “key broad cycle”, and call this cut and insert “a useful cut and insert”. We call that the key broad cycle contains this useful cut and insert, call the key general point the useful cut and insert’s key general point, call the new broad cycle this useful cut and insert’s new broad cycle, call the new broad cycle’s general point the useful cut and insert’s new key general point. At each big step, when there will be some new broad cycles, we always can get at least one useful cut and insert to produce a new broad cycle. Then we use the new broad cycle to replace its old one. Then we can continue this process until there will be no new broad cycles. So continue to try the all possible one “cut and insert”, i.e., continue to finish the rest little steps, until we cannot get any broad cycle’s break points become less. This means all the broad cycles fulfil the condition(with the least number of break points) after adding the new edge. Go to the next big step, i.e., add another edge, do the same job as above. Until all the m edges have been added and finished. After all the m big steps, we can get all the n(n-1)/2 broad cycles with the least number of break points, of course, each broad cycle at least contains one different break point or one different connecting point. So, if there are some Hamilton Cycles, we can get at least one. Time Complexity: at each step, for one broad cycle, when we cut a segment, try to insert it between two consecutive vertices at any place of the rest part of this broad cycle, there are O(n) different points to be inserted, after the insert, we need to compare to decide if the result is a new broad cycle which contains a general point with the least number of break points under the new added edge(its old one does not, i.e., its break points number minus one). The comparison needs O(1) time(by memory). For each broad cycle, there are O(n 2 ) segments, for each segment, the rotation and extension need O(n) time, at each step there are O(n 2 ) broad cycles(even the new broad cycle replaces the old one, all possible new broad cycles are within O(n 2 )), also there are m big steps, so, all the time complexity is O(n 2 )* O(n 2 )* O(n)*O(n)* O(1)*m = O(n 6 )*m. Too long, right? But this is the worst case or the theoretical case, also it can get all the n(n-1)/2 broad cycles. In fact, by a lot of test, if an undirected graph contains at least one Hamilton cycle, our algorithm’s average time complexity for getting one Hamilton cycle is only about O(n 3 ). Some of the time in the O(n 6 )*m may not be necessary. For example, trying all the O(n 2 ) broad cycles is not necessary, we can make good choice. So is the O(n 2 ) segments. How to prove the algorithm? Our way is: to check every undirected graphs to find if it fulfil our algorithm and all the properties. But how to check “every”? we can see that for each cut and insert, only several vertices take action, other vertices do not. We can delete most vertices and only study the rest part with several vertices being left. First, we explain how to delete a vertex. 1) The deleting rule is: before deleting a vertex, all the broad cycles are with the least number of break points, after deleting, this property should hold and we do not need to rearrange all the broad cycles. 2) For the …abc…, after deleting vertex b, it becomes ac, even if vertex a is not adjacent to c, at this time, at this place, we assume there is a temporary edge between vertex a and c. 3) For the …a*b*c…, after deleting vertex b, it becomes a*c, even if vertex a is adjacent to c, at this time, at this place, we assume vertex a is not adjacent to c. 4) For the …a*bc…, after deleting vertex b, it becomes a*c, even if vertex a is adjacent to c, at this time, at this place, we assume vertex a is not adjacent to c. 5) If there are some contradictions, using this rule to solve the contradictions: some edges cannot occur at the same broad cycles at the same time. For example, for the …abc… and …dbe.., vertex a and c are not adjacent, nor d and e, after deleting vertex b, we get new edges ac and de, but these two edges cannot occur at the same broad cycles at the same time. Now we decide the vertex number for our testing graphs. When we do the “cut and insert”, if we do the rotation and extension on a segment, the segment needs at least 4 vertices, for the rest of the broad cycle, we need at least one new general point to insert the segment, so the rest of the broad cycle should contain at least 4 vertices. Both together 8 vertices. Also we should keep this broad cycle’s general point, 2 vertices. We should keep the current added edge, 2 vertices. So we must test all graphs with at least 12 vertices. Then we should add a vertex to each 12-vertex graph to see if the added vertex can destroy the algorithm. So we still must test all graphs with 13 vertices. Note: each graph is not only a simple graph, but is the rest part of a big graph after being deleted many vertices. In this graph, some edges cannot occur in the same broad cycle at the same time, we call this “a limitation”. For the test graphs, we should consider all possible combinations of the limitations. How to decide the limitations? At each big step, for the old broad cycles, we can consider any limitations of no contradictions, but no limitation on the current added edge, i.e., this edge is an absolute real edge. Also, when we do the cut and insert, we do not need to add any new limitations, because the added vertex can produce new limitations. Note: adding a vertex is the reverse operation of deleting a vertex. If after we add a vertex to the graph, a former useful cut and insert is no longer a useful cut and insert, we call that the added vertex destroys the useful cut and insert. We mainly have the following six kinds of destroys: Destroy 1: if the useful cut and insert is like this: we insert a…b into …fg…cd…, vertex a is adjacent to c, vertex b is adjacent to d, but when we add a vertex x, …fg…cxd…, if x is also adjacent to a or b, we still can insert a…b… between vertex cx or xd. At this time, we say vertex x does not destroy the useful cut and insert, If x is not adjacent to a and b, we say vertex x destroys the useful cut and insert. Destroy 2: if the useful cut and insert is like this: we insert a…b into …fg…cd…, vertex a is adjacent to c, vertex b is adjacent to d, but when we add a vertex x, …fxg…cd…, but now vertex a is not adjacent to c, only axc , thus, we say vertex x destroys the useful cut and insert. Destroy 3: if the useful cut and insert is like this: we insert a…b into …fg…cd…, vertex a is adjacent to c, vertex b may be adjacent to d or may not, after inserting, we get …fg…ca…b*d…, this is the general point b*d’s new broad cycle. When we add a vertex x, …fg…cxd…, we say vertex x destroys the useful cut and insert. But if this time we still can insert a…b between cx to get a new broad cycle of the general point b*x, at this time, we still say vertex x destroys the useful cut and insert. But it produce a new useful cut and insert. Destroy 4: usually one vertex destroys one useful cut and insert, but only in next case each of the two vertices can destroy a useful cut and insert: we insert a…b into …cdef…, vertex a is adjacent to d, vertex b is adjacent to f, vertex e is adjacent to c, thus, we say each of the vertices d and e destroys the useful cut and insert. Destroy 5: if the useful cut and insert is like this: we insert a…b into …f*g…cd…, vertex a is adjacent to c, vertex b is adjacent to d, but when we add a vertex x, …f*x*g…cd…, we still can insert a…b into cd, but this time the result is not with the least number of break points. So we say vertex x destroys the useful cut and insert. Destroy 6: if vertex a and b(or more) together destroy a useful cut and insert, but deleting any one of them cannot get this useful cut and insert, only deleting both of them we can get this useful cut and insert, then we do not think vertex a or b destroys this useful cut and insert. But, if after deleting vertex a, vertex b becomes destroying. In fact, the destroy 6 is not a destroy, we only give an explanation for this case. Note: only these six kinds of destroys, no others, because the test graph is the rest part of some big graph being deleted some vertices. Note: a destroy means: there is a real new broad cycle for this destroy. If there is no such a new broad cycle for this “destroy”, it is not a destroy. For a useful cut and insert, we call the broad cycle, which can produce a new broad cycle by this useful cut and insert, a parent broad cycle, call its general point a parent general point, call this new broad cycle a child broad cycle, call the child broad cycle’s general point a child general point. If a vertex destroys some useful cut and insert, we call it a destroying vertex. If a vertex does not destroy any useful cut and insert, we call it an un-destroying vertex. Our main proof idea is: we check that any graph with 12 or 13 or 14 vertices at each of its little steps has at least one useful cut and insert. Also, we check that for any graph with 12 or 13 or 14 vertices at each of its little steps, its un-destroying vertices is at least 2 more than its destroying vertices. Then we prove that any graph with more than 14 vertices also has this property by deduction on vertex number. So, for a 15-vertex graph, if we delete an un-destroying vertex, it becomes a 14-vertex graph, because each 14-vertex graph always has at least one useful cut and insert, so does the 15-vertex graph, and so on. Now we explain a very important concept “main child general point”. The main child general point has the following properties(we can check them): 1) For each 12-vertex graph at each of its little steps, the least number of break points of any broad cycle of its one main child general point must decrease by 1 after adding the current added edge. 2) Each 12-vertex graph at each of its little steps, has at least one main child general point and also has at least one useful cut and insert for this main child general point unless it finish all the little steps of the current big step. 3) Each 13-vertex graph at each of its little steps, has at least one main child general point and also has at least one useful cut and insert for this main child general point. When we delete any one vertex except the two vertices of the main child general point, the rest 12-vertex graph still has the same main child general point and also has at least one useful cut and insert for this main child general point. 4) For each 13-vertex graph at each of its little steps, let vertex a, b, c are three distinct vertices in this graph which do not belong to the two vertices of the main child general point(say g). We want to add one vertex d into this graph. If either we delete vertex a, add vertex d, or we delete b, add d, both cases the g is the 13-vertex graph’s main child general point, then, for these 14 vertices, deleting any one vertex except the two of the main child general point, g is always the rest 13-vertex graph’s main child general point. We call g the 14-vertex graph’s main child general point. If either we delete vertex a, add vertex d, or we delete b, add d, both cases the 13-vertex graph’s main child general point is (d,c), then, for these 14 vertices, deleting any one vertex except the two of the main child general point, (d,c) is always the rest 13-vertex graph’s main child general point. If we delete a, add d, g or (d,c) is the main child general point, but if we delete b, add d, g or (d,c) is not the main child general point, then, for these 14 vertices, deleting any one vertex except the two of the main child general point (d,a), (d,a) is always the rest 13-vertex graph’s main child general point. At this time, we call (d,a) the 14-vertex graph’s main child general point. 5) From 4), we can get the corollary: for any graph with more than 13 vertices, it also has the property 4). 6) For each 12 or 13 or 14 vertices graph, at each of its little steps, for one main child general point, the number of un-destroying vertices is at least 2 bigger than the number of destroying vertices. Also we check any 14-vertex graph has at least one useful cut and insert for the main child general point at any little step. Note: this destroying only is for such useful cut and inserts: they produce the new broad cycles whose general point is the main child general point. So is the un-destroying. Now we prove any graph with more than 14 vertices also has property 6). We prove this by deduction on vertex number. Proof: we suppose any k-vertex graph has property 6) (k=14), for a k+1-vertex graph, let vertices (a,b) is one main child general point at its one little step, let d is the number of its destroying vertices, let u is the number of its un-destroying vertices, both for this main child general point. If u is at least 2 bigger than d, it is ok. If not, we first suppose d=u. At this time, the worst case is: for each vertex of u, its all possible parent general point(i.e. added any one of the other vertices except the two of the main child general point, i.e., for all the possible parent broad cycles whose general points contain this vertex of u), are destroyed by 2 vertices of d. So, if we delete one vertex of u, the number of destroying vertices is d-2, the number of un-destroying vertices is u+1, i.e., we move 2 vertices from d to u. But we can delete these two vertices again, then, the number of destroying vertices is d-2(may be more, because for the case Destroy 6, deleting one vertex may let a vertex become a destroying vertex, but this does not affect our proof.), the number of un-destroying vertices is u-1, u-1-(d-2)=1, i.e., for the k-2-vertex graph, the number of un-destroying vertices is 1 bigger than the number of destroying vertices. A contradiction. We then suppose u=d+1. At this time, the worst case is: at least for one vertex of u, its all possible parent general point(i.e. added any one of the other vertices except the two of the main child general point), are destroyed by only 1 vertex of d. So, if we delete this vertex, the number of destroying vertices is d-1, the number of un-destroying vertices is u, i.e., we move 1 vertex from d to u. But we can delete this vertex again, then, the number of destroying vertices is d-1(may be more), the number of un-destroying vertices is u-1, u-1-(d-1)=1, i.e., for the (k-1)-vertex graph, the number of un-destroying vertices is 1 bigger than the number of destroying vertices. Also a contradiction. Other cases also have the same way contradictions. So we proved any graph with more than 14 vertices also has property 6), i.e. has a lot of vertices which do not destroy any useful cut and insert for the main child general point. Because any graph with 14 vertices has at least one useful cut and insert for the main child general point at each of its little steps, so does any graph with more than 14 vertices.
5540 次阅读|45 个评论
个体、群体,概率与NP问题
热度 2 dulizhi95 2011-10-19 10:52
个体、群体,概率与 NP 问题 我曾经在以前的文章中论述过:现今已发现了 4000 多个 NP 完全问题,还会继续发现下去。所有 NP 完全之间的距离是多项式,这件事实本身强烈地昭示着( strongly imply ), NP 问题具有统一的求解规律和难解度,并且也应具有多项式量级。 当然这只是一种初略的判断,而不是严格的证明。现今,当我的多项式算法不仅能计算所有 Hamilton 环,同时还能计算所有 3SAT ,并且我的证明思路逻辑严密时, NP 等于 P就是必然的了 。 下面解释一下前面的的第一段话: 客观世界的任何一个群体,其任意个体之间某个属性的差值,与个体属性的绝对值通常都处在同一个量级。举例说来:成人的体重是百斤量级,很肥壮和很瘦的人之间体重的差值也是百斤量级,绝不可能是成人之间体重的差值最多只有几斤几两,而成人的绝对体重都是几百斤。同样,成年蚂蚁体重以克计,肥大的蚂蚁与瘦小的蚂蚁体重之差也是以克计……等等等。 再举一个例子:假使在某个太空中随机选 n 个点, n 显著大于 1 ,若其中任两个点之间的距离都不超过 10 的 10 次方米,我们就有理由认为,该太空本身的最大尺度也在 10 的 10 次方米量级。
3251 次阅读|2 个评论
伯克利工业工程系的前辈David Gale教授-稳定婚姻问题
热度 1 王军强 2011-10-12 14:18
伯克利工业工程系的前辈David Gale教授-稳定婚姻问题 (stable matching or stable marriage problem ) 稳定婚姻,就是指男女结婚后,双方都不会发生出轨行为。那怎样才能做到双方都不出轨呢?如果双方都是对方的最爱,自然不会出轨;如果有一方或双方都不是对方的最爱,则必须保证想出轨的人找不到出轨的对象。简言之,只要满足“除妻子(丈夫)外,我爱的人不爱我,爱我的人我不爱”条件,就可形成稳定的婚姻。 稳定婚姻问题(Stable Marriage Problem) 已经被证明是一个 NP 问题, 在过去的几十年里很多人开始对这一课题产生兴趣,同时越来越多的 paper 对这一问题进行深入的研究。 最为著名的研究是由 美国数学家、加州大学伯克利工业工程系教授 David Gale和加州大学洛杉矶分校 Lloyd Shapley在1962年发明的稳定婚姻的寻优策略,人们称之为延迟认可算法(Gale-Shapley算法)。 先对所有男士进行落选标记,称其为自由男。当存在自由男时,进行以下操作: ① 每一位自由男在所有尚未拒绝她的女士中选择一位被他排名最优先的女士; ② 每一位女士将正在追求她的自由男与其当前男友进行比较,选择其中排名优先的男士作为其男友,即若自由男优于当前男友,则抛弃前男友;否则保留其男友,拒绝自由男。 ③ 若某男士被其女友抛弃,重新变成自由男。 在算法执行期间,自由男们主动出击,依次对最喜欢和次喜欢的女人求爱,一旦被接受,即失去自由身,进入订婚状态;而女人们则采取“守株待兔”和“喜新厌旧”策略,对前来求爱的男士进行选择:若该男子比未婚夫强,则悔婚,选择新的未婚夫;否则拒绝该男子的求婚。被女友抛弃的男人重获自由身,重新拥有了追求女人的权利——当然,新的追求对象比不过前女友。 这样,在算法执行期间,每个人都有可能订婚多次——也有可能一开始就找到了自己的最爱,从一而终——每订一次婚,女人们的选择就会更有利,而男人们的品味则越来越差。只要男女生的数量相等,则经过多轮求婚,订婚,悔婚和再订婚之后,每位男女最终都会找到合适的伴侣——虽然不一定是自己的最爱(男人没能追到自己的最爱,或女人没有等到自己的最爱来追求),但绝对不会出现“虽然彼此相爱,却不能在一起”的悲剧,所有人都会组成稳定的婚姻。 Gale-Shapley 算法最大的意义就在于,作为一个为这些男女牵线的媒人,你并不需要亲自计算稳定婚姻匹配,甚至根本不需要了解每个人的偏好,只需要按照这个算法组织一个男女配对活动就可以了。你需要做的仅仅是把算法流程当作游戏规则告诉大家,游戏结束后会自动得到一个大家都满意的婚姻匹配。对于男性来说,从最喜欢的女孩儿开始追起是顺理成章的事;对于女性来说,不断选择最好的男人也正好符合她的利益。因此,大家会自动遵守游戏规则,不用担心有人虚报自己的偏好。 历史上,这样的“配对游戏”还真有过实际应用,并且更有意思的是,这个算法的应用居然比算法本身的提出还早 10 年。早在 1952 年,美国就开始用这种办法给医学院的学生安排工作,这被称之为“全国住院医师配对项目”。配对的基本流程就是,各医院从尚未拒绝这一职位的医学院学生中选出最佳人选并发送聘用通知,当学生收到来自各医院的聘用通知后,系统会根据他所填写的意愿表自动将其分配到意愿最高的职位,并拒绝掉其它的职位。如此反复,直到每个学生都分配到了工作。当然,那时人们并不知道这样的流程可以保证工作分配的稳定性,只是凭直觉认为这是很合理的。直到 10 年之后, Gale 和 Shapley 才系统地研究了这个流程,提出了稳定婚姻问题,并证明了这个算法的正确性。 伯克利官方资料介绍伯克利工业工程系的前辈David Gale教授 David Gale joined Berkeley in 1966 and held appointments in the departments of IEOR, Mathematics, and Economics. His work was instrumental to the development of game theory, and linear and non-linear programming. Gale’s unorthodox but influential research paper describes an “algorithmic procedure to find… a stable marriage.” Their findings from this paper have been expanded and used to match students to schools。 Gale published an influential paper on the so-called stable matching or stable marriage problem with Lloyd S. Shapley, now professor emeritus of mathematics and economics at the University of California, Los Angeles. Gale and Shapley proved that, given an equal number of men and women who rank one another in terms of romantic interest, it is possible so to pair them in marriage that no two people would rather be married to each other than to their partners. They also provided an algorithmic procedure to find such a stable marriage. Gale and Shapley’s theoretical work on this problem legitimized a procedure used to match newly graduated doctors to hospital residency programs. The paper generated an enormous literature, and variations of the matching algorithm are used to match students to schools.
个人分类: 生活点滴|11415 次阅读|1 个评论
试论围棋软件开发与NP问题
热度 1 dulizhi95 2010-9-7 07:47
试论围棋软件开发与 NP 问题 有网友给本人留言,建议我开发一个围棋软件,说那不就一切都证明了吗?此建议非常好,但要做好还有诸多困难,且就算做好了,也不意味 NP 问题的解决。 下围棋属敌对搜索,是极大极小搜索加剪枝问题中的一种。问题在于,它的分支数非常大,也就是可选的点很多,因而计算深度就只能很浅了,否则计算量和储存量都会大得惊人。不仅如此,它的状态值量化非常困难,从而在进行优劣选择以及剪枝时,非常难把握。因此,迄今最好的围棋软件只能达到业余二段的水平,与专业高段当然是相差十万八千里。 人能达到专业强九段的水平,我们不妨假定此水平极高。由此就产生了如下问题: 1 ,围棋是 NP 吗? 2 ,围棋是 NPC 吗? 3 ,此问题能在多项式内解决吗? 注意到强九段,显然,不能认为强九段的思维能力和记忆能力能满足指数型。我们不妨设想人类能出现这样顶级的围棋高手,他下棋就能达到最优,也就是说能在多项式时间内完成判断计算。这就意味着,一个明显的指数型搜索问题,有人却可在多项式内完成。他是如何办到的呢?回答只能是:充分研究后充分的知识积累以及复杂的关联信息的充分把握!由此,可以得到解决 NP 问题的某些启发。 从逻辑上可以判断,人能做到的,软件也应能做到,且不会增加计算量和储存量。 自从我的论文在网上公布后,收到过一些电子邮件和反馈信息,主要是要我寄正式版的运行程序,有的甚至表示愿意将自己的成果跟我交流。也有的规劝我不要搞了,说那极难特难,不可能搞出来。还有网友说我在 arxiv 上的那篇论文隐藏了核心内容没有公布,因而看不懂。我这里要说明的是,我在 arxiv 上的那篇文章公布了全部的核心内容,包括完整的逻辑思维线条,根本没有什么不愿公布的东西。 我最害怕碰到这样的人,用常识性东西来规劝我:你可能不理解, NP 是非常顶级的世界难题,所以你不可能搞出来;或者: Hamilton 环尽管是 NP 完全的,但它在大部分情况下很容易算,所以你的程序不能说明问题 ----- 此点我当然知情,且我在论文中早已提到过。至于它到底是怎么个容易法、分布法,我掌握得很清楚,显然无须被规劝。 我也害怕碰到这样的人,真的高手或故作高手:我的时间非常宝贵,不愿意浪费时间看你的论文,因为它不可能对。问题是,某些主动给我发邮件或给我博客留言的人,也有这个意思,我并没有招你呀? 我最希望碰到这样的人,稍花点时间看我的论文,之后产生如下结果: 1 ,表示肯定或表示自己无法确定; 2 ,从根本上否定并指出问题所在; 3 ,指出在哪个地方肯定有问题; 4 ,指出在哪个地方可能会出问题。最后,并给我解释说明的权利。 我断言,人世间不存在这样的智商:能在较短时间内,做到第 2 点或第 3 点! 再次强调,我在 arxiv 上的那篇文章就是全部,完全可以得到上述结果! 此外,我显然没有兴趣从 NP 理论知识,从算法思维能力的角度得到帮助或指点,但我希望能从英文论文写作的经验,从论文投稿的经验,以及在我论文的收尾工作上得到实质性指点和帮助,甚至包括重新组织论文结构和语言表达。当然,若是有实质价值的帮助,有较明显的工作量,那就不是帮助了,而是合作( Share ),也就是说,我不能让人白帮忙。 前些时,我对论文作了一些细节添加和修改,并在论文后面补了一段简单的概要:第一要点,第二要点,第三要点,连起来就是证明。若要否定我,须否定其中任何一个要点。将论文先后寄到两国际顶级期刊,效果依然不行。其中一个初筛关倒是过了,到了一国际知名的大牛手中,那家伙又是不给理由就拒了。该期刊在给我拒绝信时,要我有什么意见,直接 kindly 回复该大牛。在此特请教经验丰富的专家们,是否有抗辩的可能,怎样 kindly 抗辩?
个人分类: 未分类|5012 次阅读|5 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-20 00:00

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部