在C中找到函数的局部最大值时出现问题

时间:2011-04-07 00:39:13

标签: c function optimization max

我正在设计一种算法来定义一个简单的方法,能够找到区间[a,b]中给出的函数f(x)的局部最大值

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.141592653
float funtion_(float a, float x){

float result=0;
result = a * (sin (PI*x));
    return result;
}

int main (){
double A = 4.875; //average of the digits of the identification card
double a = 0.0, b =1.0; //maximum and minimum values of the interval [a, b]
double h=0;
double N;
double Max, x;
double sin_;

double inf;
printf ("input the minux value: ");
scanf ("%lf", &inf);
printf ("input the N value: ");

scanf ("%lf", &N);

h= (b-a)/N;
printf("h = %lf\n", h);

x=a-h;
Max = -inf;

do {
x = x+h;
sin_ = funtion_(A, x);
if (sin_>=Max){
    Max = sin_;
    }
}while (x==b);

printf ("Maximum value: %lf.5", Max);
return 0;
}

该算法实现函数f(x)= A * sin(pi * x),其中A是我的ID的数字的平均值,并且inf变量被赋予足够大于其所达到的值的数字。区间[a,b] = [0.1]中的函数。

算法必须找到函数的局部最大值,但最大返回值始终为零。不明白为什么。什么问题可能是我的解决方案的逻辑?,这个问题可以通过这个简单的算法解决,或者通过回溯进行一些优化是必要的吗?谢谢你的回复。

4 个答案:

答案 0 :(得分:3)

此代码有几个问题;可能最引人注目的是:

int a = 0, b = 1;
float Max, x;
/* ... */
do {
/* ... */
} while (x == b);

您无法比较intfloat的相等性。由于运气不好,它可能会在很长一段时间内运行一次但是你不能指望这段代码能够可靠地运行。

我强烈建议您将所有int变量更改为double,将所有float变量更改为double,并将所有scanf(3)和{{1}更改为printf(3)调用匹配。虽然可以在一个程序中组合不同的原始数字类型,甚至在一个表达式或语句中,但执行中的细微差别将花费您几个小时来发现。

此外,比较浮点格式的平等几乎不是一个好主意。相反,将两个数字之间的差异 epsilon 值进行比较:

if (fabs(a-b) < 0.001)
    /* consider them equal */

你可能希望缩放你的epsilon,以便它与你的问题的规模相匹配;因为float实际上只支持大约七位数的精度,所以这种比较效果不好:

if (fabsf(123456789 - 123456789.1) < 0.5)
    /* oops! fabsf(3) used to force float */
    /* and float can't tell the difference */

您可能希望找到对numerical analysis的良好介绍。 (顺便提一下,我最喜欢的课程之一。)

<强>更新

问题的核心是你的while(x == b)。我解决了这个和一些小问题,这个代码似乎工作:     #包括     #包括     #包括     #define PI 3.141592653     float funtion_(float a,float x)     {

    float result = 0;
    result = a * (sin(PI * x));
    return result;
}

int main()
{
    float A = 4.875;      //average of the digits of the identification card
    float a = 0.0, b = 1.0;   //maximum and minimum values of the interval [a, b]
    float h = 0;
    float N;
    float Max, x;
    float sin_;

    float inf;
    printf("\ninput the inf value: ");
    scanf("%f", &inf);
    printf("\ninput the N value: ");

    scanf("%f", &N);

    h = (b - a) / N;

    x = a - h;
    Max = -inf;

    do {
            x = x + h;
            sin_ = funtion_(A, x);
            if (sin_ >= Max) {
                    Max = sin_;
                printf("\n new Max: %f found at A: %f x: %f\n", Max, A, x);

            }
    } while (x < b);

    printf("Maximum value: %.5f\n", Max);
    return 0;
}

使用一些小输入运行此程序:

$ ./localmax 

input the inf value: 1

input the N value: 10

 new Max: 0.000000 found at A: 4.875000 x: 0.000000

 new Max: 1.506458 found at A: 4.875000 x: 0.100000

 new Max: 2.865453 found at A: 4.875000 x: 0.200000

 new Max: 3.943958 found at A: 4.875000 x: 0.300000

 new Max: 4.636401 found at A: 4.875000 x: 0.400000

 new Max: 4.875000 found at A: 4.875000 x: 0.500000
Maximum value: 4.87500
$ 

答案 1 :(得分:0)

您正在使用整数运算进行计算,尤其是h的初始化。所以在声明中:

h = (b-a) / N;

abN都是整数,因此表达式被计算为整数表达式,然后转换为float以进行赋值h。您可能会发现h的值为零。尝试在计算h后添加以下行:

printf("h = %f\n", h);

通过使用浮点计算修复后,您需要修复while循环。条件x = b绝对不是您想要的(我注意到它在格式化编辑之前原来是x == b,但这也不对。)

答案 2 :(得分:0)

while条件应该是:while(x <= b)

答案 3 :(得分:0)

while(x = b);

无法退出循环。 b总是1。