栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【0-1背包问题】遗传算法 python 完整代码可直接运行

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【0-1背包问题】遗传算法 python 完整代码可直接运行

1.导入所需要的库

import numpy as np
import matplotlib.pyplot as plt

2.初始化

#初始化种群,popsize代表种群个数,n代表基因长度,
def init(popsize,n):
    population=[]
    for i in range(popsize):
        pop=''
        for j in range(n):

            pop=pop+str(np.random.randint(0,2))
        population.append(pop)
    return population

3.计算fitness

#计算种群中重量和效益
def computeFitness(population,weight,profit):
    total_weight = []
    total_profit = []
    for pop in population:
        weight_temp = 0
        profit_temp = 0
        for index in range(len(pop)):
            if pop[index] == '1':
                weight_temp += int(weight[index])
                profit_temp += int(profit[index])
        total_weight.append(weight_temp)
        total_profit.append(profit_temp)
    return  total_weight,total_profit
#计算单个个体
def computesingle(single,profit):
    profit_temp = 0
    for index in range(len(single)):
        if single[index] == '1':
            profit_temp += int(profit[index])
    return profit_temp

4.筛选

#筛选符合条件的
def select(population,weight_limit,total_weight,total_profit):
    w_temp = []
    p_temp = []
    pop_temp = []
    for weight in total_weight:
        out = total_weight.index(weight)
        if weight <= weight_limit:
            w_temp.append(total_weight[out])
            p_temp.append(total_profit[out])
            pop_temp.append(population[out])
    return pop_temp,w_temp,p_temp

4.轮盘赌选择

def roulettewheel(s_pop,total_profit):

    p =[0]
    temp = 0

    sum_profit = sum(total_profit)
    for i in range(len(total_profit)):

        unit = total_profit[i]/sum_profit
        p.append(temp+unit)
        temp += unit
    new_population = []
    i0 = 0
    while i0 < popsize:
        select_p = np.random.uniform()
        for i in range(len(s_pop)):

            if select_p > p[i] and select_p <= p[i+1]:
                new_population.append(s_pop[i])
        i0 += 1
    return new_population

5.交叉、变异

def ga_cross(new_population,total_profit,pcross):#随机交配

    new = []

    while len(new) < popsize:
        mother_index = np.random.randint(0, len(new_population))
        father_index = np.random.randint(0, len(new_population))
        threshold = np.random.randint(0, n)
        if (np.random.uniform() < pcross):
            temp11 = new_population[father_index][:threshold]
            temp12 = new_population[father_index][threshold:]
            temp21 = new_population[mother_index][threshold:]
            temp22 = new_population[mother_index][:threshold]
            child1 = temp11 + temp21
            child2 = temp12 + temp22
            # new.append(child1)
            # new.append(child2)
            pro1 = computesingle(child1, profit)
            pro2 = computesingle(child2, profit)
            if pro1 > total_profit[mother_index] and pro1 > total_profit[father_index]:
                new.append(child1)
            else:
                if total_profit[mother_index] > total_profit[father_index]:
                    new.append(new_population[mother_index])
                else:
                    new.append(new_population[father_index])
            if pro2 > total_profit[mother_index] and pro1 > total_profit[mother_index]:
                new.append(child2)
            else:
                if total_profit[mother_index] > total_profit[father_index]:
                    new.append(new_population[mother_index])
                else:
                    new.append(new_population[father_index])
    return new

def mutation(new,pm):
    temp =[]
    for pop in new:
        p = np.random.uniform()
        if p < pm:
            point = np.random.randint(0, len(new[0]))
            pop = list(pop)

            if pop[point] == '0':
                pop[point] = '1'
            elif pop[point] == '1':
                pop[point] = '0'
            pop = ''.join(pop)
            temp.append(pop)
        else:
            temp.append(pop)
    return temp

总结:

遇到了不收敛的情况,但是总体上能获得最优解,代码可以运行,如果有错误感谢大神指出!

完整代码:

import numpy as np
import matplotlib.pyplot as plt


#初始化种群,popsize代表种群个数,n代表基因长度,
def init(popsize,n):
    population=[]
    for i in range(popsize):
        pop=''
        for j in range(n):

            pop=pop+str(np.random.randint(0,2))
        population.append(pop)
    return population
#计算种群中每个个体此时所代表的解的重量和效益
def computeFitness(population,weight,profit):
    total_weight = []
    total_profit = []
    for pop in population:
        weight_temp = 0
        profit_temp = 0
        for index in range(len(pop)):
            if pop[index] == '1':
                weight_temp += int(weight[index])
                profit_temp += int(profit[index])
        total_weight.append(weight_temp)
        total_profit.append(profit_temp)
    return  total_weight,total_profit

def computesingle(single,profit):
    profit_temp = 0
    for index in range(len(single)):
        if single[index] == '1':
            profit_temp += int(profit[index])
    return profit_temp

#筛选符合条件的
def select(population,weight_limit,total_weight,total_profit):
    w_temp = []
    p_temp = []
    pop_temp = []
    for weight in total_weight:
        out = total_weight.index(weight)
        if weight <= weight_limit:
            w_temp.append(total_weight[out])
            p_temp.append(total_profit[out])
            pop_temp.append(population[out])
    return pop_temp,w_temp,p_temp


def roulettewheel(s_pop,total_profit):

    p =[0]
    temp = 0

    sum_profit = sum(total_profit)
    for i in range(len(total_profit)):

        unit = total_profit[i]/sum_profit
        p.append(temp+unit)
        temp += unit
    new_population = []
    i0 = 0
    while i0 < popsize:
        select_p = np.random.uniform()
        for i in range(len(s_pop)):

            if select_p > p[i] and select_p <= p[i+1]:
                new_population.append(s_pop[i])
        i0 += 1

        # if select_p < p[0]:
        #     new_population.append(s_pop[0])
        #     i += 1
        # elif p[1] <= select_p < p[2]:
        #     new_population.append(s_pop[1])
        #     i += 1
        # for index  in range(3,len(s_pop)):
        #     if p[index - 1] < select_p <= p[index]:
        #         new_population.append(s_pop[index])
        #         i += 1
        #     break
    # print(len(new_population))
    return new_population
def ga_cross(new_population,total_profit,pcross):#随机交配

    new = []

    while len(new) < popsize:
        mother_index = np.random.randint(0, len(new_population))
        father_index = np.random.randint(0, len(new_population))
        threshold = np.random.randint(0, n)
        if (np.random.uniform() < pcross):
            temp11 = new_population[father_index][:threshold]
            temp12 = new_population[father_index][threshold:]
            temp21 = new_population[mother_index][threshold:]
            temp22 = new_population[mother_index][:threshold]
            child1 = temp11 + temp21
            child2 = temp12 + temp22
            # new.append(child1)
            # new.append(child2)
            pro1 = computesingle(child1, profit)
            pro2 = computesingle(child2, profit)
            if pro1 > total_profit[mother_index] and pro1 > total_profit[father_index]:
                new.append(child1)
            else:
                if total_profit[mother_index] > total_profit[father_index]:
                    new.append(new_population[mother_index])
                else:
                    new.append(new_population[father_index])
            if pro2 > total_profit[mother_index] and pro1 > total_profit[mother_index]:
                new.append(child2)
            else:
                if total_profit[mother_index] > total_profit[father_index]:
                    new.append(new_population[mother_index])
                else:
                    new.append(new_population[father_index])
    return new

def mutation(new,pm):
    temp =[]
    for pop in new:
        p = np.random.uniform()
        if p < pm:
            point = np.random.randint(0, len(new[0]))
            pop = list(pop)

            if pop[point] == '0':
                pop[point] = '1'
            elif pop[point] == '1':
                pop[point] = '0'
            pop = ''.join(pop)
            temp.append(pop)
        else:
            temp.append(pop)
    return temp


def plot():
    x= range(iters)

    plt.plot(x,ylable)
    plt.show()

if __name__ == "__main__":
    weight = [95,75,23,73,50,22,6,57,89,98]

    profit = [89,59,19,43,100,72,44,16,7,64]

    n = len(profit)
    weight_limit = 300
    pm = 0.05
    pc = 0.8
    popsize = 30
    iters = 500
    population = init(popsize, n)
    ylable = []
    iter = 0
    best_pop = []
    best_p = []
    best_w = []
    while iter < iters:
        # print(f'第{iter}代')
        # print("初始为",population)
        w, p = computeFitness(population, weight, profit)
        # print('weight:',w,'profit:',p)
        # print(w)
        # print(p)
        s_pop, s_w, s_p = select(population, weight_limit, w, p)

        best_index = s_p.index(max(s_p))
        ylable.append(max(s_p))
        best_pop.append(s_pop[best_index])
        best_p.append(s_p[best_index])
        best_w.append(s_w[best_index])
        # print(s_pop[best_index])
        # print(s_p[best_index])
        # print(s_w[best_index])
        # print(f'筛选后的种群{s_pop},长度{len(s_pop)},筛选后的weight{s_w},筛选后的profit{s_p}')
        new_pop = roulettewheel(s_pop, s_p)
        w,p1 = computeFitness(new_pop, weight, profit)
        # print(f'轮盘赌选择后{new_pop},{len(new_pop)}')
        new_pop1 = ga_cross(new_pop, p1, pc)
        # print(f'交叉后{len(new_pop1)}')
        population = mutation(new_pop1, pm)
        # print(population)
        # print(f'第{iter}迭代结果为{max(s_p)}')
        iter += 1
        # print(len(population1))
    best_i = best_p.index(max(best_p))
    plot()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/835356.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号