遺傳演算法使用電腦程式來模擬生物的進化過程,形象的來說,就是通過「繁殖」、「變異」,「競爭」以及自然選擇來得到問題的最優解。
遺傳演算法的基本結構如下: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...