考拉兹猜想

考拉兹猜想是一个数学上的未解之谜,至今仍未解决,考拉兹猜想的内容如下:

  • 对于自然数 n 循环执行如下操作
  • 考拉兹猜想用python证明 考拉兹猜想被证明_递归 是偶数,用 考拉兹猜想用python证明 考拉兹猜想被证明_递归 除以 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想_03
  • 考拉兹猜想用python证明 考拉兹猜想被证明_递归 是奇数,用 考拉兹猜想用python证明 考拉兹猜想被证明_递归 乘以 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_06 后加 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07
  • 如此循环操作,无论初始值是什么数字,最终都会得到 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07 。2009年验证到了数字考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_09仍然满足这一猜想,但没有得到数学上的证明,就无法断言对于任何一个自然数都满足该猜想。
问题

这里我们的考拉兹猜想的改版为:若初始值 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_10 是一个偶数,也对 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_10 进行 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_10 乘以 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_13考拉兹猜想用python证明 考拉兹猜想被证明_递归_14

例如:考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_15,但初始值为 6 ,最终就不会是 1 。

求小于 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_16 的偶数中,像上述的 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_17 或者 考拉兹猜想用python证明 考拉兹猜想被证明_递归_18

分析

  • 虽然本题在初始值时,改变了考拉兹猜想的规则,但只要继续计算下去,其最终的数字还是会像考拉兹猜想一样,最终值归为数字考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07。这是因为,在对某一个数字进行一系列的计算时,我们将第一步分离出去,那么剩下的 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_20 步骤就全都满足考拉兹猜想,因此我们可以将第一步计算的结果作为一个考拉兹猜想计算的输入值,那么接下来的计算就是纯粹的考拉兹猜想计算了,所以最终数字还是 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07
  • 对于任何一个数字的考拉兹猜想计算而言,最终都会归于这样一个数字链:考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_22,若继续计算下去,就会有循环数字链: 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_23,若计算的数字是大于 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想_24 的,则一旦结果达到考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_25,就不会再出现该数字了
  • 因此,对于本题而言,若某个数字能回到初始值,那么就意味着该数字一定出现在数字 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_25;否则,该数字就无法再计算链中回到初始值。

算法:

  • 对每一个数字进行 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想_27
  • 当结果不是 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07
  • 每个数字最终都会达到 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07 ,在每个数字到达 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07 之前,若出现与原来的初始输入的参数相等,则说明该数字计算链中出现了返回初始值的情况,此时跳出循环返回考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_31

Python代码实现

def is_loop(num):
    n = num * 3 + 1
    while n != 1:
        n =  n * 3 + 1 if n % 2 else n // 2
        if n == num:
            return True

count = 0
for num in range(2, 10000, 2):
    count += 1 if is_loop(num) else 0
print(count)

# 34

def is_loop(num):
    n = num * 3 + 1
    while n != 1:
        n =  n * 3 + 1 if n % 2 else n // 2
        if n == num:
            return True

count = 0
for num in range(2, 10000, 2):
    count += 1 if is_loop(num) else 0
print(count)

# 34

递归算法

分析
  • 基于我们上述分析可知,只需要将改版过后的考拉兹猜想计算的第一步的计算结果,视为一个输入,则接下来的计算就是考拉兹猜想的计算了。
  • 考拉兹猜想的计算,本质上就是一个递归的过程。其递归部分是:若考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_32 是偶数,则用 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_32 除以 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想_34;若考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_32 是奇数,则用 考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_32 乘以 考拉兹猜想用python证明 考拉兹猜想被证明_递归_37 后加 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_25。结合本题的特点,这个递归的终止条件是:若计算结果为 考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_25
算法
  • 因为是递归函数,所以参数n会不断变化,需要声明一个global全局变量用于保存当前传入的数字。
  • 递归函数只计算 考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_20
  • 若函数计算结果出现了考拉兹猜想用python证明 考拉兹猜想被证明_递归函数_07,则表示该数字不存在回到初始值特性,返回考拉兹猜想用python证明 考拉兹猜想被证明_考拉兹猜想用python证明_42;若函数计算结果出现了全局变量初始值,则返回考拉兹猜想用python证明 考拉兹猜想被证明_代码实现_31;若两者都不是,则继续递归下去。

Python代码实现

def is_loop(n):
    global num
    if n == 1:
        return False
    elif n == num:
        return True
    else:
        return is_loop(n=n*3+1 if n%2 else n//2)

num = None
count = 0
for n in range(2, 10000, 2):
    num = n
    if is_loop(n*3+1):      #将第一步的结果作为输入
        print(n, end=' ')   #打印符合要求的数字
        count += 1
print('\n', count)

# 2 4 8 10 14 16 20 22 26 40 44 52 106 184 206 244 274 322 526 650 668 790 866 976 1154 1300 1438 1732 1780 1822 2308 2734 3238 7288 
# 34

def is_loop(n):
    global num
    if n == 1:
        return False
    elif n == num:
        return True
    else:
        return is_loop(n=n*3+1 if n%2 else n//2)

num = None
count = 0
for n in range(2, 10000, 2):
    num = n
    if is_loop(n*3+1):      #将第一步的结果作为输入
        print(n, end=' ')   #打印符合要求的数字
        count += 1
print('\n', count)

# 2 4 8 10 14 16 20 22 26 40 44 52 106 184 206 244 274 322 526 650 668 790 866 976 1154 1300 1438 1732 1780 1822 2308 2734 3238 7288 
# 34