如何用算法绘制一张上海外滩夜景图

突发奇想:一个数学界的未解之谜

无意间想到一个有趣的数学问题,也是数学界困扰人类很久的一个谜题:

克拉茨猜想

(图片来源 【数学狂】如何形象地展示克拉茨猜想 -- Collatz Conjecture in Color_哔哩哔哩_bilibili

它也叫3n+1猜想、奇偶归一猜想、乌拉姆 (Ulam)问题、角谷猜想等... 相信你一定听说过

这个猜想的描述十分简单:

任取一正整数,如果是偶数,将其除以2。如果是奇数,将其乘以3再加1,然后重复这个过程,最后结果都是1......

我们可以尝试,随便举个例子:

13是一个奇数,那么我们将它乘3再加1,得到40,

40是一个偶数,那么我们将它除以2,得到20,

以此类推...

你会得到下面这样一个序列:

13→40→20→10→5→16→8→4→2→1

由10个数组成了这个序列,或者说13对应的序列长度为10

同理,我们再取任意一个数,依然能够得到这样一个序列,并且数一数可以知道这个序列一共有几个数字。

这个模型在算法中被称为冰雹(HailStone)模型,因为在序列中出现的数字,很类似于冰雹在空中运动的轨迹,时而上升一下(遇奇数时),时而下降(遇偶数时)......最终都会回到1。

有趣的是,这个序列中元素的个数,与最初给定的整数的大小,并不是正相关的关系,于是,我愿意探究这个关系,将其用计算机计算出来......

小试牛刀:关于我试图验证克拉茨猜想这件事

根据克拉茨猜想,我直接站在巨人的肩膀上,写出了这段代码:

public class demoHailStone {
    public static void main(String[] args) {
        int n = 1;
        int length = 1;
        for (int i = 1; i <= 100; i++) {
            n = i;
            length = 1;
            while (n > 1) {
                if (n % 2 == 1) {
                    n = 3 * n + 1;
                } else if (n % 2 == 0) {
                    n = n / 2;
                }
                length++;
            }
            System.out.println(length); // 打印这个序列的长度
        }
    }
}

n是最开始给出的整数,比如我在前面给出的13→40→20→10→5→16→8→4→2→1,这个序列,我们只需要告诉这段代码 n = 13 即可,

while循环用来计算序列的长度 length(序列的长度后面都叫为length)

现在我想得到 n = 1 、 n = 2 、 n = 3 、...、n = 100,对应所有的length

所以我又嵌套了一个for循环,循环100次。

于是,我将光标放在了i <= 的后面,肆意妄为地在小键盘上胡乱地敲击了一通,输入了一个变态的随机数字:138435

for循环了十三万多次,嵌套着while循环,run了一下

(好吧,我可能是算法黑洞……)

 好家伙,也就不到1秒的功夫,我的计算机给我返回了十三万次循环的结果,最后几行是这样的:

于是我把 i 加了1换成了138436,又run了一下,又过了不到1秒

输出台中只是在最后一行多了一个57,前面的数字都一样!

此时我已按奈不住激动的内心,两次结果告诉我:

在十三万八千四百三十六这个整数之前的所有正整数,都符合克拉茨猜想!

否则,我的程序会因为得不到n=1的情况,在循环过程中卡住,那么两次输出应该是一样的。

Of course,这并不是一个严谨的数学证明,只不过是一个小实验而已。

不禁对计算机运算的速度表示惊叹,给一个初始正整数,有时可能要算上一百多次才能回到1,更不要说我对从1到138436这十三万多个数字全测试了一个遍,也仅仅用了不到1秒的时间。

统计之美:打开脑洞发现数学就是艺术

起初,我试图发现这些数字背后的规律或者奥秘,但当我滚动着这十三万行结果,进度条怎么也不动时,我知道,这不是我这个普通人类能发现的规律,我只是大概摸索出了一些规律:

1. 最大的length貌似就是300多,没有看到更大的,也就是说很大概率上,无论给一个多大的正整数,用克拉茨算法最多计算300多次也就回到1了

2. 常出现“跟风”现象:几个相邻的整数经过克拉茨猜想算法后,返回的length连续2至多个是一样的,如下:

这样的现象贯彻始终,似乎它们约定好了“三五成群”地聚在一起,很遗憾,这其中的数学原理我还不得而知,但这样的规律实在太明显了,所以拿出来说一说。

当然,以上都像是伪科学,只能算是定性研究,所以我还是决定试着做一些统计分析,把定量的图表呈现出来。

统计分析:

在1-138436之间(我们记为样本A),任取一正整数,如果是偶数,将其除以2。如果是奇数,将其乘以3再加1,然后重复这个过程,记录每个正整数得到1的过程中,运算的次数 length 。

在这样一个相对来说并不小的样本量中,统计所有的 length 以及它对应出现的次数 count:

(前段、中段、尾段)

看到头尾小,肚子大的特点,太容易让我们联想到统计学中的大数定律了

 以length为横轴,以length出现的次数count作为纵轴,绘制散点图:

 可以观察到一个类似于“M”形状的长尾分布图,最大的length确实也就是300多了(当然可能样本A的样本量并不足够大),更具体的特征还有: 

1. 在样本A中,length的长度几乎都是400以内的,最大的length是354,只出现了1次,也就是说在克拉茨猜想的算法中,需要计算超过400次才能回到1的可能性微乎其微。

2. 在样本A中,从1-354的length并不是一直可以连续统计到的,从 length=290 开始,诸如290、293、295、以及后面很多的数...没有作为length的结果出现。(当然可能样本A的样本量并不足够大×2)

3. 在样本A的138436次的while循环运算中,出现次数最多的length是62,出现了1989次,大致计算一下比值=0.01436765,而290、293、295等等,并没有出现过,也就是说,每个length的出场率,大致上是在0%-1.436%之间的......(当然依然可能是样本A的样本量并不足够大)

4. 在样本A中,length 出现的次数随着 length 的变化,并不是平滑的,而是锯齿状的,绘制折线图:

 ……对不起,我暂时只能总结这么多了,感觉可以挖掘的太多了

最终,我还是放弃了挣扎,证明克拉茨猜想的工作,交给神去处理吧o(╥﹏╥)o

对了,最后差点忘了,我是如何用算法绘制一张上海外滩夜景图的?如是说

脑洞大开:从克拉茨猜想到上海外滩夜景

思考了良久,我似乎做了一些没有意义但是有意义的事,为逝去的这一夜叹息之时,我想到了最开始的那个问题:

“有趣的是,这个序列中元素的个数,与最初给定的整数的大小,并不是正相关的关系,于是,我愿意探究这个关系,将其用计算机计算出来......”

那这个序列的长度 length 和最初给定的整数的大小 n ,到底是什么关系啊!

当然,鉴于我并不希望看到一张杂乱无章的抽象艺术画作,所以我要把循环次数改小一些

i <= 100

以n为横轴,以length为纵轴

run

我得到了这样一张图片:

也许稍加改动,就得到了它:

 (图片来源 上海外滩夜景|摄影|环境/建筑摄影|林弋然 - 原创作品 - 站酷 (ZCOOL)

----------------Useless but Happy Ending----------------

原创内容,转载请注明出处,欢迎交流~

CSDN:@Coder_Liufan

知乎:@Wayne

email:928400563@qq.com

2022年3月29日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_Liufan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值