一段python的遗传算法代码

帮朋友写了一段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

你可能感兴趣的:(算法)