#python #алгоритм #математика
Привет! Пытаюсь реализовать метод штрафных функций для вычисления минимума функции. Ищу минимум функции Розенброка, минимизирую с помощью внешних штрафных функций: придумав свои ограничения. Сначала использую встроенную scipy.optimize.minimize: from scipy.optimize import minimize, rosen rz = lambda x: (1-x[0])**2 + 100*(x[1] - x[0]**2)**2; h_1 = lambda x: (x[0] - 2 * x[1] + 2); h_2 = lambda x: (-x[0] - 2 * x[1] + 6); h_3 = lambda x: (-x[0] + 2 * x[1] + 2); x0 = [2.3, 5]; cons = ({'type': 'ineq', 'fun': h_1}, {'type': 'ineq', 'fun': h_2}, {'type': 'ineq', 'fun': h_3}) minimize(rz, x0, constraints=cons) Которая даёт ответ: x: array([ 0.99971613, 0.99942073]) Затем пытаюсь реализовать метод штрафных функций: x_c = [2.3, 3]; i = 1; while i < 1000: curr_func = lambda x: rz(x) + i*(h_1(x)**2 + h_2(x)**2 + h_3(x)**2) x_c = minimize(curr_func, x_c).x; i *= 1.2; print(answer.x); Что выводит мне [ 2.27402022 1.4157964 ] (если увеличивать количество итераций, точка будет ещё с большими координатами). Где я ошибаюсь в реализации? Спасибо. P.S. Окончательная функция curr_func специфична для конкретно приведённых ограничений, конечно, когда все они типа inequals.
Ответы
Ответ 1
Не всегда увеличение количества итераций даст лучший результат, особенно в методах оптимизации. Как правило крутить надо параметры, которые отвечают за штраф или начальные точки, если конечно правильно реализован алгоритм. Еще один момент - надо задать точность результата, и из цикла лучше все-таки выходить, когда результат достигнет точности. Я поправил ваш алгоритм, пользуясь этой статьей x_c = [2.3, 3] i = 1 r = 1 b = 0.2 eps = 0.01 while i < 1000: if curr_func(x_c) < eps: break curr_func = lambda x: rz(x) + r*(1.0/(h_1(x)**2 + h_2(x)**2 + h_3(x)**2)) x_c = minimize(curr_func, x_c).x; i += 1 r *= b; print(x_c) print(i) [ 0.99495003 0.98991398] 3 получаем результат всего за 3 итерации.
Комментариев нет:
Отправить комментарий