美文网首页
Python调用MATLAB实现fmincon函数

Python调用MATLAB实现fmincon函数

作者: Yangrd | 来源:发表于2017-07-19 15:28 被阅读0次

    motivation:

    1.要实现“符号几何规划”的功能,使用MATLAB自带的fmincon函数来实现

    2.工程的代码是通过Python来完成的,需要Python调用MATLAB实现

    思路:

    1.使用Python直接生成约束条件,目标函数,初始值等函数

    2.使用Python来调取MATLAB接口,执行MATLAB的.m文件

    3.MATLAB的.m文件中,将输出结果写入txt文档

    4.Python读取txt文档结果


    1.MATLAB部分

        首先,简要介绍下MATLAB中自带的fmincon函数。fmincon函数是用来解决“非线性约束规划”,本文需要用到的是它解决“符合几何规划”的能力。【几何规划】的定义是,目标函数和约束条件均为系数为正的多项式,而【符号几何规划】在此基础上拓展,允许符号为负。

        fmincon函数的约束形式如下:

        其中,c(x)表示非线性多项式的不等式约束部分,注意,不等式需要严格按照“小于等于0”的格式(可以进行一些简单的不等式变换,写成右边为0的形式),ceq(x)表示非线性多项式的等式约束部分,形式同上。(b和beq是线性约束部分的参数,写成向量形式,A 和 Aeq 是线性约束部分的参数,写成矩阵形式,本文的问题场景不涉及“线性约束”条件)。lb和ub分别为x变量的上下限。在MATLAB中使用fmincon,传入参数如下:

    x=fmincon( objfunction, x0, A, b, Aeq, beq, lb, ub, st)

        在本文的问题背景下,目标函数的.m文件代码如下

    newobj.m

        约束函数的.m文件的代码如下(这里简单设置了约束函数,当需要多个约束,只需要再添加即可,形式为c = [(),(),...,()]):

    equationset.m

        fmincon函数还需要传入初始值(因为寻找的是局部最优解),根据具体情况来判断是否需要规定变量的上下边界。初始值传参的.m文件如下:

    initialValue.m

        完成了三个函数.m文件,下面需要写脚本.m文件。其具体代码如下:

    main.m

    首先,newobj.m和equationset.m需要和main.m在同一个目录下,“initial”方法是获取初始值x0,以及变量x的上下限。fmincon函数在输出时,不仅可以返回规划结果x,还能返回其他参数。此处本文用到exitflag参数,用来确定规划是否成功执行。exitflag的参数及含义如下:

    1(简单来说就是,规划成功)

    First-order optimality measure was less thanoptions.OptimalityTolerance, and maximum constraint violation was less thanoptions.ConstraintTolerance.

    -2(未找到最优解,规划失败)

    No feasible point was found.

    其他参数含义详见http://cn.mathworks.com/help/optim/ug/fmincon.html 中的 output arguments 部分。

        由于,我们需要将输出的结果保存到本地,所以在main.m的脚本文件中,加入写入txt的代码:

    写入txt的代码

        将四个.m文件放在同一个目录下,在matlab中点击运行即可获得结果。下面,本文要做的工作是通过Python来运行main.m


    2.Python部分

        在Python端口,只需要使用MATLAB提供的Python API,即可实现Python运行MATLAB的脚本。

        首先,在使用之前,需要安装MATLAB的API。安装过程非常简单(本文以在window 7环境下安装为例):

    用管理员模式打开cmd:

    cd “MATLAB安装路径\extern\engines\python”

    python setup.py install

        安装完成之后,即可在Python代码中:

    import matlab.engine

       之后,将main.m文件以及其他三个.m文件放置在.py文件的通过目录下,接下来只需要两行代码就能完成对于main.m脚本的调用

    #首先初始化engine

    eng= matlab.engine.start_matlab()

    #之后直接访问脚本文件名

    eng.main(nargout=0)

    #最后,释放engine

    eng.quit()

        现在,到main.m中指定的生成txt文档的路径下,就能找到生成的两个txt文件,只需要使用Python来读取这两个txt中的数据即可。


    2017.7.29更新

    问题:

    由于每次调用,MATLAB都会重新初始化,初始化的时间会消耗一些时间。

    eng= matlab.engine.start_matlab()

    由于实验场景要反复调用,执行MATLAB的脚本。所以尝试在for循环之外初始化,在for循环内执行MATLAB脚本,最后在for循环外退出eng。但是发现,MATLAB的脚本(脚本中有一个写入文件操作)只在第一次for循环的时候执行。只有在for循环中,执行开启eng,执行脚本和结束eng才能正常运行。

    MATLAB脚本中的“写入文件”操作是自动执行的,相当于python中的f.flush(),但是仍然只在eng退出之后,才能重新开始一个脚本运行。查找官方文档未果...

    参考文献:

    http://cn.mathworks.com/help/optim/ug/fmincon.html(fmincon函数官方文档)

    http://cn.mathworks.com/help/matlab/matlab-engine-for-python.html(Python调用MATLAB接口官方文档)

    相关文章

      网友评论

          本文标题:Python调用MATLAB实现fmincon函数

          本文链接:https://www.haomeiwen.com/subject/frjlkxtx.html