全局最优就是在可行域中目标函数最大或最小,而局部最优仅仅是指在可行域的某个邻域内目标函数最大或最小,与通常所说的极值相同。对于局部最优可供使用的算法很多,效果也不错,应运而生的软件业很多。比如基于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