0

我正在构建一个用于 sientific 计算的 Python 应用程序。该应用程序是模型预测控制器(MPC),我使用 scipy.optimize.minimize 函数作为优化算法。

solution_guess = minimize(objectiveFunction,
                                  U_guess,
                                  arg_guess,
                                  callback= None,
                                  method = "SLSQP")

其中目标函数是执行我的系统模拟的自制函数。它看起来像这样:

def objectiveFunction(x,*arg):
    U_test = x
    dt_test = arg[0]
    setpoint_test = arg[1]
    pred_horizion_length_test = arg[2]
    initStateValue_test = arg[3]
    # Defining Model Arrays
    NS_pred_horizion_test = int(pred_horizion_length_test/dt_test)+1
    pred_horizion_array_test = np.linspace(0, pred_horizion_length_test, NS_pred_horizion_test)
    SP_array_test = np.zeros(NS_pred_horizion_test) + setpoint_test
    Y_array_test = SP_array_test * 0

    # Defining parameters for the testing model
    timeDelay_test = 50
    initDelayValue_test = 0
    K_test = 4
    Tc1_test = 30
    Tc2_test = 60

    # Defining Model Object
    obj_model_test = model.secDegModel(dt = dt_test,
                                      K = K_test,
                                      Tc1 = Tc1_test,
                                      Tc2 = Tc2_test,
                                      timeDelay = timeDelay_test,
                                      initStateValue = initStateValue_test,
                                      initDelayValue = initDelayValue_test
                                      )


    ###########################################
    #|||||||||||||||||||||||||||||||||||||||||#
    #     Testing Values for U on Model       #
    #|||||||||||||||||||||||||||||||||||||||||#
    ###########################################


    # Running simulation of "real" model function
    for k in range(NS_pred_horizion_test):
        Y_array_test[k] = obj_model_test.run(u_k = U_test) 

    error = np.sum(abs(SP_array_test-Y_array_test))
    return error

我不知道的是如何取回 Y_array_test 数组,以便每次优化完成时都可以绘制它。我尝试使用全局变量,但我没有让它工作,我也不认为它是使用全局变量的良好编码方式。有人知道解决我问题的好方法吗?也许使用回调函数?(如果回调是要走的路,我不完全理解这个方法是如何工作的或者如何以一种很好的方式实现它)

4

2 回答 2

0

你为什么不做以下事情?

修改你的objectiveFunction如下

from numpy import savez

def objectiveFunction(x,*arg):
.
.
.
.
.

# Running simulation of "real" model function
for k in range(NS_pred_horizion_test):
    Y_array_test[k] = obj_model_test.run(u_k = U_test) 
# Just save Y_array_test in a file
# Add some call_no if you don't want to overwrite
# then filename would be 'Y_array_test_' + str(call_no) 
# You could increment this call_no, every time by 
# call_no = call_no + 1
savez(file_name, Y_array_test)
# Then you could plot it outside using matplotlib
error = np.sum(abs(SP_array_test-Y_array_test))
return error
于 2020-02-19T14:02:57.237 回答
0

根据您对我的第一个答案的评论并重用我的其他答案中的一些代码(这本身是通过修改@Scott(Scott Sievert)答案并使用他的drawow Github包编写的)

小鬼注意:

我没有安装drawow Github package。相反,我只是将 drawow.py 复制到我的文件夹中。(这是因为我没有找到任何通过 conda 安装它的方法。我不想使用 PyPi)

修改你的代码如下

from numpy.random import random_sample
from numpy import arange, zeros

from drawnow import drawnow
from matplotlib import use
from matplotlib.pyplot import figure, axes, ion
from matplotlib import rcParams
from matplotlib.pyplot import style
from matplotlib.pyplot import cla, close
use("TkAgg")
pgf_with_rc_fonts = {"pgf.texsystem": "pdflatex"}
rcParams.update(pgf_with_rc_fonts)
style.use('seaborn-whitegrid')

scott_fig = figure()  # call here instead!
ion()
# figure()  # call here instead!
# ion()    # enable interactivity



solution_guess = minimize(objectiveFunction,
                          U_guess,
                          arg_guess,
                          callback= None,
                          method = "SLSQP")





def objectiveFunction(x,*arg):
    .
    .
    .
    .
    .
    def draw_fig():
        # can be arbitrarily complex; just to draw a figure
        # figure() # don't call!
        scott_ax = axes()
        scott_ax.plot(x, y, '-g', label='label')
        # Need to add some pause element here
        # otherwise you won't be able to see the figure as  
        # it will change too fast
        # cla()
        # close(scott_fig)
        # show() # don't call!

    # Running simulation of "real" model function
    for k in range(NS_pred_horizion_test):
        Y_array_test[k] = obj_model_test.run(u_k = U_test)

    # Just plot Y_array_test now that you have updated it


    drawnow(draw_fig)
    # Then you could plot it outside using matplotlib
    error = np.sum(abs(SP_array_test-Y_array_test))
    return error
于 2020-02-24T06:50:58.637 回答