教你用遗传算法解决0-1背包问题||python实现

由于在本例中,设置的初始种群的数量有限,且没有设置基因突变,因此得到的结果不能保证每一次都是最优的,只能保证每一次的适应度函数在结束时都是收敛的。

# 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=' ')

 

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值