Метод покоординатного спуска на Python

Есть функция

def f(x, y):
  return (5 * (1 - x)) / (7.88 * (1 - y))

Для задачи одномерной оптимизации использую метод золотого сечения. Нужно найти такие x и y, чтобы возвращаемое значение было минимальным. x, y из отрезка [0.0001, 0.9999] Можно пример, как такое реализуется по-человечески?


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

Автор решения: Fat-Zer

Общее описание алгоритма легко находится по первой ссылке в гугле:

  1. Инициализация некоторым значением x_0

  2. повторять:
    для i=1…n

    1. фиксируем значения всех переменных кроме xi, получая одномерную функцию f(xi)
    2. проводим одномерную оптимизацию по переменной xi, любым методом одномерной оптимизации
    3. если выполнен критерий останова, то возвращаем текущее значение x=(x1,…,xn)

Как именно фиксируются значения.

В общем многомерном случае, у нас есть F(x1, x2, ... xn). Изначально мы выбираем какое-нибудь произвольное значение вектора *X⁰(x⁰1, ... x⁰n), например, в середине области.

На первой итерации (i=1) мы фиксируем все значения кроме x1, по сути подставляем их в функцию и рассмaтриваем её как функцию одной переменной: f(x1) = F(x1, x⁰2, ... x⁰n). И применяем к ней метод одномерной оптимизации, например, метод золотого сечения.

Полученный результат одномерной оптимизации заменяет x1 в векторе X⁰. Так получаем вектор . Остальные значения не меняются.

Далее для вектора проделываем аналогичные манипуляции с x2 и т.д. Когда дойдём до переменной xn, снова надо начать с x1.

Для двумерного случая f(x,y), x1 — это x. x2 — это y. т.е. сначала применяешь метод одномерной оптимизации по x, затем по y, затем снова по x и т.д.

Как задаётся сам цикл с остановкой.

Выбирается один из критериев останова, например что на i+1-м шаге функция отличается от того что было на i-м меньше чем на малую величину epc.

Условие выхода можно проверять как и после оптимизации по каждой координате так и после одного шага оптимизации по всем координатам. В первом случае будет обычный цикл while, а во-втором — цикл while со вложенным циклом for по переменным. Для двух переменных его вполне можно развернуть.

→ Ссылка