2.8 素集“乌兰现象”
美国数学家乌兰教授(S.Ulam)在一次参加科学报告会时,为了消磨时间,在一张纸上把1,2,3,…,100按逆时针的方式排成一种方形螺旋线,并标出了其中的全部素数。
他突然发现这些素数大都扎堆于一些斜线上。散会后,他在计算机上把1~65 000的整数排成逆时针方螺旋并打印出来。他发现这些素数仍然具有挤成一条直线的特性,这种现象在数学上称为“乌兰现象”。
后来,数学家们从“乌兰现象”中找到了素数的许多有趣性质。
2.8.1 方螺线中的素集线
设计程序,把整数序列1,2,3,4,…,n×n排列成n圈的方螺线数阵,1置放在中心位置,以后各整数依次按逆时针方螺线位置排列。
为清楚显示,方螺线上的素数用括号标注。
1. 设计要点
对于指定方阵的阶数n,设置i循环(i=1,2,3,…,n×n),在循环中应用试商判别法判别整数i是否为素数,并用p数组元素标注素数:p[i]=1,i为素数;否则p[i]=0。
数字方螺线是从正中间开始的。随整数m的逐步增加,位置呈逆时针方螺线展开。给方螺线的各位置确定m的值是设计的关键所在。
为此,建立存储整数m的坐标值的2维数组a[x][y]。
对于输入的整数n,计算d=n/2,d为n阶方螺线的圈数。方螺线的正中位置存储1,即a[d][d]=1,中心位置不属于任何圈。
在第i(1~d)圈的四周分为右边、上边、左边与下边,相应分4步分别在条件循环中实施赋值操作。
(1)右边向上增长,x不变y递增1,整数m递增1,a[x][y]=m;直至y=d+i转向。
while(y<d+i){m++;y++;a[x][y]=m;}
(2)上边向左增长,y不变x递减1,整数m递增1,a[x][y]=m;直至x=d-i转向。
while(x>d-i) {m++;x--;a[x][y]=m;}
(3)左边向下增长,x不变y递减1,整数m递增1,a[x][y]=m;直至y=d-i转向。
while(y>d-i){m++;y--;a[x][y]=m;}
(4)下边向右增长,y不变x递增1,整数m递增1,a[x][y]=m;直至x=d+i转向。
while(x<d+i){m++;x++;a[x][y]=m;}
每一圈4边赋值完成后,通过x++;y=d-i;过渡至下一圈的起点。
在二重循环中输出a数组元素,即打印出方螺线方阵。
显示输出时,利用p数组识别素数,同时用括号把素数括起来,以区别于其他整数。
2. 乌兰现象程序设计
3. 程序运行示例与说明
构建n阶方阵,请确定n:13 13阶方螺线方阵:(见图2-2)
图2-2 素数1+2线的乌兰现象图
可以清楚地看到图2-2中素数沿斜线(图中只画出其中两条斜线)扎堆的乌兰现象。
这些“素集线”上除了大多数为素数1外,其他非素数如39,15、33、93,85,65等大多为两个素数之积,即陈景润研究哥德巴赫猜想所得1+2中的2,是比较“接近素数”的整数。
同时,从图2-2中还可看到另一有趣的现象:奇数的平方数1,9,25,49,81等在下部半条斜线上,而偶数的平方数4,16,36,64,100等则在上部半条斜线上。
2.8.2 回旋层叠另版乌兰
图2-3 坐标系移动漫步示意图
回旋层叠方阵是另一个生动体现素数沿斜线扎堆的有趣方阵,而且更为简单,可以说是另版乌兰。
回旋层叠方阵在坐标系第一象限(包括x轴与y轴)按以下规律展开:它从原点(0,0)运动到(0,1),然后按图2-3中箭头所示方向展开,即
原点(0,0)→(0,1)→(1,1)→(1,0)→(2,0)→(2,1)→(2,2)→(1,2)→(0,2)…
行进路线上的每一个点有一个整数m,坐标原点的m=0,以后每一步m递增1。
试构建n阶回旋层叠方阵,用括号标注方阵整数m中的素数。
1. n阶回旋层叠方阵设计要点
对于指定方阵的阶数n,同样应用试商判别整数i(1~d=(n+1)×(n+1))是否为素数,并用p数组元素标注素数:p[i]=1,i为素数;否则p[i]=0,i为非素数。
为叙述方便,把方阵分成n层,并称x=k或y=k的这一“层”为第k(1~n)层,该层的“折点”坐标为(k,k)。折点把每一层分为水平段与垂直段。
同时,第k(1~n)层的两段的先后次序与k的奇偶有关。
奇数层:先水平段从左至右递增到“折点”,再垂直段从上至下递增到x轴(y=0)。
偶数层:先垂直段从下至上递增到“折点”,再水平段从右至左递增到y轴(x=0)。
设置i(1~n)循环,对第i层的两段中各点分别赋值。
(1)若i%2>0,即在奇数层。
首先,通过y++过渡到奇数层。
奇数层是先水平向右;过折点后再垂直向下。
在水平段,y坐标为i不变,x坐标与m递增1;直至x=i即到折点为止。
while(x<i){x++;m++;a[x][y]=m;}
在垂直段,x坐标为i不变,y坐标递减1,m递增1;直至y=0即到x轴为止。
while(y>0){y--;m++;a[x][y]=m;}
(2)若i%2=0,即在偶数层。
首先,通过x++过渡到偶数层。
偶数层是先垂直向上;过折点后再水平向左。
在垂直段,x坐标为i不变,y坐标与m递增1;直至y=i即到折点为止。
while(y<i){y++;m++;a[x][y]=m;}
在水平段,y坐标为i不变,x坐标递减1,m递增1;直至x=0即到y轴为止。
while(x>0){x--;m++;a[x][y]=m;}
同样,在二重循环中输出a数组元素,即打印出回旋层叠方阵。
显示输出时,利用p数组识别素数,用括号把素数括起来,以区别于其他整数。
2. 程序设计
3. 程序运行示例与说明
请输入方阵阶数n(n<100):12
输出的回旋层叠方阵的1+2线图如图2-4所示。
图2-4 回旋层叠方阵的1+2线图
从以上输出可以清楚地看到另版“乌兰现象”:图2-4中素数沿斜线扎堆(图中只画出其中两条),这些“素集线”,除了一部分为素数1之外,其他非素数如57、91,77,25、35等大多为两个素数之积,即比较“接近素数”的2。
从图2-4中还可看到另一个有趣的现象:所有偶数也聚集于它们的斜线之上,真可谓“泾渭分明”。
同时,奇数的平方数1,9,25,49,81等均相间于纵向坐标轴上,而偶数的平方数4,16,36,64等则相间于横向坐标轴上。
4. 富素斜线探索
考察图2-4中的3—5—13—19…这一素集斜线,开头10个点中8个是素数。另两个不是素数的两个点为57=3×19,91=7×13,也是比较“接近素数”的2。
同时,这一素集线的斜率为正,即斜线呈现递增态势,比方螺线分别向两头递增更为形象直观。
把这一素集线上的数表示成第m行的函数f(m),归纳得到:
f(m)=m2+m+1(当m为奇数时)
f(m)=m2+m-1(当m为偶数时)
应用以上公式,可以非常方便地探求这一素集线上的1+2分布,有兴趣的读者可自行设计程序探索,此处从略。