国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

C#數值計算之模擬退火法簡介(二)

2024-07-21 02:24:48
字體:
來源:轉載
供稿:網友
在上一篇文章中講述了模擬退火的基本原理,以下以一個實際的例子來說明,其中所有的源碼已貼出,可以從中了解到很多細節。



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




解:根據題意,我們設計冷卻表進度表為:

即初始溫度為100

衰減參數為0.95

馬可夫鏈長度為10000

metropolis的步長為0.02

結束條件為根據上一個最優解與最新的一個最優解的之差小于某個容差。





使用metropolis接受準則進行模擬, 程序如下



/*

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

* 日期:2004-4-16

* 作者:armylau

* email:[email protected]

* 結束條件為兩次最優解之差小于某小量

*/

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 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與我:[email protected]

另,模擬退火還可以應用到其它更多更復雜的問題,如“推銷員問題”等組合優化問題。本例只是求一個二維函數的最小值問題,而且其冷卻表參數的選擇也過于簡單,只能作用一個初步的入門簡介,請讀者注意。





l 參考文獻:

1. http://www.computer-dictionary-online.org/index.asp?q=simulated+annealing 計算機詞典

2. numeric recipes in c

3. 計算方法叢書 非數值并行算法 (第一冊) 模擬退火算法

菜鳥學堂:
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤山市| 阿拉善左旗| 金乡县| 会同县| 灵台县| 房产| 庆安县| 麟游县| 盐津县| 南澳县| 阿拉尔市| 林口县| 广平县| 阳泉市| 朝阳县| 如东县| 宁夏| 运城市| 鹿泉市| 桦南县| 大港区| 黔江区| 灵石县| 汝阳县| 延庆县| 浏阳市| 宁阳县| 沂水县| 独山县| 同仁县| 普兰店市| 尤溪县| 建平县| 岱山县| 晋江市| 广平县| 绥化市| 达尔| 宝坻区| 武威市| 屏边|