Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Метод координатного спуска  (Прочитано 8532 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sd
Постоялец

by
Offline Offline

« : 18-10-2014 06:10 » 

Ребята, приветствую.
Проблема вот в чем, нужно написать алгоритм поиска минимума многомерной функции методом Гаусса-Зейделя (или координатного спуска). В качестве метода поиска минимума одномерной функции использовать метод золотого сечения. Я написал функции на Си++, одна функция находит минимум одномерной функции методом золотого сечения, другая - непосредственно метод координатного спуска.
Для примера была дана тестовая целевая функция с начальными значениями.
Код:
F(x1, x2, x3) = exp(x1 + x2 + x3)/(x1*x2^2*x3^3);
x1_0 = 0.5, x2_0 = 0.5, x3_0 = 0.5;
Шаг (H) = 0.5;
Погрешность (eps) = 0.0001;

У меня возникло, пока что, два вопроса:
1) Какие границы отрезка передавать в метод золотого сечения?
2) Зачем нужен шаг, если поиск минимума одномерной функции проводится по методу золотого сечения, а не через частные производные
Код:
double full_function(double x1, double x2, double x3) {return (exp(x1 + x2 + x3)/(x1 * x2 * x2 * x3 * x3 * x3));}
double f2(double x2, double x1, double x3) {return (exp(x1 + x2 + x3)/(x1 * x2 * x2 * x3 * x3 * x3));}
double f3(double x3, double x1, double x2) {return (exp(x1 + x2 + x3)/(x1 * x2 * x2 * x3 * x3 * x3));}
double golden_section(func_ptr f, double first_var, double second_var, double eps, double a, double b);

int _tmain(int argc, _TCHAR* argv[])
{
    double eps = 0.0001;
    double step = 0.5;
    int steps_count = 100;
    double x10 = 0.5, x20 = 0.5, x30 = 0.5;
    double x1 = x10, x2 = x20, x3 = x30;
    double B = full_function(x10, x20, x30), A = 0;

    for(int i = 0; i < steps_count; i++) {
        A = B;

        x1 = golden_section(full_function, x2, x3, eps, x1, x1 + step);
        x2 = golden_section(f2, x1, x3, eps, x2, x2 + step);
        x3 = golden_section(f3, x1, x2, eps, x3, x3 + step);
       
        B = full_function(x1, x2, x3);

        if(fabs(A - B) <= eps)
        {
            std::cout << i+1 << std::endl;
            break;
        }
    }

    std::cout << x1 << std::endl;
    std::cout << x2 << std::endl;
    std::cout << x3 << std::endl;
    std::cout << full_function(x1, x2, x3) << std::endl;

    return 0;
}

метод golden_section работает правильно и возвращает значение аргумента при котором значение функции будет минимальным на заданном отрезке. Это я проверял на нескольких различных примерах.
В итоге программа выдает результат не такой, который должен быть, но довольно близкий к нему. Это только на этом примере. Переписывал целевые функции для других примеров (с последующей корректировкой функций main и golden_section), вообще ерунда какая-то получается.
В общем, если кто видит ошибки/недочеты в моей реализации и(или) может ответить на вопросы, написанные выше, ответьте, пожалуйста.

Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines