一、遗传算法简介
二、二次分配问题描述
三、Python代码实现
import math
import random
import matplotlib.pyplot as plt
def getPermutation(n, x): #n为全排列的数量,x为一个二进制数
"""
这是一个逆康托函数
"""
nums = []
x = '0b' + x #加上二进制标签才能利于后面的计算
x = eval(x)
for i in range(1,n+1):
nums.append(i)
x = x-1
out = []
while nums:
p = x//math.factorial(len(nums)-1)
try:
out.append(nums[p])
except:
pass
x = x-p*math.factorial(len(nums)-1)
try:
nums.pop(p)
except:
pass
return out
def init(n):
'''这是一个生成初始种群的函数'''
Max = math.factorial(n) #Max是全排列的最大个数
max_n = len(bin(Max)) - 2 #max_n为一个染色体的长度
cs = []
individual = 100
for i in range(individual):
x = random.randint(1, Max)
x = str(bin(x)[2:])
len_x = len(x)
x = '0'*(max_n - len_x) + x #没有到长度前面用0补齐
cs.append(x)
return cs
def fitness(cs,n,v1,v2): #cs中每一个元素对应一个值
'''这是一个计算目标函数值的函数'''
fitness1 = [] #将值存在fitnees1[]中
for i in cs:
loca = getPermutation(n,i) #用逆康托函数求出全排列列表
cost_sum = 0
#二维矩阵遍历
for j in range(n):
for k in range(n):
loca1 = loca.index(j+1)
loca2 = loca.index(k+1)
cost = v2[j][k]*v1[loca1][loca2] #核心的计算函数
cost_sum = cost_sum + cost
fitness1.append(cost_sum)
return fitness1
def filter_max(cs,fitness1):
'''这是一个筛选函数'''
out = 80 #out为一次剔除的个体数
for i in range(out):
x = max(fitness1)
index = fitness1.index(x)
fitness1.pop(index)
cs.pop(index)
return cs,fitness1
def cross(cs,fitness1):
'''
交叉函数,传入cs,返回cs
'''
out = 80 #与剔除函数保持一致
for i in range(out):
proba = random.randint(1,10000)
y = len(cs)
#print('len(y):',y)
z = len(cs[0])
if proba >= 900: #依据概率交叉
#随机找两个个体交叉
index1 = random.randint(0,y-1)
index2 = random.randint(0,y-1)
cs1 = str(cs[index1])
cs2 = str(cs[index2])
new1 = cs1[0:17] + cs2[0:z-17]
cs.append(new1)
else:
index = fitness1.index(min(fitness1))
cs_new = cs[index]
cs.append(cs_new)
return cs
def Mutation(cs,fitness1): #cs为种群
'''变异函数
传入一个种群,返回一个种群'''
proba = random.randint(1,10000)
index = fitness1.index(min(fitness1))
if proba > 100:
y = len(cs)
max_n = len(cs[0])
r1 = random.randint(0,y-1)
r2 = random.randint(0,max_n-1)
if r1 != index:
cs_i = list(cs[r1]) #cs_i为被操作的基因
x = int(cs_i[r2])
cs_i[r2] = str(1-x)
cs_i = ''.join(cs_i)
cs[r1] = cs_i
return cs
if __name__ == '__main__':
v1 = [[0 ,1 , 2 , 2 , 3 , 4 , 4 , 5 , 3 , 5 , 6 , 7],
[1, 0 , 1 , 1 , 2 , 3 , 3 , 4 , 2 , 4 , 5 , 6],
[2 , 1 , 0 , 2 , 1 , 2 , 2 , 3 , 1 , 3 , 4 , 5],
[2 , 1 , 2 , 0 , 1 , 2 , 2 , 3 , 3 , 3 , 4 , 5],
[3 , 2 , 1 , 1 , 0 , 1 , 1 , 2 , 2 , 2 , 3 , 4],
[4 , 3 , 2 , 2 , 1 , 0 , 2 , 3 , 3 , 1 , 2 , 3],
[4 , 3 , 2 , 2 , 1 , 2 , 0 , 1 , 3 , 1 , 2 , 3],
[5 , 4 , 3 , 3 , 2 , 3 , 1 , 0, 4 , 2 , 1 , 2],
[3 , 2, 1 , 3 , 2 , 3 ,3 , 4 , 0 , 4 , 5 , 6],
[5 , 4 , 3 , 3 , 2 , 1 , 1 , 2 , 4 , 0 , 1 , 2],
[6 , 5 , 4 , 4 , 3 , 2 , 2 , 1 , 5 , 1 , 0 , 1],
[7 , 6 , 5 , 5 , 4 , 3 , 3 ,2 , 6 , 2 , 1 , 0]]
v2 = [[0 , 3 , 4 , 6 , 8 , 5 , 6 , 6 , 5 , 1 , 4 , 6],
[3 , 0 , 6 , 3 , 7 , 9 , 9 , 2 , 2 , 7 , 4 , 7],
[4 , 6 , 0 , 2 , 6 , 4 , 4 ,4 ,2 ,6 ,3 ,6],
[6 , 3 , 2 , 0 , 5 , 5 , 3 , 3 , 9 , 4 , 3 , 6],
[8 , 7 , 6 , 5 , 0 , 4 , 3 , 4 , 5 , 7 , 6 ,7],
[5 , 9 , 4 , 5 , 4 , 0 , 8 , 5 , 5 , 5 , 7 , 5],
[6 , 9 , 4 , 3 , 3 ,8 ,0 , 6 , 8 , 4 , 6 , 7],
[6 , 2 , 4 , 3 , 4 , 5 ,6 ,0 ,1 ,5 ,5 , 3],
[5 , 2 , 2 , 9 , 5 , 5 , 8 , 1 , 0 , 4 , 5 , 2],
[1 , 7 , 6 , 4 , 7 , 5 , 4 , 5 , 4 , 0 , 7 , 7],
[4 , 4 , 3 , 3 ,6 ,7 ,6 ,5 ,5 ,7 ,0 , 9],
[6 , 7 , 6 , 6 , 7 , 5 , 7 , 3 , 2 , 7 , 9 , 0]]
answer = []
cs = init(12)
fitness1 = fitness(cs,12,v1,v2)
evolution = 1200
for i in range(evolution):
cs,fitness1 = filter_max(cs,fitness1)
cs =cross(cs,fitness1)
fitness1 = fitness(cs,12,v1,v2)
for i in range(100):
cs = Mutation(cs,fitness1)
print(min(fitness1))
answer.append(min(fitness1))
print("最小解为:",min(answer))
plt.plot(answer)
#print(cs)
#print(fitness1)