Многомерная нелинейная оптимизация в python

#python #nonlinear-optimization

#python #нелинейная оптимизация

Вопрос:

У меня есть несколько разных блоков в моей программе на основе Python, где каждый блок представляет нелинейную функцию f(x, l) с x представлением класса, содержащего несколько разных параметров (здесь обозначенных как k , l и m ). Функция воздействует на эти параметры. Эти функции (здесь называемые A , B , C и т.д.) Могут быть связаны друг с другом, так что я могу получить такие конструкции, как

 x_0->A(l_1)->B(l_2)->C(l_3)->x_1
 

т.Е. я беру начальный класс x_0 , помещаю его A вместе с определенным значением l_1 , использую измененный класс x_A в качестве входных B данных, получаю новый результирующий класс x_B и так далее, пока не получу x_1 конечный результат. Конечно, я также могу повторно использовать эти функции, создавая такие структуры, как

 x_0->A(l_1)->B(l_2)->A(l_3)->C(l_4)->x_1
 

Из-за задействованных нелинейностей я не могу изменить порядок в этом расположении.
Теперь моя цель — оптимизировать один (или несколько, в зависимости от моей цели) параметров в классе x . Теперь я мог бы попробовать, изменив порядок задействованных функциональных блоков, количество используемых функциональных блоков и дополнительные параметры l_n , но это довольно громоздко из-за характера перебора. Более того, как только один или несколько входных параметров k l или m изменяются, я должен повторить этот процесс.

Следовательно, существуют ли функции / методы, которые уже доступны в Python, которые я мог бы использовать здесь?

Короткий пример может быть:

 def function_A(x_0, l_0):
    return x_0 * np.exp(-l_0)

def function_B(x_0, l_0):
    return x_0 * np.cos(l_0)

def function_C(x_0, l_0):
    return np.power(x_0, l_0)

def fit_functions(init_val, function_list, l_list):
    cur_val = init_val
    for i, elem in enumerate(function_list):
        cur_val = elem(cur_val, l_list[i])

    return cur_val

init_val = 1
ret_val = fit_functions(init_val, [function_A, function_C, function_B, function_A], [1.1, 2.4, 0.2, 1]) #Example call of fit_functions
 

Теперь я хотел бы максимизировать ret_val при использовании от 1 до 5 функциональных блоков, состоящих из function_A to function_C . Ни порядок, ни количество блоков не являются фиксированными, в идеале это должно зависеть от подхода оптимизации

Комментарии:

1. Какие оптимизации вы пытаетесь выполнить конкретно? Ваш вопрос кажется очень общим, и на него трудно ответить, основываясь только на описании. Не могли бы вы предоставить MWE?

2. @fgoudra: Я попытался добавить короткий пример, хотя это всего лишь очень сокращенный пример, основанный на моем приложении. Я надеюсь, что это улучшит вопрос

3. да, на мой взгляд, это намного понятнее! Я понимаю, что вы пытаетесь сделать.

Ответ №1:

Существует много способов оптимизации функции. В вашем случае я бы предложил переделать вашу проблему и оптимизировать независимо для каждого количества используемых функций. Другими словами, оптимизируйте первый раз при использовании только одной функции, затем 2 и три и т.д.

Для каждой из этих оптимизаций оптимизируйте порядок / тип используемых функций с начальными параметрами. Т.е.: вы хотите оптимизировать новую функцию, которая принимает в качестве аргумента последовательность используемых функций (в форме с плавающей запятой, поскольку алгоритмы оптимизации обычно работают в реальном пространстве).

 # exemple for 4 functions
def func_to_optimize(f1, f2, f3, f4, l1, l2, l3, l4):
    # get what functions to use since f1, f2,... are floats
    if f1 < 1:
        f1func = function_A
    elif f1 > 1 and f1 < 2:
        f1func = function_B
    # etc...
    # since we want to maximize, you minimize the inverse
    return 1 / function_to_fit([init_val, [f1func, f2func, f3func, f4func], [l1, l2, l3, l4])
 

И затем вы можете использовать функцию scipy.optimize.minimize для вычисления минимального значения этой функции с помощью выбранного алгоритма. Эта функция была бы наиболее «стандартным» способом сделать это. Вы также можете попытаться найти более продвинутые модули, которые используют другие методы оптимизации, если это не работает (например, генетические алгоритмы и еще много чего).

 from scipy.optimize import minimize

minimize(func_to_optimize,   # function to optimize
         [0, 0, 0, 0],       # initial guess, here it would correspond to 4 times function_A
         args=[1.1, 2.4, 0.2, 1],  # the other "fixed args" of the function (here your l parameters)
         bounds=[[0, 4]] * 4,  # the function arguments bounds. I.e.: if you have 5 different function to fit, bound each arguments that specify a function between 0 and 4.
         )