Тернарный поиск

Не могли бы подсказать в чем ошибка? На отрезке [0;2] с точностью 0.5 программа должна выводить примерно 0.9, но в данном случае выводит 1.8.

#include <stdio.h>
#include <math.h>
double f(double x) {
    return (x*x*x - 3.0*x);
}
double ternar(double a, double b, double eps) {
    double l, r, mr, ml;
    r = b;
    l = a;
    while (fabs(r - l) > eps) {
        ml = l + (r - l)/3.0;
        mr = r - (r - l)/3.0;
        if(f(ml) < f(mr))
            l = ml;
        else 
            r = mr;
    }
        return (l+r)/2.0;
}
int main () {
    double a, b, eps;
    puts("a b eps");
    scanf ("%lf %lf %lf", &a, &b, &eps);
    printf ("Ternar: %lf\n", ternar(a, b, eps));
}

Ответы (1 шт):

Автор решения: AlexGlebe

У вас функция ищет максимум. Чтобы она искала минимум нужно исправить на f(ml) > f(mr). Можно написать универсальный вариант :

Поиск минимума / максимума :

// если направление левой части такое же как в середине
// то левую часть отбрасываем
if((f(l)-f(ml))*(f(ml)-f(mr)) > 0)
    l = ml;
else
  // если направление правой части такое же как в середине
  // то правую часть отбрасываем
    if((f(ml)-f(mr))*(f(mr)-f(r)) > 0)
        r = mr; 
    else {
      // если обе средние точки равны, то их
      // и выбираем обе
        l = ml ;
        r = mr; }

или попроще, без умножений :

if(((f(l)>f(ml))&&(f(ml)>f(mr))) ||
   ((f(l)<f(ml))&&(f(ml)<f(mr))))
    l = ml;
else
    r = mr;
→ Ссылка