【问题标题】:Bisection method. Optimise function in C code二分法。 C代码中的优化函数
【发布时间】:2021-04-19 16:33:49
【问题描述】:

我的老师对我的二分法代码发表了评论。他说“函数的计算次数没有优化,其实每次迭代,函数计算3次,虽然一次就够了。”

您能帮我优化计算吗?实际上,我什至看不到该函数在哪一点被计算了 3 次。

#include<stdio.h>
#include<math.h>
#include<time.h>

double f(double x); //Function
int res(int i, double a, double b, double ξ, double ε1, double ε2); //Print result
double Bisection(double a, double b, double ε1, double ε2); //Bisection method

int main()
{
    double a=-10, b=0, ξ, h=0.5, α, x1, x2, ε1, ε2;
    int i=0;

    printf("\nf(x) = 2^x - 2 * cos(x)");
    printf("\nStart of the interval a = %.0lf", a);
    printf("\nEnd of the interval b = %.0lf", b);
    printf("\nEnter error ε1 for function = ");
    scanf("%lf", &ε1);
    printf("Enter error ε2 for argument = ");
    scanf("%lf", &ε2);
    printf("\n\nSOLUTION:");

    //selection of roots
    x1=a;
    x2=x1+h;
    while (x2<=b)
    {
        if ((f(x1)*f(x2))<0) 
        {
            i++;
            printf("\n\n%d) %d root of the function is in the interval [%.1f, %.1f]\n",i, i, x1, x2);
            printf("\nn\t     a\t\t   b\t\t ξ\t     f(ξ)\t     ε1\t\t    ε2\n");
            Bisection(x1,x2,ε1,ε2); //Bisection method
        }
        x1=x2;
        x2=x1+h;
    }
    return 0;
}

//Function
double f(double x) 
{
   double y;
   y=pow(2,x)-2*cos(x);
   return y;
}

//Print result
int res(int i, double a, double b, double ξ, double ε1, double ε2) 
{
   printf("%d\t%10.7f    %10.7f    %10.7f    %10.7f    %e    %e\n", i, a, b, ξ, f(ξ), ε1, ε2);
   return 0;
}

//Bisection method
double Bisection(double a, double b, double ε1, double ε2)
{
    double ξ=(a+b)/2; //Middle of the interval
    double α;
    int i=0;
    if (f(ξ)==0) 
    {
        printf("Root: %f \n\n", ξ);
    }
    else 
    {
        while ((fabs(f(ξ))>ε1) && ((fabs(b-a)/2)>ε2)) //The accuracy of the definition of the root
        {
            if ((f(a)*f(ξ))<0) 
            {
                b=ξ;
            }
            else 
            {
                a=ξ;
            }
            ξ=(a+b)/2;
            res(i+1, a, b, ξ, ε1, ε2); //Print results
            i++;
        }
        printf("Root ξ=%.7f found after %d iterations\n", ξ, i);
        printf("Function f(ξ)=%.10f found after %d iterations\n", f(ξ), i);
    }
    return 0;
}

Results

【问题讨论】:

  • Re “我什至看不到函数在哪一点被计算了 3 次”:在(fabs(f(ξ))&gt;ε1) 中,f(ξ) 计算函数。在(f(a)*f(ξ))&lt;0f(a)f(ξ) 中计算函数。那是三倍。
  • 请注意,ξε1 等标识符名称可能不受支持。
  • @ Eric Postpischil,是的,但是如果没有这些计算,我该如何进行计算。在(fabs(f(ξ))&gt;ε1) 我正在检查准确性,在(f(a)*f(ξ))&lt;0 我也在检查条件。这就是二分法的工作原理。我不知道如何一步将其结合起来,甚至不确定是否可能。

标签: c optimization bisection


【解决方案1】:

只包括相关行

替换:

double Bisection(double a, double b, double ε1, double ε2)
{
    double ξ=(a+b)/2;

    if (f(ξ)==0) 

    else 
    {
        while ((fabs(f(ξ))>ε1) && ((fabs(b-a)/2)>ε2))
        {
            if ((f(a)*f(ξ))<0) 

            ξ=(a+b)/2;
        }
   }

double Bisection(double a, double b, double ε1, double ε2)
{
    double ξ=(a+b)/2; 

    double val = f(ξ); // Here is the magic

    if (val==0) 

    else 
    {
        while ((fabs(val)>ε1) && ((fabs(b-a)/2)>ε2))
        {
            if ((f(a) * val )<0) 

            ξ=(a+b)/2;
            val = f(ξ); // And here
       }
   }

这并不是我们所说的真正的秘密技巧。它只是将返回值保存在变量中,并尽可能使用该变量而不是函数调用。如果函数的参数发生变化,那么您需要再次执行该函数。这是一个将字符串变为大写的简单示例。

void uppercase(char *str) {
    // Bad, because it's not necessary to calculate the string
    // length every iteration.
    for(size_t i=0; i<strlen(str); i++)     
        str[i] = toupper(str[i]);
}

// Instead, do this

void uppercase(char *str) {
    size_t len = strlen(str);    // Precalculate and reuse in loop
    for(size_t i=0; i<len; i++)            
        str[i] = toupper(str[i]);
}

【讨论】:

  • @klutt,谢谢你的解释!我不知道这个技巧。我现在知道了。我刚开始学习,这是我的第一个 C 代码。
  • @Gelios 没问题,但这确实是你应该直接问老师的事情;)
  • 这仍然会在每次迭代中评估 f 两次,在 f(a)f(ξ) 中。
  • @EricPostpischil 我的目标不是一个完整的解决方案。我只是想通过将函数调用保存在变量中来展示重用函数调用的技术。如果需要,请随时发布带有完整解决方案的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多