Могу ли я экспортировать тело Ограничения как математическую функцию? - PullRequest
0 голосов
/ 05 июня 2019

Я пытаюсь реализовать «алгоритм поддержки гиперплоскостей Extendes» (https://link.springer.com/article/10.1007/s10898-015-0322-3), используя pyomo версии 5.3 и bonmin. Алгоритм решает выпуклый MINLP с линейной целевой функцией. По сути, алгоритм создает гиперплоскости для создания плотноголинеарная переоценка допустимого множества. Это работает из-за выпуклости допустимого множества.

Для второго шага алгоритма у меня есть две точки как результаты решения двух подзадач. Первая точка x_NLP являетсявыполнимая точка исходной задачи. Вторая точка x_LP - это решение, полученное, если нелинейные ограничения игнорируются, а целочисленные переменные ослабляются. Если x_LP нарушает нелинейные ограничения, новая гиперплоскость должна быть создана вточка x_k = lambda_k*x_NLP + (1-lambda_k)*x_LP, так что max(g(x_k))==0 для всех нелинейных ограничений. Таким образом, x_k лежит на линии, соединяющей x_NLP и x_LP.

Я думал об использовании метода деления пополам (что-то вроде: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.bisect.html). У меня уже есть рабочая функция, которая сохраняет всенелинейные ограничения модели в списке.Таким образом, я мог бы вычислить lambda_k для каждого нарушенного ограничения и использовать наименьшую лямбду, поскольку выполнимый набор является выпуклым, чтобы получить x_k

Теперь есть ли способ извлечь тела ограничений как математическоеfunction?

Вот пример, с которым я работаю (весь код был бы довольно длинным, так как я определил бы много функций для работы с pyomo-моделями):

model_ESH = ConcreteModel(name = "Example 1")

model_ESH.x1 = Var(bounds=(1,20), domain=Reals)
model_ESH.x2 = Var(bounds=(1,20), domain=Integers)

model_ESH.obj = Objective(expr=(-1)*model_ESH.x1-model_ESH.x2)

model_ESH.g1 = Constraint(expr=0.15*((model_ESH.x1 - 8)**2)+0.1*((model_ESH.x2 - 6)**2)+0.025*exp(model_ESH.x1)*((model_ESH.x2)**(-2))-5<=0)
model_ESH.g2 = Constraint(expr=(model_ESH.x1)**(-1) + (model_ESH.x2)**(-1) - ((model_ESH.x1)**(0.5)) * ((model_ESH.x2) ** (0.5))+4<=0)
model_ESH.l1 = Constraint(expr=2 * (model_ESH.x1) - 3 * (model_ESH.x2) -2<=0)
model_ESH.pprint()
2 Var Declarations
    x1 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     1 :  None :    20 : False :  True :  Reals
    x2 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     1 :  None :    20 : False :  True : Integers

1 Objective Declarations
    obj : Size=1, Index=None, Active=True
        Key  : Active : Sense    : Expression
        None :   True : minimize :  - x1 - x2

3 Constraint Declarations
    g1 : Size=1, Index=None, Active=True
        Key  : Lower : Body                                                                             : Upper : Active
        None :  -Inf : -5 + 0.15*( -8 + x1 )**2.0 + 0.1*( -6 + x2 )**2.0 + 0.025 * exp( x1 ) * x2**-2.0 :   0.0 :   True
    g2 : Size=1, Index=None, Active=True
        Key  : Lower : Body                                        : Upper : Active
        None :  -Inf : 4 + x1**-1.0 + x2**-1.0 - x1**0.5 * x2**0.5 :   0.0 :   True
    l1 : Size=1, Index=None, Active=True
        Key  : Lower : Body             : Upper : Active
        None :  -Inf : -2 + 2*x1 - 3*x2 :   0.0 :   True

6 Declarations: x1 x2 obj g1 g2 l1

Две точки Iуже полученные сохраняются в виде массивов:

x_NLP = [7.44903017 8.53504579]
x_LP = [20 20]

Нарушенное нелинейное ограничение для x_LP равно g1.Как указывалось выше, в целом несколько нелинейных ограничений могут быть нарушены.

Теперь я хочу найти точку x_k = lambda_k*x_NLP + (1-lambda_k)*x_LP

, чтобы

g1(x_k)==0.

Могу ли я сделать это с помощью scipy, используя что-то вроде:

`` `` scipy.optimize.bisect (g1.body, x_NLP, x_LP) `` `?

Пример наЛинка, размещенная выше, показывает эту функцию для простой функции.Могу ли я извлечь g1.body таким образом, чтобы это работало?

Я открыт для других предложений, чтобы найти x_k.Важная часть заключается в том, что я получаю точку, чтобы использовать ее для создания гиперплоскостей.

...