前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数值优化——单纯形法

数值优化——单纯形法

作者头像
巴山学长
发布2021-03-30 11:42:28
5780
发布2021-03-30 11:42:28
举报
文章被收录于专栏:巴山学长巴山学长

之前过冷水和分享了几期优化算法的方法后就没有再更新相关类推文了,最近有接触单纯形法的学习,本期就和大家分享一下用单纯形法的思想来来求函数的极值。

对问题min f(x) ,在n维空间中适当选取n+1个点x0,x1,....xn,xn+1构成一个单纯形。一般可以要求这n+1 个点使向量组x1-x0,x2-x0,.... xn-x0线性无关。

(1)计算函数值f(xi) ,i=0,1,....n f.0.1 决定坏点xh和好点xl,于是

(2)计算除去点xh外的n个点的中心,并且求出反射点

(3)若fr=f(xr)≥fh,则进行压缩,即令xs=xh+λ(xr-xh) ,并求出fs,然后转步骤(5),其中λ为给定的压缩系数,若 fr< fh ,则转步骤(4)。 (4)进行扩张,即令

计算fe,若fefr,则令xs=xe否则,令xs=xrfs=fr

(5)若fs<< span="">fh则用xs替换xh,fs替换fh,把这样得到的新点xs和其他n个点构成一个新的单纯形,重新确定xhxl,然后返回步骤(2);若fsfh则转步骤(6)。

(6)若

则计算结束。取x=xl

过冷水在整理文稿的时候就觉得理解起来好抽象,还不如自己给我一段代码让我自己看,为了让读者理解起来比较容易一点,以

为案例演示单纯形法的思路

(1)任取一组解,初始值1(x=9,y=9),解得f1=192;

(2)从(x=9,y=9)任意出发改变到其它两个点2(x=11,y=9),3(x=9,y=11);解得f2=228;f2=264;

(3)以上三个点(f1,f2,f3)从函数的最大点向对边中点做平行四边形,得到新的点4(11,7),这里过冷水插一句已知三角形三点(1 、2、3),平行四边形的第四个点是怎么求出来的?总不能一眼就看出来是(11,7)吧1

(4)弃去步骤3中函数值最大的点2(11,9),将(1,3,4)组建成新的新的三角形,然后重复步骤三寻找第四点的方法不断操作就可以得到函数的极小值点。

根据上述方法可以编程

代码语言:javascript
复制
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

看上去该代码很简单,实际过冷水在编程化的过程中遇到了很多问题,具这个案例只是为了让读者理解单纯形法是怎么实现最优解的计算的,该方法不仅仅局限于二维,多维也是可以的,只不过不建议使用过冷水自编程序,实战水平怎么样,谁用谁知道。

再次过冷水和大家分享比较完整的单纯形法原程序求解

代码语言:javascript
复制
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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 巴山学长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档