C 用二元搜索和递归求函数的根
有人能解释一下,为什么我们需要最大值和最小值之间的差值小于误差(三次方程的根)?背后的逻辑是什么?为什么我们需要返回min 代码如下:C 用二元搜索和递归求函数的根,c,algorithm,binary-search,C,Algorithm,Binary Search,有人能解释一下,为什么我们需要最大值和最小值之间的差值小于误差(三次方程的根)?背后的逻辑是什么?为什么我们需要返回min 代码如下: #include <stdio.h> #include <stdlib.h> double func(double x) { return x * x * x + 2 * x * x - 2; } double zeroFinder(double min, double max, double error) { i
#include <stdio.h>
#include <stdlib.h>
double func(double x)
{
return x * x * x + 2 * x * x - 2;
}
double zeroFinder(double min, double max, double error)
{
if ((max - min) < error)
{
return min;
}
double x = (max + min) / 2;
if (func(x) < 0)
{
min = x;
}
else
{
max = x;
}
return zeroFinder(min, max, error);
}
int main(void)
{
zeroFinder(0.0, 1.0, 0.01);
zeroFinder(0.0, 1.0, 0.001);
zeroFinder(0.0, 1.0, 0.000001);
zeroFinder(0.0, 1.0, 0.0000000001);
return 0;
}
#包括
#包括
双功能(双x)
{
返回x*x*x+2*x*x-2;
}
双寻零器(双最小、双最大、双错误)
{
如果((最大-最小)<错误)
{
返回最小值;
}
双x=(最大+最小)/2;
if(func(x)<0)
{
min=x;
}
其他的
{
max=x;
}
返回寻零器(最小、最大、错误);
}
内部主(空)
{
寻零器(0.0,1.0,0.01);
寻零器(0.0,1.0,0.001);
寻零器(0.0,1.0,0.000001);
寻零器(0.0,1.0,0.0000000001);
返回0;
}
该算法正在实现一种称为。我们的想法是从一个间隔开始(在您的例子中由max
和min
分隔),计算中点处的值,然后适当缩短间隔
这与实线上的二进制搜索完全相同。然而,由于我们试图找到一个实值,函数可能不会在有限的迭代次数内(例如,当答案是saysqrt(2)
)终止于实值。此外,由于该方法计算浮点变量,因此通常无法获得准确的值。然而,迭代算法应该在有限的迭代集合中终止。因此,当间隔足够小时(即abs(max-min)
),我们可以让函数终止。这意味着获得的答案在正确答案的某个错误值范围内
正如@Elyasin在评论中提到的,代码可以返回max
、min
或两者之间的任何值作为答案。可能需要考虑打开和关闭间隔,因此返回(max+min)/2.0
也是一个安全的赌注。对于递归函数,必须有一些基本情况,可以在不递归的情况下找到答案,否则递归永远不会停止
编写代码的人选择说,当x坐标之间的间隙小于指定的错误时,您与根的距离足够近。当这两个值足够近时,返回哪一个值并不重要,但可能(max+min)/2.0
会更好。但是必须返回一些值作为“x坐标,它足够接近根”
请注意,代码不安全。如果min
和max
都计算为负值,则可能不会收敛到一个解;如果它们都计算为正值,则可能不会收敛到一个解。eps是将接受的误差限值。
在许多在线法官(OJ)中,你会发现小于10^-6,10^-8的相对误差将被忽略。
假设eps=0.000001,那么如果(max-min)的值小于eps,则表示
我们达到了我们期望的结果…我想给你一个分数,因为我是这个网站的新手,我没有足够的声誉分数。无论如何,谢谢!欢迎使用Stack Overflow。请注意,在这里说“谢谢”的首选方式是向上投票好的问题和有用的答案(一旦你有足够的声誉这么做),并接受对您提出的任何问题的最有帮助的答案(这也会给您的声誉带来一点提升)。请查看页面,以及