全局最优就是在可行域中目标函数最大或最小,而局部最优仅仅是指在可行域的某个邻域内目标函数最大或最小,与通常所说的极值相同。对于局部最优可供使用的算法很多,效果也不错,应运而生的软件业很多。比如基于AMPL的求解器就有三四十之多。由于全局最优求解的复杂性与困难程度,发展进程十分缓慢。填充函数法是其典型代表。这里基于AMPL实现了一下传统的填充函数法,效果还不错哟!上代码吧。
param PI=3.1415926535898;
param epsl1=0.01;
param epsl2=0.0001;
param N=100;
param xc{1..N};
param fc;
param s;
let s:=10;
param r;
let r:=5;
param loop;
param L:=-20;
param U:=10;
var x{1..N}:=0,>=L,<=U;
for{i in 1..N} let xc[i]:=x[i];
var fun1=PI/10*(100*sin(PI*x[1])^2 +
sum{i in {1..N-1}}((x[i]-1)^2*(1+10*sin(PI*x[i+1])^2)+1000*(x[N]-1)^2));
var fun2=1/(s+fun1)*exp(-sum{i in 1..N}(x[i]-xc[i])^2/r^2);
minimize obj1: fun1;
minimize obj2: fun2;
option solver minos;
option solver_msg 0;
option show_stats 0;
solve obj1;
for{i in 1..N} let xc[i]:=x[i];
let fc:=obj1;
let loop:=1;
repeat
{
let x[ceil(loop/2)]:=xc[ceil(loop/2)]+(-1)^(loop)*0.1*Uniform01();
solve obj2;
solve obj1;
display obj1,fc;
if abs(obj1-fc)<=epsl1 and sqrt(sum{i in 1..N} (x[i]-xc[i])^2)<=epsl2 then break;
if obj1<fc then
{
let s:=10;
let r:=5;
let loop:=1;
for{i in 1..N} let xc[i]:=x[i];
let fc:=obj1;
}
if obj1>fc then
{
if loop<2*N then
{
let r:=r+1;
let s:=2*s;
let loop:=loop+1;
}
else
{
break;
}
}
}
输出结果如下:
MINOS 5.51: MINOS 5.51: MINOS 5.51: obj1 = 29.5456
fc = 30.9442
MINOS 5.51: MINOS 5.51: obj1 = 14.2997
fc = 29.5456
MINOS 5.51: MINOS 5.51: obj1 = 2.82457
fc = 14.2997
MINOS 5.51: MINOS 5.51: obj1 = 7.84603
fc = 2.82457
MINOS 5.51: MINOS 5.51: obj1 = 0.313841
fc = 2.82457
MINOS 5.51: MINOS 5.51: obj1 = 2.82457
fc = 0.313841
MINOS 5.51: MINOS 5.51: obj1 = 0.313841
fc = 0.313841
MINOS 5.51: MINOS 5.51: obj1 = 1.25537
fc = 0.313841
MINOS 5.51: MINOS 5.51: obj1 = 2.82457
fc = 0.313841
MINOS 5.51: MINOS 5.51: obj1 = 8.90891e-15
fc = 0.313841
MINOS 5.51: MINOS 5.51: obj1 = 1.25537
fc = 8.90891e-15
MINOS 5.51: MINOS 5.51: obj1 = 1.25537
fc = 8.90891e-15
MINOS 5.51: MINOS 5.51: obj1 = 5.64882
fc = 8.90891e-15
MINOS 5.51: MINOS 5.51: obj1 = 5.33542
fc = 8.90891e-15
MINOS 5.51: MINOS 5.51: obj1 = 9.58524e-15
fc = 8.90891e-15