BasinHopping очень очень медленно для простой оптимизации - PullRequest
1 голос
/ 11 апреля 2019

Рассмотрим следующую простую задачу оптимизации.

from symfit import parameters, Eq, Ge, Fit, log
from symfit.core.minimizers import BasinHopping

n = 3
# xdata = np.sort(np.random.choice(range(1, 4*n), n))
xdata = [2, 8, 11]
print(xdata)
p1, p2, p3 = parameters('p1, p2, p3')
model = p1*p2*p3
# model = log(p1)+log(p2)+log(p3)
constraints = [
    Eq(xdata[0]*p1+(xdata[1]-xdata[0])*p2+(xdata[2]-xdata[1])*p3, 1),
    Ge(p1, p2),
    Ge(p2, p3),
    Ge(p3, 0.00001)
    ]

fit2 = Fit(- model, constraints=constraints)
print(fit2.execute(options={"ftol": 1e-12}))
fit0 = Fit(- model, constraints=constraints, minimizer=BasinHopping)
print(fit0.execute())

Это дает оптимальное значение как:

Parameter Value        Standard Deviation
p1        1.666668e-01 nan
p2        7.407405e-02 nan
p3        7.407405e-02 nan

для fit0 и fit2. Общее время выполнения для обоих составляет около 3 секунд. BasinHopping использует 567 итераций.

Теперь давайте просто возьмем журналы целевой функции. Итак имеем:

model = log(p1)+log(p2)+log(p3)

вместо строки model = выше. Это должно дать точно такой же результат и действительно fit2 работает и занимает около 1 секунды Однако происходит следующее:

fit0 (то есть BasinHopping) занимает 110137 итераций и 7 минут для вычисления оптимального значения.

Что здесь не так?

...