日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大白话解析模拟退火算法、遗传算法入门

發(fā)布時(shí)間:2025/3/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大白话解析模拟退火算法、遗传算法入门 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

優(yōu)化算法入門系列文章目錄(更新中):

  1.?模擬退火算法

  2.?遺傳算法

?

一. 爬山算法 ( Hill Climbing )

???????? 介紹模擬退火前,先介紹爬山算法。爬山算法是一種簡單的貪心搜索算法,該算法每次從當(dāng)前解的臨近解空間中選擇一個(gè)最優(yōu)解作為當(dāng)前解,直到達(dá)到一個(gè)局部最優(yōu)解。

???????? 爬山算法實(shí)現(xiàn)很簡單,其主要缺點(diǎn)是會陷入局部最優(yōu)解,而不一定能搜索到全局最優(yōu)解。如圖1所示:假設(shè)C點(diǎn)為當(dāng)前解,爬山算法搜索到A點(diǎn)這個(gè)局部最優(yōu)解就會停止搜索,因?yàn)樵贏點(diǎn)無論向那個(gè)方向小幅度移動(dòng)都不能得到更優(yōu)的解。

圖1

?

?

二. 模擬退火(SA,Simulated Annealing)思想

???????? 爬山法是完完全全的貪心法,每次都鼠目寸光的選擇一個(gè)當(dāng)前最優(yōu)解,因此只能搜索到局部的最優(yōu)值。模擬退火其實(shí)也是一種貪心算法,但是它的搜索過程引入了隨機(jī)因素。模擬退火算法以一定的概率來接受一個(gè)比當(dāng)前解要差的解,因此有可能會跳出這個(gè)局部的最優(yōu)解,達(dá)到全局的最優(yōu)解。以圖1為例,模擬退火算法在搜索到局部最優(yōu)解A后,會以一定的概率接受到E的移動(dòng)。也許經(jīng)過幾次這樣的不是局部最優(yōu)的移動(dòng)后會到達(dá)D點(diǎn),于是就跳出了局部最大值A(chǔ)。

???????? 模擬退火算法描述:

???????? 若J( Y(i+1) )>= J( Y(i) ) ?(即移動(dòng)后得到更優(yōu)解),則總是接受該移動(dòng)

???????? 若J( Y(i+1) )< J( Y(i) ) ?(即移動(dòng)后的解比當(dāng)前解要差),則以一定的概率接受移動(dòng),而且這個(gè)概率隨著時(shí)間推移逐漸降低(逐漸降低才能趨向穩(wěn)定)

  這里的“一定的概率”的計(jì)算參考了金屬冶煉的退火過程,這也是模擬退火算法名稱的由來。

  根據(jù)熱力學(xué)的原理,在溫度為T時(shí),出現(xiàn)能量差為dE的降溫的概率為P(dE),表示為:

    P(dE) = exp( dE/(kT) )

  其中k是一個(gè)常數(shù),exp表示自然指數(shù),且dE<0。這條公式說白了就是:溫度越高,出現(xiàn)一次能量差為dE的降溫的概率就越大;溫度越低,則出現(xiàn)降溫的概率就越小。又由于dE總是小于0(否則就不叫退火了),因此dE/kT < 0 ,所以P(dE)的函數(shù)取值范圍是(0,1) 。

  隨著溫度T的降低,P(dE)會逐漸降低。

  我們將一次向較差解的移動(dòng)看做一次溫度跳變過程,我們以概率P(dE)來接受這樣的移動(dòng)。

  關(guān)于爬山算法與模擬退火,有一個(gè)有趣的比喻:

  爬山算法:兔子朝著比現(xiàn)在高的地方跳去。它找到了不遠(yuǎn)處的最高山峰。但是這座山不一定是珠穆朗瑪峰。這就是爬山算法,它不能保證局部最優(yōu)值就是全局最優(yōu)值。

  模擬退火:兔子喝醉了。它隨機(jī)地跳了很長時(shí)間。這期間,它可能走向高處,也可能踏入平地。但是,它漸漸清醒了并朝最高方向跳去。這就是模擬退火。

?

下面給出模擬退火的偽代碼表示。

?

三. 模擬退火算法偽代碼

代碼 /*
* J(y):在狀態(tài)y時(shí)的評價(jià)函數(shù)值
* Y(i):表示當(dāng)前狀態(tài)
* Y(i+1):表示新的狀態(tài)
* r: 用于控制降溫的快慢
* T: 系統(tǒng)的溫度,系統(tǒng)初始應(yīng)該要處于一個(gè)高溫的狀態(tài)
* T_min :溫度的下限,若溫度T達(dá)到T_min,則停止搜索
*/
while( T?>?T_min )
{
  dE?
=?J( Y(i+1) )?-?J( Y(i) ) ;?

  if?( dE?>=0?)?//表達(dá)移動(dòng)后得到更優(yōu)解,則總是接受移動(dòng)
Y(i+1)?=?Y(i) ;?//接受從Y(i)到Y(jié)(i+1)的移動(dòng)
  else
  {
//?函數(shù)exp( dE/T )的取值范圍是(0,1) ,dE/T越大,則exp( dE/T )也
if?( exp( dE/T )?>?random(?0?,?1?) )
Y(i
+1)?=?Y(i) ;?//接受從Y(i)到Y(jié)(i+1)的移動(dòng)
  }
  T?
=?r?*?T ;?//降溫退火 ,0<r<1 。r越大,降溫越慢;r越小,降溫越快
  /*

  * 若r過大,則搜索到全局最優(yōu)解的可能會較高,但搜索的過程也就較長。若r過小,則搜索的過程會很快,但最終可能會達(dá)到一個(gè)局部最優(yōu)值
  */
  i?
++?;
}

四. 使用模擬退火算法解決旅行商問題

  旅行商問題 ( TSP , Traveling Salesman Problem ) :有N個(gè)城市,要求從其中某個(gè)問題出發(fā),唯一遍歷所有城市,再回到出發(fā)的城市,求最短的路線。

  旅行商問題屬于所謂的NP完全問題,精確的解決TSP只能通過窮舉所有的路徑組合,其時(shí)間復(fù)雜度是O(N!) 。

  使用模擬退火算法可以比較快的求出TSP的一條近似最優(yōu)路徑。(使用遺傳算法也是可以的,我將在下一篇文章中介紹)模擬退火解決TSP的思路:

1. 產(chǎn)生一條新的遍歷路徑P(i+1),計(jì)算路徑P(i+1)的長度L( P(i+1) )

2. 若L(P(i+1)) < L(P(i)),則接受P(i+1)為新的路徑,否則以模擬退火的那個(gè)概率接受P(i+1) ,然后降溫

3. 重復(fù)步驟1,2直到滿足退出條件

  產(chǎn)生新的遍歷路徑的方法有很多,下面列舉其中3種:

1. 隨機(jī)選擇2個(gè)節(jié)點(diǎn),交換路徑中的這2個(gè)節(jié)點(diǎn)的順序。

2. 隨機(jī)選擇2個(gè)節(jié)點(diǎn),將路徑中這2個(gè)節(jié)點(diǎn)間的節(jié)點(diǎn)順序逆轉(zhuǎn)。

3. 隨機(jī)選擇3個(gè)節(jié)點(diǎn)m,n,k,然后將節(jié)點(diǎn)m與n間的節(jié)點(diǎn)移位到節(jié)點(diǎn)k后面。

?

五. 算法評價(jià)

?? ? ? ?模擬退火算法是一種隨機(jī)算法,并不一定能找到全局的最優(yōu)解,可以比較快的找到問題的近似最優(yōu)解。?如果參數(shù)設(shè)置得當(dāng),模擬退火算法搜索效率比窮舉法要高。



遺傳算法 ( GA , Genetic Algorithm ) ,也稱進(jìn)化算法 。 遺傳算法是受達(dá)爾文的進(jìn)化論的啟發(fā),借鑒生物進(jìn)化過程而提出的一種啟發(fā)式搜索算法。因此在介紹遺傳算法前有必要簡單的介紹生物進(jìn)化知識。

?

?

一.進(jìn)化論知識?

  作為遺傳算法生物背景的介紹,下面內(nèi)容了解即可:

  種群(Population):生物的進(jìn)化以群體的形式進(jìn)行,這樣的一個(gè)群體稱為種群。

  個(gè)體:組成種群的單個(gè)生物。

  基因?( Gene )?:一個(gè)遺傳因子。?

  染色體?( Chromosome )?:包含一組的基因。

  生存競爭,適者生存:對環(huán)境適應(yīng)度高的、牛B的個(gè)體參與繁殖的機(jī)會比較多,后代就會越來越多。適應(yīng)度低的個(gè)體參與繁殖的機(jī)會比較少,后代就會越來越少。

  遺傳與變異:新個(gè)體會遺傳父母雙方各一部分的基因,同時(shí)有一定的概率發(fā)生基因變異。

?

  簡單說來就是:繁殖過程,會發(fā)生基因交叉( Crossover ) ,基因突變 ( Mutation ) ,適應(yīng)度( Fitness )低的個(gè)體會被逐步淘汰,而適應(yīng)度高的個(gè)體會越來越多。那么經(jīng)過N代的自然選擇后,保存下來的個(gè)體都是適應(yīng)度很高的,其中很可能包含史上產(chǎn)生的適應(yīng)度最高的那個(gè)個(gè)體。

?

?

二.遺傳算法思想?

  借鑒生物進(jìn)化論,遺傳算法將要解決的問題模擬成一個(gè)生物進(jìn)化的過程,通過復(fù)制、交叉、突變等操作產(chǎn)生下一代的解,并逐步淘汰掉適應(yīng)度函數(shù)值低的解,增加適應(yīng)度函數(shù)值高的解。這樣進(jìn)化N代后就很有可能會進(jìn)化出適應(yīng)度函數(shù)值很高的個(gè)體。

  舉個(gè)例子,使用遺傳算法解決“0-1背包問題”的思路:0-1背包的解可以編碼為一串0-1字符串(0:不取,1:取) ;首先,隨機(jī)產(chǎn)生M個(gè)0-1字符串,然后評價(jià)這些0-1字符串作為0-1背包問題的解的優(yōu)劣;然后,隨機(jī)選擇一些字符串通過交叉、突變等操作產(chǎn)生下一代的M個(gè)字符串,而且較優(yōu)的解被選中的概率要比較高。這樣經(jīng)過G代的進(jìn)化后就可能會產(chǎn)生出0-1背包問題的一個(gè)“近似最優(yōu)解”。

?

  編碼:需要將問題的解編碼成字符串的形式才能使用遺傳算法。最簡單的一種編碼方式是二進(jìn)制編碼,即將問題的解編碼成二進(jìn)制位數(shù)組的形式。例如,問題的解是整數(shù),那么可以將其編碼成二進(jìn)制位數(shù)組的形式。將0-1字符串作為0-1背包問題的解就屬于二進(jìn)制編碼。

?

  遺傳算法有3個(gè)最基本的操作:選擇,交叉,變異。

?

  選擇:選擇一些染色體來產(chǎn)生下一代。一種常用的選擇策略是?“比例選擇”,也就是個(gè)體被選中的概率與其適應(yīng)度函數(shù)值成正比。假設(shè)群體的個(gè)體總數(shù)是M,那么那么一個(gè)體Xi被選中的概率為f(Xi)/( f(X1) + f(X2) + …….. + f(Xn) ) 。比例選擇實(shí)現(xiàn)算法就是所謂的“輪盤賭算法”( Roulette Wheel Selection ) ,輪盤賭算法的一個(gè)簡單的實(shí)現(xiàn)如下:

?

輪盤賭算法 /*
* 按設(shè)定的概率,隨機(jī)選中一個(gè)個(gè)體
* P[i]表示第i個(gè)個(gè)體被選中的概率
*/
int?RWS()
{
m?
=0;
r?
=Random(0,1);?//r為0至1的隨機(jī)數(shù)
for(i=1;i<=N; i++)
{
/*?產(chǎn)生的隨機(jī)數(shù)在m~m+P[i]間則認(rèn)為選中了i
* 因此i被選中的概率是P[i]
*/
m?
=?m?+?P[i];
if(r<=m)?return?i;
}
}

?

交叉(Crossover):2條染色體交換部分基因,來構(gòu)造下一代的2條新的染色體。例如:

交叉前:

00000|011100000000|10000

11100|000001111110|00101

交叉后:

00000|000001111110|10000

11100|011100000000|00101

染色體交叉是以一定的概率發(fā)生的,這個(gè)概率記為Pc 。

?

變異(Mutation):在繁殖過程,新產(chǎn)生的染色體中的基因會以一定的概率出錯(cuò),稱為變異。變異發(fā)生的概率記為Pm 。例如:

變異前:

000001110000000010000

變異后:

000001110000100010000

?

適應(yīng)度函數(shù)?( Fitness Function ):用于評價(jià)某個(gè)染色體的適應(yīng)度,用f(x)表示。有時(shí)需要區(qū)分染色體的適應(yīng)度函數(shù)與問題的目標(biāo)函數(shù)。例如:0-1背包問題的目標(biāo)函數(shù)是所取得物品價(jià)值,但將物品價(jià)值作為染色體的適應(yīng)度函數(shù)可能并不一定適合。適應(yīng)度函數(shù)與目標(biāo)函數(shù)是正相關(guān)的,可對目標(biāo)函數(shù)作一些變形來得到適應(yīng)度函數(shù)。

?

?

三.基本遺傳算法的偽代碼?

?

?

基本遺傳算法偽代碼 /*
* Pc:交叉發(fā)生的概率
* Pm:變異發(fā)生的概率
* M:種群規(guī)模
* G:終止進(jìn)化的代數(shù)
* Tf:進(jìn)化產(chǎn)生的任何一個(gè)個(gè)體的適應(yīng)度函數(shù)超過Tf,則可以終止進(jìn)化過程
*/
初始化Pm,Pc,M,G,Tf等參數(shù)。隨機(jī)產(chǎn)生第一代種群Pop

do
{?
  計(jì)算種群Pop中每一個(gè)體的適應(yīng)度F(i)。
  初始化空種群newPop
  do
  {
    根據(jù)適應(yīng)度以比例選擇算法從種群Pop中選出2個(gè)個(gè)體
    if?( random (?0?,?1?)?<?Pc )
    {
      對2個(gè)個(gè)體按交叉概率Pc執(zhí)行交叉操作
    }
    if?( random (?0?,?1?)?<?Pm )
    {
      對2個(gè)個(gè)體按變異概率Pm執(zhí)行變異操作
    }
將2個(gè)新個(gè)體加入種群newPop中
} until ( M個(gè)子代被創(chuàng)建 )
用newPop取代Pop
}until ( 任何染色體得分超過Tf, 或繁殖代數(shù)超過G )
?

?

?

四.基本遺傳算法優(yōu)化?

?  下面的方法可優(yōu)化遺傳算法的性能。

?  精英主義(Elitist Strategy)選擇:是基本遺傳算法的一種優(yōu)化。為了防止進(jìn)化過程中產(chǎn)生的最優(yōu)解被交叉和變異所破壞,可以將每一代中的最優(yōu)解原封不動(dòng)的復(fù)制到下一代中。

?  插入操作:可在3個(gè)基本操作的基礎(chǔ)上增加一個(gè)插入操作。插入操作將染色體中的某個(gè)隨機(jī)的片段移位到另一個(gè)隨機(jī)的位置。

?

?

五. 使用AForge.Genetic解決TSP問題

  AForge.NET是一個(gè)C#實(shí)現(xiàn)的面向人工智能、計(jì)算機(jī)視覺等領(lǐng)域的開源架構(gòu)。AForge.NET中包含有一個(gè)遺傳算法的類庫。

?

  AForge.NET主頁:http://www.aforgenet.com/

  AForge.NET代碼下載:http://code.google.com/p/aforge/

?

  介紹一下AForge的遺傳算法用法吧。AForge.Genetic的類結(jié)構(gòu)如下:


圖1. AForge.Genetic的類圖

?

?

?? 下面用AForge.Genetic寫個(gè)解決TSP問題的最簡單實(shí)例。測試數(shù)據(jù)集采用網(wǎng)上流傳的中國31個(gè)省會城市的坐標(biāo):

?

13042312
36391315
41772244
37121399
34881535
33261556
32381229
41961004
4312790
4386570
30071970
25621756
27881491
23811676
1332695
37151678
39182179
40612370
37802212
36762578
40292838
42632931
34291908
35072367
33942643
34393201
29353240
31403550
25452357
27782826
23702975

?

?

?

操作過程:

?? (1) 下載AForge.NET類庫,網(wǎng)址:http://code.google.com/p/aforge/downloads/list

?? (2) 創(chuàng)建C#空項(xiàng)目GenticTSP。然后在AForge目錄下找到AForge.dll和AForge.Genetic.dll,將其拷貝到TestTSP項(xiàng)目的bin/Debug目錄下。再通過“Add Reference...”將這兩個(gè)DLL添加到工程。

?? (3) 將31個(gè)城市坐標(biāo)數(shù)據(jù)保存為bin/Debug/Data.txt 。

?? (4) 添加TSPFitnessFunction.cs,加入如下代碼:

?

TSPFitnessFunction類 using?System;
using?AForge.Genetic;

namespace?GenticTSP
{
///<summary>
///?Fitness function for TSP task (Travaling Salasman Problem)
///</summary>
publicclass?TSPFitnessFunction : IFitnessFunction
{
//?map
privateint[,] map?=null;

//?Constructor
public?TSPFitnessFunction(int[,] map)
{
this.map?=?map;
}

///<summary>
///?Evaluate chromosome - calculates its fitness value
///</summary>
publicdouble?Evaluate(IChromosome chromosome)
{
return1/?(PathLength(chromosome)?+1);
}

///<summary>
///?Translate genotype to phenotype?
///</summary>
publicobject?Translate(IChromosome chromosome)
{
return?chromosome.ToString();
}

///<summary>
///?Calculate path length represented by the specified chromosome?
///</summary>
publicdouble?PathLength(IChromosome chromosome)
{
//?salesman path
ushort[] path?=?((PermutationChromosome)chromosome).Value;

//?check path size
if?(path.Length?!=?map.GetLength(0))
{
thrownew?ArgumentException("Invalid path specified - not all cities are visited");
}

//?path length
int?prev?=?path[0];
int?curr?=?path[path.Length?-1];

//?calculate distance between the last and the first city
double?dx?=?map[curr,?0]?-?map[prev,?0];
double?dy?=?map[curr,?1]?-?map[prev,?1];
double?pathLength?=?Math.Sqrt(dx?*?dx?+?dy?*?dy);

//?calculate the path length from the first city to the last
for?(int?i?=1, n?=?path.Length; i?<?n; i++)
{
//?get current city
curr?=?path[i];

//?calculate distance
dx?=?map[curr,?0]?-?map[prev,?0];
dy?
=?map[curr,?1]?-?map[prev,?1];
pathLength?
+=?Math.Sqrt(dx?*?dx?+?dy?*?dy);

//?put current city as previous
prev?=?curr;
}

return?pathLength;
}
}
}

?

?

?? (5) 添加GenticTSP.cs,加入如下代碼:

?

GenticTSP類 using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?System.IO;

using?AForge;
using?AForge.Genetic;


namespace?GenticTSP
{
class?GenticTSP
{

staticvoid?Main()
{
StreamReader reader?
=new?StreamReader("Data.txt");

int?citiesCount?=31;?//城市數(shù)

int[,] map?=newint[citiesCount,?2];

for?(int?i?=0; i?<?citiesCount; i++)
{
string?value?=?reader.ReadLine();
string[] temp?=?value.Split('');
map[i,?
0]?=int.Parse(temp[0]);?//讀取城市坐標(biāo)
map[i,?1]?=int.Parse(temp[1]);
}

//?create fitness function
TSPFitnessFunction fitnessFunction?=new?TSPFitnessFunction(map);

int?populationSize?=?1000;?//種群最大規(guī)模

/*?
* 0:EliteSelection算法?
* 1:RankSelection算法?
* 其他:RouletteWheelSelection 算法
*?
*/
int?selectionMethod?=0;

//?create population
Population population?=new?Population(populationSize,
new?PermutationChromosome(citiesCount),
fitnessFunction,
(selectionMethod?
==0)???(ISelectionMethod)new?EliteSelection() :
(selectionMethod?
==1)???(ISelectionMethod)new?RankSelection() :
(ISelectionMethod)
new?RouletteWheelSelection()
);

//?iterations
int?iter?=1;
int?iterations?=5000;?//迭代最大周期

//?loop
while?(iter?<?iterations)
{
//?run one epoch of genetic algorithm
population.RunEpoch();

//?increase current iteration
iter++;
}

System.Console.WriteLine(
"遍歷路徑是: {0}", ((PermutationChromosome)population.BestChromosome).ToString());
System.Console.WriteLine(
"總路程是:{0}", fitnessFunction.PathLength(population.BestChromosome));
System.Console.Read();

}
}
}

?

?

?

網(wǎng)上據(jù)稱這組TSP數(shù)據(jù)的最好的結(jié)果是?15404 ,上面的程序我剛才試了幾次最好一次算出了15402.341,但是最差的時(shí)候也跑出了大于16000的結(jié)果。

我這還有一個(gè)版本,設(shè)置種群規(guī)模為1000,迭代5000次可以算出15408.508這個(gè)結(jié)果。源代碼在文章最后可以下載。

?

總結(jié)一下使用AForge.Genetic解決問題的一般步驟:

?? (1) 定義適應(yīng)函數(shù)類,需要實(shí)現(xiàn)IFitnessFunction接口

?? (2) 選定種群規(guī)模、使用的選擇算法、染色體種類等參數(shù),創(chuàng)建種群population

?? (3)設(shè)定迭代的最大次數(shù),使用RunEpoch開始計(jì)算

?

本文源代碼下載



from:?http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

http://www.cnblogs.com/heaad/archive/2010/12/23/1914725.html

總結(jié)

以上是生活随笔為你收集整理的大白话解析模拟退火算法、遗传算法入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。