Проблема нахождения локального максимума функции в C - PullRequest
4 голосов
/ 07 апреля 2011

Я разрабатываю алгоритм для определения простого метода, способного найти локальный максимум функции f (x), заданной в интервале [a, b]

#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 - среднее число цифр моего идентификатора, а переменной inf присваивается число, значительно превышающее значения, достигнутые функция в интервале [a, b] = [0,1].

Алгоритм должен найти локальный максимум функции, но это максимум возвращает всегда ноль. не понимаю почему. Какая проблема может быть в логике моего решения? Эта проблема может быть решена с помощью этого простого алгоритма, или необходима некоторая оптимизация путем возврата? Спасибо за ваши ответы.

Ответы [ 4 ]

3 голосов
/ 07 апреля 2011

Несколько проблем с этим кодом;Вероятно, наиболее ярким является:

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

Вы не можете сравнить int и float на равенство.Это может работать время от времени из-за глупой удачи :), но вы не можете ожидать, что этот код будет работать надежно.

Я настоятельно рекомендую изменить все ваши int переменные на double, все ваши floatпеременные double и все вызовы scanf(3) и printf(3) для сопоставления.В то время как вы можете комбинировать различные типы примитивных чисел в одной программе и даже в одном выражении или операторе, тонкие различия в исполнении займут у вас несколько часов.

Кроме того, сравнение форматов с плавающей запятой дляравенство почти никогда не бывает хорошей идеей.Вместо этого сравните разницу между двумя числами со значением epsilon :

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

Вы можете масштабировать свой эпсилон, чтобы оносоответствует масштабу вашей проблемы;поскольку float на самом деле поддерживает только около семи цифр точности, это сравнение не сработает:

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

Возможно, вы захотите найти хорошее введение в численный анализ .(Кстати, один из моих любимых занятий в школе.:)

update

Суть проблемы - ваша while(x == b).Я исправил это и несколько мелких проблем, и этот код, кажется, работает: #include #include #include #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
$ 
0 голосов
/ 07 апреля 2011

Если условие while будет: while (x <= b) </p>

0 голосов
/ 07 апреля 2011

while (x = b);

Нет способа выйти из цикла. б всегда 1.

0 голосов
/ 07 апреля 2011

Вы выполняете свои вычисления, в частности инициализацию h, с целочисленной арифметикой.Таким образом, в выражении:

h = (b-a) / N;

a, b и N - все целые числа, поэтому выражение оценивается как целочисленное выражение, а затем преобразуется вfloat для присвоения h.Возможно, вы обнаружите, что значение h равно нулю.Попробуйте добавить следующую строку после вычисления h:

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

После того, как вы исправите это, выполнив вычисления с плавающей запятой, вам нужно исправить цикл while.Условие x = b определенно не то, что вы хотите (я заметил, что это было изначально x == b до того, как вы отредактировали форматирование, но это тоже неправильно).

...