此示例显示如何为模拟退火功能创建和管理选项simulannealbnd
使用优化选择
在全局优化工具箱中。
simulannealbnd
搜索使用模拟退火的最小功能。对于这个例子,我们使用simulannealbnd
最小化目标函数dejong5fcn
.这个函数是一个两个变量的实值函数,并且有许多局部极小值,使其难以优化。只有一个全局最小值在x =(-32、-32)
,在那里f(x)= 0.998
.为了定义我们的问题,我们必须定义目标函数、起点和由范围指定的界限-64 <= x(i) <= 64
为每一个x(我)
.
ObjectiveFunction = @dejong5fcn;startingPoint = [-30 0];Lb = [-64 -64];Ub = [64 64];
这个函数plotobjective.
在工具箱中,在范围内绘制目标函数-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
可以通过“选项”参数接受一个或多个绘图函数。此功能对于在运行时可视化求解器的性能是有用的。使用绘图功能使用优化选择
.工具箱包含一组绘图功能可供选择,或者您可以提供自己的自定义绘图功能。
要选择多个绘图功能,请设置Plotfcn.
通过备份选择优化选择
函数。对于本例,我们选择saplotbestf
,这绘制了每次迭代的最佳功能值,saplottemperature
,这显示了每次迭代时每个维度的当前温度,saplotf
,显示当前函数值(请记住,当前值不一定是最好的值),以及Saplotstopping.
,这绘制了每十个迭代的停止标准的百分比满足。
选项= Optimoptions(@simulannealbnd,......“PlotFcn”,{@ saplotbestf,@ saplottemperature,@ saplotf,@ saplotstopping});
运行的能手。
simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);
优化终止:更改最佳函数值小于options.functiontolerance。
模拟退火中使用的温度参数控制整体搜索结果。每个尺寸的温度用于限制该维度的搜索程度。工具箱允许您指定初始温度以及在解决方案过程中更新温度的方法。两个温度相关的选项是InitialTemperature.
和温度浮出水
.
指定初始温度
默认初始温度为每个维度设置为100。如果希望初始温度在不同的尺寸中不同,则必须指定温度的向量。如果在每个维度中以不同方式缩放问题,则这可能是必要的。例如,
选项= Optimoptions(@simulannealbnd,“InitialTemperature”,[300 50]);
InitialTemperature.
可以设置为长度小于变量数(维数)的向量;解算器通过取初始温度向量的最后一个元素将向量扩展到剩余维度。这里我们想让初始温度在所有维度上都是相同的所以我们只需要指定一个温度。
options.InitialTemperature = 100;
指定温度函数
默认温度功能使用simulannealbnd
叫做temperatureexp
.在温度XP时分中,任何给定步长的温度为.95倍前一步骤的温度。这使得最初使温度慢慢下降,但最终比其他方案更快地变得更冷。如果需要另一种方案,例如,Boltzmann时间表或“快速”日程安排退火,然后temperatureboltz
要么温度快餐
可以分别使用。要选择快速温度计划,我们可以更新我们以前创建的选项,更改温度浮出水
直接。
选项.TemperatureFCN = @TemperatureFast;
指定再次退火
Reannealing是退火过程的一部分。在接受一定数量的新点之后,将温度提升到更高的值,希望重新开始搜索并从局部最小值移出。执行重新入射,太快可能无法帮助求解器识别最小,因此相对较高的间隔是一个不错的选择。可以使用eannealing发生的间隔来设置ReannealInterval.
选择。在这里,我们将默认的重新退火间隔减少到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(OperateFunction,初始点,LB,UB,选项);
优化终止:更改最佳函数值小于options.functiontolerance。
fprintf('找到的最佳函数值是:%g\n', fval);
得到的最佳函数值为1.99203
而且,
[x,fval] = simulannealbnd(OperateFunction,初始点,LB,UB,选项);
优化终止:更改最佳函数值小于options.functiontolerance。
fprintf('找到的最佳函数值是:%g\n', fval);
找到的最佳功能值为:10.7632
在前两次运行中simulannealbnd
给出不同的结果。
如果在求解器运行之间使用返回的信息重置随机数生成器的状态,就可以重现我们的结果simulannealbnd
.simulannealbnd
返回当时的随机数发生器的状态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(OperateFunction,初始点,LB,UB,选项);
优化终止:更改最佳函数值小于options.functiontolerance。
fprintf('找到的最佳函数值是:%g\n', fval);
得到的最佳函数值为20.1535
simulannealbnd
使用六种不同的标准来确定何时停止求解器。simulannealbnd
在超过最大迭代或函数评估时停止;默认情况下,最大迭代次数设置为inf,最大函数评估数是3000 * numberofvariables.
.simulannealbnd
跟踪的函数值的平均变化MaxStallIterations
迭代。如果平均变化小于功能公差,FunctionTolerance
,算法就会停止。当目标函数值达到时,求解器也将停止ObjectiveLimit
.最后,解算器将在跑完for后停止MaxTime
秒。这里我们设置FunctionTolerance
1 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