一篇有情怀的Python伪技术贴
本文作者:张邯
本文编辑:周聪聪
技术总编:张学人
有问题,不要怕!访问
http://www.wuhanstring.com/uploads/5_aboutus/爬虫俱乐部-用户问题登记表.docx (复制到浏览器中)下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~
爬虫俱乐部的github主站正式上线了!我们的网站地址是:https://stata-club.github.io,粉丝们可以通过该网站访问过去的推文哟~
爬虫俱乐部隆重推出数据定制及处理业务,您有任何网页数据获取及处理方面的难题,请发邮件至我们邮箱statatraining@163.com,届时会有俱乐部高级会员为您排忧解难!
近日,与一个朋友茶话春谈,朋友神秘严肃地说起一件趣闻:“我这里有个好玩的东西。你拿任何一个自然数,若是奇数便乘上三再加一,若是偶数便除以二,如此往复,尽归于一。”我大惊,这规则看起来简练漂亮,结论更是显露着强大的宿命感,莫不是“上帝之手”造出的又一奇迹?这激起我强烈的热情想要——打破它!
我迫不及待地拿出手机开始写起来,就用我喜欢的3来会会它!
3 10 5 16 8 4 2 1
阵亡得也太快了……
没关系,我还有幸运数字7!
7 22 11 34 17 52 26 13 40 20 10 5 ……
写到5我已经知道,刚刚的历史一幕又要重演……
我有些悻悻,慢慢开始酝酿投降,毕竟自然数“千千万”,我这小脑袋可不是电脑……对!电脑!何不让电脑帮我绝地反击?毕竟上亿次的基本计算在它不过是弹指一瞬的呀!
于是我一脸坏笑地拿出我的宝贝电脑打开Sublime准备写个小脚本,朋友见我如此认真,也只噙笑看着我码代码,仿佛结局已了然于心,无尽苍凉,反而耐心无比,不急不慌。不多时,一段小小的脚本便写好了~
#初始化
collatz=[[0],[1]]
N = 10000000
for num in range(2,N+1):
temp = []
temp.append(num)
#迭代生成序列
while num > 1:
if num % 2 == 1:
num = 3*num + 1
else:
num = num/2
temp.append(num)
#序列生成结束,判断是否归为1
if num != 1:
print("%s不符合规则!" % num)
#将算好的序列加入到collatz二维列表中
我将上线设置在10000000(即N的值),告诉它若找到那个“特例”便告诉我。然后眼含热泪、满怀期许地让它运行起来,顿时心情澎湃不已!去吧皮卡丘!!
春风暖中带凉,我虽与朋友闲聊着别的话题,却总是有意无意撇向屏幕,企图在某个瞬间拿到它为我找到的数字去吓朋友一跳,顺便邀一顿好饭吃一吃~然而并没有……直到达到上限程序结束,完成任务鸣锣收兵……它完成了它的既定任务却没有完成我的心愿,我的失落之情溢于言表。朋友不想我竟如此执着,便道出其中原委:
原来这个游戏早就出现了,是我孤陋寡闻才不知天高地厚。它虽然简洁但却有很多名字,你可能听过其中一个:(3x+1)问题、冰雹猜想、角谷猜想、哈塞猜想、乌拉姆猜想或叙拉古猜想。它曾在上世纪七十年代风靡美国各大高校,最早由德国的collatz提出,日本角谷也曾提出类似猜想,而据他所知到现在数学届也没有严谨的证明,有人像我一样想借助电脑暴力计算,也都无功而返。这个迭代规则生成的序列称为collatz序列,它其实不仅仅归结于1,更准确地说,是归结于“4-2-1”。
爬虫俱乐部是您身边的科研助手,能够为您在数据处理、实证研究中提供帮助。承蒙近四万粉丝的支持与厚爱,我们在腾讯课堂推出了网络视频课程,专注于数据整理、网络爬虫、循环命令编制和结果输出…李老师及团队精彩地讲解,深入浅出,注重案例与实战,让您更加快速高效地掌握Stata技巧及数据处理的精髓,而且可以无限次重复观看,在原有课程基础上已上传了全新的内容!百分百好评,简单易学,一个月让您从入门到精通。绝对物超所值!观看学习网址:
https://ke.qq.com/course/286526?tuin=1b60b462,
敬请关注!
回来后,我好奇地望着电脑算出的一大堆collatz序列,有种望着这世界的芸芸众生的错觉。
1
2,1
3,10, 5, 16, 8, 4, 2, 1
4,2, 1
5,16, 8, 4, 2, 1
6,3, 10, 5, 16, 8, 4, 2, 1
7,22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1
8,4, 2, 1
9,28, 14, 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1
10,5, 16, 8, 4, 2, 1
……
我将前十个序列绘制成图展示序列从初始数字到“1”的发展历程,其中横坐标表示迭代次数,纵坐标表示序列的每个数字:
有的数在最高处一泻千里再无翻身之日;有的数一直在最开始的水平徘徊直到“4-2-1”;有的数起起伏伏才归于“终点”;有的数原本开始向下却在谷底冉冉升起走向巅峰……突然想起之前中级宏观林老师画的人生曲线,再看看这张图,岂不是世间百态,尽述于此?
而哪个数字又能代表正在读这篇文字的你?
网上还有关于它的序列长度(即迭代次数)和峰值(即序列中出现的最大值)的讨论。有些数字看似普通,它的序列却鹤立鸡群一般十分醒目,“27”这个数字在讨论中出现的频率尤其之高。于是我将100以内的collatz序列的长度和峰值分别画成柱状图进行观察,其中横坐标表示初始数字,纵坐标表示序列长度(峰值):
这里有一些非常明显的结论:27之所以常被人提起,是因为它是第一个序列长度超过100的数字,相应的,峰值非常大,高达9232。而且像27这样的数字并不多,隔一段出现一个。更有趣的是,它们的峰值都是9232。
至此,关于collazt猜想的探索暂时落下帷幕。春日闲暇的小娱乐,写成伪技术贴中的小品文,分享出来,供君消遣~
最后附上代码,为有兴趣的读者提供些参考:
# -*- coding: utf-8 -*-
"""
Created on Tue Mar 12 10:01:32 2019
@author: sweetyjujube
"""
# data ---------------------------------------
N = 100
# Function -----------------------------------
def collatz_builder(N):
'''
此函数返回一个二维列表collatz,列表的index即为该行要做迭代处理的数字
'''
#初始化
col = [[0],[1]]
for num in range(2,N+1):
temp = []
temp.append(num)
#迭代生成序列
while num > 1:
if num % 2 == 1:
num = 3*num + 1
else:
num = num/2
temp.append(num)
#序列生成结束,判断是否归为1
if num != 1:
print("%s不符合规则!" % num)
#加入到collatz二维列表中
temp = [int(x) for x in temp]
col.append(temp)
return col
def draw_line(data):
'''
此函数将给出的collatz序列画出折线图,进行平滑处理
生成文件collatz.html
'''
from pyecharts import Line
line = Line("collatz",'by SweetyJujube')
#添加数据
x = list(range(max(count)))
for i in range(N+1):
y = data[i]
while len(x)!=len(y):
y.append(1)
line.add(str(i),x,y,is_smooth = True,is_lengend_show = False)
#渲染
line.render("c:\collatz.html")
def draw_bar(data,name):
'''
此函数将给出的collatz序列长度画出柱状图
生成文件count.html
'''
from pyecharts import Bar
bar = Bar("collatz_"+name,'by SweetyJujube')
#添加数据
x = list(range(len(data)))
bar.add(name,x,data)
#渲染
name = "c:\\"+ name +".html"
bar.render(name)
# Main ------------------------------------------------
#生成collatz序列
collatz = collatz_builder(N)
#计算峰值和序列长度
peak = [max(x) for x in collatz]
count = [len(x) for x in collatz]
#画图
draw_line(collatz)
draw_bar(count,"count")
draw_bar(peak,"peak")
对爬虫俱乐部的推文累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!
往期推文推荐
关于我们
微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。