我用Python创建了一个程序来寻找Fermat最后定理的解决方案(我知道这是不可解决的,但我只是将它用作编程练习)。费马的最后定理指出:
对于n大于2的任何整数值,没有三个正整数a,b和c满足等式a ^ n + b ^ n = c ^ n。
来源:Wikipedia
我的算法(在Python中)在这里:
from fractions import Fraction
def root(num):
return num ** Fraction(1 / power)
def two_numbers():
a = b = 1
while True:
yield a, b
if a == b:
a += 1
b = 1
else:
b += 1
def test(a, b):
return root((a ** power) + (b ** power)) % 1 == 0
power = int(input('Power: '))
generator = two_numbers()
for a, b in generator:
result = test(a, b)
print(a, b, result)
if result:
break
当使用12的幂(在提示时输入12
)运行时,它将停在:
17 1 True
这可能是由于分数指数的不准确所致。
我怎么知道它是否被舍入,或者否则解决了这个问题?
答案 0 :(得分:3)
Fraction
不能代表无理数,因此即使您使用它也会遇到舍入错误。避免浮点数完全没有留下舍入错误的余地:
def is_perfect_kth_power(n, k):
low = 1
high = 1
# Find an upper bound for the binary search
while high**k < n:
high *= 2
while low + 1 < high:
midpoint = (low + high) // 2
if n < midpoint**k:
high = midpoint
elif midpoint**k < n:
low = midpoint
else:
return True
return False
由于你试图找到不存在的东西,我不认为运行时是一个问题。
答案 1 :(得分:1)
是的,
的相对错误的第一个订单项为17(17**12+1)**(1.0/12)
是
1.0/(p*a^p) = 1.0/(12*17**12) = 1.43031501388558e-16.
这小于机器epsilon 2.2e-16
,即不足以影响分数功率计算中使用的64位浮点数的尾数。
您可以使用
def test(a, b):
num=a**power+b**power;
c=root(num);
return num - int(c+0.5)**power == 0
直到由于从float转换为整数的溢出问题而失败。
您可以反转一阶相对误差的计算。您可以从c
大于a
的等式得出,因此您需要c
至少a+1
为整数。插入给出了
a**p+b**p >= (a+1)**p = a**p + p*a**(p-1) + ...
通过二项式定理,至少你想要
b**p > p*a**(p-1) <==> b > a*(p/a)**(1/p)
使用此下限应该避免这些舍入问题。
对于a=17
,这会将17
作为b
的下限,因此无需根据规则b<a
进行尝试。对于a=171
,下限为138
,c>=172
的第一个案例确实属于b=138
。
答案 2 :(得分:1)
我会使用以下策略继续使用整数:
对于所需范围内a
的所有值,请计算a^n
,
扫描所需范围内b
的所有值并计算a^n + b^n
;同时,维护变量c
并始终确保(c-1)^n < a^n + b^n <= c^n
。
随着a^n + b^n
的增加,只有右手不等式可能会失效,您可以根据需要多次递增c
来修复。要初始化c
,只需注意a^n < a^n + 1
并以c= a
开头即可。
n= 2
m= 50
for a in range(1, m+1):
an= a ** n
c= a; cn= an
for b in range(a+1, m+1):
anbn= an + b ** n
while anbn > cn:
c+= 1
cn= c ** n
if anbn == cn: # Bingo!
print a, b, c
对于案例n=2
,
3 4 5
5 12 13
6 8 10
7 24 25
8 15 17
9 12 15
9 40 41
10 24 26
12 16 20
12 35 37
14 48 50
15 20 25
15 36 39
16 30 34
18 24 30
20 21 29
20 48 52
21 28 35
24 32 40
24 45 51
27 36 45
28 45 53
30 40 50
33 44 55
36 48 60
40 42 58
...
(请注意,我们从b= a+1
开始,以避免重复。)
答案 3 :(得分:0)
在这里,你的问题来自精确。您可以通过以下方式查看:
print(np.finfo(float).eps)
# 2.22044604925e-16
或
print(np.finfo(np.float32).eps)
# 1.19209e-07
为了更加精确,您可以使用“Decimal”librairie并更新您的根函数:
from decimal import Decimal
def root(num, power):
return Decimal(num ** Decimal(1 / power))