使用遺傳演算法計算方程的最大值

2021-04-09 06:34:19 字數 4739 閱讀 1714

遺傳演算法使用電腦程式來模擬生物的進化過程,形象的來說,就是通過「繁殖」、「變異」,「競爭」以及自然選擇來得到問題的最優解。

遺傳演算法的基本結構如下:t =

0;

initialize(p(t));     

//找出原始解集

evaluate(p(t));   

//評估解集中是否有最優解

while

(not termination condition)

dopp(t) 

=parent_select(p(t));    

//選擇父體

pp(t) 

=crossover(pp(t));        

//父體之間互換資訊

p(t+1) 

=mutate(pp(t));          

//變異,引入多樣性

evaluate(p(t+1

));                  

//評估是否有最優解t =

t+1;

end 

while

return

the best solution

求解問題:max f(x, y) = 21.5 + x * sin(4x * pi) + y * sin(20y * pi); 

其中 -3.0 <= x <= 12.1, 4.1 <= y <=5.8; 要求解精確到小數點之後1位。

如果我們要用遺傳演算法解決問題,第一步要解決的是如何表示每乙個個體。一般情況下,我們使用乙個二進位制的整數來表示乙個個體,整數的位數與所要表示的精度有關,如:

如果用m表示x(精確到小數點後t位)所需要的二進位制位串的長度,則m滿足:

(xmax- xmin) * 10t

<= 2m - 1;

則由二進位制編碼(bin)到實數的轉換如下:

x = xmin + decimal(bin) * (xmax- xmin ) / (2m - 1);

所以,在本例中,x可以用8位二進位制串表示, y可以用5位二進位制串表示。

由於此時就是計算這個方程的最大值,所以可以簡單的取表示式f(x, y)來作為評估的函式。其函式值越大,表示評估的適應度越大。

選擇的策略有很多。在本問題中,由於使用函式本身做評估函式,即評估的適應度越大,選擇的概率應該越大,所以可以使用輪盤賭策略來進行選擇,具體步驟如下:

計算種群中每個個體的適應度之和f =  ∑eval(k);

計算每個個體的選擇概率 p

k = eval(k) / f;

計算每個個體的累計概率 q

k = q

k-1 + p

k

產生乙個0~1的隨機數r, 如果q

k-1

<= r  <=  q

k , 則選擇第k個個體。

遺傳運算元主要指個體之間進行雜交和變異。

對於雜交,可以使用輪盤賭策略來選擇部分父體進行資訊的兩兩部分交換,交換的位置可以隨機確定。

對於變異,同樣可以使用輪盤賭策略來選擇部分父體進行變異。隨機的將表示這個個體的二進位制位串的某個位求反。

由於使用函式本身做評估函式,故不可能根據評估的最大值來作為終止條件。這個時候可以選擇迭代的次數作為終止的限制。

#include 

<

iostream

>

#include 

<

vector

>

#include 

<

utility

>

#include 

<

bitset

>

#include 

<

algorithm

>

#include 

<

string

>

#include 

<

cmath

>

#include 

<

cstdlib

>

#include 

<

ctime

>

#include 

<

cassert

>

using

namespace

std;

const

double

pi =

3.1415926535

;const

double

pc =

0.75

;     

//雜交概率

const

double

pm =

0.015

;  //

變異概率

const

double

x_low =-

3.0;

const

double

x_up 

=12.1

;const

double

y_low 

=4.1

;const

double

y_up 

=5.8

;const

short

left_bit =8

;const

short

righ_bit =5

;const

short

bit 

=left_bit 

+righ_bit;

const

short

gen 

=1000

;   

//迭代次數

const

short

count =20

;  //

種群規模

vector

<

pair

<

bitset

<

bit>

, double

>

>

sol_set(count);  

//最終選擇個體的儲存位置

vector

<

pair

<

bitset

<

bit>

, double

>

>

temp(count);

void

initialize();

void

evaluate();

void

parent_select();

void

crossover();

void

mutate();

//目標函式

double

func(

double

x, double

y)...

//

使用隨機數初始化種群

void

initialize()

...pair

<

bitset

<

bit>

, double

>

sol(bitvec, 

0.0);

sol_set[i] 

=sol;}}

//

對種群中的個體進行評估

void

evaluate()

...}

//

使用輪盤賭策略選擇個體

void

parent_select()

...vector

<

double

>

pq(count);

for(i =0

; i 

<

count; i++)

...srand((unsigned 

short

) time(null));

for(i =0

; i 

<

count; i++)

...sol_set.swap(temp);}

//按照輪盤賭策略雜交

void

crossover()

...}

intm, n, j;

while

(index.size() 

>=2)

...}}}

//

按照輪盤賭策略變異

void

mutate()

...}

pair

<

bitset

<

bit>

, double

>

sol;

bitset

<

bit>

a;while

(index.size() 

>0)

...}

int

main(

intargc, 

char

**argv)

...for

(i =

0; i 

<

count; i++)

...return0;

}

程式比較簡單,基本上都是自解釋的。

由於遺傳演算法經過大量的隨即選擇過程,故最終的結果不一定正確。在這個題目中,按照微積分的方法算出最大值為38.5左右(精確到小數點後1位)。計算的結果可能會接近這個值,也可能離這個值很遠。多計算幾次看看。

Matlab遺傳演算法求函式最大值

主函式函式main.m global bitlength 定義3個全域性變數 global boundsbegin global boundsend boundsbegin 2 boundsend 2 precision 0.0001 運算精確度 bitlength ceil log2 bounds...

遺傳演算法求解函式最大值c 實現

遺傳演算法求解步驟 1.使用隨機方法產生乙個有n個染色體的初始種群 2.對群體中的每乙個染色體,計算其適應值 3.從群體中隨機選擇一些染色體構成乙個新的群體 常用方法 輪盤賭選擇,錦標賽選擇 4.以一定概率進行交叉 單點交叉 多點交叉 5.以一定概率進行變異 6.返回第2步,以一定的迭代次數進行迴圈...

用遺傳演算法求解二元函式最大值

為了更好的理解遺傳演算法的運算過程,下面用手工的計算間的模擬遺傳演算法的各個主要的執行步驟 例 求下述二元函式的最大值 max f x1,x2 x1 2 x2 2 1 個體編碼 遺傳演算法的運算物件是表示個體的符號串,所以必須把變數x1,x2編碼位一種符號串。本題中,用無符號二進位制整數來表示。因x...