由于在本例中,设置的初始种群的数量有限,且没有设置基因突变,因此得到的结果不能保证每一次都是最优的,只能保证每一次的适应度函数在结束时都是收敛的。
# coding utf-8
import random
x ={
1: [10, 15],
2: [15, 25],
3: [20, 35],
4: [25, 45],
5: [30, 55],
6: [35, 70]
}
# 定义终止界限
FINISH_LIMT = 0 []
# 重量界限
WEIGHT_LIMIT = 80
# 染色体长度
CHROMOSOME_SIZE =6
# 精选次数
SELECT_NUMBER = 4
# 记录上一代的最大值
max_last = 0
# 记录上一代和上上一代的适应函数的差
diff_last = 10000
# 随机精选出四个个体
# 用来初始化整个种群
def init():
chromosomes_state1 = '100100'
chromosomes_state2 = '101010'
chromosomes_state3 = '010101'
chromosomes_state4 = '101011'
chromosomes_states = [chromosomes_state1, chromosomes_state2, chromosomes_state3, chromosomes_state4]
return chromosomes_states
# 计算种群的适应度
# 将所有存入包中大的物品的重要的和作为当前种群的适应度
def fitness(chromosomes_states):
fitnesses = []
for chromosomes_state in chromosomes_states:
value_sum = 0
weight_sum = 0
# enumerate将数据对象组合为索引序列,同时列出数据下标和数据
for i,v in enumerate(chromosomes_state):
if int(v)==1:
weight_sum += x[i+1][0]
value_sum += x[i + 1][1]
fitnesses.append([value_sum,weight_sum])
return fitnesses
# 当这次的差异值和上次的差异值都小于终止界限
# 就可以认为适应度函数这时候已经开始收敛了
# 可以认为当前的种群已经达到最优的一代
def is_finished(fitnesses):
global max_last
global diff_last
max_current = 0
# 获得当前的适应度函数的最大值
for v in fitnesses:
if v[1]>max_current:
max_current = v[1]
diff = max_current - max_last
# 判断差异值,来决定是否已经到达了最优的种群
if diff<FINISH_LIMT and diff_last < FINISH_LIMT:
return True
else:
# 对最大值和和差异值进行更新
diff_last = diff
max_last = max_current
return False
# 精选下一代
# 先淘汰掉不能适应环境的,即淘汰重量大于80的
# 随机从上一代能适应环境的种群个体中选出几个个体进行下一代的繁衍
# 记录下精选个体的位置(同一个个体可能被选多次),因此slelect_index中可能有两个值是相同的
def filter(chromosomes_states,fitnesses):
index = len(fitnesses) - 1
while index >= 0:
index -= 1
if fitnesses[index][1] > WEIGHT_LIMIT:
chromosomes_states.pop(index)
fitnesses.pop(index)
select_index = [0] * len(chromosomes_states)
# 开始进行精选
for i in range(SELECT_NUMBER):
j = chromosomes_states.index(random.choice(chromosomes_states))
select_index[j] += 1
return select_index
# 产生下一代
# 从精选的四个个体里面依次取一个个体,再从能适应环境的个体中随机的取一个个体
# 交配产生新的下一代
def crossover(chromosomes_states,select_index):
chromosomes_states_new = []
tmp = chromosomes_states[:]
index = len(chromosomes_states) - 1
while index >= 0:
index -= 1
chromosomes_state = tmp.pop(index)
for i in range(select_index[index]):
chromosomes_state_x =random.choice(chromosomes_states)
# 随机产生基因序列的交配位置
pos = random.choice(range(1,CHROMOSOME_SIZE-1))
chromosomes_states_new.append(chromosomes_state[:pos]+chromosomes_state_x[pos:])
return chromosomes_states_new
# 种群的初始化
chromosomes_states = init()
# 让种群最多繁衍100代
n = 100
while n>0:
n -= 1
# 计算当前第100-i代种群的适应度
fitnesses = fitness(chromosomes_states)
for i in fitnesses:
print(i, end=' ')
# 利用相关条件判断当前的这一代是否能达到结束遗传的条件
if is_finished(fitnesses):
break
# 精选
select_index = filter(chromosomes_states,fitnesses)
# 产生下一代
chromosomes_states = crossover(chromosomes_states,select_index)
print()
print()
for i in chromosomes_states:
print(i,end=' ')