! 该文件是Corana等人模拟退火算法的一个示例! 用于实现和修改的多模态稳健优化! 戈菲、费里尔和罗杰斯。计算上面的行! 摘要为1,例程本身(SA)及其补充! 例程,位于第232-990行。Judge等人的一个多模态示例。! (FCN)位于线路150-231上。这个文件的其余部分(第1-149行)是一个! 具有适用于Judge示例的值的驱动程序例程。因此,这! 示例已准备好运行。! 为了理解算法,第236行SA的文档-! 484应该与论文中描述的部分一起阅读! 模拟退火。然后,下面的行将帮助用户! 精通模拟退火的实现。! 学习使用SA:根据以下建议使用Judge中的示例函数! 了解SA的工作原理。当你这样做的时候,你应该! 准备好使用它在大多数功能与相当数量的专业知识。! 1.按原样运行程序,确保其运行正常。看一看! 中间输出,并查看其如何随温度优化! (T) 跌倒。注意如何达到最佳点以及如何! 降低T降低VM。! 2.仔细查看SA的文档,以便! 有点道理。根据报纸,它应该不会那么难! 找出答案。第68-70页描述了算法的核心! 以及第94-95页。另见Corana等人,第264-9页。! 3.了解它如何选择积分并决定上坡和! 下坡移动,设置IPRINT=3(非常详细的中间输出)! MAXEVL=100(只有100个函数求值来限制输出)。! 4.要了解不同温度的重要性,请尝试启动! 一个非常低的值(比如T=10E-5)。你会发现它永远不会! 脱离局部最优(在退火术语中,它! 淬火)&(ii)步长(VM)将非常小。这个! 是算法的关键部分:随着温度(T)的下降,步进长度也一样。在这里的一个小问题中,请注意VM是如何快速! 从初始值重置。因此,输入VM不是很! 重要。这就是在! 算法正在进行中。! 5.查看不同参数的效果及其对! 算法的速度,尝试RT=.95&RT=.1。请注意! 大大不同的优化速度。同时尝试NT=20。注释! 这个示例函数很容易优化,因此它将! 容忍这些参数的重大变化。RT和NT是! 应该调整参数以修改! 算法及其鲁棒性。! 6.尝试使用LB或UB约束算法。模拟模块_内部! 摘要:! 模拟退火是一种全局优化方法! 在不同的局部最优值之间。从初始点开始! 算法进行了一步,并对函数进行了评估。当最小化! 函数,则接受任何下坡步骤,并从此处重复该过程! 新观点。可以接受上坡台阶。因此,它可以逃离本地! 奥蒂玛。这个艰难的决定是根据大都会标准做出的! 优化过程继续进行,步长下降! 算法接近全局最优。由于算法使关于要优化的功能的假设很少! 对非二次曲面的鲁棒性。稳健性程度! 可以由用户调整。事实上,模拟退火可以用作用于复杂函数的本地优化器。! 模拟退火的这种实现被用于“全局优化”! 模拟退火统计函数,“Goffe,Ferrier和! 罗杰斯,《计量经济学杂志》,第60卷,第1/2期,1994年1月/2月,pp。! 65-100. 简单地说,我们发现它即使不优于多个! 针对困难的优化重新启动传统优化例程! 问题。! 有关此例程的更多信息,请联系其作者:! 比尔·戈夫,bgofe@whale.st.usm.edu! Fortran 90中的这个版本是由Alan Miller编写的。! 它与Lahey的ELF90编译器兼容。! 注意:最后三个参数已从子程序sa中删除! 是工作数组,现在是例程的内部。! 电子邮件:amiller@bigpond.net.au! 网址:http://users.bigpond.net.au/amiller网站! Fortran 90最新版本-1997年8月3日隐含无整数,参数::dp=SELECTED_REAL_KIND(14,60)! 以下变量位于COMMON/raset1中/真实,保存::u(97),抄送,光盘,厘米整数,保存::i97,j97包含子程序sa(n,x,max,rt,eps,ns,nt,棉结,maxevl,lb,ub,c,iprint&iseed1、iseed2、t、vm、xopt、fopt、nacc、nfcnev、nobds、ier)! 版本:3.2! 日期:1994年1月22日。! 与2.0版相比的差异:! 1.如果试验超出界限,则随机选择一个点! 从LB(i)到UB(i。与2.0版不同,此试用版是! 评估并计入验收和拒收。! 所有相应的文档也已更改。! 与3.0版相比的差异:! 1.如果VM(i)>(UB(i)-LB(i)),则VM设置为UB(i)-LB。! 想法是,如果T相对于LB&UB较高,大多数! 分数将被接受,导致VM上升。但是,在这个! 在这种情况下,VM没有什么意义;特别是如果VM! 大于可接受区域。将VM设置为此大小! 仍然允许选择允许区域的所有部分。! 与3.1版相比的差异:! 1.测试初始温度是否为正。! 2.精心编写语句。! 3.参考文件更新。! 简介:! 此例程实现连续模拟退火全局! Corana等人的文章“最小化”中描述的优化算法! 具有“模拟退火”的连续变量的多模态函数! 算法”(第13卷,第3期,第262-280页)! ACM数学软件交易。! 快速(也许太快)概述SA:! SA试图找到N维函数的全局最优解。! 它同时向上和向下移动,并作为优化过程! 继续,它专注于最有希望的领域。! 首先,它在步长范围内随机选择一个试验点! VM(长度为N的向量)。这个! 在此试验点评估功能并比较其值! 到初始点的值。! 在最大化问题中,接受所有上坡移动! 算法从试验点继续。下坡运动可能! 认可的;这个决定是根据大都会标准做出的。它使用T! (温度)和下坡运动的概率大小! 方式。T越小,下坡动作越大! 此举可能会被接受。如果试验被接受! 算法从这一点出发。如果被拒绝,另一分! 而是选择进行试验评估。! VM的每个元素都会定期调整! 接受该方向的功能评估。! T的下降通过以下方式施加到具有RT变量的系统上! T(i+1)=RT*T(i),其中i是第i次迭代。因此,当T下降时,! 下坡动作不太可能被接受! 拒绝率上升。考虑到虚拟机的选择方案,虚拟机失败了。! 因此,随着T下降,VM下降,SA关注最有希望的! 优化区域。! 参数T的重要性:! 参数T对于成功使用SA至关重要。它会影响! VM,算法搜索最优值的步长。对于! 初始T小,步长可能太小;因此还不够! 可以计算函数的全局最优值。用户! 应仔细检查中间输出中的VM(设置IPRINT=! 1) 以确保VM是适当的。The relationship between the! 初始温度和产生的步长是函数! 依赖。! 确定符合以下条件的起始温度! 优化一个函数,首先进行试运行是值得的。设置! RT=1.5和T=1.0。当RT>1.0时,温度升高,VM! 也会上升。然后选择产生足够大VM的T。! 对于算法的修改及其使用的许多细节,! (尤其是计量经济学应用)参见Goffe,Ferrier! 和罗杰斯,“统计函数的全局优化! 模拟退火”,《计量经济学杂志》,第60卷,第1/2期,! 1994年1月/2月,第65-100页。! 有关更多信息,请联系! 比尔·戈菲! 经济与国际商务系! 美国南密西西比大学! 哈蒂斯堡,MS 39506-5072(601)266-4484(办公室)! (601)266-4920(传真)! bgofe@whale.st.usm.edu(互联网)! 这里的参数尽可能与中的参数同名! Corana等人在第266-8页对算法的描述。! 在本说明中,SP为单精度,DP为双精度,! INT是整数,L是逻辑值,(N)表示长度为N的数组。! 因此,DP(N)表示长度N的双精度数组。! 输入参数:! 注:建议值通常来自Corana等人。To大幅减少运行时间,见Goffe等人,第90-1页! 关于选择适当RT和NT的建议。! N-要优化的函数中的变量数。(内景)! X-函数变量的起始值! 优化。(DP(N))! MAX-表示函数应该最大化还是最小化。! 真值表示最大化,而假值表示! 最小化。中间输出(参见IPRINT)将此纳入! 账户。(左)! RT-温度折减系数。建议的值! Corana等人的数据为0.85。更多建议见Goffe等人。(DP)! EPS-终止误差容限。如果最终功能最后一个棉结温度的值与! 当前温度下的相应值小于! EPS和当前温度下的最终功能值! 与当前最佳功能值相差小于! EPS,执行终止,返回IER=0。(EP)! NS—循环数。NS*N功能评估后! 调整VM,使所有功能评估的大约一半! 被接受。建议值为20。(内景)! NT—降温前的迭代次数。之后! NT*NS*N功能评估,温度(T)改变Corana等人建议的RT.值为! 最大值(100,5*N)。更多建议请参见Goffe等人。(内景)! NEPS-用于决定术语的最终函数值的数量-! 国家。参见EPS。建议值为4。(内景)! MAXEVL-函数求值的最大数目。如果是的话! 超过,IER=1。(内景)! LB-允许的解决方案变量的下限。(DP(N))! UB-允许的解决方案变量的上限。(DP(N))! 如果算法选择X(I)。LT.LB(I)或X(I)。GT.UB(I),! I=1,N,从内部随机选择一个点。这个! 这将算法集中于UB和LB内的区域。! 除非用户希望将搜索集中到特定区域、UB和LB应设置为非常大的正值! 和负值。请注意! 向量X应该在这个区域内。还要注意LB和UB固定在位置上,而VM以最后一个为中心! 接受的优化函数的变量测试集。! C-控制步长调整的矢量。建议的! 所有元素的值都是2.0。(DP(N))! IPRINT-控制SA内的打印。(INT)! 值:0-未打印任何内容。! 1-起始值的函数值和! 每个温度前的汇总结果! 减少。这包括最佳! 到目前为止找到的函数值,总计! 移动次数(分为上坡、,! 下坡,接受和拒绝)! 越界测试次数! 在此找到的新optima数! 温度,电流最佳X和步长VM。请注意,有! 每次之前的N*NS*NT功能评估! 温度降低。最后,通知是在实现终止时也会给出! 标准。! 2-每个新步长(VM),当前最佳! X(XOPT)和当前试验X(X)。这个! 让用户了解X轴的距离! 偏离XOPT以及VM如何适应! 到函数。! 3-每个功能评估、验收或! 拒绝和新优化。对于许多问题,! 这个选项可能需要一棵小树! 如果使用硬拷贝。这个选项是最好的! 用于学习算法。一个小的! 因此,当! 使用IPRINT=3。! 建议值:1! 注:对于给定的IPRINT值,较低的值! 使用选项(0除外)。! ISEED1-随机数生成器RANMAR的第一个种子。! 0≤ISEED1≤31328。(整数)! ISEED2-随机数生成器RANMAR的第二个种子。! 0≤ISEED2≤30081。ISEED1的不同值! ISEED2将导致一个完全不同的序列! 下坡动作的测试点和决定(当! 最大化)。参见Goffe等人如何使用! 测试SA的结果。(INT)! 输入/输出参数:! T-输入时,初始温度。参见Goffe等人的建议。输出时为最终温度。(DP)! VM-步长向量。在输入方面,它应该包括以下区域! 给定起始值X的利息。对于点X(I),下一个! 选择的试验点是从X(I)-VM(I)到X(I)+VM(I)。! 由于VM进行了调整,因此接受了大约一半的分数,! 输入值不是很重要(即该值为关,SA将VM调整为正确的值)。(DP(N))! 输出参数:! XOPT-优化函数的变量。(DP(N))! FOPT-函数的最佳值。(DP)! NACC-可接受的功能评估的数量。(内景)! NFCNEV-功能评估的总数。在未成年人中! 点,请注意第一个求值在! 算法核心;它只是初始化! 算法。(内景)。! NOBDS-试验功能评估总数! 会超出LB和UB的范围。请注意! 在LB和UB之间随机选择一个试验点。(整数)! IER-错误返回编号。(内景)! 值:0-正常返回;达到终止标准。! 1-功能评估数量(NFCNEV)为! 大于最大值(MAXEVL)。! 2-起始值(X)不在! 边界(LB和UB)。! 3-初始温度不是正值。! 99-不应被看到;仅在内部使用。! 必须在调用例程中确定维度的工作数组:! RWK1(DP(NEPS))(南非FSTAR)! RWK2(DP(N))(XP“”)! IWK(国际(N))(NACP“”)! 注意:在Fortran 90版本中,这些是自动数组。! 所需功能(包括):! EXPREP-替换函数EXP以避免不足和溢出。! 对于非IBM-型主管道,可能需要对其进行修改-! 框架。(DP)! RMARIN-初始化随机数生成器RANMAR。! RANMAR-实际的随机数生成器。请注意! RMARIN必须首先运行(SA执行此操作)。它产生均匀的[0,1]上的随机数。这些例程来自! Usenet的comp.lang.fortran。有关参考,请参阅! “走向通用随机数生成器”! 乔治·马尔萨格里亚(George Marsaglia)和阿里夫·扎曼(Arif Zaman),佛罗里达州! 大学报告:FSU-SCRI-87-50(1987)。! 它后来被F.James修改并发表在! 《伪随机数生成器综述》! 更多信息,联系stuart@ads.com。这些! 例程被设计为可在任何机器上移植! 尾数为24位或更多。我发现它产生了! IBM 3081和Cray Y-MP上的结果相同。! 所需子程序(包括):! PRTVEC-打印矢量。! PRT1。。。PRT10-打印中间输出。! FCN-要优化的功能。表格是! 子程序FCN(N,X,F)! 隐含无! 整数,参数::dp=SELECTED_REAL_KIND(14,60)! 整数,意图(IN)::N! 真实(dp),意图(IN)::X(N)! 真实(dp),意图(OUT)::F! ...! F=F(X)的功能代码! ...! 返回结束! 注:这与多变量中使用的形式相同! IMSL第10版库中的最小化算法。! 机器特定功能:! 1.如果在非IBM类型的main上使用,则可能需要修改EXPREP-! 框架。注意EXPREP中的不足和溢出。! 2.一些FORMAT语句使用G25.18;对于! 一些机器。! 3.RMARIN和RANMAR设计为便携式;他们不应该! 导致任何问题。! 键入所有外部变量。真实(dp),意图(IN)::lb(:),ub(:)实(dp),意图(输入输出)::x(:),t,vm(:)真实(dp),意图(OUT)::xopt(:),fopt整数,INTENT(IN)::n,ns,nt,neps,maxevl,iprint,ised1,ised2整数,INTENT(OUT)::nacc,nfcnev,nobds,ier逻辑,意图(IN)::最大! 键入所有内部变量。真实(dp)::f,fp,p,pp,比率,xp(n),fstar(neps)整数::nup,ndown,nrej,nnew,lnobds,h,i,j,m,nacp(n)逻辑::退出接口子程序fcn(n,θ,h)隐含无整数,参数::dp=SELECTED_REAL_KIND(14,60)整数,意图(IN)::n真实(dp),意图(IN)::θ(:)真实(dp),意图(OUT)::h结束子例程fcn端部接口! 初始化随机数生成器RANMAR。呼叫rmarin(ised1,ised2)! 设置初始值。nacc=0nobds=0nfcnev=0ier=99DO i=1,nxopt(i)=x(i)nacp(i)=0结束DOfstar=1.0D+20! 如果初始温度不是正值,则通知用户并! 返回到调用例程。如果(t<=0.0),则写入(*,'(/,“初始温度不是正值。”/&&“重置变量t”/)')ier=3返回结束IF! 如果初始值超出范围,请通知用户并返回! 调用例程。DO i=1,nIF((x(i)>ub(i))。或者。(x(i)<lb(i)))然后调用prt1()ier=2返回结束IF结束DO! 使用输入X计算函数,返回值为F。调用fcn(n,x,f)! 如果要最小化该功能,请切换该功能的符号。! 请注意,所有中间和最终输出都会切换回符号! 为用户消除任何可能的混淆。如果(.NOT.max)f=-fnfcnev=nfcnev+1fopt=ffstar(1)=f如果(iprint>=1)调用prt2(max,n,x,f)! 启动主回路。注意,如果(i)算法! 成功地优化了功能或(ii)功能太多! 功能评估(大于MAXEVL)。100 nup=0nrej=0新宽度=0向下=0lnobds=0DO m=1,ntDO j=1,纳秒溶解氧h=1,n! 生成XP,X的试用值。注意使用VM选择XP。DO i=1,n如果(i==h),则xp(i)=x(i)+(ranmar()*2.-1.)*vm(i)ELSE公司xp(i)=x(i)结束IF! 如果XP超出界限,请选择一个界限内的点进行试用。IF((xp(i)<lb(i))。或者。(xp(i)>ub(ixp(i)=磅(i)+(ub(i)-lb(i))*ranmar()lnobds=lnobds+1nobds=nobds+1如果(i打印>=3)调用prt3(max,n,xp,x,f)结束IF结束DO! 使用试验点XP评估功能,并返回FP。调用fcn(n,xp,fp)IF(.NOT.max)fp=-fpnfcnev=nfcnev+1如果(iprint>=3)调用prt4(max,n,xp,x,fp,f)! 如果发生过多的函数求值,请终止算法。如果(nfcnev>=maxevl)则调用prt5()IF(.NOT.max)fopt=-foptier=1返回结束IF! 如果功能值增加,则接受新点。如果(fp>=f)则如果(i打印>=3),则写入(*,'(“接受点”)')结束IFx(1:n)=xp(1:1n)f=fpnacc=nacc+1nacp(h)=钠化钠(h)+1nup=nup+1! 如果大于任何其他点,则记录为新的最佳值。如果(fp>fopt)则如果(i打印>=3),则写入(*,'(“新优化”)')结束IFxopt(1:n)=xp(1:1n)fopt=fpnew=新建+1结束IF! 如果得分较低,则使用大都会标准来决定! 接受或拒绝。ELSE公司p=表达式((fp-f)/t)pp=兰玛()如果(pp<p)那么如果(iprint>=3)呼叫prt6(最大值)x(1:n)=xp(1:1n)f=fpnacc=nacc+1nacp(h)=钠化钠(h)+1ndown=ndown+1ELSE公司nrej=nrej+1如果(iprint>=3)呼叫prt7(最大值)结束IF结束IF结束DO结束DO! 调整VM,以便接受大约一半的评估。DO i=1,n比率=DBLE(nacp(i))/DBLE(ns)如果(比率>.6),则vm(i)=vm(i)*(1.+c(i)*(比率-.6)/.4)ELSE如果(比率<.4)则vm(i)=vm(i)/(1.+c(i)*((.4-比率)/.4))结束IF如果(vm(i)>(ub(ivm(i)=ub(i)-lb(i)结束IF结束DO如果(i打印>=2),则调用prt8(n,vm,xopt,x)结束IFnacp(1:n)=0结束DO如果(i打印>=1)则调用prt9(最大、n、t、xopt、vm、fopt、nup、ndown、nrej、lnobds、nnew)结束IF! 检查终止标准。quit=.false。fstar(1)=fIF((fopt-fstar(1))<=eps)quit=.true。DO i=1,棉结IF(ABS(f-fstar(i))>eps)quit=.false。结束DO! 适当时终止SA。如果(退出)那么x(1:n)=xopt(1:1n)ier=0如果(.NOT.max)fopt=-fopt如果(iprint>=1)调用prt10()返回结束IF! 如果不符合终止标准,则准备另一个回路。t=rt*tDO i=棉结,2,-1fstar(i)=fstar(i-1)结束DOf=foptx(1:n)=xopt(1:1n)! 再次循环。转到100结束子例程sa函数表达式(rdum)结果(fn_val)! 此函数替换exp以避免不足和溢出! 专为IBM 370型机器设计。可能需要修改! 它适用于其他机器。注意! EXPREP对算法没有影响。真实(dp),意图(IN)::rdum真实(dp)::fn_val如果(rdum>174.dp)则fn_val=3.69D+75ELSE如果(rdum<-180.+dp),则fn_val=0.0_dpELSE公司fn_val=经验(rdum)结束IF返回END FUNCTION表达式亚常规rmarin(ij,kl)! 此子例程和下一个函数生成随机数。请参见! SA的评论以了解更多信息。唯一不同于! 原始代码是(1)确保RMARIN首先运行的测试! 因为SA确保已完成此操作(此测试没有! 在IBM的VS Fortran下编译)和(2)将ivec键入为integer! 因为没有使用ivec。除了这些例外情况,以下都是! 线条是原始的。! 这是随机数生成器的初始化例程! RANMAR()公司! 注:种子变量的值可以介于:0<=IJ<=31328! 0<=KL<=30081整数,意向(IN):ij,kl整数::i,j,k,l,ii,jj,m真实::s,t如果(ij<0.或.ij>31328.或.kl<0.或.kl>30081),则写入(*,'(A)')'第一个随机数种子必须有值'&'介于0和31328'写入(*,“(A)”)“第二个种子的值必须介于0和30081之间”停止结束IFi=国防部(ij/177177)+2j=MOD(ij,177)+2k=MOD(kl/169178)+1l=模量(kl,169)DO ii=1,97s=0.0t=0.5DO jj=1,24m=国防部(国防部(i*j,179)*k,179)i=jj=kk=米l=国防部(53*l+1169)如果(MOD(l*m,64)>=32)则s=s+t结束IFt=0.5*t结束DOu(ii)=s结束DO立方厘米=362436.0/16777216.0cd=7654321.0/16777216.0厘米=16777213.0/16777216.0i97=97j97=33返回结束子例程rmarin函数ranmar()结果(fn_val)真实::fn_val! 局部变量真实::uniuni=u(i97)-u(j97)IF(uni<0.0)uni=uni+1.0u(i97)=unii97=i97-1如果(i97==0)i97=97j97=j97-1如果(j97==0)j97=97cc=cc-cdIF(cc<0.0)cc=cc+cmuni=uni-ccIF(uni<0.0)uni=uni+1.0fn_val=单一返回结束功能ranmar子程序prt1()! 该子程序打印中间输出,PRT2到! PRT10.注意,如果SA将函数最小化! 功能值和方向(向上/向下)全部颠倒! 输出与实际功能优化相对应。这个! 更正是因为SA的编写是为了最大化功能和! 它通过最大化负a函数来最小化。写入(*,'(/,“起始值(X)超出界限”/&&“(lb AND ub).执行终止,没有任何”/&&“optimization.respecify x,ub OR lb,以便”/&&“磅(i)<x(i)<ub(i),i=1,n.”/)')返回结束子例程prt1子程序prt2(max,n,x,f)真实(dp),意图(IN)::x(:),f整数,意图(IN)::n逻辑,意图(IN)::最大写入(*,'(“”)')呼叫prtvec(x,n,‘初始x’)如果(最大值)那么写入(*,'(“首字母F:”,/,G25.18)')FELSE公司写入(*,'(“初始F:”,/,G25.18)')-F结束IF返回结束子例程prt2子程序prt3(max,n,xp,x,f)真实(dp),意图(IN)::xp(:),x(:)整数,意图(IN)::n逻辑,意图(IN)::最大写入(*,'(“”)')呼叫prtvec(x,n,‘当前x’)如果(最大值)那么写入(*,'(“当前F:”,G25.18)')FELSE公司写入(*,'(“当前F:”,G25.18)')-F结束IF调用prtvec(xp,n,'TRIAL X')写入(*,'(“超出界限后拒绝的点”)')返回结束子例程prt3子程序prt4(max,n,xp,x,fp,f)实数(dp),实数(IN)::xp(:),x(:)整数,意图(IN)::n逻辑,意图(IN)::最大写入(*,'(“”)')呼叫prtvec(x,n,‘当前x’)如果(最大值)那么写入(*,'(“当前F:”,G25.18)')F呼叫prtvec(xp,n,'TRIAL X')写入(*,'(“结果F:”,G25.18)')fpELSE公司写入(*,'(“当前F:”,G25.18)')-F呼叫prtvec(xp,n,'TRIAL X')写入(*,'(“结果F:”,G25.18)')-fp结束IF返回结束子例程prt4子程序prt5()写入(*,'(/,“太多功能评估;考虑”/&&“增加maxevl或eps,或减少”/&&“nt OR rt.这些结果可能是”/“poor.”,/)')返回结束子例程prt5子程序prt6(最大值)逻辑,意图(IN)::最大如果(最大值)那么写下(*,'(“虽然较低,但可以接受点”)')ELSE公司写下(*,'(“虽然更高,但可以接受分数”)')结束IF返回结束子例程prt6子程序prt7(最大值)逻辑,意图(IN)::最大如果(最大值)那么写入(*,'(“下限被拒绝”)')其他写入(*,'(“拒绝高点”)')结束IF返回结束子例程prt7子程序prt8(n,vm,xopt,x)实数(dp)、实数(IN)::vm(:)、xopt(:)和x(:)整数,意图(IN)::n写入(*,'(/,“步长调整后的中间结果”,/)')调用prtvec(vm,n,‘新步长(vm)’)呼叫prtvec(xopt,n,‘当前最佳X’)呼叫prtvec(x,n,‘当前x’)写入(*,'(“”)')返回结束子例程prt8子程序prt9(max,n,t,xopt,vm,fopt,nup,ndown,nrej,lnobds,neww)实数(dp)、实数(IN)::xopt(:)、vm(:),t、fopt整数,INTENT(IN)::n,nup,ndown,nrej,lnobds,new逻辑,意图(IN)::最大! 局部变量整数::totmovtotmov=nup+ndown+nrej写入(*,'(/,“下次降温前的中间结果”,/)')写入(*,'(“当前温度:”,G12.5)')t如果(最大值)那么写入(*,'(“迄今为止最大功能值:”,G25.18)')fopt写入(*,'(“总移动数:”,I8)')totmov写入(*,'(“爬坡:”,I8)')nup写入(*,'(“接受下坡:”,I8)')下坡写入(*,'(“拒绝下坡:”,I8)')nrej写入(*,'(“越界试验:”,I8)')lnobds写入(*,'(“新最高温度:”,I8)')新ELSE公司写入(*,'(“迄今为止的最小功能值:”,G25.18)')-fopt写入(*,'(“总移动数:”,I8)')totmov写入(*,'(“下坡:”,I8)')nup写入(*,'(“已接受爬坡:”,I8)')向下写入(*,'(“拒绝爬坡:”,I8)')nrej写入(*,'(“试验越界:”,I8)')lnobds写下(*,'(“新最低温度:”,I8)')新结束IF呼叫prtvec(xopt,n,‘当前最佳X’)调用prtvec(vm,n,‘步长(vm)’)写入(*,'(“”)')返回结束子例程prt9子程序prt10()写入(*,'(/,“SA达到终止标准.IER=0.”,/)')返回结束子例程prt10子程序prtvec(vector,ncols,name)! 此子程序打印名为vector的双精度矢量。! 将打印要素1至NCOLS。NAME是字符变量! 描述向量的。请注意,如果在呼叫中指定了NAME! PRTVEC,必须用引号括起来。如果超过10个! VECTOR中的元素,每行将打印10个元素。整数,意图(IN)::ncolsREAL(dp),INTENT(IN)::矢量(ncols)字符(长度=*),意图(IN)::name整数::i,行,ll写入(*,1001)名称如果(ncols>10)则线=INT(ncols/10.)DO i=1,行ll=10*(i-1)写入(*,1000)矢量(1+ll:10+ll)结束DO写入(*,1000)矢量(11+ll:ncols)ELSE公司写入(*,1000)矢量(1:ncols)结束IF1000格式(10(g12.5,''))1001格式(/,25(''),a)返回结束子例程prtvec模拟终端模块_内部程序simann使用模拟_内部隐含无整数,参数::n=2,棉结=4实型(dp)::lb(n),ub(n)整数::ns,nt,nfcnev,ier,iseed1,iseed 2,i,maxevl,iprint&nacc,诺贝尔奖逻辑::最大! 在IBM大型机上将下溢设置为零。! 呼叫XUFLOW(0)! 设置输入参数。max=.false。每股收益=1.0D-6rt=.5iseed1=1iseed2=2ns=20nt=5最大值=100000i打印=1DO i=1,n磅(i)=-1.0D25ub(i)=1.0D25c(i)=2.0结束DO! 注意从Judge函数的局部优化开始,而不是全局优化。x(1)=2.354471x(2)=-0.319186! 设置输入/输出参数的输入值。t=5.0vm(1:n)=1.0写入(*,1000)n,max,t,rt,eps,ns,nt,neps,maxevl,iprint,iseed1,iseed调用prtvec(x,n,“起始值”)调用prtvec(vm,n,‘初始步长’)调用prtvec(lb,n,‘下限’)呼叫prtvec(ub,n,“上限”)呼叫prtvec(c,n,‘c矢量’)写入(*,'(/,“****驱动器例行输出结束****”/&&“调用sa.****之前的****”)调用sa(n,x,max,rt,eps,ns,nt,neps,maxevl,lb,ub,c,iprint,iseed1&iseed2、t、vm、xopt、fopt、nacc、nfcnev、nobds、ier)写入(*,'(/,“****SA****之后的结果”)')致电prtvec(xopt,n,‘解决方案’)调用prtvec(vm,n,‘最后一步长度’)写入(*,1001)fopt,nfcnev,nacc,nobds,t,ier1000格式(/,'模拟退火示例',/,/&'参数数量:',i3,'最大化:',l5,/&“初始温度:”,g8.2,“RT:”,g8.2.,“EPS:”,g8.2,/&“NS:”,i3,“NT:”,i2,“NEPS:”,i2,/&“MAXEVL:”,i10,“IPRINT:”,“i1,”ISEED1:“,i4&“ISEED2:”,i4)1001格式(/,'最佳函数值:',g20.13&/,'功能评估数量:',i10&/,'接受的评估数量:',i10&/,'越界评估数:',i10&/,'最终温度:',g20.13,'IER:',i3)停止结束程序simann子程序fcn(n,θ,h)! 这个子程序来自Judge等人,the Theory and! 计量经济学实践,第二版,第956-7页。有两个优化:! F(.864,1.23)=16.0817(全局最小值),F(2.35,-.319)=20.9805。隐含无整数,参数::dp=SELECTED_REAL_KIND(14,60)整数,意图(IN)::n真实(dp),意图(IN)::θ(:)真实(dp),意图(OUT)::h! 局部变量整数::i真实(dp)::y(20)、x2(20)和x3(20)y(1)=4.284y(2)=4.149y(3)=3.877y(4)=0.533y(5)=2.211y(6)=2.389y(7)=2.145y(8)=3.231y(9)=1.998y(10)=1.379y(11)=2.106y(12)=1.428y(13)=1.011y(14)=2.179y(15)=2.858y(16)=1.388y(17)=1.651y(18)=1.593y(19)=1.046y(20)=2.152x2(1)=.286x2(2)=.973x2(3)=.384x2(4)=.276x2(5)=.973x2(6)=.543x2(7)=.957x2(8)=.948x2(9)=.543x2(10)=.797x2(11)=.936x2(12)=.889x2(13)=.006x2(14)=.828x2(15)=.399x2(16)=.617x2(17)=.939x2(18)=.784x2(19)=.072x2(20)=.889x3(1)=.645x3(2)=.585x3(3)=.310x3(4)=.058x3(5)=.455x3(6)=.779x3(7)=.259x3(8)=.202x3(9)=.028x3(10)=.099x3(11)=.142x3(12)=.296x3(13)=0.175x3(14)=.180x3(15)=.842x3(16)=.039x3(17)=.103x3(18)=.620x3(19)=.158x3(20)=.704h=0.0_dpDO i=1,20h=(θ(1)+θ(n)*x2(i)+(θ结束DO返回结束子例程fcn