다음은 내 코드입니다. 제약 조건 abs (expr1) = abs (expr2)가 주어지면 표현식 abs (expr1)을 최대화하고 있습니다.
import numpy as np
from gekko import GEKKO
#init
m = GEKKO(remote=False)
x2,x3,x4,x5,x6,x7,x8 = [m.Var(lb=-2*np.pi, ub=2*np.pi) for i in range(7)]
#constraint
m.Equation((1/8)*m.abs(m.cos((1/2)*x6)*(m.sin(x2)*m.sin(x4)*m.sin((1/2)*x7)*((-4)*m.cos(x3)*m.cos((1/2)*x5)*m.cos(x8)+(3+m.cos(x5))*m.sin(x3)*m.sin(x8))+m.cos(x2)*m.cos((1/2)*x7)*m.sin((1/2)*x4)*(8*m.cos(x3)*m.cos(x5)*m.cos(x8)+(-1)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*m.sin(x3)*m.sin(x8)))) == (1/8)*m.abs(m.sin((1/2)*x6)*(4*m.cos(x3)*m.cos(x8)*(m.cos((1/2)*x5)*m.cos((1/2)*x7)*m.sin(x2)*m.sin(x4)+2*m.cos(x2)*m.cos(x5)*m.sin((1/2)*x4)*m.sin((1/2)*x7))+(-1)*m.sin(x3)*((3+m.cos(x5))*m.cos((1/2)*x7)*m.sin(x2)*m.sin(x4)+m.cos(x2)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*m.sin((1/2)*x4)*m.sin((1/2)*x7))*m.sin(x8))))
#objective
m.Obj(-((1/8)*m.abs(m.cos((1/2)*x6)*(m.sin(x2)*m.sin(x4)*m.sin((1/2)*x7)*((-4)*m.cos(x3)*m.cos((1/2)*x5)*m.cos(x8)+(3+m.cos(x5))*m.sin(x3)*m.sin(x8))+m.cos(x2)*m.cos((1/2)*x7)*m.sin((1/2)*x4)*(8*m.cos(x3)*m.cos(x5)*m.cos(x8)+(-1)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*m.sin(x3)*m.sin(x8))))))
#Set global options
m.options.IMODE = 3
#execute
m.solve()
#output
print('')
print('Results')
print('x2: ' + str(x2.value))
print('x3: ' + str(x3.value))
print('x4: ' + str(x4.value))
print('x5: ' + str(x5.value))
print('x6: ' + str(x6.value))
print('x7: ' + str(x7.value))
print('x8: ' + str(x8.value))
내가 얻는 해결책은 유효한 해결책이지만 최선의 해결책은 아닌 모든 x_i = 0입니다. 예를 들면
x2,x3,x4,x5,x6,x7,x8 = 0.9046, 1.9540, 1.8090, 0, 1.8090, 6.2832, 4.3291
제약 조건을 충족하고 (소수점 5 자리까지) 목표는 -0.3003에 도달합니다 (아직 최고는 아니지만 예). 나는 공차 옵션을 가지고 놀려고했지만 소용이 없었다. 등식 제약을 제거하면 목표가 최대 값 -1에 올바르게 도달합니다.
솔버가 제로 솔루션을 사용하지 않는 이유는 무엇입니까?
Gekko의 솔버는 전역 최소화 기가 아니라 로컬 최소화 기입니다. 문제는 sin
및 cos
함수에 많은 지역 최소값이 있습니다. 다중 시작 방법 또는 시뮬레이션 된 어닐링 과 같은 전역 접근 방식을 사용하여 전역 최소값을 얻을 수 있습니다 . 다중 시작 방법으로 스크립트 수정을 사용했습니다. -2*np.pi
와 사이의 임의 값 2*np.pi
은 변수를 초기화하는 데 사용됩니다.
for xi in x:
xi.value = np.random.rand(20)*4*np.pi - 2*np.pi
IMODE=2
이 모든 경우를 동시에 해결합니다.
m.options.IMODE = 2
많은 경우를 수행해야하는 경우 여러 스레드를 사용하여이 계산을 병렬화 할 수 있습니다 . 또한 0에서 비 연속 미분 문제를 방지 하려면 m.abs3
대신로 전환해야 m.abs
합니다. 또 다른 전략은 절대 값을 피하기 위해 방정식의 양쪽을 제곱하는 것입니다. 다음은 완전한 버전입니다.
import numpy as np
from gekko import GEKKO
#init
m = GEKKO(remote=False)
x = [m.Var(lb=-2*np.pi, ub=2*np.pi) for i in range(7)]
for xi in x:
xi.value = np.random.rand(20)*4*np.pi - 2*np.pi
x2,x3,x4,x5,x6,x7,x8 = x
#constraint
m.Equation((1/8)*m.abs3(m.cos((1/2)*x6)*(m.sin(x2)*m.sin(x4)*m.sin((1/2)*x7)*\
((-4)*m.cos(x3)*m.cos((1/2)*x5)*m.cos(x8)+(3+m.cos(x5))*m.sin(x3)*m.sin(x8))+\
m.cos(x2)*m.cos((1/2)*x7)*m.sin((1/2)*x4)*(8*m.cos(x3)*m.cos(x5)*m.cos(x8)+\
(-1)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*m.sin(x3)*m.sin(x8)))) == \
(1/8)*m.abs3(m.sin((1/2)*x6)*(4*m.cos(x3)*m.cos(x8)*(m.cos((1/2)*x5)*\
m.cos((1/2)*x7)*m.sin(x2)*m.sin(x4)+2*m.cos(x2)*m.cos(x5)*m.sin((1/2)*\
x4)*m.sin((1/2)*x7))+(-1)*m.sin(x3)*((3+m.cos(x5))*m.cos((1/2)*x7)*\
m.sin(x2)*m.sin(x4)+m.cos(x2)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*\
m.sin((1/2)*x4)*m.sin((1/2)*x7))*m.sin(x8))))
#objective
obj = m.Intermediate(-((1/8)*m.abs3(m.cos((1/2)*x6)*(m.sin(x2)*m.sin(x4)*\
m.sin((1/2)*x7)*((-4)*m.cos(x3)*m.cos((1/2)*x5)*m.cos(x8)+(3+m.cos(x5))*\
m.sin(x3)*m.sin(x8))+m.cos(x2)*m.cos((1/2)*x7)*m.sin((1/2)*x4)*(8*m.cos(x3)*\
m.cos(x5)*m.cos(x8)+(-1)*(5*m.cos((1/2)*x5)+3*m.cos((3/2)*x5))*\
m.sin(x3)*m.sin(x8))))))
m.Obj(obj)
#Set global options
m.options.IMODE = 2
#execute
m.solve()
#output
print('')
print('Best Result')
i = np.argmin(obj.value)
print('x2: ' + str(x2.value[i]))
print('x3: ' + str(x3.value[i]))
print('x4: ' + str(x4.value[i]))
print('x5: ' + str(x5.value[i]))
print('x6: ' + str(x6.value[i]))
print('x7: ' + str(x7.value[i]))
print('x8: ' + str(x8.value[i]))
print('obj: ' + str(obj.value[i]))
목표가 -0.5 인 최상의 솔루션이 여러 개 있습니다.
Best Result
x2: -3.1415936876
x3: 6.2545093655
x4: 3.1415896007
x5: -2.0848973806e-05
x6: -4.7122128433
x7: -4.712565114
x8: 0.029076147797
obj: -0.50000008426
Best Result
x2: -3.1416640191
x3: 3.1415941185
x4: 3.1415948958
x5: -3.1416088732
x6: 1.5708701192
x7: -4.7124627728
x8: -3.1415893349
obj: -0.5000000992
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다