知道斜边有效地计算所有毕达哥拉斯三元组

时间:2010-01-28 01:05:33

标签: c# math pythagorean

给定一个hypoteneuse(c典型方程a*a + b*b = c*c),计算ab的所有可能整数值的有效方法是什么,{ {1}}?

注意:我看到a < b大于c,因此1e12大于c*c,我可以告诉long.MaxValue但是,适合c*c

5 个答案:

答案 0 :(得分:7)

所有毕达哥拉斯三元组(a,b,c)满足某些整数k,m和n的性质,

a = k(m ^ 2-n ^ 2),b = 2kmn,c = k(m ^ 2 + n ^ 2)

首先考虑因素c。然后,对于c的每个不同因子k(即,对于因子的每个不同子集,乘以一起),找到满足c / k =(m ^ 2 + n ^ 2)的所有m和n。做后者将比其他人建议的蛮力方法花费更少的时间(你只需找到总和为c / k而不是c ^ 2的方格),但会识别所有三元组(a,b,c) 。您也不需要使用bignums,因为所有中间结果都适合长。

我还建议你查看“更通用的毕达哥拉斯三重计算器”标题下的网页http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Pythag/pythag.html,其中包含一个用javascript编写的嵌入式计算器,它正是你想要的。

答案 1 :(得分:6)

有一种数学解决方案,即使对于较大的c值,也能快速找到a和b。 不幸的是,事情并非那么简单。我试图给出一个简短的算法解释。我希望它不会太混乱。

由于给出了c并且你正在寻找a和b,你基本上想要解决丢番图问题 形式方程式

n=x^2+y^2,

其中给出了n。 n = c * c是一个正方形并没有多大帮助,因此我正在描述任何n的解。如果n是素数,那么你可以使用 Fermat's theorem,决定你的等式是否可以解决,并使用,正如Moron指出Hermite-Serret算法找到解决方案,如果有的话。

要解决n不是素数的情况,最好使用 Gaussian integers。 (高斯整数只是具有积分系数的复数)。特别注意到x + yi的范数

N(x+yi) = x^2+y^2.

因此必须找到高斯整数x + yi,其范数为n。 由于范数是乘法的,因此对于n的因子求解该等式然后乘以单个等式的高斯整数就足够了。 让我举个例子。我们要解决

65 = x^2 + y^2.

这相当于找到x,y这样

N(x+yi) = 65

超过高斯整数。我们考虑65 = 5 * 13,然后我们使用费马注意两者 图5和13的实施例可以表示为两个正方形的总和。最后,我们通过使用Hermite-Serret算法的强力发现

N(2+i) = N(1+2i) = ... = 5
N(2+3i) = N(3+2i) = ... = 13

注意,我已经用负系数省略了Gaussion整数2-i,-2 + i等。 这些当然也是解决方案。

因此,我们现在可以将这些解决方案相乘以获得

65 = 5 * 13 = N(2 + i)* N(2 + 3i)= N((2 + i)*(2 + 3i))= N(1 + 8i)

65 = 5 * 13 = N(2 + i)* N(3 + 2i)= N((2 + i)*(3 + 2i))= N(4 + 7i)。

因此,人们得到两个解决方案

1*1 + 8*8 = 65
4*4 + 7*7 = 65

其他组合,例如负系数也需要检查。 除了排列和改变标志外,他们不提供新的解决方案。


要计算所有解决方案,还可以添加无需计算c * c的内容。 找到c的因素是必要的。此外,由于a和b都小于c,因此高斯整数的乘积不能用64位整数系数表示。因此,如果小心,64位整数就足以解决问题。当然,使用像Python这样没有这种溢出问题的语言总是更容易。

答案 2 :(得分:0)

不妨去BigNum图书馆。

至于找到a和b的有效方法:

对于b的每个值(从c-1开始并向下直到b * b

答案 3 :(得分:0)

a的值为1,b的值为c。

c*c - b*ba*a进行比较。如果他们是平等的,你就有了匹配。

根据哪一方面较大而改变a和b,直到它们相同为止。

答案 4 :(得分:0)

给出一个c:

因为b> a,如果a是最小值(a = 1),b = sqrt(c * c - 1)。

因此b必须介于该值和c -1之间。

此外,由于b必须是整数,因此需要找到第一个为整数的值。

Now, a property of squares:
The squares are: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, ...
The differences: -, 3, 5, 07, 09, 11, 13, 15, 17, 019, 021, ...
That means a square can be written as a summation of ODD numbers:
    1 + 3 + 5 + 7 + n+...
where n = number the summation is a square of.

因此,正好有小于c * c的c平方数,您可以使用简单的减法来识别它们。

回到开头,取b = sqrt(c c - 1),向下舍入并取b b,得到方b必须在上面,并且 a = 1 。找到c c - (a a + b b)。这应该为您提供必须添加的数字才能达到c * c。

由于您可以将3 + 5 + 7 + ...添加到a​​,b+2 + b+4 + b+6 + ...添加到b,您只需根据总和而不是广场本身找到正确的字词:)