本文摘要(由AI生成):
该文章介绍了在Matlab中实现单纯形法的具体案例,包括初始化参数、计算函数值、排序和选择最优解等步骤。如果函数值的变化小于给定的阈值,则直接返回均值作为最优解。否则,通过排序和比较函数值,逐步逼近最优解。在逼近过程中,根据一定的规则选择新的顶点,并计算新的函数值,更新最优解。最后,使用递归调用NeldSearch函数进行迭代优化,直到达到最优解。虽然单纯形法在实际操作中较少使用,但作为一种思路可以用于算法锻炼。
由George Dantzig发明的单纯形法(simplex algorithm)在数学优化领域中常用于线性规划问题的数值求解。单纯形是将N 维的问题转化为N 1个顶点的凸包,构成一个多胞体,比如直线上的一个线段,平面上的一个三角形,三维空间中的一个四面体等等,都是单纯形。单纯形法作为优化算法中的较为简单的一种方法,常常用于入门和进阶。本期过冷水就和大家分享一下用单纯形法的思想来求函数的极值的具体程序实现。
为了更好的方便大家对单纯形法的理解,最好是举一个具体的案例
(a)首先我们需要任意给出一个点,作为迭代的初始值1使用,解得f1=192;
(b)从1任意出发赋予不同的步长改变到其它两个点2和3,并且求出其对应的值f2=228;f2=264;
(c)根据得到的三个点(f1,f2,f3),从函数的最大点向对边中点做平行四边形,得到新的点4,就这样我们就实现了我们给予的一种迭代方法。
(d)弃去步骤3中函数值最大的点2将(1,3,4)组建成新的新的三角形,然后重复步骤三寻找第四点的方法不断操作就可以得到函数的极小值点。
看上去该代码很简单,这个案例只是为了让读者理解单纯形法是怎么实现最优解的计算的,这个思路是没有问题的,在实际运行过程中总是发想在寻优过程中会找到两个相同点在这之后就会反复循环,没有办法真正找到最优点。这是一件非常头疼的事。形法的思路不仅仅可以应用于二维,多维问题也可以得到解决。主要核心是构建一个合适的凸包,在此过冷水再给大家一个函数案例:
具体的程序化实现为:
clear triangle=[9 9;9 11;11 9]; f=(triangle(:,1)-1).^2 2*(triangle(:,2)-1).^2; a=0; while sum(f)>=sum((triangle(:,1)-1).^2 2*(triangle(:,2)-1).^2); f=(triangle(:,1)-1).^2 2*(triangle(:,2)-1).^2; [m,~]=find(max(f)==f);[n,~]=find(max(f)~=f); dot=[sum(triangle(n,:))-triangle(m,:)]; triangle(m,:)=dot; a=a 1; Dot(a,:)=dot; end ans= Dot(a-1,:) ans = 1 1
clc;clear xx.x1=[8,9]; xx.x2=[10,11]; xx.x3=[8,11]; xx.alpha = 2; xx.beta = 0.5; xx.epsilon = 1e-2; [ xx ] = NeldSearch( xx ); function [ param ] = NeldSearch( param ) initPts = [param.x3;param.x2;param.x1]; disp(initPts); fvals = [func(param.x3) func(param.x2) func(param.x1)]; if(max(fvals) - min(fvals) < param.epsilon) param.solve = mean(initPts); disp('最优化结果'); param.solve return; end %先排序; [~,index]= sort(fvals); %默认升序; %确定b,g,w; param.x3 = initPts(index(1),:);%3 param.x2 = initPts(index(2),:);%2 param.x1 = initPts(index(3),:);%1 param.x4 = (param.x3 param.x2)/2;%4 param.x5 = param.x4 (param.x4 - param.x1);%5 if(func(param.x5) < func(param.x3)) param.x6 = param.x4 param.alpha*(param.x4-param.x1);%6 if(param.x6 < param.x5) param.x1 = param.x6; else param.x1 = param.x5; end elseif(func(param.x3) < func(param.x5) && func(param.x5) <= func(param.x2)) param.x1 = param.x5; elseif(func(param.x2) < func(param.x5) && func(param.x5) <= func(param.x1)) param.x7 = param.x4 param.beta*(param.x5-param.x4);%7 param.x1 = param.x7; else param.x8 = param.x4 - param.beta*(param.x4-param.x1);%8 if(func(param.x8) < func(param.x1)) param.x1 = param.x8; else param.x9 = (param.x1 param.x3)/2;%9 param.x1 = param.x9; param.x10 = (param.x2 param.x3)/2;%10 param.x2 = param.x10; end end plot(param.x3(1),param.x3(2),'*',param.x2(1),param.x2(2),'*',param.x1(1),param.x1(2),'*'); param = NeldSearch(param); %递归; end function f = func(point) x1= point(1); x2= point(2); f = 4*(x1-5)^2 (x2-6)^2; end
以上就是本期过冷水想和大家分享的关于Matlab实现单纯形法的具体案例。过冷水在实际操作过程中很少使用单纯形法,因为单纯形法运算迭代次数太多,不如牛顿迭代法好用,但是作为一种思路可以用于作为算法锻炼。过冷水也会在后期和大家分享其它使用的优化算法的,敬请期待。