
8.1 考拉兹猜想的实验验证
现在我们来编程验证这个猜想,验证程序需要完成三个任务:
(1)验证这个猜想在10000以内是否都成立。
(2)记录每一个数各经过多少次运算才回到1,并在二维图上打一个点,水平轴表示数本身,垂直轴表示运算次数,比如前面我们验证过的13,经过9次运算回到1,那么就在(13,9)这个位置标一个点。
(3)如果某个数经过若干次运算以后,又回到它自己,那么会构成一个循环,一直不会结束,程序需要防止出现这种情况。
分析:
每次核算一次一个数是否能归一,可能需要多次运算,而且每计算一次,计数器还要加1,最终返回总运算次数。可以用一个函数来完成这两项工作,这个函数接收一个输入,返回是否归一以及计算次数。
计算结果可以存入一个列表里面,列表的索引就是这个数,列表里存储运算次数。
可以用模块matplotlib来进行绘图,第9章专门讲述matplotlib。
代码如下:

这个程序有几处新的Python知识点:
(1)import…as…句法,该语句的意思就是使用as之后的变量名来引用这个模块。其好处是在程序中对模块的引用变得简洁,在程序中本来应该使用matplotlib.pyplot这个变量名,现在全部简写为plt。
(2)第24行,我们的函数调用方式是testResult,times=collatz(i),collatz()返回两个变量,因此赋值表达式的左边有两个变量。
(3)第22行,定义了一个空的列表,第26行、28行通过列表函数append()往列表尾巴上添加一个新的元素。
(4)第30~33行用matplotlib画图(见图8-1),这个模块的内容很丰富,下一章专门讲如何用matplotlib来画图。本例中,fig=plt.figure(1)创建一个图,此时图中还没有任何东西。
ax=fig.add_subplot(1,1,1),在这个图上只画一个坐标平面ax,ax.scatter(range(1,10 000),L,color='r',marker='.'),在ax这个坐标平面上画一个散点图,range(1,10 000),说明X轴从1一直到10 000,每次增加1,参数L中存放从1到10 000的每个数字经过多少次运算才归一。color='r'指定散点颜色是红色,marker='.'指定点的形状就是个圆点。

图8-1 图形化结果

图8-1的横坐标表示1~10 000的每一个数字,纵坐标是X轴对应的数字经过多少次运算后才归一,图形上看明显展示出了鱼鳞状的规律性。