如何使用 Python 在目标函数中包含惩罚?壁虎

计算科学 优化 Python 壁虎
2021-12-08 23:51:32

我试图在我的目标函数中加入“大 M” 惩罚

我想使用入口x 向量值作为函数中的入口值。该函数的返回值最初采用一个固定的最大值,我想避免在给定 x 值的情况下返回高于固定值的值的解决方案。

最好的方法是什么?

我用一种方法写了一些代码,但我不知道这是否是一个好方法

#from calculator import calculateConcentration
'GEKKO MODELING'
from gekko import GEKKO
m = GEKKO()
m.options.SOLVER=1  # APOPT is an MINLP solver

a_max = 30

# Initialize variables
x = []
x1 = m.Var(value=20,lb=20, ub=6555)  #integer=True
x2 = m.Var(value=0,lb=0,ub=10000)  #integer=True
x3 = m.sos1([30, 42, 45, 55])

x = [x1, x2, x3]
# Equations
m.Equation((x1 * x2* x3) * 10 ** (-6)>=50)

def fun(x):
    return 44440 + ((np.pi * x[0] * x[1] * x[2]) * 10 ** (-4))**0.613 #+ penalty(x)

#def penalty(x):
#    a = calculateConcentration(x)
#    if (a>a_max):
#        return 10**10
#    else:
#        return 0

x = [400,300,19]

'GEKKO Optimization'
m.Obj(fun(x))

m.solve(disp=False) # Solve
print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))

print('Objective: ' + str(m.options.objfcnval))
2个回答

我认为你应该坚持你目前的配方。如果你想使用惩罚,我会增加你的功能。计算你的函数本身,然后添加表单的惩罚

dJ=(yymax)3
. 这将严重惩罚任何值y>ymax. 但这会告诉您的优化器寻找较低的 y 值。最好的选择是如果您的优化器提供边界/约束,请输入y<ymax作为你的约束。

我在概念表述上犯了一个错误。如果您正在使用带有约束的优化算法,那么您只需要正确开发约束,作为变量的函数。

在这种情况下,我很担心,因为一些约束是不同问题变量的函数,但另一个约束是属性值的结果,这取决于优化问题变量。一切都应该在约束中,在这种情况下,应该如下:

'Generic packages'
import numpy as np
import time
inicio = time.time()

'GEKKO MODELING'
from gekko import GEKKO


A_max = 5

class PContr(object):
    def __init__(self, A, flA, cpB):
        self.A = A
        self.flA = flA
        self.cpB = cpB
    'Ps' 
    def PA(self, x):
        if self.A < 10:
            dPA = 8.2*10**(-3)*x[2] + 0.14
            return dPA
        else:
            dPA = 3.2*10**(-2)*x[2] + 0.14 
            return dPA

m = GEKKO()
x1 = m.Var(value=20,lb=20, ub=6555)  #integer=True
x2 = m.Var(value=1,lb=1,ub=100)  #integer=True
x3 = m.sos1([30, 42, 45, 55])
x3.value = 1.0

x = [x1, x2, x3]

obj = PContr(1.20, 300, 1.40)
dPA = obj.PA(x)

'Process Constraints'
m.Equation(dPA<=A_max)


def fun(x):
    return 22223 + (x[0] * x[1] * x[2])**0.83

m.Obj(fun(x))

# Change to True to initialize with IPOPT
init = False
if init:
    m.options.SOLVER=3  
    m.solve(disp=False) # Solve

m.options.SOLVER=1
m.solve(disp=True) # Solve

print('Results')
print('x1: ' + str(x1.value))
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('Objective: ' + str(m.options.objfcnval))

##Execution time
final = time.time()
print('Tiempo de ejecucion:', (final-inicio), 's')