我可以将约束体导出为数学函数吗?

2024-09-29 19:26:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用pyomo版本5.3和bonmin实现“支持超平面算法的Extendes”(https://link.springer.com/article/10.1007/s10898-015-0322-3)。该算法用线性目标函数求解凸最小线性规划问题。从本质上说,该算法创建超平面以创建对可行集的严格线性高估。这是因为可行集是凸的

对于算法的第二步,我有两点作为解决两个子问题的结果。第一点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_NLPx_LP的线上

我正在考虑使用二分法(类似:https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.bisect.html)。我已经有了一个工作函数,它将所有违反非线性约束的模型保存在一个列表中。因此,我可以为每个违反的约束计算lambda_k,并使用最小的lambda,因为可行集是凸的,以获得x_k

现在,有没有一种方法可以将约束体提取为数学函数

下面是我正在使用的示例(整个代码相当长,因为我定义了许多用于处理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

我已经获得的两点保存为数组:

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的建议。重要的是我得到了点,这样我就可以用它来创建超平面


Tags: lambdakey函数nonetruesizeindexmodel

热门问题