应用最优化方法及MATLAB实现——第3章代码实现

news2025/1/18 17:00:39

一、概述

        在阅读最优方法及MATLAB实现后,想着将书中提供的代码自己手敲一遍,来提高自己对书中内容理解程度,巩固一下。

        这部分内容主要针对第3章的内容,将其所有代码实现均手敲一遍,中间部分代码自己根据其公式有些许的调整,但最后运算结果与书中所给结果一致。

        修改的部分我会在下面进行单独说明并标注上我这样做的原因。

二、具体代码

(一)计算函数文件

        因为书中所给出的示例代码,所使用的函数都是一样的。所以将其单独罗列出来。

        其中,f_test1.m如下所示。

function y = f_test1(x)
% 该函数的主要作用是编写函数,用于计算函数输出值
% x为函数输入值
% y为函数输出值
    y = 2 * x ^2 - x - 1;
end

        f_test2.m如下所示。

function y = f_test2(x)
% 该函数的主要作用是编写函数,用于计算函数输出值
% x为函数输入值
% y为函数输出值
    x1 = x(1);
    x2 = x(2);
    y = x1 ^2 + x2 ^2 - 1;
end

        f_test3.m如下所示。

function y = f_test3(x)
% 该函数的主要作用是编写函数,用于计算函数输出值
% x为函数输入值
% y为函数输出值
    if(x <= 2)
        y = -x + 3;
    else
        y = x / 2;
    end
end

        这些文件每个方法使用的都是一样的。

(二)对分搜索法

        1.对分搜索法函数文件

        这个文件主要参照书中的,没有改动。

function [alpha_star, x_next, f_next, k] = Dichotomous_search(f_test, x_current, d_current, alpha_lower, alpha_upper, tolerance)
% 该函数针对对分搜索法的实现
% 输入参数说明
% f_test, 目标函数
% x_current, x在向量空间中的当前点(已确定)
% d_current, f_test在向量空间中的搜索方向(已确定)
% alpha_lower, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始下届
% alpha_upper, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始上届
% tolerance, 最终区间的要求宽度,精度不能小于扰动量
    
% 输出参数说明
% alpha_star, 完成对分搜索后输出的步长
% x_next, x_next = x_current + alpha_star * d_current;局部最优点
% f_next, 局部最优点对应的函数值
% k,迭代次数

    disturbance_quantity = 0;
    if(tolerance >= 1e-8)
        disturbance_quantity = 1e-9;
    else
        disturbance_quantity = 0.1 * tolerance;
    end
    
    % 初始值
    k = 0;
    alpha_lower_k = alpha_lower;
    alpha_upper_k = alpha_upper;
    alpha_left_k = (1/2)*(alpha_lower_k + alpha_upper_k) - disturbance_quantity;
    alpha_right_k = (1/2)*(alpha_lower_k + alpha_upper_k) + disturbance_quantity;
    x_alpha_left_k = x_current + alpha_left_k * d_current;
    x_alpha_right_k = x_current + alpha_right_k * d_current;
    f_alpha_left_k = f_test(x_alpha_left_k);
    f_alpha_right_k = f_test(x_alpha_right_k);

    % 进入循环
    while(abs(alpha_upper_k - alpha_lower_k) > tolerance)
        if(f_alpha_right_k > f_alpha_left_k)
            alpha_upper_k = alpha_right_k;
        elseif(f_alpha_right_k < f_alpha_left_k)
            alpha_lower_k = alpha_left_k;
        else
            alpha_upper_k = alpha_right_k;
            alpha_lower_k = alpha_left_k;
        end
        alpha_left_k = (1/2)*(alpha_lower_k + alpha_upper_k) - disturbance_quantity;
        alpha_right_k = (1/2)*(alpha_lower_k + alpha_upper_k) + disturbance_quantity;
        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;
        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_right_k = f_test(x_alpha_right_k);
        k = k + 1;
    end
    alpha_star = (alpha_right_k + alpha_left_k) / 2;
    x_next = x_current + alpha_star * d_current;
    f_next = f_test(x_next);
end

        2.对应的主运行文件

        放开相应的注释即可。

% 这个文件作为第3章的主文件

% 清空所有
close;
clear;
clc;

% 对分搜索法实现
% 第一个示例
% x_current = -0.5;
% d_current = 1;
% alpha_lower = 0;
% alpha_upper = 1;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Dichotomous_search(@f_test1, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 第二个示例
% x_current = [2, 2];
% d_current = [-1, -1];
% alpha_lower = 0;
% alpha_upper = 2;
% tolerance = 1e-6;
% [alpha_star, x_next, f_next, k] = Dichotomous_search(@f_test2, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 第三个示例
x_current = 3;
d_current = -1;
alpha_lower = 0;
alpha_upper = 2;
tolerance = 1e-4;
[alpha_star, x_next, f_next, k] = Dichotomous_search(@f_test3, x_current, d_current, alpha_lower, alpha_upper, tolerance);

(三)三点等间隔搜索法

        1.三点等间隔搜索法

function [alpha_star, x_next, f_next, k] = Trisection_search(f_test, x_current, d_current, alpha_lower, alpha_upper, tolerance)
% 该函数针对三点等间隔的实现
% 输入参数说明
% f_test, 目标函数
% x_current, x在向量空间中的当前点(已确定)
% d_current, f_test在向量空间中的搜索方向(已确定)
% alpha_lower, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始下届
% alpha_upper, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始上届
% tolerance, 最终区间的要求宽度,精度不能小于扰动量
    
% 输出参数说明
% alpha_star, 完成对分搜索后输出的步长
% x_next, x_next = x_current + alpha_star * d_current;局部最优点
% f_next, 局部最优点对应的函数值
% k,迭代次数
    
% 初始化
k = 0;
% 这两个是每次迭代过程中的上下界
alpha_lower_k = alpha_lower;
alpha_upper_k = alpha_upper;

alpha_left_k = alpha_lower_k + (1/4) * (alpha_upper_k - alpha_lower_k);
alpha_middle_k = alpha_lower_k + (1/2) * (alpha_upper_k - alpha_lower_k);
alpha_right_k = alpha_lower_k + (3/4) * (alpha_upper_k - alpha_lower_k);

x_alpha_left_k = x_current + alpha_left_k * d_current;
x_alpha_middle_k = x_current + alpha_middle_k * d_current;
x_alpha_right_k = x_current + alpha_right_k * d_current;

f_alpha_left_k = f_test(x_alpha_left_k);
f_alpha_middle_k = f_test(x_alpha_middle_k);
f_alpha_right_k = f_test(x_alpha_right_k);

% 这部分代码书写是一种计算方法,不太精准,部分信息没有使用到
% while abs(alpha_upper_k -alpha_lower_k) > tolerance
%     if (f_alpha_left_k < f_alpha_middle_k) && (f_alpha_left_k < f_alpha_right_k)
%         % alpha_lower_k = alpha_lower;
%         alpha_upper_k = alpha_middle_k;
%     elseif (f_alpha_middle_k < f_alpha_left_k) && (f_alpha_middle_k < f_alpha_right_k)
%         alpha_lower_k = alpha_left_k;
%         alpha_upper_k = alpha_right_k;
%     else 
%         alpha_lower_k = alpha_middle_k;
%         % alpha_upper_k = alpha_upper
%     end
% k = k + 1;
% alpha_left_k = alpha_lower_k + (1/4) * (alpha_upper_k - alpha_lower_k);
% alpha_middle_k = alpha_lower_k + (1/2) * (alpha_upper_k - alpha_lower_k);
% alpha_right_k = alpha_lower_k + (3/4) * (alpha_upper_k - alpha_lower_k);
% 
% x_alpha_left_k = x_current + alpha_left_k * d_current;
% x_alpha_middle_k = x_current + alpha_middle_k * d_current;
% x_alpha_right_k = x_current + alpha_right_k * d_current;
% 
% f_alpha_left_k = f_test(x_alpha_left_k);
% f_alpha_middle_k = f_test(x_alpha_middle_k);
% f_alpha_right_k = f_test(x_alpha_right_k);
% end

% 第二种方法,可以重复利用三点等间隔搜索法的信息
while abs(alpha_upper_k -alpha_lower_k) > tolerance
    if (f_alpha_left_k < f_alpha_middle_k) && (f_alpha_left_k < f_alpha_right_k)
        % alpha_lower_k = alpha_lower;
        alpha_upper_k = alpha_middle_k;

        alpha_left_k = alpha_lower_k + (1/4) * (alpha_upper_k - alpha_lower_k);
        alpha_middle_k = alpha_left_k;
        alpha_right_k = alpha_lower_k + (3/4) * (alpha_upper_k - alpha_lower_k);

        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_middle_k = x_current + alpha_middle_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;

        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_middle_k = f_alpha_left_k;
        f_alpha_right_k = f_test(x_alpha_right_k);
    elseif (f_alpha_middle_k < f_alpha_left_k) && (f_alpha_middle_k < f_alpha_right_k)
        alpha_lower_k = alpha_left_k;
        alpha_upper_k = alpha_right_k;

        alpha_left_k = alpha_lower_k + (1/4) * (alpha_upper_k - alpha_lower_k);
        % alpha_middle_k = alpha_left_k;
        alpha_right_k = alpha_lower_k + (3/4) * (alpha_upper_k - alpha_lower_k);

        x_alpha_left_k = x_current + alpha_left_k * d_current;
        % x_alpha_middle_k = x_current + alpha_middle_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;

        f_alpha_left_k = f_test(x_alpha_left_k);
        % f_alpha_middle_k = f_alpha_left_k;
        f_alpha_right_k = f_test(x_alpha_right_k);
    else 
        alpha_lower_k = alpha_middle_k;
        % alpha_upper_k = alpha_upper

        alpha_left_k = alpha_lower_k + (1/4) * (alpha_upper_k - alpha_lower_k);
        alpha_middle_k = alpha_right_k;
        alpha_right_k = alpha_lower_k + (3/4) * (alpha_upper_k - alpha_lower_k);

        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_middle_k = x_current + alpha_middle_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;

        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_middle_k = f_alpha_right_k;
        f_alpha_right_k = f_test(x_alpha_right_k);
    end
k = k + 1;
end

alpha_star = (alpha_left_k + alpha_right_k) / 2;
x_next = x_current + alpha_star * d_current;
f_next = f_test(x_next);
end

        2.主函数运行文件

        放开相应注释即可。

% 这个是三点等间隔搜索法的主程序

% 清空变量
close;
clear;
clc;

% 示例一
% x_current = -0.5;
% d_current = 1;
% alpha_lower = 0;
% alpha_upper = 1;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Trisection_search(@f_test1, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例二
% x_current = [2, 2];
% d_current = [-1, -1];
% alpha_lower = 0;
% alpha_upper = 2;
% tolerance = 1e-6;
% [alpha_star, x_next, f_next, k] = Trisection_search(@f_test2, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例三
x_current = 3;
d_current = -1;
alpha_lower = 0;
alpha_upper = 2;
tolerance = 1e-4;
[alpha_star, x_next, f_next, k] = Trisection_search(@f_test3, x_current, d_current, alpha_lower, alpha_upper, tolerance);

        3.一些说明

        在三点搜索法的实现过程中,目前放开注释的是比较符合书中思路的,在前面有一部分注释掉的实现方式,如图所示。

        使用这一部分代码时候,也是可以运行成功的,但是计算效率不高,因为三点搜索法的一些条件没有利用到,重新计算函数值这些会浪费一定时间,但是代码简单,比较好理解,也好书写。

(四) Fibonacci搜索法

        1.Fibonacci搜索法函数文件

function [alpha_star, x_next, f_next, k] = Fibonacci_search(f_test, x_current, d_current, alpha_lower, alpha_upper, tolerance)
% 该函数针对Fibonacci搜索法的实现
% 输入参数说明
% f_test, 目标函数
% x_current, x在向量空间中的当前点(已确定)
% d_current, f_test在向量空间中的搜索方向(已确定)
% alpha_lower, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始下届
% alpha_upper, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始上届
% tolerance, 最终区间的要求宽度,精度不能小于扰动量
    
% 输出参数说明
% alpha_star, 完成对分搜索后输出的步长
% x_next, x_next = x_current + alpha_star * d_current;局部最优点
% f_next, 局部最优点对应的函数值
% k,迭代次数

% 计算斐波那契数列数列需要多少个
Fibonacci_series_upper = (alpha_upper - alpha_lower) / tolerance;
% 这里不需要第1个,实际上是从第二个开始
Fibonacci_series = [1, 2];
n = 2;
while (Fibonacci_series(n) <= Fibonacci_series_upper)
    n = n + 1;
    Fibonacci_series(n) = Fibonacci_series(n-1) + Fibonacci_series(n-2);
end

% 使用斐波那契数列进行搜索,注意到第n-2位置
k = 0;
alpha_lower_k = alpha_lower;
alpha_upper_k = alpha_upper;
Length_k = (Fibonacci_series(n - 1) / Fibonacci_series(n)) * (alpha_upper_k - alpha_lower_k);
alpha_left_k = alpha_upper_k - Length_k;
alpha_right_k = alpha_lower_k + Length_k;
x_alpha_left_k = x_current + alpha_left_k * d_current;
x_alpha_right_k = x_current + alpha_right_k * d_current;
f_alpha_left_k = f_test(x_alpha_left_k);
f_alpha_right_k = f_test(x_alpha_right_k);
while k < n - 2
    k = k + 1;
    if(f_alpha_left_k < f_alpha_right_k)
        % alpha_lower_k = alpha_lower;
        alpha_upper_k = alpha_right_k;
        Length_k = (Fibonacci_series(n - k - 1) / Fibonacci_series(n - k)) * (alpha_upper_k - alpha_lower_k);
        alpha_right_k = alpha_left_k;
        alpha_left_k = alpha_upper_k - Length_k;
        % alpha_right_k = alpha_lower_k + Length_k;  
        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;
        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_right_k = f_test(x_alpha_right_k);
    else
        alpha_lower_k = alpha_left_k;
        % alpha_upper_k = alpha_right_k;
        Length_k = (Fibonacci_series(n - k - 1) / Fibonacci_series(n - k)) * (alpha_upper_k - alpha_lower_k);
        alpha_left_k = alpha_right_k;
        % alpha_left_k = alpha_upper_k - Length_k;
        alpha_right_k = alpha_lower_k + Length_k;  
        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;
        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_right_k = f_test(x_alpha_right_k);
    end
end

k = k + 1;
disturbance_quantity = 0.1 * tolerance;
alpha_left_k = (1/2)*(alpha_lower_k + alpha_upper_k) - disturbance_quantity;
alpha_right_k = (1/2)*(alpha_lower_k + alpha_upper_k) + disturbance_quantity;
x_alpha_left_k = x_current + alpha_left_k * d_current;
x_alpha_right_k = x_current + alpha_right_k * d_current;
f_alpha_left_k = f_test(x_alpha_left_k);
f_alpha_right_k = f_test(x_alpha_right_k);

if (f_alpha_left_k < f_alpha_right_k)
    alpha_upper_k = alpha_right_k;
elseif (f_alpha_left_k > f_alpha_right_k)
    alpha_lower_k = alpha_left_k;
else
    alpha_upper_k = alpha_right_k;
    alpha_lower_k = alpha_left_k;
end
 
alpha_star = (alpha_lower_k + alpha_upper_k) / 2;
x_next = x_current + alpha_star * d_current;
f_next = f_test(x_next);
end

        2.主函数运行文件

        放开相应注释即可。

% 这个文件主要用来进行斐波那契搜索法的运行

close;
clear;
clc;

% 示例一
% x_current = -0.5;
% d_current = 1;
% alpha_lower = 0;
% alpha_upper = 1;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Fibonacci_search(@f_test1, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例二
x_current = [2, 2];
d_current = [-1, -1];
alpha_lower = 0;
alpha_upper = 2;
tolerance = 1e-6;
[alpha_star, x_next, f_next, k] = Fibonacci_search(@f_test2, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例三
% x_current = 3;
% d_current = -1;
% alpha_lower = 0;
% alpha_upper = 2;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Fibonacci_search(@f_test3, x_current, d_current, alpha_lower, alpha_upper, tolerance);

(五)黄金分割法

         1.黄金分割法函数文件

function [alpha_star, x_next, f_next, k] = Golden_section_search(f_test, x_current, d_current, alpha_lower, alpha_upper, tolerance)
% 该函数针对黄金分割法的实现
% 输入参数说明
% f_test, 目标函数
% x_current, x在向量空间中的当前点(已确定)
% d_current, f_test在向量空间中的搜索方向(已确定)
% alpha_lower, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始下届
% alpha_upper, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始上届
% tolerance, 最终区间的要求宽度,精度不能小于扰动量
    
% 输出参数说明
% alpha_star, 完成对分搜索后输出的步长
% x_next, x_next = x_current + alpha_star * d_current;局部最优点
% f_next, 局部最优点对应的函数值
% k,迭代次数

% 黄金分割点
golden_ratio = 1 / (0.5 * (1 + sqrt(5)));

% 使用斐波那契数列进行搜索,注意到第n-2位置
k = 0;
alpha_lower_k = alpha_lower;
alpha_upper_k = alpha_upper;
Length_k = golden_ratio * (alpha_upper_k - alpha_lower_k);
alpha_left_k = alpha_upper_k - Length_k;
alpha_right_k = alpha_lower_k + Length_k;
x_alpha_left_k = x_current + alpha_left_k * d_current;
x_alpha_right_k = x_current + alpha_right_k * d_current;
f_alpha_left_k = f_test(x_alpha_left_k);
f_alpha_right_k = f_test(x_alpha_right_k);
while abs(alpha_upper_k - alpha_lower_k) > tolerance
    k = k + 1;
    if(f_alpha_left_k < f_alpha_right_k)
        % alpha_lower_k = alpha_lower;
        alpha_upper_k = alpha_right_k;
        Length_k = golden_ratio * (alpha_upper_k - alpha_lower_k);
        alpha_right_k = alpha_left_k;
        alpha_left_k = alpha_upper_k - Length_k;
        % alpha_right_k = alpha_lower_k + Length_k;  
        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;
        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_right_k = f_test(x_alpha_right_k);
    else
        alpha_lower_k = alpha_left_k;
        % alpha_upper_k = alpha_right_k;
        Length_k = golden_ratio * (alpha_upper_k - alpha_lower_k);
        alpha_left_k = alpha_right_k;
        % alpha_left_k = alpha_upper_k - Length_k;
        alpha_right_k = alpha_lower_k + Length_k;  
        x_alpha_left_k = x_current + alpha_left_k * d_current;
        x_alpha_right_k = x_current + alpha_right_k * d_current;
        f_alpha_left_k = f_test(x_alpha_left_k);
        f_alpha_right_k = f_test(x_alpha_right_k);
    end
end
 
alpha_star = (alpha_lower_k + alpha_upper_k) / 2;
x_next = x_current + alpha_star * d_current;
f_next = f_test(x_next);
end

        2.主函数运行文件

% 这个文件主要用来进行黄金分割法的运行

close;
clear;
clc;

% 示例一
% x_current = -0.5;
% d_current = 1;
% alpha_lower = 0;
% alpha_upper = 1;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Golden_section_search(@f_test1, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例二
x_current = [2, 2];
d_current = [-1, -1];
alpha_lower = 0;
alpha_upper = 2;
tolerance = 1e-6;
[alpha_star, x_next, f_next, k] = Golden_section_search(@f_test2, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例三
% x_current = 3;
% d_current = -1;
% alpha_lower = 0;
% alpha_upper = 2;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Golden_section_search(@f_test3, x_current, d_current, alpha_lower, alpha_upper, tolerance);

        3.一些说明

        这里我稍微更改了一下实现方式,主要是针对于更新后的边界。书中原有方法如下所示,由于黄金分割法跟Fibonacci搜索法基本原理相似,所以,我就采用跟Fibonacci搜索法相似的更新方法。

        更新方法如下所示。写的比较粗糙,但原理一致。

(六)三点二次插值法

        1.三点二次插值法

function [alpha_star, x_next, f_next, k] = Quadratic3points_search(f_test, x_current, d_current, alpha_lower, alpha_upper, tolerance)
% 该函数针对三点二次插值法的实现
% 输入参数说明
% f_test, 目标函数
% x_current, x在向量空间中的当前点(已确定)
% d_current, f_test在向量空间中的搜索方向(已确定)
% alpha_lower, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始下届
% alpha_upper, 从x_current出发,沿着d_current得到一个步长的单谷区间,该单谷区间的初始上届
% tolerance, 最终区间的要求宽度,精度不能小于扰动量
    
% 输出参数说明
% alpha_star, 完成对分搜索后输出的步长
% x_next, x_next = x_current + alpha_star * d_current;局部最优点
% f_next, 局部最优点对应的函数值
% k,迭代次数

 
    
% 初始值
k = 0;
alpha_lower_k = alpha_lower;
alpha_upper_k = alpha_upper;

alpha_left_k = alpha_lower_k;
alpha_right_k = alpha_upper_k;
alpha_middle_k = (alpha_left_k + alpha_right_k) / 2;

x_alpha_left_k = x_current + alpha_left_k * d_current;
x_alpha_right_k = x_current + alpha_right_k * d_current;
x_alpha_middle_k = x_current + alpha_middle_k * d_current;

f_alpha_left_k = f_test(x_alpha_left_k);
f_alpha_right_k = f_test(x_alpha_right_k);
f_alpha_middle_k = f_test(x_alpha_middle_k);

% 用来保证算法能够启动,因为需要|ak+1-ak|作为判断条件,但第一次无法
% 计算这个,通过100 * tolerance保证能够进入循环进行运算,之后再进行
% 更新
gap_k = 100 * tolerance;
alpha_interpolation_previous = -100;

while gap_k > tolerance
    k = k + 1;
    a1 = (f_alpha_left_k - f_alpha_middle_k) * (alpha_middle_k - alpha_right_k) * (alpha_right_k - alpha_left_k);
    a2 = f_alpha_left_k * (alpha_middle_k - alpha_right_k) + f_alpha_middle_k * (alpha_right_k - alpha_left_k) + f_alpha_right_k * (alpha_left_k - alpha_middle_k);
    alpha_interpolation_k = (1/2) * ((alpha_left_k + alpha_middle_k) + (a1 / a2));
    x_alpha_interpolation_k = x_current + alpha_interpolation_k * d_current;
    f_alpha_interpolation_k = f_test(x_alpha_interpolation_k);

    alpha_interpolation_current = alpha_interpolation_k;
    alpha_middle_previous = alpha_middle_k;
    f_alpha_middle_previous = f_alpha_middle_k;

    if ((alpha_left_k < alpha_interpolation_k) && (alpha_interpolation_k < alpha_middle_k))
        if (f_alpha_interpolation_k <= f_alpha_middle_k)
            alpha_right_k = alpha_middle_k;
            f_alpha_right_k = f_alpha_middle_k;
            alpha_middle_k = alpha_interpolation_k;
            f_alpha_middle_k = f_alpha_interpolation_k;
        else
            alpha_left_k = alpha_interpolation_k;
            f_alpha_left_k = f_alpha_interpolation_k;
        end
    end

    if ((alpha_middle_k < alpha_interpolation_k) && (alpha_interpolation_k < alpha_right_k))
        if (f_alpha_interpolation_k <= f_alpha_middle_k)
            alpha_left_k = alpha_middle_k;
            f_alpha_left_k = f_alpha_middle_k;
            alpha_middle_k = alpha_interpolation_k;
            f_alpha_middle_k = f_alpha_interpolation_k;
        else
            alpha_right_k = alpha_interpolation_k;
            f_alpha_right_k = f_alpha_interpolation_k;
        end
    end
    gap_k = abs(alpha_interpolation_current - alpha_interpolation_previous);
    alpha_interpolation_previous = alpha_interpolation_current;
end
    
f_alpha_interpolation_current = f_alpha_interpolation_k;
if (f_alpha_interpolation_current <= f_alpha_interpolation_k)
    alpha_star = alpha_interpolation_k;
else
    alpha_star = alpha_middle_previous;
end

x_next = x_current + alpha_star * d_current;
f_next = f_test(x_next);
end

        2.主函数运行文件

% 这个文件主要用来进行斐波那契搜索法的运行

close;
clear;
clc;

% 示例一
% x_current = -0.5;
% d_current = 1;
% alpha_lower = 0;
% alpha_upper = 1;
% tolerance = 1e-4;
% [alpha_star, x_next, f_next, k] = Quadratic3points_search(@f_test1, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例二
% x_current = [2, 2];
% d_current = [-1, -1];
% alpha_lower = 0;
% alpha_upper = 2;
% tolerance = 1e-6;
% [alpha_star, x_next, f_next, k] = Quadratic3points_search(@f_test2, x_current, d_current, alpha_lower, alpha_upper, tolerance);

% 示例三
x_current = 3;
d_current = -1;
alpha_lower = 0;
alpha_upper = 2;
tolerance = 1e-4;
[alpha_star, x_next, f_next, k] = Quadratic3points_search(@f_test3, x_current, d_current, alpha_lower, alpha_upper, tolerance);

        3.一些说明

        如果按照文中代码,如图所示红色部分圈出来的。在针对第一个和第二个示例的时,运行结果跟书中一致,跟前面几种方法是相同的。

        但如果运行第三个示例的话,按照书中这种方法,则不会运行处正确结果。原因是因为这样计算出来的gap_k永远为0,程序只会迭代一次就结束。

        更改完成的代码如上面所示,主要是提前将alpha_interpolation_previous进行初始化,这个值我设置为了-100,可以设置不可能达到的数字,这样能够保证每次运行都可以成功。其次,我将alpha_interpolation_previous的更新放在循环的最后,这样解决了上述问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1920166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows系统MySQL的安装,客户端工具Navicat的安装

下载mysql安装包&#xff0c;可以去官网下载&#xff1a;www.mysql.com。点击downloads 什么&#xff1f;后面还有福利&#xff1f; 下载MySQL 下载企业版&#xff1a; 下载Windows版 5点多的版本有点低&#xff0c;下载8.0.38版本的。Window系统。下载下面的企业版。不下载…

网安防御保护-小实验

1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问DMZ区的FTP服务器和HTTP服务器&#xff0c;仅能ping通…

Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析

Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析 文章目录 Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析一、前言二、隐藏实现1、xml 文件中隐藏PreferenceScreen 的某个条目2、普通Preference条目的隐藏的Java代码实现3、SwitchPreference条…

bevfomer self-att to transformer to tensorrt

self-attentation https://blog.csdn.net/weixin_42110638/article/details/134016569 query input* Wq key input* Wk value input* Wv output 求和 query . key * value detr multiScaleDeformableAttn Deformable Attention Module&#xff0c;在图像特征上&#…

STM32读取LX-224总线舵机信息

一、舵机指令包格式 帧头&#xff1a; 连续收到两个 0x55 ,表示有数据包到达。ID: 每个舵机都有一个 ID 号。ID 号范围 0&#xff5e;253,转换为十六进制 0x00&#xff5e;0xFD。广播 ID: ID 号 254(0xFE) 为广播 ID,若控制器发出的 ID 号为 254(0xFE)&#xff0c;所有的舵机均…

DockerFile文件解析

DockerFile 要研究自己如何做一个镜像&#xff0c;而且微服务项目打包上云部署&#xff0c;Docker就是最方便的。 微服务打包成镜像&#xff0c;任何装了Docker的地方&#xff0c;都可以下载使用&#xff0c;极其的方便。 流程&#xff1a;开发应用>DockerFile>打包为…

c++ 建造者模式

文章目录 建造者模式为什么使用建造者模式建造者模式实现步骤实现示例建造者模式优缺点 建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;是面向对象设计模式中的一种&#xff0c;主要用于创建复杂对象。这种模式将对象的构建过程与其表示分离&#xff0c;允许用…

Qt+ESP32+SQLite 智能大棚

环境简介 硬件环境 ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器 基本工作流程 上位机先运行&#xff0c;下位机启动后尝试连接上位机连接成功后定时上报传感器数据到上位机&#xff0c;上位机将信息进行处理展示判断下位机传感器数据&#xff0c;如果超过设置的阈值&a…

电商出海第一步,云手机或成重要因素

电商出海第一步并非易事&#xff0c;挑战和机遇并存&#xff0c;出海企业或个人或将借助云手机从而达成商业部署全球化的目的&#xff1b; 下面我们从网络稳定、数据安全、成本、以及多平台适配方面来看&#xff0c;究竟为什么说云手机会成为出海的重要因素&#xff1b; 首先…

图谱动态240709

本期将分享近期全球知识图谱相关 行业动态、会议资讯、论文推荐 —--| 行业动态 |--— 微软开源GraphRAG 7月2日&#xff0c;微软开源了GraphRAG&#xff0c;一种基于图的检索增强生成(RAG) 方法&#xff0c;可以对私有或以前未见过的数据集进行问答&#xff08;开源地址&…

ENSP防火墙

实验拓扑图 需求&#xff1a; ENSP的配置&#xff1a; 防火墙&#xff1a; 交换机&#xff1a; 华为防火墙的配置&#xff1a; 接口配置&#xff1a; 安全区域&#xff1a; 安全策略&#xff1a; 办公区访问DMZ&#xff1a; 生产区访问DMZ&#xff1a; 游客区只能访问门户网…

USB转RS485+RS232+TTL串口电路

USB转RS485RS232TTL电路 USB转RS485RS232TTL电路如下图所示&#xff0c;可实现USB转RS485RS232TTL串口&#xff0c;一个电路模块即可实现电路调试过程中用到常用接口。 电路模块上留有2.54MM单排针接口和接线端子两种接线方式&#xff0c;可接线和跳线。电路模块同时有5V和3.3V…

Vulkan入门系列0- Vulkan与OpenGL的区别

一:概述 Vulkan 是新一代图形和计算API,是由科纳斯组织(Khronos Group)维护的一套跨平台的、开放标准的、现代GPU 的编程接口,它仅仅是规定了一套编程接口,并没有接口的具体实现,实现是由硬件厂商适配实现的,市面上像NVIDIA、AMD和Intel等国际大厂基本提供了完整的…

C++ enum class转常量

当使用 enum class 时&#xff0c;它具有更强的类型安全性和隔离性&#xff0c;因此需要显式转换才能访问其底层整数值。 std::underlying_type_t 是一个类型别名&#xff0c;它返回枚举类型的底层类型。 to_underlying 函数提供了一种方便的方式来执行这种转换&#xff0c;特别…

vb.netcad二开自学笔记8:界面之任务窗格

使用net可以创建一个类似属性面板的自定义的任务窗格&#xff0c;从而实现应用程序更丰富的人机交互。 1、添加一个自定义控件 2、在前面创建的代码框架内增加一个命令函数ShowMyPalette Imports System.Windows.Media.Imaging Imports Autodesk.AutoCAD.ApplicationServices …

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…

5G中的RedCap

5G中的RedCap&#xff1a;降低能力的重要性和实现方式 随着5G技术的推广和普及&#xff0c;设备和终端的多样化使得网络能力的管理变得更加复杂和关键。RedCap&#xff08;Reduced Capability&#xff09;作为一个重要的概念&#xff0c;旨在解决设备能力差异对网络服务和用户…

基于PID控制器的双容控制系统matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1PID控制器的基本原理 4.2双容水箱系统的数学模型 5.完整工程文件 1.课题概述 基于PID控制器的双容控制系统matlab仿真&#xff0c;仿真输出PID控制下的水位和流量两个指标。 2.系统仿真结果 &…