- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565359 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174831
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)" T4 M1 K; O7 j; s. W4 {
7 }1 o/ {( s3 `: [
一、遗传算法介绍
1 A) J4 g& {6 [
2 _6 X/ l7 }# l0 r9 A7 R 遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。1 B3 `. | E8 ]9 A0 k B3 `) Y' K
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 107 T/ \$ S$ D; [* J
; c5 q3 H4 @& z
1、将自变量x进行编码
2 o7 s. s% c8 v2 B- f7 H0 _ i Y; p5 h. j5 l5 F
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
' J0 D+ r0 s' z1 n+ K# d
, ]: }5 k, r* v5 k9 W2、计算目标函数值3 t% c6 W- ]# U" L$ [ b5 t
& I# X8 D9 @/ `+ U, T6 c) [ 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
: x* N% I! E- _) N7 v1 t5 B" p0 C% {) N
3、适应度函数
1 f# `& L d C* D% X8 U* y" ?& i2 V4 R \8 ^
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
7 l: q- i2 g+ u H* e2 l1 N
( o" q# I+ X; y$ T+ K$ E3 D3 }9 u4、自然选择
$ M% B& ?1 M+ K8 N8 e/ a0 G ~5 Z
& T7 x, E2 g6 J& g1 S自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:1 C. a7 g$ }6 _) x" D7 |
0 [/ L/ M+ ^$ R% m
假设种群中共5个个体,适应度函数计算出来的个体适应性列表是fitvalue = [1 ,3, 0, 2, 4] ,totalvalue = 10 , 如果将fitvalue画到圆盘上,值的大小表示在圆盘上的面积。在转动轮盘的过程中,单个模块的面积越大则被选中的概率越大。选择的方法是将fitvalue转化为[1 , 4 ,4 , 6 ,10], fitvalue / totalvalue = [0.1 , 0.4 , 0.4 , 0.6 , 1.0] . 然后产生5个0-1之间的随机数,将随机数从小到大排序,假如是[0.05 , 0.2 , 0.7 , 0.8 ,0.9],则将0号个体、1号个体、4号个体、4号个体、4号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。; }4 ~- W/ K9 w# x8 v" A5 G
$ N( j/ F$ `- H$ l$ `3 m) `
5、繁殖' f+ k& [, P0 Q9 T/ w
0 ?6 Q; ` I2 i3 E+ O4 t1 ]假设个体a、b的基因是0 p D' U* d6 {5 Y7 @
, [! w7 h( k- I! h4 w* Z
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]& z, y/ r/ U# q# U6 R
T$ o' a9 d2 {b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]/ i" U9 ~# K, e2 l8 a6 @7 Z
& ^" G) m U- A9 T" E+ ^, f这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:* _2 L, n. ~7 i, ^: J( B$ K- U
9 T2 s/ @3 q- [* y; ?
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
4 X! [: A7 W3 t9 t3 a7 W$ j# a
* }# X% i- ^# F7 vb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
2 m8 V1 b( q$ i) \$ ~* A8 P l! z" c3 j- A: W* l
交换后为:
7 U7 T! d1 E( ~( k4 C( _. F [8 q" s7 i! x; g% K
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
7 c4 x# q3 J; E
- x: t; r; {% |+ y; a/ m3 {6 @b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
$ E& a9 d+ z# u3 h% d; O' \ P# X9 _, V7 s
6、突变" |$ w* w9 z$ b, |' z9 y$ v
: U6 s# ^: [! N% C8 `
遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
! t) o2 C8 g0 V9 O" t7 L& h7 ?% ~- S
二、代码
: R: A6 O' X- J- n6 ]6 mdef b2d(b): #将二进制转化为十进制 x∈[0,10]
. T) t8 H' @) s) D0 y t = 0
3 W% F/ z8 V% W5 L. a for j in range(len(b)):
9 E4 i- C5 |! f" Q' s0 M, |" Z t += b[j] * (math.pow(2, j))
9 X1 k% ^: Y4 z) g t = t * 10 / 1023
3 _0 o+ O, M7 _6 ~/ t5 S$ V return t N) @1 S7 J. V. d0 Q" a
: X" c* ]6 z8 t
popsize = 50 #种群的大小
& H" v% F, }8 h; ?; l#用遗传算法求函数最大值:+ }/ E0 a0 S0 h
#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]: r, \: _! n2 I; v; B# c2 c& O
0 j2 f$ P' y5 p0 p" v. ^- Y0 I, U
chromlength = 10 #基因片段的长度
6 Z7 S. h. c+ R( E9 Cpc = 0.6 #两个个体交叉的概率2 Z Z4 a/ X+ [4 D' W* Z
pm = 0.001; #基因突变的概率
) s4 ` m: C) d& l% g$ Kresults = [[]]
' C7 p: \, ?7 M' u V! tbestindividual = []
1 r4 ` h9 E$ |1 Y; ?2 bbestfit = 04 M1 \. y3 C& G+ B
fitvalue = []8 @ E) O3 ]5 U( S
tempop = [[]]" I0 L$ ?9 {. r6 c M2 P6 t* x
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]5 G0 S% o+ v. s+ ?; z* @2 O' `
for i in range(100): #繁殖100代4 R5 }# T5 E# x3 J D3 `
objvalue = calobjvalue(pop) #计算目标函数值% r% R6 S/ D; e& d. ]4 X
fitvalue = calfitvalue(objvalue); #计算个体的适应值, u, g% z$ w4 G) \4 R
[bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
, L3 p$ B$ {# J; A1 v% Y results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来/ h6 q$ ~ {& ^6 o& t
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
( {! L! I$ L6 F! f' R crossover(pop, pc) #交叉繁殖
9 U. b* Z; e/ o2 H mutation(pop, pc) #基因突变9 E0 ]9 H" o4 [! Z
* H8 V! I1 n( F- [3 e/ J& \: p9 B2 E! A9 _6 T% G+ b% D7 e
results.sort() ' { x. w* F7 M! J
print(results[-1]) #打印函数最大值和对应的3 u0 M M( Y% P5 u
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。" T) R) W7 {7 R2 _7 P% _
fitvalue = []
0 x0 \ }! [ Y4 u- T) M. X( I temp = 0.05 A8 u' r W9 @
Cmin = 0;
- e) { p1 F* e: [6 n for i in range(len(objvalue)):
$ @/ \9 W0 [6 Q- j2 { if(objvalue + Cmin > 0):
( f( G" a4 j8 A2 ]/ S- m+ z0 }) ] temp = Cmin + objvalue- h: i5 f' @& `& U/ S7 m
else:
/ J9 o5 V+ y* M5 L6 H temp = 0.0
% |- W A1 z0 J$ d4 b' c+ o fitvalue.append(temp), D. J+ I. e' h) C3 Y$ @
return fitvalue5 {% \3 n6 e0 ? V/ d: I
import math
& ?) m& |+ ^( K; ~: c8 [' J8 a: ?0 k* [+ I' `- U
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)9 b5 {9 l5 R6 ]8 s
temp = [];% X6 A6 x" \) Y: W. N
for i in range(len(pop)):! j- r0 G- _" w6 K
t = 0;3 j- ?: B5 M6 J: {) L) F3 r
for j in range(10):
) {8 W3 O0 f o t += pop[j] * (math.pow(2, j))
/ W, r M5 ]: \) z) o temp.append(t)4 A) h( J1 I2 n! ^# K
return temp
0 h- g/ |: b3 ^, q4 z Y% B- L( m5 X* S7 M2 L& j
def calobjvalue(pop): #计算目标函数值
+ E2 j- t" m$ G temp1 = [];( C: W, w- {$ V. X7 V# @
objvalue = [];
1 i# @ _! k4 n+ `$ p temp1 = decodechrom(pop)
7 g$ L0 d+ P; Z) F for i in range(len(temp1)):
! v" A; G' ?2 h q8 E( u9 k x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)5 w" e# V& y! B
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))/ p: q0 t2 n, d# t
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
5 i" h: s/ a- y E- B+ a) t+ Bdef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
. u" \3 t& F' k! p% R3 d px = len(pop)
. {5 r: v6 N9 i/ Z' n- ?# b- v# } bestindividual = []
5 d$ P& \9 z; N8 R* g bestfit = fitvalue[0]" S& D$ T( x* `8 f! ^: c% S
for i in range(1,px):
( M# N) J6 @1 W if(fitvalue > bestfit):
; ]& m/ n1 |2 R6 O8 X; f bestfit = fitvalue; N1 t$ }) r; Q" P. {
bestindividual = pop
5 M1 O3 ^+ m- _ N7 T return [bestindividual, bestfit]& ~6 P) ]# A, C" F, K
import random
* o! f: b9 J' P5 g- [9 O$ O3 Q+ ]: _# z
def sum(fitvalue):
+ J$ I; E! U/ F+ q' C total = 0
8 z I" E! u( d% r; m2 B for i in range(len(fitvalue)):% p1 r; P) n! i0 e: V [
total += fitvalue
3 M I- {& A- F6 o return total
; ?# I: e5 {# \0 N9 b" q# [) n4 b1 E) J" L* {! B5 ]5 W' c5 |1 F
def cumsum(fitvalue):" ?, s {( n2 z M
for i in range(len(fitvalue)):
$ y& U7 t( ?" \: C+ h& a t = 0;
% n+ ?. p) C; W9 z5 U% @* r j = 0;
& _6 b% s {7 n( x9 P7 M while(j <= i):
( F$ ?! B+ P |5 ]) U: ]9 j8 J9 o6 t$ K* \ t += fitvalue[j]4 {( P2 @5 M% V- s% V- e* t0 A
j = j + 1: z8 M1 L9 u; K
fitvalue = t;
' W1 b/ k2 v, t+ n: ]0 ?0 j3 @- w) q$ D: z, q+ R4 g: f
def selection(pop, fitvalue): #自然选择(轮盘赌算法)
& U, E" y3 m$ N& f# @ newfitvalue = []
- d7 A1 u {: \8 x; z totalfit = sum(fitvalue) Y% n0 [# w* u& A5 n' S+ o G
for i in range(len(fitvalue)): X( W5 C$ e* U. z" I
newfitvalue.append(fitvalue / totalfit)/ H, H7 B( `7 D) z" F1 }# R" c+ T2 q7 M$ S
cumsum(newfitvalue)
& r2 W, n J& A3 \5 d G ms = [];
6 T) ~" Z# q* K+ L9 [( J poplen = len(pop)
- i) K/ i) S8 A$ I0 G5 I for i in range(poplen):
* c1 U: \" G0 M ms.append(random.random()) #random float list ms2 U8 I7 P9 D5 R& U9 R' A
ms.sort()& l) Y o. ~ A: q- o$ e+ u4 k
fitin = 0
' o' b& [/ w- s, i newin = 0( V1 |$ ^( R6 n4 E
newpop = pop7 a% H. r$ @: U. m
while newin < poplen:. i! m& D" T/ l" f
if(ms[newin] < newfitvalue[fitin]):
; d% z: u4 ]3 f: h newpop[newin] = pop[fitin]
. t% n3 B) Z- e) \ e; U newin = newin + 11 {; p: D, T* H
else:2 ~0 o/ l; S+ }3 l8 k
fitin = fitin + 1
3 M. K: B0 V* M' e2 X8 D/ r4 Z pop = newpop& b& \1 q, g: D1 k4 ^
import random
6 }3 t0 ^' R0 K( |
, `3 t7 T7 H8 U3 u7 b6 ~' m) kdef crossover(pop, pc): #个体间交叉,实现基因交换
+ K) d8 G' W$ A, i poplen = len(pop)
- L6 o- @0 v3 r' X for i in range(poplen - 1):- D2 Y! g* E! e2 n! J- |
if(random.random() < pc):0 f }+ G0 i [7 A, U& b9 I
cpoint = random.randint(0,len(pop[0]))
1 X- ~7 h0 D( `5 H) {2 Q2 c* ] temp1 = []
. s5 i, z4 z6 R1 { temp2 = []# h! m' X$ a f- y2 [
temp1.extend(pop[0 : cpoint])' K+ K( `% v) } X, Q
temp1.extend(pop[i+1][cpoint : len(pop)])% E* Y7 q- Z$ R; e
temp2.extend(pop[i+1][0 : cpoint])
- A' H' s; j% J$ o5 d temp2.extend(pop[cpoint : len(pop)])
! q P, V* q/ M/ K5 X- _+ ] pop = temp1) W) p7 @. O' G& M! n! J k
pop[i+1] = temp2% y Y, b' H! w$ h9 a3 O! z7 W
import random
6 V4 k' n+ z2 x5 f" ?% H
: [2 r4 g/ S7 l4 r5 Z, rdef mutation(pop, pm): #基因突变 D$ f: @2 z# [* Y' X2 L4 \3 D
px = len(pop)
: @$ b, c0 L" [9 `) n py = len(pop[0])' F/ h! G! s8 V
B) o Q1 ?7 C* K for i in range(px):6 u2 e5 X7 R% D5 h/ h
if(random.random() < pm):& K5 m: n- z5 }) b5 p
mpoint = random.randint(0,py-1)5 y( H/ U. P. J4 s
if(pop[mpoint] == 1):8 |6 C* W/ K; n4 B$ R6 y
pop[mpoint] = 0& L' e, A- G! a1 p; D
else:% N- `# H& Z6 `! d) n) K
pop[mpoint] = 1
0 L3 H1 W7 S! `
: _7 x* ?& c; I' m+ ^) h) l0 g. S8 E
————————————————& \, Q$ P- Z$ \9 d
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# w& @* u$ m. f& S! e+ h9 y" B
原文链接:https://blog.csdn.net/u010902721/article/details/23531359- h6 h$ \6 T' x+ E! Q
* L9 T6 q; t+ |
5 S+ S7 c/ _- x2 L9 | |
zan
|