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

news/2025/2/15 6:16:02/

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

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

克拉茨猜想

(图片来源 【数学狂】如何形象地展示克拉茨猜想 -- 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日


http://www.ppmy.cn/news/678556.html

相关文章

40个使用HDR的超棒夜景摄影照片展示

摄影概念在不同的镜头和滤镜下的显示完全不一样。高动态光照渲染(HDR)使用高定义分辨率来把光线呈现出独特的效果。这些照片都是在傍晚或者黑夜中拍摄的效果。多数是来自街道或者房子的光线的效果。渲染出非常隆重的气氛并且非常非常引人注目。希望大家喜欢&#xff01; Trier…

Java 时间工具类

借鉴网上资源与工作中经验整理的时间工具类&#xff08;主要针对java.util.Date的使用&#xff0c;java8后的时间工具下期整理&#xff09;&#xff0c;欢迎大家一起完善补充。Slf4j public class DateUtils {/*** 定时器时间*/public static final String FORMAT_CRON "…

绘制七彩圆圈

#DrawSevenColorfulCircles.py import turtle colors [red,orange,yellow,green,blue,indigo,purple] for i in range(7): c colors[i] turtle.color(c,c) turtle.begin_fill() turtle.rt(360/7) turtle.circle(50) turtle.end_fill() turtle.done()

uniapp radio如何实现取消选中

uniapp 内置radio组件明确表示&#xff0c;不能取消选中&#xff0c;那如果要实现取消选中呢&#xff1f; 只要在外层加上label或者其他标签包裹&#xff0c;或者直接加入click事件然后加入事件控制radio的值改变即可 <label class"radio" click"changeAll&…

七彩光环制作

先看效果图&#xff1a; 第一步&#xff1a;新建设文件800*800,填充黑色。 第二步&#xff1a;执行滤镜->渲染->电影灯光 第三步&#xff0c;执行4次第二步&#xff0c;得到如下结果 第四步&#xff1a;执行滤镜扭曲->旋转扭曲 第五步&#xff1a;执行滤镱->扭曲-…

C语言开发七彩连珠游戏,七彩连珠游戏介绍 七彩连珠单机版运行及玩法介绍

七彩连珠是一款非常有趣的益智类消除小游戏&#xff0c;七彩连珠游戏有点像小时候玩五子棋的游戏&#xff0c;游戏中有七种颜色的球&#xff0c;您需要消掉相同颜色的小球&#xff0c;挑战最高分。本次小编给大家分享的是七彩连珠单机版&#xff0c;下载解压后运行即可。 七彩连…

绘制旋转七彩动画_VC源码_易语言源码

实现方法&#xff1a; 使用GDIPlus&#xff0c;FillPie方法&#xff0c;把各个色块当饼形图画出。 void CRotateAnimation::DrawPie(HDC hDC) {Gdiplus::Graphics* pGraphicsnew Gdiplus::Graphics(hDC);pGraphics->SetSmoothingMode(SmoothingModeHighQuality);Gdiplus::C…