Ограничения неравенства не работают так.
Как упомянуто в документах , они определены как
g(x) <= 0
, и вам нужно написать g(x)
, работать так. В ваших случаях это не так. Вы возвращаете только один скаляр для одного измерения. Вам нужно вернуть вектор с тремя измерениями, формы (3,)
.
. В вашем случае вы можете попробовать вместо этого использовать ограничения равенства, поскольку это может позволить немного лучший взлом. Но я все еще не уверен, будет ли это работать, так как эти оптимизаторы не работают так. И все это, вероятно, оставит оптимизатор с довольно ухабистой и прерывистой целевой функцией. Вы можете прочитать о Смешанное целочисленное нелинейное программирование (MINLP), возможно, начать здесь .
Есть еще одна причина, по которой ваш подход не будет работать, как ожидалось Поскольку оптимизаторы работают с числами с плавающей запятой, они, вероятно, никогда не найдут число в вашем массиве при оптимизации и угадывании новых решений.
Это иллюстрирует проблему:
import numpy as np
Z = np.array([-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1])
print(0.7999999 in Z) # False, this is what the optimizer will find
print(0.8 in Z) # True, this is what you want
Возможно, вам следует попытаться определить Ваша проблема таким образом, что позволяет использовать ограничение неравенства для всего диапазона Z
.
Но давайте посмотрим, как это может работать.
Ограничение равенства определяется как
h(x) == 0
Таким образом, вы можете использовать
def Cond_1(x):
if x[2] in Z:
return numpy.zeros_like(x)
else:
return numpy.ones_like(x) * 1.0 # maybe multiply with some scalar?
Идея состоит в том, чтобы вернуть массив [0.0, 0.0, 0.0]
, который удовлетворяет ограничению равенства, если число найдено. В противном случае верните [1.0, 1.0, 1.0]
, чтобы показать, что он не удовлетворен.
Предостережения :
1.) Возможно, вам придется настроить это так, чтобы он возвращал массив типа [0.0, 0.0, 1.0]
, чтобы показать оптимизатору, какое измерение вам не нравится, поэтому оптимизатор можно сделать более точные предположения, настроив только одно измерение.
2.) Возможно, вам придется вернуть большее значение, чем 1,0, чтобы установить невыполненное ограничение равенства. Это зависит от реализации. Оптимизатор может подумать, что 1.0 - это хорошо, так как он близок к 0.0. Так что, возможно, вам нужно что-то попробовать [0.0, 0.0, 999.0]
.
Это решает проблему с измерением. Но все равно не найдем никаких чисел, подходящих для упомянутой выше вещи с плавающей запятой.
Но мы можем попытаться взломать это, как
import numpy as np
Z = np.array([-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1])
def Cond_1(x):
# how close you want to get to the numbers in your array
tolerance = 0.001
delta = np.abs(x[2] - Z)
print(delta)
print(np.min(delta) < tolerance)
if np.min(delta) < tolerance:
return np.zeros_like(x)
else:
# maybe you have to multiply this with some scalar
# I have no clue how it is implemented
# we need a value stating to the optimizer "NOT THIS ONE!!!"
return np.ones_like(x) * 1.0
sol = np.array([0.5123, 0.234, 0.2])
print(Cond_1(sol)) # True
sol = np.array([0.5123, 0.234, 0.202])
print(Cond_1(sol)) # False
Здесь - некоторые рекомендации по оптимизации. Чтобы убедиться, что все работает надежно, попробуйте запустить оптимизацию с разными начальными значениями. Алгоритмы глобальной оптимизации могут не иметь начальных значений, если используются с границами. Оптимизатор каким-то образом дискретизирует пространство.
Что вы можете сделать, чтобы проверить надежность вашей оптимизации и улучшить общие результаты:
Оптимизация по всему региону [-512, 512]
(для всех трех измерений)
Попробуйте 1/2 от этого: [-512, 0]
и [0, 512]
(8 дополнительных оптимизаций, 2 для каждого измерения)
Попробуйте 1/3 от этого: [-512, -171]
, [-171, 170]
, [170, 512]
(27 субоптимизаций, 3 для каждого измерения)
Теперь сравните конвергентные результаты, чтобы увидеть, нашла ли полная глобальная оптимизация тот же результат
Если глобальный оптимизатор не нашел "настоящие" минимумы, а подоптимизацию:
- ваша целевая функция слишком сложна для всего домена
- попробуйте другой глобальный оптимизатор
- настройте параметры (возможно, 999 для ограничения равенства)
- Я часто использую субоптимизация как часть нормального процесса, а не только для тестирования. Специально для проблем с черным ящиком.
Пожалуйста, посмотрите также эти ответы:
Scipy.optimize Ограничение неравенства - Какая сторона неравенства считается?
функция минимизации Сципи