这个例子展示了如何创建和管理模拟退火函数的选项simulannealbnd
使用optimoptions
在全局优化工具箱中。
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,output] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流('迭代次数为:%d\n', output.iterations);
迭代次数为:1095
流(函数计算的次数为:%d\n, output.funccount);
功能评估次数:1104次
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为2.98211
请注意,当您运行这个示例时,您的结果可能与上面所示的结果不同,因为模拟退火算法使用随机数来生成点。
simulannealbnd
可以通过“options”参数接受一个或多个plot函数。此特性对于在运行时可视化求解器的性能非常有用。图功能选用optimoptions
.工具箱包含一组可供选择的绘图函数,或者您可以提供自己的自定义绘图函数。
若要选择多个绘图功能,请设置PlotFcn
选项,通过optimoptions
函数。对于本例,我们选择saplotbestf
,它在每次迭代时绘制最佳函数值,saplottemperature
,表示每次迭代时各维度的当前温度,saplotf
,其中显示了当前函数值(请记住,当前值不一定是最好的),和saplotstopping
,其中绘制了每10次迭代满足停止条件的百分比。
选项= optimoptions(@simulannealbnd,...“PlotFcn”, {@saplotbestf、@saplottemperature @saplotf, @saplotstopping});
运行求解器。
simulannealbnd (ObjectiveFunction startingPoint,磅,乌兰巴托,选项);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
模拟退火中使用的温度参数控制整体搜索结果。每个维度的温度用于限制该维度中的搜索范围。工具箱允许您指定初始温度以及在求解过程中更新温度的方法。两个与温度相关的选项是InitialTemperature
和TemperatureFcn
.
指定初始温度
每个维度的默认初始温度设置为100。如果你想让初始温度在不同维度上是不同的,那么你必须指定一个温度向量。当问题在每个维度上的规模不同时,这可能是必要的。例如,
选项= optimoptions(@simulannealbnd,“InitialTemperature”, 50 [300]);
InitialTemperature
可以设置一个长度小于向量数的变量(维数);求解器通过取初始温度向量的最后一个元素,将向量扩展到其余维度。这里我们希望初始温度在所有维度上都是相同的,所以我们只需要指定单个温度。
选项。InitialTemperature = 100;
指定温度函数
所使用的默认温度函数simulannealbnd
被称为temperatureexp
.在temperatureexp调度中,任何给定步骤的温度都是前一步温度的.95倍。这导致温度开始缓慢下降,但最终比其他方案更快地降低。如果需要另一种方案,例如玻尔兹曼计划或“快速”计划退火,则temperatureboltz
或temperaturefast
可分别使用。要选择快速温度计划,我们可以更新之前创建的选项,更改TemperatureFcn
直接。
选项。TemperatureFcn = @temperaturefast;
指定再次退火
再退火是退火工艺的一部分。在接受了一定数量的新点之后,温度被提高到一个更高的值,希望重新开始搜索并移出局部最小值。过早执行重退火可能无助于求解器识别最小值,因此相对较高的间隔是一个不错的选择。属性可以设置重新退火发生的间隔时间ReannealInterval
选择。在这里,我们将默认的重新退火间隔减少到50,因为函数在许多区域似乎是平坦的,求解器可能会很快卡住。
选项。ReannealInterval = 50;
现在我们已经设置了新的温度选项,我们再次运行求解器
[x,fval,exitFlag,output] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流('迭代次数为:%d\n', output.iterations);
迭代次数为:1306
流(函数计算的次数为:%d\n, output.funccount);
功能评估的数量为:1321
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为:16.4409
simulannealbnd
是一种非确定性算法。这意味着在不更改任何设置的情况下多次运行求解器可能会得到不同的结果。这是因为simulannealbnd
在生成后续点和确定是否接受新点时使用MATLAB®随机数生成器。每次生成随机数时,随机数生成器的状态都会发生变化。
为了看到这一点,跑了两趟simulannealbnd
解算器收益率:
[x,fval] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为1.99203
而且,
[x,fval] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为10.7632
在前两次运行中simulannealbnd
给出不同的结果。
通过返回的信息,在求解器运行之间重置随机数生成器的状态,就可以重新生成结果simulannealbnd
.simulannealbnd
返回随机数生成器当时的状态simulannealbnd
在输出参数中调用。此信息可用于重置状态。在这里,我们使用此输出信息重置运行之间的状态,以便接下来两次运行的结果相同。
[x,fval,exitFlag,output] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为:20.1535
我们重置随机数生成器的状态。
strm = RandStream.getGlobalStream;strm。State = output.rngstate.State;
现在,让我们跑吧simulannealbnd
一次。
[x,fval] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为:20.1535
simulannealbnd
使用六种不同的标准来确定何时停止求解器。simulannealbnd
当超过最大迭代数或函数求值时停止;默认情况下,最大迭代次数设置为Inf,函数计算的最大次数为3000 * numberOfVariables
.simulannealbnd
跟踪函数值的平均变化MaxStallIterations
迭代。如果平均变化小于函数容差,FunctionTolerance
,则算法将停止。当目标函数值达到时,求解器也会停止ObjectiveLimit
.最后求解器将在运行后停止MaxTime
秒。这里我们设置了FunctionTolerance
1 e-5。
选项。FunctionTolerance = 1e-5;
运行simulannealbnd
解算器。
[x,fval,exitFlag,output] = simulannealbnd(objecvefunction,startingPoint,lb,ub,options);
优化终止:最佳函数值的更改小于options.FunctionTolerance。
流('迭代次数为:%d\n', output.iterations);
迭代次数为:1843
流(函数计算的次数为:%d\n, output.funccount);
函数评估的数量为:1864
流(发现的最佳函数值为:%g\n, fval);
最佳函数值为:6.90334