这一篇文章,我们将会讲一下在mathematica中实现模拟退火法的方式。
其实,在mathmatica中最优化算法里是内置了模拟退火法的,我们可以看下面的例子。
NMinimize[{100 (y - x^2)^2 + (1 - x)^2, -2.084 <= x <= 2.084 && -2.084 <= y <= 2.084}, {x, y}, Method -> "SimulatedAnnealing"]
>> {0,{x->1,y->1}}
在上面指定Method -> "SimulatedAnnealing"就是使用模拟退火法。
那么,为什么我还要来讲使用mathematica来进行模拟退火法呢,其实我是想利用这个例子来说明一下如何写mathematica的函数包,及mathematica的函数包如何使用,好了,下面开始吧。
哦,还有个事情,就是如果想看mathematica数值非线性最优化全局最优解,可以在帮助文档中搜索:tutorial/ConstrainedOptimizationGlobalNumerical
文章目录(Table of Contents)
模拟退火法例子
BeginPackage["tuihuoLXS`"]
tuihuoLXS::usage = "tuihuoLXS[一组位置坐标]将给出经退火算法优化后的结果,起始概率默认为0.8,可用setInitial设定;停止概率默认为0.2,可通过setEnd设定;每次退火的大小默认为.01,可用setStep设定";
setInitial::usage ="setInitial[初始概率],如setInitial[.8]";
setEnd::usage = "setEnd[停止概率]";
setStep::usage = "setEnd[退火步数]";
evaluationFunction::usage="评估函数,即测试总距离"
Begin["`Private`"]
Ncity;(*城市个数*)
step=.01;
Tstart=.8;(*初始温度*)
Tend=.2;(*停止温度*)
setInitial[n_/;0<n<1]:=Tstart=n;(*设置初始概率*)
setEnd[n_/;0<n<1]:=Tend=n;
setStep[n_/;0<n<1]:=step=n;(*设置步数*)
acceptQ:=RandomChoice[{initialT,1}->{True,False}];(*是否接受当前结果*)
evaluationFunction[list_]:=
Total[EuclideanDistance@@@Partition[list,2,1]];(*计算某条路线的总距离*)
newRoute[list_]:=
ReplacePart[list,{#1->list[[#2]],#2->list[[#1]]}&@@RandomSample[Range[Ncity],2]];
mainfunction[list_]:=
(
routeNew=newRoute[list];
{old,new}=evaluationFunction/@{list,routeNew};
If[new < old, routeNew,If[acceptQ,initialT=initialT-step;routeNew,list]]
);(*迭代函数*)
tuihuoLXS[initialList_]/;MatrixQ[initialList]&&And@@(NumberQ/@Flatten[initialList]):=
(
initialT = (Tstart&)[];
Ncity = Length@initialList;
Nlist = N[initialList];
NestWhile[mainfunction,Nlist,(#;initialT>Tend)&]
);(*主函数*)
End[]
EndPackage[]
函数包编写
我们可以看到上面函数包的编写需要使用BeginPackage["tuihuoLXS"]开头,EndPackage[]结尾,中间为了使变量私有化,需要有Begin["
Private`"]和End[]
第二个地方,我们可以看到最上面有setEnd::usage='',那么其实是为了写函数的说明的。我们下面可以看一下函数包的使用说明。
函数包的使用方式
就直接看下面的图片了。
我们通过Names["tuihuoLXS`*"]查看函数包里所有的函数
通过?函数名来查看函数的使用方法
以上,就是使用了模拟退火法的例子,来说明了在mathematica中如何编写函数包和使用函数包。
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论