C#数值计算之模拟退火法简介(二)

原创 2004年04月19日 00:01:00

在上一篇文章中讲述了模拟退火的基本原理,以下以一个实际的例子来说明,其中所有的源码已贴出,可以从中了解到很多细节。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


使用模拟退火法求函数f(x,y) = 5sin(xy) + x2 + y2的最小值

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />

 

解:根据题意,我们设计冷却表进度表为:

即初始温度为100

衰减参数为0.95

马可夫链长度为10000

Metropolis的步长为0.02

结束条件为根据上一个最优解与最新的一个最优解的之差小于某个容差。

 

 

使用METROPOLIS接受准则进行模拟, 程序如下

 

/*

 *  模拟退火法求函数f(x,y) = 5sin(xy) + x^2 + y^2的最小值

 *  日期:2004-4-16

 *  作者:ARMYLAU

* EMAIL:armylau2@163.com

 *  结束条件为两次最优解之差小于某小量

 */

using System;

namespace SimulateAnnealing

{

     class Class1

     {

          // 要求最优值的目标函数

         static double ObjectFunction( double x, double y )

         {

              double z = 0.0;

              z = 5.0 * Math.Sin(x*y) + x*x + y*y;

              return z;

         }

 

         [STAThread]

         static void <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Main(string[] args)

         {

              // 搜索的最大区间

              const double XMAX = 4;

              const double YMAX = 4;

                  

              // 冷却表参数

              int      MarkovLength = 10000;            // 马可夫链长度

              double   DecayScale = 0.95;               // 衰减参数

              double   StepFactor = 0.02;              // 步长因子

              double   Temperature = 100;          // 初始温度

              double   Tolerance = 1e-8;          // 容差

 

              double   PreX,NextX;                // prior and next value of x

              double   PreY,NextY;                // prior and next value of y

              double   PreBestX, PreBestY;        // 上一个最优解

              double   BestX,BestY;               // 最终解

              double   AcceptPoints = 0.0;         // Metropolis过程中总接受点

 

              Random rnd = new Random();           

 

              // 随机选点

              PreX = -XMAX * rnd.NextDouble() ;

              PreY = -YMAX * rnd.NextDouble();

              PreBestX = BestX = PreX;

              PreBestY = BestY = PreY;

                           

              // 每迭代一次退火一次(降温), 直到满足迭代条件为止

              do

              {

                   Temperature *=DecayScale;

                   AcceptPoints = 0.0;

 

                   // 在当前温度T下迭代loop(即MARKOV链长度)次

                   for (int i=0;i<MarkovLength;i++)

                   {

                       // 1) 在此点附近随机选下一点

                       do

                       {

                            NextX = PreX + StepFactor*XMAX*(rnd.NextDouble()-0.5);

                            NextY = PreY + StepFactor*YMAX*(rnd.NextDouble()-0.5);

                       }

                       while ( !(NextX >= -XMAX && NextX <= XMAX && NextY >= -YMAX && NextY <= YMAX) );

 

                       // 2) 是否全局最优解

                       if (ObjectFunction(BestX,BestY) > ObjectFunction(NextX,NextY))

                       {

                            // 保留上一个最优解

                            PreBestX =BestX;

                            PreBestY = BestY;

                            // 此为新的最优解

                            BestX=NextX;

                            BestY=NextY;

                       }

 

                       // 3) Metropolis过程

                       if( ObjectFunction(PreX,PreY) - ObjectFunction(NextX,NextY) > 0 )

                       {

                            // 接受, 此处lastPoint即下一个迭代的点以新接受的点开始

                            PreX=NextX;

                            PreY=NextY;

                            AcceptPoints++;

                                                       

                       }

                       else

                       {

                            double change = -1 * ( ObjectFunction(NextX,NextY) - ObjectFunction(PreX,PreY) ) / Temperature ;

                            if( Math.Exp(change) > rnd.NextDouble() )

                            {

                                 PreX=NextX;

                                 PreY=NextY;

                                 AcceptPoints++;

                            }

                            // 不接受, 保存原解

                       }

                   }

              Console.WriteLine("{0},{1},{2},{3}",PreX, PreY, ObjectFunction ( PreX, PreY ), Temperature);

 

              } while( Math.Abs( ObjectFunction( BestX,BestY) ObjectFunction (PreBestX, PreBestY)) > Tolerance );

 

              Console.WriteLine("最小值在点:{0},{1}",BestX, BestY);

              Console.WriteLine( "最小值为:{0}",ObjectFunction(BestX, BestY) );

         }

     }

}

 

l          结果:

最小值在点:-1.07678129318956,1.07669421564618

最小值为:-2.26401670947686

 

l          后记:

原来想写一系列的文章,介绍如何用C#解数值问题,这是因为在CSDN上很少有数值计算方面的文章,所以希望能有所补充。

         一开始在网上搜索模拟退火的资料并想作为C#数值计算的一个例子,找不到现成的源码。后来自己实验了很久,终于将此程序写出,不敢私藏,拿出来作用模拟退火或者用C#解数值算法问题的一个入门例子。

本文尽量避免太过学术化,如数学和物理名称和公式,仓促下笔,有很多地方可能讲得不是很清楚,希望各位体谅。任何问题或批评,可EMAIL与我:armylau2@163.com

另,模拟退火还可以应用到其它更多更复杂的问题,如“推销员问题”等组合优化问题。本例只是求一个二维函数的最小值问题,而且其冷却表参数的选择也过于简单,只能作用一个初步的入门简介,请读者注意。

 

 

l          参考文献:

1.   http://www.computer-dictionary-online.org/index.asp?q=simulated+annealing 计算机词典

2.   Numeric Recipes in C

3.   计算方法丛书  非数值并行算法  (第一册)  模拟退火算法

 

计算梯度的三种方法: 数值法,解析法,反向传播法

计算梯度的三种方法: 数值法,解析法,反向传播法
  • xuluhui123
  • xuluhui123
  • 2017年01月13日 13:18
  • 1731

集体智慧编程——优化搜索算法:爬山法,模拟退火算法,遗传算法-Python实现

在优化问题中,有两个关键点 代价函数:确定问题的形式和规模之后,根据不同的问题,选择要优化的目标。如本文涉及的两个问题中,一个优化目标是使得航班选择最优,共计12个航班,要使得总的票价最少且每个人的等...
  • bcj296050240
  • bcj296050240
  • 2016年03月09日 23:12
  • 3901

模拟退火算法_数学建模系列

对于那些受大自然的运行规律或者面向具体问题的经验、规则启发出来的方法,人们常常称之为启发式算法。模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状...
  • DearRita
  • DearRita
  • 2016年08月18日 03:09
  • 1038

模拟退火算法系列之(二):一个实例

模拟退火算(Simulated Annealing)法是一种基于蒙特卡洛思想设计的近似求解最优化问题的方法。本文通过一个实例来编程演示模拟退火的执行。特别地,我们这里所采用的实例是著名的“旅行商问题”...
  • baimafujinji
  • baimafujinji
  • 2016年09月18日 13:37
  • 3437

MATLAB模拟退火算法模板

为了参加国赛,这几天学了模拟退火算法,整理下当做模板方便国赛的时候用。 模拟退火用于处理最优化问题,可以求出当目标函数取得最小值时的决策变量的值。 在编写程序时需要根据具体问题设计算法,算法描述为...
  • pangel18
  • pangel18
  • 2016年08月29日 08:31
  • 6859

模拟退火算法2(实例分析)--Matlab算法

模拟退火算法2(实例分析)--Matlab算法 此篇文章为我一学长(Hong Yilin)所作,我又进行了一些加工,在此只为学习使用。 此篇为模拟退火算法的实例分析,模拟退...
  • Lee_lg
  • Lee_lg
  • 2015年09月08日 17:56
  • 7218

大白话解析模拟退火算法(simulate annealing)

转自:http://www.cnblogs.com/heaad/ 一. 爬山算法 ( Hill Climbing )          介绍模拟退火前,先介绍爬山算法。爬山算法是一种简单的贪...
  • kai940325
  • kai940325
  • 2015年01月29日 10:46
  • 6477

模拟退火算法Python实现

作者:金良(golden1314521@gmail.com) csdn博客:http://blog.csdn.net/u012176591 import numpy as np coordinate...
  • a14206149
  • a14206149
  • 2016年03月09日 16:35
  • 1781

“模拟退火算法的并行化”之“工欲善其事,必先利其器”

书接上回《“模拟退火算法的并行化”之“接手‘硬骨头’”》,在我接手这项任务后,就要进行项目评估了。 孙子曰:“夫未战而庙算胜者,得算多也,未战而庙算不胜者,得算少也。多算胜,少算不胜,而况于无算乎...
  • gadoop
  • gadoop
  • 2016年04月07日 13:48
  • 393

模拟退火算法

模拟退火算法是用来求解最优化问题的算法。比如著名的TSP问题,函数最大值最小值问题等等。接下来将以如下几个方面来详细介绍模拟退火算法。 Contents 1. 模拟退火算法认识 ...
  • ACdreamers
  • ACdreamers
  • 2013年08月17日 10:28
  • 69415
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#数值计算之模拟退火法简介(二)
举报原因:
原因补充:

(最多只允许输入30个字)