Как оптимизировать минимизацию вектор-функции в Python? - PullRequest
0 голосов
/ 22 февраля 2019

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

import numpy as np
import scipy.optimize as opt
def f(x, a, b, c):
    f = a * x**2 + b * x + c
return f

Я хотел бы найти x, который минимизирует функцию для различного набора значений a, b, c, скажем, для

a = [-1, 0, 1]
b = [0, 1, 2]
c = [0, 1]

ATM У меня есть три вложенных цикла и минимизация:

for p1 in a:
    for p2 in b:
         for p3 in c:
            y = opt.minimize(f, x0=[0, ], args=(p1, p2, p3, ))
            print(y)

, что очень медленно для вычислений, которые я делаю, но я пока не нашел ничего лучшего.Итак, кто-нибудь знает способ или пакет, который позволил бы мне повысить эффективность?

1 Ответ

0 голосов
/ 03 марта 2019

Вы можете использовать комбинацию различных техник для повышения эффективности вашего скрипта:

  1. Используйте itertools.product для создания каждой возможной комбинации в списке a, b, c
  2. Использованиеmultiprocessing для параллельного выполнения минимизации.

Кроме этого, я не могу придумать способ оптимизировать эффективность кода.Как было отмечено в комментарии, постоянное значение c не влияет на минимизацию.Но я уверен, что квадратичная функция - только пример.

Я взял код многопроцессорной части из здесь .

Вот рабочий код.

import numpy as np
import scipy.optimize as opt
import itertools
from multiprocessing import Pool

def f(x, a, b, c):
    f = a * x**2 + b * x + c
    return f

def mini(args):
    res = opt.minimize(f, x0=np.array([0]), args=args)
    return res.x

if __name__=="__main__":
    a = np.linspace(-1,2,100)
    b = np.linspace(0,2,100)
    c = [0, 1]
    args = list(itertools.product(a,b,c))
    print("Number of combos:" + str(len(args)))
    p = Pool(4)
    import time
    t0 = time.time()
    res = p.map(mini, args)
    print(time.time()-t0)

Даже эти 20000 комбинаций требуют всего 5,28 секунды на моем среднем ноутбуке.

...