Pyomo中多阶段模型的工作示例

时间:2019-01-27 03:18:38

标签: pyomo

This paper描述了Pyomo的微分和代数方程框架。它还提到了多阶段问题。但是,它没有显示此问题的完整示例。这样的例子在某处存在吗?

1 个答案:

答案 0 :(得分:1)

以下内容演示了使用Pyomo的DAE系统进行的多阶段优化问题的完整的最小工作示例:

#!/usr/bin/env python3
#http://www.gpops2.com/Examples/OrbitRaising.html
from pyomo.environ import *
from pyomo.dae import *
from pyomo.opt import SolverStatus, TerminationCondition
import random
import matplotlib.pyplot as plt

T      = 10                            #Maximum time for each stage of the model
STAGES = 3                             #Number of stages

m        = ConcreteModel()             #Model
m.t      = ContinuousSet(bounds=(0,T)) #Time variable
m.stages = RangeSet(0, STAGES)         #Stages in the range [0,STAGES]. Can be thought of as an integer-valued set

m.a  = Var(m.stages, m.t)               #State variable defined for all stages and times
m.da = DerivativeVar(m.a, wrt=m.t)      #First derivative of state variable with respect to time
m.u  = Var(m.stages, m.t, bounds=(0,1)) #Control variable defined for all stages and times. Bounded to range [0,1]

#Setting the value of the derivative.
def eq_da(m,stage,t):                           #m argument supplied when function is called. `stage` and `t` are given values from m.stages and m.t (see below)
  return m.da[stage,t] == m.u[stage,t]          #Derivative is proportional to the control variable
m.eq_da = Constraint(m.stages, m.t, rule=eq_da) #Call constraint function eq_da for each unique value of m.stages and m.t

#We need to connect the different stages together...
def eq_stage_continuity(m,stage):
  if stage==m.stages.last():                    #The last stage doesn't connect to anything
    return Constraint.Skip                      #So skip this constraint
  else:                                         
    return m.a[stage,T]==m.a[stage+1,0]         #Final time of each stage connects with the initial time of the following stage
m.eq_stage_continuity = Constraint(m.stages, rule=eq_stage_continuity)

#Boundary conditions
def _init(m):
  yield m.a[0,0] == 0                           #Initial value (at zeroth stage and zeroth time) of `a` is 0
  yield ConstraintList.End
m.con_boundary = ConstraintList(rule=_init)     #Repeatedly call `_init` until `ConstraintList.End` is returned

#Objective function: maximize `a` at the end of the final stage
m.obj = Objective(expr=m.a[STAGES,T], sense=maximize)

#Get a discretizer
discretizer = TransformationFactory('dae.collocation')

#Disrectize the model
#nfe (number of finite elements)
#ncp (number of collocation points within finite element)
discretizer.apply_to(m,nfe=30,ncp=6,scheme='LAGRANGE-RADAU')

#Get a solver
solver = SolverFactory('ipopt', keepfiles=True, log_file='/z/log', soln_file='/z/sol')
solver.options['max_iter']           = 100000
solver.options['print_level']        = 1
solver.options['linear_solver']      = 'ma27'
solver.options['halt_on_ampl_error'] = 'yes'

#Solve the model
results = solver.solve(m, tee=True)

print(results.solver.status)
print(results.solver.termination_condition)

#Retrieve the results in a pleasant format
r_t = [t               for s in sorted(m.stages) for t in sorted(m.t)]
r_a = [value(m.a[s,t]) for s in sorted(m.stages) for t in sorted(m.t)]
r_u = [value(m.u[s,t]) for s in sorted(m.stages) for t in sorted(m.t)]

plt.plot(r_t, r_a, label="r_a")
plt.plot(r_t, r_u, label="r_u")
plt.legend()
plt.show()