• 指数爆炸随想


        从《程序员的数学》上看来,转载注明华科小涛@http://www.cnblogs.com/hust-ghtao忍者

        所谓爆炸,其实并不是真正的爆炸。指数爆炸是指数字呈现爆炸式增长。如果遇到的问题包含指数爆炸就要注意了。因为一旦处理不好,该问题可能会膨胀到难以收拾的地步。相反,若能巧妙利用“指数爆炸”,它将成为解决问题的有利武器。

    1. 体验指数爆炸的威力

        我们将通过折纸问题、倍数游戏和解密难题来体验一下指数爆炸的威力!

    1.1 折纸问题

        假设现在有一张厚度为 1mm 的纸,纸质非常的柔软,可以对折无数次。每对折一次,厚度翻一番。已知:地球距离月球约为39万公里,请问对折多少次后厚度能超过地月距离呢?

        在计算之前,我们先凭感觉估计一下对折多少次能达到月球。100万次会不会太多了?1万次差不多吧?你觉得几次合适呢?

    答案是39次有木有,只要39次啊!仅仅对折了39次,就让 1mm 的纸的厚度达到了地球到月球的距离,实在是让人大吃一惊!仅仅反复折纸,数字就不断翻倍,就很快得出了非常庞大的数字。我们把这种情况称为“指数爆炸”。之所以称为指数爆炸是因为折纸的厚度(CodeCogsEqn(11))的指数 n 就是对折次数。

    1.2 倍数游戏

        如果我们要解决的问题中包含倍数游戏--指数爆炸,就要注意了。因为包含指数增长的问题,即是初看比较简单,但是问题稍微复杂一点,就会变得难以解决。

        程序中有控制程序运行的“设置选项”:

    f9198618367adab43898b5a98ad4b31c8601e494,图中有两个二值图标,它们能分别切换选中状态(On/Off)。选中不同的状态,程序的执行就会有所不同。程序员必须测试自己开发的程序能否正常运行。如果测试不完备,程序就有可能崩溃或挂起。甚至可能发生文件破损,工作成果丢失等情况。

        在了解了以上内容后,让我们思考这样一个问题:假定程序中有 5 个复选框,每个复选框都有 On/Off 两种状态。要测试设定选项的所有情况,需要几次呢?若将设定选项改为 30 个复选框,答案又是什么?

        因为一个复选框有两种状态,所以 n 个复选框的测试次数为CodeCogsEqn(11)。当有 5 个复选框时,结果为CodeCogsEqn(12)次。而当有 30 个复选框时,测试的次数应为: CodeCogsEqn(13)

        30个复选框说起来也不算多。打开稍微大点的应用程序选项就知道了,不过尽管如此,光测试30个设定选项的可能性,就需要测试10亿7374万1824次。假设测试1次只需1分钟,要完成这么多测试,也要2000多年啊!所以,要一个不漏地测试设定选项的所有可能是不现实的。

    1.3 解密难题

        现在使用的密码,是用俗称“密钥”的随机字节流来加密的。如果加密算法没有任何弱点,那就只能“一个不漏”地去破解了。即做出和密钥长度长度相同的字节流,尝试破译密文。这种密码破译法称为暴力破解法。

        被用作密钥的字节流长度越长,暴力破解就越费时。我们用二进制来表示密钥:

    如果密钥的长度只有 3 位,那么正确的密钥必是下列八种情况之一:

    000、001、010、011、100、101、110、111. 即如果密钥为3位,那么最多试8次就能破解密文。

        一般地,设字长为 n ,则密钥的可能性为CodeCogsEqn(11)。每增加一位,试解次数就翻倍,也就是说这里包含了指数爆炸。

    捕获,这就很难用暴力破解法破解了。

    假设构成宇宙的每一个基础粒子都是一台现代的超级计算机。即便这些不计其数的超级计算机,从宇宙诞生开始一刻不停的试解密钥,试到现在也试不完512位密钥的所有情况。

    2. 二分查找——利用指数爆炸进行查找

        指数爆炸,虽然可怕,但也可以为我们所用。

    二分查找是在数据中找出目标数据时“总是判断目标数据所在范围内正中间数据”的方法。

    下图有 15 个数按顺序排列。假设要在其中查找特定数据(67)。要求这些数字从小到大排列,并且要查找的数字必为其中之一:

    捕获

    我们要反复“判断正中间的数”,通过3次就能找到 67:

    捕获

        要知道二分查找利用了指数爆炸的威力,只需判断10次,就能在2047个数据中找到目标数据。判断20次就能在2097151个数据中找到目标数据。判断30次就能在2147483647个数据中找到目标数据。

        二分查找的关键在于,每判断一次就能筛掉近一半的查找对象,判断 n 次就能从CodeCogsEqn(14)个数中找出目标数据。

    3. 对数——掌握指数爆炸的工具

    3.1  对数图表

        一旦发生指数爆炸,数字就会变得非常的庞大。我们来看一下处理这种庞大数据的工具——对数。

        我们知道,在难以处理的庞大数字,它的对数都是更易处理的较小的数字。用普通图表示折纸的厚度时,曲线会骤然上升,很难处理。但是在对数图表中,指数爆炸也能表现的很好:

    捕获

    对数图标能够帮助我们把握发生指数爆炸的数急速增长的情况。

    3.2 用加减法实现乘除法

        乘除法比加减法难,使用对数就可以将乘除法转化成加减法。

    根据:捕获。现在假设2个正数A和B相乘。我们不直接用A乘以B,而是指行如下步骤:

    • 分别求出“A的对数”和“B的对数”
    • 把“A的对数”和“B的对数”相加
    • 相加的结果进行乘方。

    虽然很简单,但是前提要将对数做成表。在出现现代计算机以前,被广泛使用的计算尺就是有效使用对数进行乘法和除法的工具。

    4. 总结

        与倍数游戏相似,仅反复翻倍几次数值就骤然增长,所以我们在解决问题时务必要注意指数爆炸。否则即使费力写出了程序,可能也要几千年才出结果,哈哈哈!

        另一方面,将指数爆炸为我所用,它就能称为解决问题的利器,像二分查找和对数都是利用了指数爆炸!

        最后,知道有限是相对的,如果对于人类来说是不可及的,和无限又有什么区别。

  • 相关阅读:
    WebForm捆绑压缩js和css(WebForm Bundling and Minification)
    2017.4.15
    .NET Core + docker入门
    微软官方教程视频入口
    C# struct和class
    法线的变换的一些概念
    透视投影矩阵的一些概念
    视图矩阵ViewMatrix一些概念
    矩阵一些概念
    向量一些概念
  • 原文地址:https://www.cnblogs.com/hust-ghtao/p/4156592.html
Copyright © 2020-2023  润新知