美文网首页算法
对素数和NP问题的理解

对素数和NP问题的理解

作者: _shen | 来源:发表于2018-04-02 15:48 被阅读94次

    对于未来我们无知的太多,但是我们的逻辑推理却存在一种递推的巧妙工具,虽然未来是发散的,但是我们却可以找到前一个和后一个之间的过渡规律,即使我们不知道最终会是什么样子,但是我们却能够肯定说未来一定是现在经过一定演化的结果。比如F(n) = F(n-1) + F(n-2),那么只要我们知道了F(n-1)和F(n-2),那么我们就可以计算出F(n),F(n-1) 与 F(n-2)之和等于F(n)实质上就是这种演化规律。举个生活中的例子,比如太阳的东升西落,经过我们长期的观察总结便得出了一个规律,按照这个规律我们在下午看到了太阳西落,那么我们会非常自信的说:明天太阳一定会从东方升起。理性思维让我们的世界充满了更加的确定性和可认识性,但是世界的全部真就都如此一样?谁也不能肯定的说世界就是如此秩序和规律,因为世界是发散的,我们无法看到世界发展的尽头,甚至有人怀疑世界真的运动吗?世界真的存在吗?对于这些高深的问题,我们知之甚少,甚至是一无所知。

    我们从小就学习数数,学习数学,但是我们对数字的认识依旧是贫乏的,我们知道无穷大,还知道无穷大的无穷大,这是一条没有尽头的路,我们知道的仅仅只是数字之间的一种接替比较关系,比如200+1 = 201,也就说在200之后还有一个比他大1的数,但是我们不知道200之后到底还有多少的数字。我们知道有n趋向于无穷大,我们还知道n^2比n这个趋向于无穷大还要大。从这些例子中我们可以看出,我们知道仅仅只是事物演变过程中的接替承载关系,而且这种关系可能也是不稳定的不现实的。在我们的数学世界里,数字是连续的、前后紧密接替衔接起来的,但是在现实世界中,我们却仅仅只能发现间断式存在的事物,比如电子的跃迁、光电效应。生活中,我们也总是能够感觉到在电脑显示器中看到与现实差异很大的画面,似乎显示器中的画面颜色更加鲜艳美丽,而现实中的光线颜色是零散地分布着。

    前面做了这么多铺垫,实际上就是为了引出下面的问题:存在最大素数吗?什么是素数,只能够被1和它本身整除的数字就是素数,也称为质数。咋一看,我们可能都会回答不存在最大素数,这种感觉源于我们对数字无限性的认识,因为我们无法找到数字的极限,我们也无法得知是否存在一个最大素数,可能一些人就是这样理解和回答这个问题的。但是数学家从来不做这种不靠谱的回答,他们总是要给出一种证明办法,他们用反证法证明,给出了一个确定的答案:不存在一个最大素数。

    假若素数只有有限多个,设最大的一个是P,从2到P的全体素数是:2,3,5,7,11…,P。所有的素数都在这里,此外再没有别的素数了。现在我们来考察上面从2到P的全体素数相乘再加1这个数,记为A,即:

    A = 2×3×5×7×11×…×P + 1

    我们知道:A是一个大于1的正整数,它不是素数,就是合数。

    • 如果A是素数,那么就得到了一个比素数P还要大的素数,这与素数P是最大素数的假设矛盾;
    • 如果A是合数,那么它一定能够被某个素数整除,设这个素数为G。因为A被从2到P的任何一个素数除,余数都为1,也就是说A不能被从2到P的任何一个素数整除,因此能够整除A的素数G不在从2到P这个素数序列中,那么G一定是比P更大的素数,这也证明了P不是最大素数的假设。

    通过这个最大素数问题我想说明什么东西呢?就是想说明如何在一个发散的问题中寻求其内在的规律。尽管数字的世界是发散没有尽头,但是数字之间却拥有这内在关联性,即7 = 6+1,1001 = 1000+1,我们正是通过这种内在递推接替关系(内在牵制承载关系),才最终解决了发散的问题。但是现实世界中的问题远远不是数字问题这么简单,如果事物之间的递推接替关系也在发生着演变,那么我们就很难通过这种方式去求解一个发散的问题。就比如困扰人们很久的NP(非确定性多项式)问题,就是因为在一个递推接替关系变化的发散世界中求解确定性规律,这是非常难的,因为规律本身也发生着变化。

    前面我们说明了最大素数不存在,强调一点:我们仅仅只是证明了最大素数不存在。其实这个问题可以转化为是否存在一种公式,将这个数字代入之后直接得出结果。从素数的性质来看,是要寻找任何一个只能够被1和它本身整除的数字,我们一般能够想到的办法就是从比它小的所有整数中去试,只有当每个数字试过之后,我们才能够判断它是不是符合这种性质,因为我们实在找不出上一个素数和下一个素数之间的比较稳定的递归关系。当数字比较小的时候,我们采用暴力的穷举法去一个一个试,但是当这个数字变得非常大的时候,我们需要穷举的个数也会变得非常庞大,其实这也就是NP问题,对于判断是否为素数这个问题的时间复杂度,我们不能计算得出一个稳定的值,实际上就是一个和数字一样的发散值。讲清楚了这些,我们也会明白为什么迄今为止,人们仍未找到任何易于计算的素数公式。就是因为上一个素数和下一个素数之间不存在这种递推接替关系,在发散的数字世界中,素数公式就成为了一个发散问题。

    按照上面的思路,我们很容易可以用计算机实现素数的判断:

    bool is_Prime(int n) {
      for (int i = 2; i < n; i++) {
        if (n % i === 0) {
          return false;
        }
        return true;
      }
    }
    

    但是这样的方法效率非常低,我们知道一个数如果可以进行因式分解,那么分解时得到的两个数一定是一个小于sqrt(n),一个大于sqrt(n),因此我们只需要遍历到sqrt(n)就可以了。

    bool is_Prime(int n) {
      int num = sqrt(n);
      for (int i = 2; i <= num; i++) {
        if (n % i === 0) {
          return false;
        }
        return true;
      }
    }
    

    正式因为素数具有的这种特性,也成就了素数非常巨大的实用价值,那就是非对称加密算法。两个素数A和B相乘之后的乘积C在分解的时候只有唯一的一种分解方案,就是A和B(1和它本身不算分解),因此具备唯一性。如果我们采用合数相乘,或者素数和合数相乘,就不具备这种唯一性,因为合数具有多种分解方案。我们可以非常容易的得到两个非常大的素数的乘积,但是当我们拿到这个数字的时候,我们却很难反推出这个乘积是由哪两个质数相乘得到的。因为在乘积分解的时候,除了1和它本身外(这里不算分解),只有这两个大素数符合条件,但我们此时是不知道这两个大素数,只有从最小的素数2开始试,逐步排除,而我们又没有一个素数的计算公式。RSA正是利用了整数因式分解的复杂特性和素数乘积因式分解的唯一性。

    相关文章

      网友评论

      • 七孔桥:太佩服你的思维逻辑啦,这种逻辑性强的文章我能看个一知半解就已经很不错了。文中代码看着像pythone呢?
        _shen:@七孔桥 这么高的评价:smile:,文中的代码是C

      本文标题:对素数和NP问题的理解

      本文链接:https://www.haomeiwen.com/subject/oylxhftx.html