优化模型---002-GA遗传算法

遗传算法

在遗传算法中 个体也称为染色体 由二进制串组成 用一串二进制表示一个个体

选择算子
模拟自然界 的优胜劣汰 运用个体适应度来进行概率选择
轮盘选择: 适应度占的总适应度是选择的概率
fit(xi) 占 总fit 的 Bi

进行累加 c1=b1 c2=c1+b2 c3=c2+b3 ...
抽一个rand  比较rand和c1 c2 计算rand>c的个数 若为n  则选择n+1为留下的个体


交叉算子
模拟交配过程 随机选两个个体 交叉算子以概率pc对他们执行交叉 交叉包括了一点交叉和两点交叉

变异算子
每个个体 有pm的概率发生变异 个体中的每个bit都可能变异 变异即取反

算法实现

maxmize(x) = -x^2 + 10cos(2Πx) + 30 -5<x<5
精度维0.01 则编码要有1000个变化 2^10 = 1024
所以为编码长度10 解码: x = -5 + 10/1024 * 编码值

import math
import random


# 计算适应值
def get_fit(x):
	res = -x ** 2 + 10 * math.cos(2 * 3.14 * x) + 30
	return res


# 得到编码
def get_binary(x):
	s = ''
	# 映射到 0 --- 1000

	# -5 == 0   5 == 1023
	# 将x 映射到 0 - 1023
	x = int((x + 5) * 102.4)
	# print(x)
	while x != 0:
		bit = x % 2
		s += str(bit)
		x = x // 2
	while len(s) != 10:
		s += '0'
	return s[::-1]


# 得到初始种群数
def get_init_x():
	res = []
	for i in range(20):
		res.append(round(random.uniform(-5, 5), 2))

	return res


def unzip(binary_num):
	res = 0
	binary_num = binary_num[::-1]
	# print(binary_num)
	for j in range(10):
		res += int(binary_num[j]) * (2 ** j)
		# print(int(binary_num[j]) * (2 ** j) )
		# print("res{},2**i{}".format(res,2**i))
	res = res / 102.4 - 5
	return round(res, 2)


def select_fit(binary_list):
	x_list = []
	c_list = []
	for i in binary_list:
		x_list.append(unzip(i))

	fit_list = [get_fit(i) for i in x_list]
	b_list = [i / sum(fit_list) for i in fit_list]

	c_list.append(b_list[0])

	for i in range(1, 20):
		# print(i,i-1)
		c_list.append(b_list[i] + c_list[i - 1])
	# print(c_list)

	"""
	开发日志:
		改写轮盘算法了了
		# 保留一半
	"""
	father_list = []
	for i in range(10):
		cmd = random.uniform(0, 1)
		k = 0
		for i in c_list:
			if cmd > i:
				k += 1
			else:
				break
		father_list.append(binary_list[k])

	return father_list


# 杂交函数
def crossover(father_list, cpoint, pc):
	# cpoint 杂交分割
	# pc 杂交概率
	while len(father_list) < 20:
		parent_1 = list(father_list[random.randint(0, len(father_list) - 1)])
		parent_2 = list(father_list[random.randint(0, len(father_list) - 1)])
		# print(parent_1)
		# print(parent_2)
		# print('\n')
		if random.uniform(0, 1) < pc:
			temp = parent_1[cpoint:]
			# print("temp:{}".format(temp))
			# print(parent_1,parent_2)
			parent_1[cpoint:] = parent_2[cpoint:]
			parent_2[cpoint:] = temp
			# print(parent_1,parent_2)
			temp1 = ''
			temp2 = ''
			father_list.append(temp1.join(parent_1))
			father_list.append(temp2.join(parent_2))

	return father_list


# 突变

def mutation(g_list, pc):
	res_list = []
	res = ''
	for i in g_list:
		i = list(i)
		# print(i)
		for j in range(len((i))):
			p = random.uniform(0, 1)
			if p < pc:
				if i[j] == '0':
					i[j] = '1'
				else:
					i[j] = '0'
		# print(i)
		res = res.join(i)
		# print(res)
		res_list.append(res)
		res = ''

	return res_list


init_x = get_init_x()
binary_list = []
for x in init_x:
	binary_list.append(get_binary(x))

for i in range(10000):
	father_list = select_fit(binary_list)
	# print(father_list)
	father_list = crossover(father_list, 8, 0.4)
	binary_list = mutation(father_list, 0.1)


	# print(father_list)
	# print(res_list)
pre_list = []
for i in binary_list:
	n = unzip(i)
	pre_list.append(get_fit(n))
print(max(pre_list))

x_list = [i/100 for i in range(-500,500)]

y_list = []
for i in x_list:
	res = get_fit(i)
	y_list.append(res)

print(max(y_list))
posted @ 2022-04-23 17:00  cc学习之路  阅读(148)  评论(0)    收藏  举报