早上睡醒躺床上不想起来,想到一个好玩的东西:
任意数字,如果是偶数,就除以2;如果是奇数,乘以一个奇数o并加一(奇数乘以奇数必定是奇数,加一变偶数);反复进行这个步骤,最后这个动荡的数列会不会收敛呢?
(偶数除以2的极限结果必然是偶数2或任意一个奇数,如果是偶数2,那么它除以2下一步就是奇数1,并开始一个循环m-n-1-m-n-1)
------------------------------------------------------
>角谷猜想
出于好奇心,我上网查了一下,是有人想过这个问题的,只不过把奇数o设为定值3,也被叫做冰雹猜想||角谷猜想:
对于任意一个数n(n>0):
1)如果它是偶数,将它除以2
2)如果它是奇数,将它乘以3并加一
重复以上步骤,最后这个数字会收敛于1,并重复4-2-1-...的过程
用程序验证这个某个数是否符合这个猜想:
public static void main(String[] args){
jiaogu(17);
}
private static int jgCount=0;
public static void jiaogu(int a){
System.out.println(jgCount++ +":"+a);
if(a<=1 || jgCount>=9999999)return ;
if(a%2==0){
a/=2;
}else{
a=3*a+1;//奇数o为3
}
jiaogu(a);
}
用程序直接暴力验证猜想:
public static void checkJiaogu(int TOP){
//检验[1,top]范围内的数是否符合角谷猜想
int top=TOP;
int tryTime=100000;
for(int i=2;i<=top;i++){
int a=i,j=0;
for(j=0;j<tryTime;j++){
if(a==1)break;
else{
if(a%2==0){
a/=2;
}
else{
a=3*a+1;
}
}
}
if(j!=tryTime){
//成功归一
if(i==top){
System.out.println("Success checking number [1,top].");
}
}
else {
System.out.println("Failed at number: "+i+"after trying "+tryTime+" times.");break;
}
}
}
观察这个猜想,其要点(进一步的推论)有两个:
a)从数字n(n>0)出发,经过任意个步骤,必然不能回到数字n,即不能有自循环;
b)从数字n(n>0)出发,经过任意个步骤,数列必然收敛不会发散,无法朝着无限大的方向前进,即必然自封闭。
看着好像很简单,然而看了看相关资料,没有一个数学家能证明出来_(:зゝ∠)_
那算了,我一个程序员,果断放弃。
不过...玩玩还是可以的。
------------------------------------------------------
>分析
这个猜想最诱人的一点是,观察2)可知,数列收敛到1,必定是在数列中的某个数字碰触到2^n(1 2 4 8 16 32 64....)中的任意一个数字;而2^n这个数列的长度是无限长的,说明数列在游走过程中,“很可能”碰触到这个数字,进而导致收敛。看着似乎非常容易证明。
因此问题被转化为:
是否能找到一个m,使得3*n+1=2^m成立,(m>=1;n为奇数;m、n均为正整数)
对任意奇数n,显然上式并不能恒成立。因此,求其等价,即3*n属于奇数域O,使得其成立。使得上面式子成立的奇数域应该为O:{4^k-1,k为大于等于1的正整数}
为什么是4^k-1呢?因为显然4^k属于数列2^m,3*n属于O,则上式必成立。
此时又有一个先决条件,是否对于每个整数n,3*n都能属于O?即4^k-1是否整除3?
答案是肯定的:
问题又被归结于:数列在动荡时,是否能碰触到一个数字n,这个数字n属于 奇整数集O':{(4^k-1)/3,k为大于等于1的正整数}
这时候问题从碰触到2^k长度的尺寸上一下缩小到了2^(k-1)(4^k是2^k的一半)的长度尺寸上,看着就没原来那么容易解了_(:зゝ∠)_
------------------------------------------------------
>程序员眼中的数列与o=3
用同样的思路去处理任意奇乘数o,发现每次要碰触到的长度尺寸会缩减为2^[k-(o-1)/2],如o=3时为2^(k-1),o=5时为2(k-2)....尺寸一点一点被缩小,也就是说越来越难收敛...
对于一般数列,同样的道理,o=5时,必定要遇上O(5)={16^k-1,..};o=7时,必定要遇上O(7)={64^k-1,...},即O(o)={[2^(o-1)]^k-1,...} (O(o)/o必为整数,证明方法同上)
可能的范围越来越小,在o趋向极大时,要使数列最终会变成收敛为一个数1时,从n出发必定会遇上一个极大数MaxO(因为MaxO必定要比o大上非常多倍,但并不唯一)。这就非常玄学和难证了。
仅考虑o=3的情况,经过数列演变,要证明角谷猜想,就是要证明为什么[O(3)/3](或者说4^k)一定在数列之中,而且是对所有出发数字都成立。
例如:从n=17出发,经1) 、2)步骤的数列:(5属于O(3)/3={4^k-1,...},即(4^2-1)/3)
17 52 26 13 40 20 10 [5] (16) 8 4 2 1 4 2 1 4 2 1....
那么问题又来了....作为程序员,我看到的问题又变成了这样:面对一个程序黑盒,已知输入与输出,证明黑盒中必过已知节点。我来解释一下这个说法,输入就是出发数n,输出就是归一数1,必过的节点就是O(3)/3。
从逻辑出发,角谷过程是下面两个语句:
if(a%2==0)a/=2;
else a=3*a+1;
这两个语句决定了黑盒中的程序走向,编程对比这个走向:
public static void checkProcess(int TOP){
//输出[0,TOP]范围内的程序走向
int top=TOP;
int tryTime=100000;
for(int i=2;i<=top;i++){
int a=i,j=0;
System.out.print(i+" : ");
for(j=0;j<tryTime;j++){
if(a==1)break;
else{
if(a%2==0){
a/=2;
System.out.print("L");//程序走向
}
else{
a=3*a+1;
System.out.print("R");
}
}
}
System.out.println();
if(j!=tryTime){
//成功归一
if(i==top){
System.out.println("Success checking number [1,"+top+"].");
}
}
else {
System.out.println("Failed at number: "+i+"after trying "+tryTime+" times.");break;
}
}
}
输出结果:
遇到RLLLL就是遇到数列"5 16 8 4 2 1"了。要想具体从RLRLRLR之类的数列中总结出规律,我觉得....不可能吧...
所以民科什么的,算了吧...