帮朋友写了一段python的遗传算法,需求我也不太懂,图像处理用。抽象出来就是一个固定函数生成的随机点,用这些随机点去拟合出函数的三个参数。
空余时间很急的就写完了,很粗糙,有很多可以优化的地方,尤其交叉当时也不知道怎么想的,实数编码竟然这么交叉,回头自己看都恶心;适应度函数设置的也不好,不能有效区分适应度空间,导致轮盘赌选择效果也不明显。
先留在这里,有时间优化一版。
# -*- coding: utf-8 -*-
import math
import random
import time
import numpy as np
#轮盘赌选择
def rouletteWheelSelect(fitness):
sumFits = sum(fitness)
minFits = min(fitness)
rndPoint = random.uniform(minFits,sumFits)
accumulator = 0.0
for ind, val in enumerate(fitness):
accumulator += val
if accumulator >= rndPoint:
return ind
#以概率p返回1或-1
def select(p):
if random.random() len(str_b):
for i in xrange(len(str_a)-len(str_b)):
str_b = '0'+str_b
else:
for i in xrange(len(str_b)-len(str_a)):
str_a = '0'+str_a
else:
if len(str_a) > len(str_b):
for i in xrange(len(str_a)-len(str_b)):
str_b = str_b+'0'
else:
for i in xrange(len(str_b)-len(str_a)):
str_a = str_a+'0'
t = random.randint(1,max(len(str_a),len(str_b)))
new_str_a = str_b[0:t] + str_a[t:str_len]
new_str_b = str_a[0:t] + str_b[t:str_len]
if type_a == int:
a = int(new_str_a)
b = int(new_str_b)
else:
try:
a = float(new_str_a)
b = float(new_str_b)
except ValueError:
print 'ValueError', new_str_a, new_str_b
return a, b
# 变异,整数+1或-1,浮点数加0.1的n次方或减0.1的n次方
def mutate(a, range_a, p):
if select(p):
if type(a) == int:
a += select(0.5)
else:
a += select(0.5)*0.1**(random.randint(1,len(str(range_a[1]))-1))
if a < range_a[0]:
a = range_a[0]
elif a > range_a[1]:
a = range_a[1]
else:
pass
else:
pass
return a
#原函数
def functionI(i, x, y, z):
return np.sqrt((i-y)**2*np.tan(z)**2+x**2)
#适应度函数
def getFitness(row, column, x, y, z, target):
delta = 0
for i in xrange(column):
result = int(functionI(i, x, y, z))
delta += abs(result - target[i][0])
return row*column - delta
#初始化
def init(row, column, size):
indvs = []
for i in xrange(size):
indvs.append([random.randint(0, row), random.randint(0, column), round(random.uniform(0, np.pi/2.0),5)])
return indvs
gen_max = 500
size = 50
Pcross = 0.4
Pmutate = 0.1
row = 100
column = 200
alpha = 18; gamma=100; phi=0.48504296874976705
line = []
for x in xrange(column):
y = int(functionI(x, alpha, gamma, phi))
if 0< y one:
two = one
one = fitness[n]
elif fitness > two:
two = fitness[n]
else:
pass
new_indvs[0] = indvs[fitness.index(one,0,len(fitness))]
new_indvs[1] = indvs[fitness.index(two,0,len(fitness))]
best_indv = new_indvs[0]
best_fitness = one
print i, one, new_indvs[0]
if one == row*column:
break
m += 2
while m < size:
index1 = rouletteWheelSelect(fitness)
index2 = rouletteWheelSelect(fitness)
(idv1_x, idv1_y, idv1_z) = (indvs[index1][0], indvs[index1][1], indvs[index1][2])
(idv2_x, idv2_y, idv2_z) = (indvs[index2][0], indvs[index2][1], indvs[index2][2])
(idv1_x, idv2_x) = cross(idv1_x, idv2_x, int, Pcross)
(idv1_y, idv2_y) = cross(idv1_y, idv2_y, int, Pcross)
(idv1_z, idv2_z) = cross(idv1_z, idv2_z, float, Pcross)
(idv1_x, idv1_y, idv1_z) = (mutate(idv1_x, [0, row], Pmutate),
mutate(idv1_y, [0, column], Pmutate),
mutate(idv1_z, [0, round(np.pi/2.0, 5)], Pmutate))
(idv2_x, idv2_y, idv2_z) = (mutate(idv2_x, [0, row], Pmutate),
mutate(idv2_y, [0, column], Pmutate),
mutate(idv2_z, [0, round(np.pi/2.0, 5)], Pmutate))
(new_indvs[m][0], new_indvs[m][1], new_indvs[m][2]) = (idv1_x, idv1_y, idv1_z)
(new_indvs[m+1][0], new_indvs[m+1][1], new_indvs[m+1][2]) = (idv2_x, idv2_y, idv2_z)
m += 2
indvs = new_indvs
print best_fitness,best_indv