【问题标题】:I cant figure out how to send an array out of the optimization.minimize function我不知道如何从 optimization.minimize 函数中发送一个数组
【发布时间】:2020-02-16 19:36:11
【问题描述】:

我正在构建一个用于智能计算的 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 数组,以便每次优化完成时都可以绘制它。我尝试使用全局变量,但我没有让它工作,我也不认为它是使用全局变量的良好编码方式。有人知道解决我问题的好方法吗?也许使用回调函数? (如果回调是要走的路,我不完全理解这个方法是如何工作的或如何以一种好的方式实现它)

【问题讨论】:

  • 回调的签名是'callback(xk)',其中xk是当前参数向量。
  • x0 是起始猜测向量。 x1 是第一个向量。 x2 秒,xk 第 k 个向量,以此类推。
  • 要使用回调,您的要求只需要处理 U(如 U_guess、U_test)。但是你想要 Y_array_test 数组。因此,如果没有一些体操,似乎不太可能使用回调。

标签: python scientific-computing mpc


【解决方案1】:

你为什么不做以下事情?

如下修改你的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

【讨论】:

  • 谢谢你,这是一个很好的解决我的问题的方法。但是最好有一种方法可以将数据从目标函数发送回代码而不将其保存/加载到文件中......
  • 你只是想要一个数组的图,对吧? @user2929502 也许这可以帮助stackoverflow.com/a/57305659/7952027
【解决方案2】:

基于您在 my first answer 上的 cmets 并重用来自 my other answer 的一些代码(这本身是通过修改 @Scott (Scott Sievert) answer 并使用他的 drawnow Github package 编写的)

小贴士:

我没有安装 drawnow 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

【讨论】:

    猜你喜欢
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多