• 大小: 139KB
    文件类型: .zip
    金币: 1
    下载: 0 次
    发布日期: 2021-06-10
  • 语言: Matlab
  • 标签: Powell  

资源简介

Powell MATLAB代码

资源截图

代码片段和文件信息

function pos4 = PowellAdvanced()
% Powell算法,步骤详解可参见如下名字的文件
% “第五次模式搜索法和Powell算法.pdf”
% 以下代码是改进的Powell算法

% 初始化两个方向
d1.x = 1;
d1.y = 0;
d2.x = 0;
d2.y = 1;

% 初始化坐标,随机获取
pos1.x = floor(rand * 1000);
pos1.y = floor(rand * 1000);

% 输出此初始坐标
fprintf(‘\nOriginal Position:‘);
fprintf(‘\npos.x = %d‘ pos1.x);
fprintf(‘\npos.y = %d‘ pos1.y);

delta = abs(det([d1.x d2.x; d1.y d2.y]));

% 容差值
tolvalue = 1e-20;
% 计算det时的容差
toldelta = 1;

lamda=zeros(12);

% 无限循环
while 1
    % 一维黄金搜索,沿着d1的方向,计算lamda
    lamda(1) = GoldSegeOpt(pos1 d1);
    % 方向d1上的最优点坐标
    pos2.x = pos1.x + lamda(1) * d1.x;
    pos2.y = pos1.y + lamda(1) * d1.y;
    
    % 一维黄金搜索,沿着d2的方向,计算lamda
    lamda(2) = GoldSegeOpt(pos2 d2);
    pos3.x = pos2.x + lamda(2) * d2.x;
    pos3.y = pos2.y + lamda(2) * d2.y;
    
    % 两个方向都计算后,加速搜索的方向,为dn - d1
    d3.x = pos3.x - pos1.x;
    d3.y = pos3.y - pos1.y;    
    
    % 沿着加速方向,再搜索一次
    templamda = GoldSegeOpt(pos3 d3);
    pos4.x = pos3.x + templamda * d3.x;
    pos4.y = pos3.y + templamda * d3.y;
    
    % 如果两轮循环得到的坐标小于容差值
    if dist(pos4 pos1) < tolvalue
        break;
    end
    
    % 将n次基本搜索得到的lamda按大到排序
    [val ind] = sort(abs(lamda) ‘descend‘);
    
    % 计算新的delta,根据解决方法(3)中行列式计算公式
    sumd = sqrt((pos4.x -pos1.x)^2 +(pos4.y -pos1.y)^2);
    delta = val(1) / sumd * delta;
    
    % 如果计算后的det值大于它的容差值
    if delta > toldelta
        % 给d3归一化
        sumd = sqrt(d3.x^2 + d3.y^2);
        d3.x = d3.x ./ sumd;
        d3.y = d3.y ./ sumd;
        
        % 更新方向
        if 1 == ind(1)
            d1 = d3;
        else
            d2 = d3;
        end
    end
    
    % 更新初始坐标,进行下一轮循环
    pos1 = pos4;
end
end

%% 子函数
% ****************************************************
% 黄金分割法搜索到最优的lamda
function lamda = GoldSegeOpt(pos dir)
% 此方法计算pos坐标在dir方向上的最优坐标

% 最优点可以认为是:
%     best.x = pos.x + lamda * dir.x
%     best.y = pos.y + lamda * dir.y
% 此函数输出的是最优点所对应的lamda

% 进退法确定lamda的区间
[a b] = JinTui(pos dir);

% 黄金值
g = 0.382;

% 第一次迭代的中间值
c = a + g * (b - a);
d = b - g * (b - a);

% 容差值
tol = 1e-6;

% 计算中间值对应的目标函数值
fc = target(pos.x + c * dir.x pos.y + c * dir.y);
fd = target(pos.x + d * dir.x pos.y + d * dir.y);

while 1
    % 如果lamda左右边界距离小于容差值,退出循环
    if (b - a) < tol
        lamda = (a + b)/2;
        break;
    end
    % 按黄金分割法更新
    if fc < fd
        b = d;
        fd = fc;
        d = c;
        c = a + g * (b - a);
        fc = target(pos.x + c * dir.x pos.y +c *dir.y);
    else
        a = c;
        fc = fd;
        c = d;
        d = b - g * (b - a);
        fd = target(pos.x + d * dir.x pos.y +d *dir.y);
    end
end
end
% ****************************************************
% 进退法确定lamda的大致区间
function [a b] = JinTui(pos dir)
% 进退法确定lamda的大致区间

l1 = rand;

% 此处不要设置太小,否则计算时间太长
h = 1;

f1 = target(pos.x pos.y);
k = 0;
% ****************************************************

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     目录           0  2017-06-23 20:03  Powell\
     文件        4418  2014-07-10 10:35  Powell\PowellAdvanced.m
     文件        3727  2014-07-10 09:12  Powell\PowellBasic.m
     文件      189122  2014-07-09 21:01  Powell\Powell算法.pdf

评论

共有 条评论