数学建模社区-数学中国

标题: 求最小最大优化,MATLAB与LINGO得到的解不同 [打印本页]

作者: junma01    时间: 2015-9-1 20:58
标题: 求最小最大优化,MATLAB与LINGO得到的解不同
我们知道MATLAB中有fminimax求最小最大优化函数,而LINGO中有min=@Smax()求优化模块。本人要优化的函数经过分析只有一个极小点,那么局部最优就是全局最优。这样以来,用MATLAB和LINGO求得的结果该一致才对呀?可是我做出的结果却不一致。具体代码分别如下,请教大神帮分析其中的原因!
MATLAB代码:
function optical
clc;clear all;
A=[-1.2 0.7 -1.1;0.5 -0.8 -1.4;2.8 0.8 0.7];b=[12 -3 1]';
s=[0 0.1011 0.3700 0.5495 0 0]';
y1=[114.5626,0.1260,-0.7482,1.000,0,0]';
y2=[-59.5062,0.0869,0.5866,0,1,0]';
y3=[8.2231,-0.0701,-0.0042,0,0,1]';
x=[0.9080 0.2629 0.3263]';
%x=[0.1375 -0.9225 0.3606]';
  k0=[1000,80,-1110]; [k,fval,maxfval,exitflag,output]=fminimax(@fun3,k0)

function f=fun3(k)
    z=s+k(1)*y1+k(2)*y2+k(3)*y3;
f(1)=norm(A*x+b*z(2),2);
f(2)=norm(A*(A*x+b*z(2))+b*z(3),2);
f(3)=norm(A*(A*(A*x+b*z(2))+b*z(3))+b*z(4),2);
f(4)=norm(A*(A*(A*(A*x+b*z(2))+b*z(3))+b*z(4))+b*z(5),2);
f(5)=norm(A*(A*(A*(A*(A*x+b*z(2))+b*z(3))+b*z(4))+b*z(5))+b*z(6),2);
end
end


LINGO代码:
model:
sets:
object /1..5/: f;
input /1..6/: z;
tejie /1..6 /:s;
ji1 /1..6/:y1;
ji2 /1..6/:y2;
ji3 /1..6/:y3;
A1 /a1..a3/;
A2 /a4..a6/;
Assign(A1,A2):A;
state0 /1..3/:x0;
state1 /1..3/:x;
state2 /1..3/:m;
state3 /1..3/:u;
state4 /1..3/:w;
state5 /1..3/:v;
C /1..3/:b;
endsets
data:
s=0,0.1011,0.3700,0.5495,0,0;
y1=114.5626,0.1260,-0.7482,1.000,0,0;
y2=-59.5062,0.0869,0.5866,0,1,0;
y3=8.2231,-0.0701,-0.0042,0,0,1;
A=-1.2 0.7 -1.1
  0.5 -0.8 -1.4
   2.8 0.8 0.7;
b=12 -3 1;
x0=0.9080 0.2629 0.3263;                                                
!x0=0.1375 -0.9225 0.3606;                           
enddata
init:
k1,k2,k3=10,-1,1;
endinit
!z(I)=s(I)+k1*y1(I)+k2*y2(I)+k3*y3(I);
@for(input(I): z(I)=s(I)+k1*y1(I)+k2*y2(I)+k3*y3(I));
calc:
x(1)=(A(1,j)*x0(j)+b(1)*z(2));x(2)=(A(2,j)*x0(j)+b(2)*z(2));x(3)=(A(3,j)*x0(j)+b(3)*z(2));
m(1)=(A(1,j)*x(j)+b(1)*z(3));m(2)=(A(2,j)*x(j)+b(2)*z(3));m(3)=(A(3,j)*x(j)+b(3)*z(3));
u(1)=(A(1,j)*m(j)+b(1)*z(4));u(2)=(A(2,j)*m(j)+b(2)*z(4));u(3)=(A(3,j)*m(j)+b(3)*z(4));
w(1)=(A(1,j)*u(j)+b(1)*z(5));w(2)=(A(2,j)*u(j)+b(2)*z(5));w(3)=(A(3,j)*u(j)+b(3)*z(5));
v(1)=(A(1,j)*w(j)+b(1)*z(6));v(2)=(A(2,j)*w(j)+b(2)*z(6));v(3)=(A(3,j)*w(j)+b(3)*z(6));
endcalc
f(1)=((x(1))^2+(x(2))^2+(x(3))^2)^0.5;
f(2)=((m(1))^2+(m(2))^2+(m(3))^2)^0.5;
f(3)=((u(1))^2+(u(2))^2+(u(3))^2)^0.5;
f(4)=((w(1))^2+(w(2))^2+(w(3))^2)^0.5;
f(5)=((v(1))^2+(v(2))^2+(v(3))^2)^0.5;
min=@smax(f(1),f(2),f(3),f(4),f(5));
@free(k1);@free(k2);@free(k3);
end





作者: liwenhui    时间: 2015-9-2 09:34
两个程序都能运行,确实存在差异。把你的原始问题放上来,一起研究一下可以吗?

作者: wujianjack2    时间: 2015-9-2 13:29
   很明显LINGO程序写得不对。

作者: junma01    时间: 2015-9-2 19:15
wujianjack2 发表于 2015-9-2 13:29
很明显LINGO程序写得不对。

您好,我也感觉不大对,那按照MATLAB的代码,正确的该是怎么样的呢?可以帮我更正么?刚接触LINGO,不熟悉啊

作者: junma01    时间: 2015-9-2 19:16
liwenhui 发表于 2015-9-2 09:34
两个程序都能运行,确实存在差异。把你的原始问题放上来,一起研究一下可以吗?

您好,感谢回复,原问题就是MATLAB代码的优化问题啊,现在就是LINGO代码有问题啊!

作者: wujianjack2    时间: 2015-9-2 19:28
junma01 发表于 2015-9-2 19:15
您好,我也感觉不大对,那按照MATLAB的代码,正确的该是怎么样的呢?可以帮我更正么?刚接触LINGO,不熟悉 ...

  有变量索引时用@FOR()函数,如@FOR(nAX(i, j): x(i) = A(i, j)*x0(j) + b(i)*z(i));这种形式,来计算需要的值,注意的问题就是集合的定义,根据你的问题来具体作一下修改,还是很简单的,自己写一下。

作者: junma01    时间: 2015-9-5 22:07
本帖最后由 junma01 于 2015-9-6 08:37 编辑
wujianjack2 发表于 2015-9-2 19:28
有变量索引时用@FOR()函数,如@FOR(nAX(i, j): x(i) = A(i, j)*x0(j) + b(i)*z(i));这种形式,来计算需 ...

大神,这样写对吗:
model:

sets:
AA/1,2,3/:b,x,k;
link(AA,AA):a;
ji/1..6/:s,y1,y2,y3,z;
endsets

data:
a=-1.2 0.7 -1.1
        0.5 -0.8 -1.4
        2.8 0.8 0.7;                ! 3*3;
s=0 0.1011 0.3700 0.5495 0 0; ! 1*6;
y1=114.5626  0.1260  -0.7482  1.000  0  0;                ! 1*6;
y2=-59.5062  0.0869  0.5866  0  1  0;                ! 1*6;
y3=8.2231  -0.0701  -0.0042  0  0  1;                ! 1*6;
x=0.9080 0.2629 0.3263;
b=12        -3        1;
enddata

@for(AA(i)bnd(-1,k(i),1));

min=@smax(        (@sum(AA(i)(@sum(AA(j):a(i,j)*x  (j)))+b(i)*(s(2)+k(1)*y1(2)+k(2)*y2(2)+k(3)*y3(2)))^2))^(1/2),
               
                (@sum(AA(i)(@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*x(i)))+b(j)*
                        (s(2)+k(1)*y1(2)+k(2)*y2(2)+k(3)*y3(2)))))+b(i)*(s(3)+k(1)*y1(3)+k(2)*y2(3)+k(3)*y3(3)))^2))^(1/2),

                (@sum(AA(i)(@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*((@sum(AA(j):a(i,j)*x  (j)))+b(i)*
                        (s(2)+k(1)*y1(2)+k(2)*y2(2)+k(3)*y3(2)))        ))+b(j)*(s(3)+k(1)*y1(3)+k(2)*y2(3)+k(3)*y3(3)))))+b(i)*
                        (s(4)+k(1)*y1(4)+k(2)*y2(4)+k(3)*y3(4)))^2))^(1/2),

                (@sum(AA(i)(@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*((@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*x  (i)))+b(j)*
                        (s(2)+k(1)*y1(2)+k(2)*y2(2)+k(3)*y3(2)))))+b(i)*(s(3)+k(1)*y1(3)+k(2)*y2(3)+k(3)*y3(3)))))+b(j)*
                        (s(4)+k(1)*y1(4)+k(2)*y2(4)+k(3)*y3(4)))))+b(i)*(s(5)+k(1)*y1(5)+k(2)*y2(5)+k(3)*y3(5)))^2))^(1/2),

                (@sum(AA(i)(@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*((@sum(AA(j):a(i,j)*((@sum(AA(i):a(j,i)*
                ((@sum(AA(j):a(i,j)*x(j)))+b(i)*(s(2)+k(1)*y1(2)+k(2)*y2(2)+k(3)*y3(2)))))+b(j)*
                        (s(3)+k(1)*y1(3)+k(2)*y2(3)+k(3)*y3(3)))))+b(i)*(s(4)+k(1)*y1(4)+k(2)*y2(4)+k(3)*y3(4)))))+b(j)*
                        (s(5)+k(1)*y1(5)+k(2)*y2(5)+k(3)*y3(5)))))+b(i)*(s(6)+k(1)*y1(6)+k(2)*y2(6)+k(3)*y3(6)))^2))^(1/2));
end
这里为了缩短求解时间,把k(i)限定在-1到1了,因为MATLAB的求解结果也在这个范围。可是,运行半个小时求出的最小最大值为大概为9.8,比MATLAB求出的4.9578大很多啊,应该是LINGO求得的解小于或等于MATLAB求得解才对啊。


作者: junma01    时间: 2015-9-6 08:38
junma01 发表于 2015-9-5 22:07
大神,这样写对吗:
model:

这个回复中所有表情符合处都是冒号,不知道为何系统自己改为了这些表情符号。





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5