除了强力方法之外,什么可以是一个很好的编程算法来解决下面的等式?
找到n = 100的所有x,y和z;
x^2 + y^2 + z^2 = n;
x,y,z应为正整数。
答案 0 :(得分:0)
这是关于n的线性时间的解决方案:
'use strict';
(function(){
class CalendarComponent {
constructor() {
this.eventSources = [];
this.uiConfig = {
calendar : {
editable : true,
header : {
left : 'prev,next,today',
centre : 'title',
right : 'month,agendaWeek,agendaDay'
}
}
}
}
}
angular.module('sangamApp',['ui.calendar'])
.component('calendar', {
templateUrl: 'app/calendar/calendar.html',
controller: CalendarComponent
});
})();
通过计算给定x和y的z的必要值并检查它是否为整数,它除去了一个与蛮力解相比的内环。
对于n:
的值所需的测试次数和解决方案int x, y, z;
int n = 1000;
int tests = 0;
int solutions = 0;
// loop through all possible x values
for(x = 1; x * x * 3 <= n; x++)
{
// compute target sum of y^2 + z^2
int m = n - x * x;
for(y = x; y * y * 2 <= m; y++)
{
tests++;
// compute z and check if it's an integer:
z = (int)(Math.sqrt(m - (y * y)));
if((x * x) + (y * y) + (z * z) == n)
{
System.out.println(""+x+" "+y+" "+z);
solutions++;
}
}
}
System.out.println(tests);
System.out.println(solutions);
似乎没有任何方法可以摆脱外部循环,因为你需要循环使用多个解决方案,但是你可以提前出去&#34;并通过检查m是the sum of two squares
来避免内部操纵这是链接算法的简单实现,但是有更多先进的分解算法(例如Pollard&#39; rho):
n tests solutions
5000 1081 8
500000 108749 45
50000000 10879762 232
您可以在此检查中包含内部循环:
public static boolean isSumOfTwoSquares(int m)
{
for(int i = 2; i * i <= m; i++)
{
int exponent = 0;
while(m % i == 0)
{
m /= i;
exponent++;
}
if((m % 4 == 3) && ((exponent & 1) != 0))
return false;
}
return true;
}
结果:
if(isSumOfTwoSquares(m))
鉴于 n tests solutions
5000 777 8
500000 72162 45
50000000 6511184 232
功能足够快,可能会出现这种情况。与没有早期出现的更简单的算法不同,测试的数量对n的值更加敏感。
算法都具有约束x&lt; = y&lt; = z。我希望所有没有这种约束的解决方案都可以置换解决方案,每个约束解决方案都会有6(3!)。
答案 1 :(得分:0)
通过一些数学运算,您可以获得稍微快一点的解决方案。 X^2 模 4 要么是 0 要么是 1,所以只有当三个数字都是偶数或都是奇数时,3 个平方的和才为 0 或 3,这样可以节省四分之三的工作量。实际上,如果 n 模 4 = 0,那么您可以通过将 n/4 的解乘以 2 来找到所有解。
我们有一个类似的事情,其中 x^2 模 9 是 0、1 或 -1,具体取决于 x 模 3。所以总和不能是 +/- 4 模 9,总和 = +/- 3 意味着所有三个变量为 +/- 1 模 3。