目标函数存在累加的非线性优化问题的求解思路(1)

马上要毕业了,最近正在弄毕业论文(快马加编),这几天被一个优化问题卡住了,花了点时间对matlab和lingo的对非线性规划问题的求解方法进行了一个总结,适合小白或者懂一点点相关知识的朋友

,希望能帮上有需要的朋友,要是哪里有问题欢迎交流,但是不要骂我,我玻璃心。

首先简单说一下线性规划问题的形式,下面是矩阵形式:

 

目标函数存在累加的非线性优化问题的求解思路(1)

一般就是上面这种形式,一个优化问题中可能存在不等式约束、等式约束、变量范围约束和变量类型约束。先来个简单的实例:

 

目标函数存在累加的非线性优化问题的求解思路(1)

 

如果用matlab求解,要先把它转化成标准型(标准型为求极小值,约束条件中常数项在右侧):

目标函数存在累加的非线性优化问题的求解思路(1)

 

 

来看matlab的求解方法:

Matlab的非线性约束最优化问题的求解器是fmincon,如果要解线性问题或者无约束问题也有类似的求解器,调用方式都差不多。

求解器的具体形式是: [x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub)

这里的fun就是优化目标,x0是初始解,A是不等式约束的系数项,b是不等式约束对应的常数项,Aeq,beq对应等式约束,lb与xb就是范围约束。Fun,x0,A,b为必选,其他的为可选。x是求解器得到的解,fval是求解器得到的最优值。

由于我们的约束中只存在不等式约束,所以只需要设置fun,x0,A,b。

fun就是我们的优化目标,这里可以利用matlab的匿名函数(优化目标简单的时候就可以用匿名函数),具体形式是:

  fun=@(x) -x(1)*x(2)*x(3)

这里的@是用于声明变量,@(x)就是表示我们的自变量为x。

之后就是A与b:

  A = [1,2,3;-1,-2,-3]

  b = [72;0]

A与b的每一行要对应,用;来分割行

x0是初始解,需要我们自己设置,这个理论上随便设置,这里设置为:

  x0 = [5,5,5]

在优化问题中可能存在多个解,我们可以试着多次改变x0,看看能不能得到其他解。

下面就是整体代码:

  fun=@(x) -x(1)*x(2)*x(3);

  A = [1,2,3;-1,-2,-3];

  b = [72;0];

  x0 = [5,5,5];

  [x,fval]=fmincon(fun,x0,A,b);

运行之后在matlab的变量栏就能看到求解结果了。

 

但其实很多时候,我们的目标函数不可能这么简单,比如我们的优化目标中存在变量累加的情况,或者约束条件中存在奇怪的形式,如我要解的东西就存在下面形式:

目标函数存在累加的非线性优化问题的求解思路(1)

 

这看着还可以,但写起来很恶心的,特别是这种累加形式,理论上我们可以把累加拆开,然后采用匿名函数的形式,一个一个写(我一开始就这么干的),结果我的目标函数就变成了:

 目标函数存在累加的非线性优化问题的求解思路(1)

 

 

这只是一部分,我还没写完,写到一半发现好丢人啊,这也太没水平了。

感觉这种累积形式的函数应该能用for循环来写,但由于之前没怎么写过也不太明白。后面百度搜了一下也没搜到相关内容,可能是我没学好信息检索这门课。之后看了下书,大概知道怎么操作了。

这里把我的目标函数改改,举个栗子来做说明for循环怎么用于目标函数的定义。

目标函数存在累加的非线性优化问题的求解思路(1)

 

 

后面这项的Xavg是指x的平均值,这一项类似于一个平方差。

首先新建一个matlab脚本,我们把优化目标写成一个函数,第一行写上:

function f= qiujie(x) //我的脚本名称就是qiujie,这个可以自己修改

分析一下这个目标项,后面那个有点复杂,需要求平均,因为for循环是从x1一个一个加到x50的,所以一开始没有这个信息,因此我们可以用两个循环来做,第一个循环就是优化目标的第一项,同时记录x1...x50,根据记录的x1...x50,第二个循环就可以加上第二项了。

这里的ck,tk都是常数项,所以我们提前设置好,比如

  ck = [1,2,3,...,50]

  tk = [1,2,3...50]

先定义一个f,再定义一个t用于存储x1...x50的信息

  f = 0;

  t = 0;//t用来记录

接下来就可以用for循环来写了,

  for i= 1:50

         f = f+(x(k)-c(k))*x(k)^t(k);//第一项

         t = t+x(k);

  end

现在求一下平均值,并加上后面那项

  t = t/50

  for i = 1:50

         f = f -(x(k)-t)^2;//第二项

  end

这样我们的优化目标项就定义好了,之后我们把约束项定义好,就可以进行求解了,形式为:

  [x,fval]=fmincon(@qiujie,x0,A,b);

上面就是整个求解过程的思路,具体情况需要根据自己的需求来写。

不过这样看其实也还好,但很多时候约束项才是让人头疼的,比如我们的系数矩阵A,当变量比较多时,系数矩阵会很大,如果有规律,我们可以利用for循环来写,但如果系数矩阵没有规律,通常需要我们人工输入,目前我还不知道在matlab中怎么能很好解决这个问题,有知道的可以v我一下。(我觉得一般应该是有规律的)

Lingo求解非线性约束优化问题:

暂时还没学完,学完再写。

 

上一篇:资源分享之JSP课程设计(**都不用)


下一篇:Kotlin + 协程 + Retrofit ,kotlin枚举