python 带条件的变量

hmae6n7t  于 2023-11-16  发布在  Python
关注(0)|答案(2)|浏览(131)

我正在用Gekko处理一个优化问题,我有一个复杂的方程,其中有许多变量和,但这不是问题。主要的困难是编写一个变量,在其计算中涉及条件,假设这个变量被称为“X”,并按照EQUATION中提到的方法计算,我如何实现它?


的数据
我读了Conditional Statements with Gekko,但我仍然怀疑。

4ktjp1zp

4ktjp1zp1#

逻辑约束可以通过带有二进制开关变量的m.if3()(或m.if2() MPCC形式)来实现。

# conditionals
c1 = m.if3(a/b-10,1,0) # check if a/b>10
c2 = m.if3(10-a*b,1,0) # check if a*b<=10

字符串
这些开关变量可以用来计算X

# output
# when c1=0 (a/b>10), X=0
# when c1=1 (a/b<10) and c2=1 (a*b>10), X=a-b
# when c1=1 (a/b<10) and c2=0 (a*b<10), X=1
X = m.Var()
m.Equation(X==c1*c2*(a-b) + c1*(1-c2)*(1))


的数据
下面是模拟中这个简单测试用例的完整脚本,其中a的值是一个值范围。

from gekko import GEKKO
m = GEKKO(remote=False)
a = m.Param([0.5,1,2,3,4,6,8,12,15,20,30,40,50])
b = 2
d = m.Intermediate(a/b); e=m.Intermediate(a*b)
# conditionals
c1 = m.if3(a/b-10,1,0) # check if a/b>10
c2 = m.if3(10-a*b,1,0) # check if a*b<=10
# output
# when c1=0 (a/b>10), X=0
# when c1=1 (a/b<10) and c2=1 (a*b>10), X=a-b
# when c1=1 (a/b<10) and c2=0 (a*b<10), X=1
X = m.Var()
m.Equation(X==c1*c2*(a-b) + c1*(1-c2)*(1))

# solve
m.options.IMODE=2
m.solve(disp=True)

print(a.value)
print(X.value)

# generate plot of results
import matplotlib.pyplot as plt
plt.subplot(4,1,1)
plt.plot(a.value,X.value,'b-o',label='X')
plt.legend(); plt.grid()
plt.subplot(4,1,2)
plt.plot(a.value,d.value,'k-o',label='a/b')
plt.plot([0.5,50],[10,10],'k--')
plt.legend(); plt.grid()
plt.subplot(4,1,3)
plt.plot(a.value,e.value,'r-o',label='a*b')
plt.plot([0.5,50],[10,10],'r--')
plt.legend(); plt.grid()
plt.subplot(4,1,4)
plt.plot(a.value,c1.value,'k:x',label='c1 (a/b<10)')
plt.plot(a.value,c2.value,'r:x',label='c2 (a*b<10)')
plt.legend(); plt.grid(); plt.xlabel('a')
plt.tight_layout(); plt.savefig('results.png',dpi=300)
plt.show()


这现在可以用于优化以最大化、最小化或达到X的目标值,例如调整a的值以最大化X

from gekko import GEKKO
m = GEKKO(remote=False)
a = m.Var(lb=0,ub=100)
b = 2
d = m.Intermediate(a/b); e=m.Intermediate(a*b)
# conditionals
c1 = m.if3(a/b-10,1,0) # check if a/b>10
c2 = m.if3(10-a*b,1,0) # check if a*b<=10
# output
# when c1=0 (a/b>10), X=0
# when c1=1 (a/b<10) and c2=1 (a*b>10), X=a-b
# when c1=1 (a/b<10) and c2=0 (a*b<10), X=1
X = m.Var()
m.Equation(X==c1*c2*(a-b) + c1*(1-c2)*(1))
m.Maximize(X)

# solve
m.options.IMODE=3
m.solve(disp=True)

print(f'a={a.value[0]}')
print(f'X={X.value[0]}')


这给出了正确的解决方案:

a=20.0
X=18.0


请注意,在Gekko中,>>=对于数值优化是等价的。a=20.0的解是在X=a-bX=0之间的切换条件下。模拟结果显示X=0a=20,而优化结果显示X=18a=20。有默认的求解器容差(m.options.RTOL用于方程,m.options.RTOL用于目标),允许在正确答案的1e-6范围内求解。

1zmg4dgp

1zmg4dgp2#

这就是你想要的吗?

if 10<a/b:
  x=0
elif a/b<10 and 10<a*b:
  x=a*b
else:
  x=1

字符串

相关问题