愚か者のモデリング-シミュレーテッドアニーリングアルゴリズム

このブログは、Qingfeng先生のビデオ(https://www.bilibili.com/video/BV1hK41157JL?t=2141)に基づいています。Qingfeng
先生の授業計画からの関連する写真がブログで使用されます。


1.問題の説明:

次の質問を見てみましょう

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
dpを学んだ学生は、上記の4つの問題の最後の3つは基本的にdpで解決できることに気付くでしょう。はい、可能ですが、ここでは別のアプローチを見ていきます。

これらの問題は、特定の目的関数の最大値を見つける問題に変換できることがわかりました。一般的な問題では、すべて最小値を求めています。ボールの最大値に遭遇した場合、負の符号も発生する可能性があります。最小値を見つけるために追加されます。


2.予備的な考え

関数の最小値を求めているので、この関数の定義域をトラバースできます。試験の一部の数学の問題では、問題を解決するために、列挙の要素の差を0.01のオーダーに定義するだけでよいことがよくあります。しかし、実際の問題では、0.01の桁は十分に正確ではありませんが、精度を上げると、アルゴリズムの複雑さも増します。これは、暴力的なアルゴリズムが実行できないことを示しています。

最初に概念を紹介しましょう:
ヒューリスティックアルゴリズム:最適解を検索するプロセスでは、元の検索プロセスで取得した情報が使用され、この情報が検索プロセスを最適化します(人気のポイントは時間にメモリを使用することです)

以下で紹介する山登り法は、発見的アルゴリズムです。
まず、次の関数を見てください。
ここに画像の説明を挿入

1.解空間で最初の解をランダムに見つける

2.初期解の位置に応じて、関数値が左に減少する場合は、左または右に移動することを選択できます(距離が小さいほど良いですが、計算量が増加します)(最小値を探します)、次に左に移動します。

3.最小値が見つかるまで、2のプロセスを繰り返します。

方法自体は難しくありませんが、方法には大きな制限があります。局所的な最適解を見つけるのは簡単です。

この問題を解決するには、シミュレーテッドアニーリングアルゴリズムを導入する必要があります。


3.シミュレーテッドアニーリングアルゴリズム

3.1:シミュレーテッドアニーリングアルゴリズムの概要:

シミュレーテッドアニーリングアルゴリズムは、固体アニーリングの原理に基づいており、固体を十分に高いレベルに加熱してからゆっくりと冷却する確率ベースのアルゴリズムです。加熱すると、固体の内部粒子は増加に伴って無秩序になります。温度が高くなると、内部エネルギーが増加します。大きく、ゆっくりと冷却すると粒子は徐々に規則正しくなり、各温度で平衡状態に達し、最終的に室温で基底状態に達し、内部エネルギーが最小になります。

3.2山登り法との類似点と相違点:
上記で提案した山登り法は、焼きなましの導入を容易にすることです。山登り法の主な欠点は、局所的な最適解を見つけやすいことです。進む方向は毎回関数値の大きさによって制限されるということです。死んでいるので、関数値が減少する方向は考慮していません。この点で、シミュレーテッドリターンアルゴリズムが改善されています。

3.3具体的な実現

ここに画像の説明を挿入

私たちが断るなら、それは登山方法ではありません、それなら私たちは絶対に断ることはできません。
ここに画像の説明を挿入

pを決定するために
、0〜1の範囲の関数y = e ^(-x)を見つける必要があります。これは、0〜1の値の範囲の関数であり、xが増加するにつれて減少します。
ここに画像の説明を挿入
これはまだ最終的な形式ではないため、関数を変更します。早期に検索しているため、より広い範囲の検索を行うには、初期の比較的大きなpが必要ですが、後者は比較的小さく、pは時間の影響を受けます。変形で機能する必要があります

ここに画像の説明を挿入
Ctは時間の影響を受ける変数です。
ここに画像の説明を挿入
この式は、いくつかの物理的な知識から導き出されます。

3.4コード:

コードで使用されるメソッド(初心者以外はスキップできます)

rand(x,y);//产生由随机生成的0~1的数组成的x*y的矩阵

scatter(x,y,'*r')//在x,y处绘制一个*r形式的点

title()//给函数设置标题

num2str()//数字转化成字符串

zeros(x,y);//生成一个x,y型的0矩阵

合計コード:


%% 绘制函数的图形
x = -3:0.01:3;
y = 11*sin(x) + 7*cos(5*x);
figure
plot(x,y,'b-')
hold on  % 不关闭图形,继续在上面画图

%% 参数初始化
narvs = 1; % 变量个数
T0 = 100;   % 初始温度
T = T0; % 迭代中温度会发生改变,第一次迭代时温度就是T0
maxgen = 300;  % 最大迭代次数
Lk = 200;  % 每个温度下的迭代次数
alfa = 0.95;  % 温度衰减系数
x_lb = -3; % x的下界
x_ub = 3; % x的上界

%%  随机生成一个初始解
x0 = zeros(1,narvs);
for i = 1: narvs
    x0(i) = x_lb(i) + (x_ub(i)-x_lb(i))*rand(1);    
end
y0 = Obj_fun1(x0); % 计算当前解的函数值
h = scatter(x0,y0,'*r');  % scatter是绘制二维散点图的函数(这里返回h是为了得到图形的句柄,未来我们对其位置进行更新)

%% 定义一些保存中间过程的量,方便输出结果和画图
max_y = y0;     % 初始化找到的最佳的解对应的函数值为y0
MAXY = zeros(maxgen,1); % 记录每一次外层循环结束后找到的max_y (方便画图)

%% 模拟退火过程
for iter = 1 : maxgen  % 外循环, 我这里采用的是指定最大迭代次数
    for i = 1 : Lk  % 内循环,在每个温度下开始迭代
        y = randn(1,narvs);  % 生成1行narvs列的N(0,1)随机数
        z = y / sqrt(sum(y.^2)); % 根据新解的产生规则计算z
        x_new = x0 + z*T; % 根据新解的产生规则计算x_new的值
        %%此生成新解的方法参考matlab模拟退火
        % 如果这个新解的位置超出了定义域,就对其进行调整
        for j = 1: narvs
            if x_new(j) < x_lb(j)
                r = rand(1);
                x_new(j) = r*x_lb(j)+(1-r)*x0(j);
            elseif x_new(j) > x_ub(j)
                r = rand(1);
                x_new(j) = r*x_ub(j)+(1-r)*x0(j);
            end
        end
        x1 = x_new;    % 将调整后的x_new赋值给新解x1
        y1 = Obj_fun1(x1);  % 计算新解的函数值
        if y1 > y0    % 如果新解函数值大于当前解的函数值
            x0 = x1; % 更新当前解为新解
            y0 = y1;
        else
            p = exp(-(y0 - y1)/T); % 根据Metropolis准则计算一个概率
            if rand(1) < p   % 生成一个随机数和这个概率比较,如果该随机数小于这个概率
                x0 = x1; % 更新当前解为新解
                y0 = y1;
            end
        end
        % 判断是否要更新找到的最佳的解
        if y0 > max_y  % 如果当前解更好,则对其进行更新
            max_y = y0;  % 更新最大的y
            best_x = x0;  % 更新找到的最好的x
        end
    end
    MAXY(iter) = max_y; % 保存本轮外循环结束后找到的最大的y
    T = alfa*T;   % 温度下降
    pause(0.01)  % 暂停一段时间(单位:秒)后再接着画图
    h.XData = x0;  % 更新散点图句柄的x轴的数据(此时解的位置在图上发生了变化)
    h.YData = Obj_fun1(x0); % 更新散点图句柄的y轴的数据(此时解的位置在图上发生了变化)
end

disp('最佳的位置是:'); disp(best_x)
disp('此时最优值是:'); disp(max_y)

pause(0.5)
h.XData = [];  h.YData = [];  % 将原来的散点删除
scatter(best_x,max_y,'*r');  % 在最大值处重新标上散点
title(['模拟退火找到的最大值为', num2str(max_y)])  % 加上图的标题

%% 画出每次迭代后找到的最大y的图形
figure
plot(1:maxgen,MAXY,'b-');
xlabel('迭代次数');
ylabel('y的值');
toc

おすすめ

転載: blog.csdn.net/jahup/article/details/108986130