马上要毕业了,最近正在弄毕业论文(快马加编),这几天被一个优化问题卡住了,花了点时间对matlab和lingo的对非线性规划问题的求解方法进行了一个总结,适合小白或者懂一点点相关知识的朋友
,希望能帮上有需要的朋友,要是哪里有问题欢迎交流,但是不要骂我,我玻璃心。
首先简单说一下线性规划问题的形式,下面是矩阵形式:
一般就是上面这种形式,一个优化问题中可能存在不等式约束、等式约束、变量范围约束和变量类型约束。先来个简单的实例:
如果用matlab求解,要先把它转化成标准型(标准型为求极小值,约束条件中常数项在右侧):
来看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的变量栏就能看到求解结果了。
但其实很多时候,我们的目标函数不可能这么简单,比如我们的优化目标中存在变量累加的情况,或者约束条件中存在奇怪的形式,如我要解的东西就存在下面形式:
这看着还可以,但写起来很恶心的,特别是这种累加形式,理论上我们可以把累加拆开,然后采用匿名函数的形式,一个一个写(我一开始就这么干的),结果我的目标函数就变成了:
这只是一部分,我还没写完,写到一半发现好丢人啊,这也太没水平了。
感觉这种累积形式的函数应该能用for循环来写,但由于之前没怎么写过也不太明白。后面百度搜了一下也没搜到相关内容,可能是我没学好信息检索这门课。之后看了下书,大概知道怎么操作了。
这里把我的目标函数改改,举个栗子来做说明for循环怎么用于目标函数的定义。
后面这项的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求解非线性约束优化问题:
暂时还没学完,学完再写。