主要内容

模拟退火方法

此示例演示如何创建和管理模拟退火函数的选项simulannealbnd使用最佳选择在全局优化工具箱中。

优化问题设置

simulannealbnd搜索使用模拟退火的最小功能。对于这个例子,我们使用simulannealbnd最小化目标函数dejong5fcn.这个函数是一个两个变量的实值函数,并且有许多局部极小值,使其难以优化。只有一个全局最小值在x =(-32、-32),在那里f(x)=0.998.为了定义我们的问题,我们必须定义目标函数、起点和由范围指定的界限-64 <= x(i) <= 64为每一个x(我)

ObjectiveFunction = @ dejong5fcn;突出点= [-30 0];lb = [-64 -64];UB = [64 64];

这个函数情节目标在工具箱中绘制目标函数的范围-64<=x1<=64,-64 <= x2 <= 64

plotobjective (ObjectiveFunction (-64 64;-64 64]);视图(-15150);

图中包含一个轴。轴包含两个类型为“曲面”、“轮廓”的对象。

现在,我们可以运行simulannealbnd使我们的目标函数最小化。

rng违约%的再现性[x, fval exitFlag、输出]= simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('迭代的数量是:%d \ n',输出。
迭代人数是:1095
fprintf('函数求值的数量为:%d\n', output.funccount);
职能评价的数目为:1104
fprintf('找到的最佳函数值是:%g\n',fval);
得到的最佳函数值为2.98211

请注意,当您运行这个示例时,您的结果可能与上面显示的结果不同,因为模拟退火算法使用随机数来生成点。

添加可视化

simulannealbnd可以通过“选项”参数接受一个或多个绘图函数。此功能对于在运行时可视化求解器的性能是有用的。使用绘图功能使用最佳选择。工具箱包含一组可供选择的绘图函数,或者您可以提供自己的自定义绘图函数。

要选择多个绘图功能,请设置绘图仪通过最佳选择函数。对于本例,我们选择saplotbestf,它在每次迭代中绘制最佳函数值,saplottemperature,显示每次迭代时每个维度的当前温度,saplotf,显示当前函数值(请记住,当前值不一定是最好的值),以及水母,它绘制了每十次迭代满足的停止条件的百分比。

options=options(@simulannealbnd,...“PlotFcn”,{@saplotbestf,@saplottemperature,@saplotf,@saplotstopping});

运行的能手。

simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);

图模拟退火包含4个轴。标题最佳功能值为0.998004的轴1包含类型为line的对象。标题当前温度的轴2包含类型为bar的对象。标题当前功能值为0.998004的轴3包含类型为line的对象。标题停止条件的轴4包含类型为bar的对象。

优化终止:最佳函数值的更改小于options.FunctionTolerance。

指定温度选项

模拟退火中使用的温度参数控制总体搜索结果。每个维度的温度用于限制该维度中的搜索范围。工具箱允许您指定初始温度,以及在求解过程中更新温度的方法。两个与温度相关的选项是初始温度温度Fcn

指定初始温度

每个标注的默认初始温度设置为100。如果希望初始温度在不同维度上不同,则必须指定温度向量。当问题在每个维度上的比例不同时,这可能是必要的。例如

options=options(@simulannealbnd,“InitialTemperature”,[300 50]);

初始温度可以设置为长度小于变量数(维数)的向量;解算器通过取初始温度向量的最后一个元素将向量扩展到剩余维度。这里我们想让初始温度在所有维度上都是相同的所以我们只需要指定一个温度。

选项。初始温度=100;

指定温度函数

默认温度功能使用simulannealbnd被称为temperatureexp. 在temperatureexp计划中,任何给定步骤的温度都是上一步骤温度的.95倍。这导致温度开始缓慢下降,但最终比其他方案更快变冷。如果需要另一种方案,例如Boltzmann计划或“快速”计划退火,则temperatureboltz或者温度场可以分别使用。要选择快速温度计划,我们可以更新以前创建的选项,更改温度Fcn直接。

options.TemperatureFcn=@temperaturefast;

指定再次退火

再退火是退火过程的一部分。在接受一定数量的新点后,温度将升高到更高的值,希望重新开始搜索并移出局部极小值。过早执行重新对齐可能无法帮助解算器确定最小值,因此相对较高的间隔是一个不错的选择。可以使用再神经选择。在这里,我们将默认的重新退火间隔减少到50,因为函数在许多区域看起来是平的,求解器可能会很快卡住。

选项.ReannealInterval = 50;

现在我们已经设置了新的温度选项,我们再次运行解算器

[x, fval exitFlag、输出]= simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('迭代的数量是:%d \ n',输出。
迭代人数是:1306
fprintf('函数求值的数量为:%d\n', output.funccount);
函数评价次数为:1321次
fprintf('找到的最佳函数值是:%g\n',fval);
找到的最佳函数值为:16.4409

复制的结果

simulannealbnd是一个非确定性算法。这意味着在不改变任何设置的情况下多次运行求解器可能会得到不同的结果。这是因为simulannealbnd使用MATLAB®随机数生成器,当它生成后续点时,也当它决定是否接受新点时。每产生一个随机数,随机数生成器的状态就会改变。

要看到这一点,有两组simulannealbnd解算器产量:

[x,fval]=simulannealbnd(目标函数、起始点、lb、ub、选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('找到的最佳函数值是:%g\n',fval);
得到的最佳函数值为1.99203

而且,

[x,fval]=simulannealbnd(目标函数、起始点、lb、ub、选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('找到的最佳函数值是:%g\n',fval);
找到的最佳功能值为:10.7632

在前两次运行中simulannealbnd给出了不同的结果。

如果在求解器运行之间使用返回的信息重置随机数生成器的状态,就可以重现我们的结果simulannealbndsimulannealbnd返回当时随机数生成器的状态simulannealbnd在输出参数中调用。此信息可用于重置状态。在这里,我们使用此输出信息重置两次运行之间的状态,以便下两次运行的结果相同。

[x, fval exitFlag、输出]= simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('找到的最佳函数值是:%g\n',fval);
找到的最佳功能值为:20.1535

我们重置了随机数生成器的状态。

strm = RandStream.getGlobalStream;strm。状态= output.rngstate.State;

现在,让我们跑吧simulannealbnd一次。

[x,fval]=simulannealbnd(目标函数、起始点、lb、ub、选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('找到的最佳函数值是:%g\n',fval);
找到的最佳功能值为:20.1535

修改停止条件

simulannealbnd使用六种不同的条件来确定何时停止解算器。simulannealbnd超过最大迭代次数或函数计算次数时停止;默认情况下,最大迭代次数设置为Inf,最大函数求值次数设置为3000 * numberofvariables.simulannealbnd跟踪的函数值的平均变化MaxStallIterations迭代。如果平均变化小于功能公差,FunctionTolerance,算法就会停止。当目标函数值达到时,求解器也将停止ObjectiveLimit.最后,解算器将在跑完for后停止MaxTime秒。这里我们设置FunctionTolerance1 e-5。

选项。FunctionTolerance = 1 e-5;

运行simulannealbnd解算器。

[x, fval exitFlag、输出]= simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
fprintf('迭代的数量是:%d \ n',输出。
迭代次数为:1843次
fprintf('函数求值的数量为:%d\n', output.funccount);
功能评估的数量为:1864
fprintf('找到的最佳函数值是:%g\n',fval);
找到的最佳函数值为:6.90334

另见

相关话题