遗传算法(Genetic Algorithm)之deap学习笔记(三): 多目标优化算法1:背包问题

文章介绍了一个使用PythonDEAP库来解决多目标背包问题的示例。DEAP是一个用于进化算法的框架,文中通过创建适应度函数、遗传操作(交叉和变异)以及NSGA2选择策略,实现了一个遗传算法,以同时最大化价值和最小化重量。代码包括了问题定义、个体生成、种群初始化、评估、交叉和变异操作,并展示了结果的图形化输出。
摘要由CSDN通过智能技术生成

背包问(The knapsack problem)是一个多目标问题:给定一组可能的物品,每个物品都有一个重量和一个值,最大化袋中物品的价值,同时最小化重量。 对包内物品的数量也有重量限制和数量限制。

定义问题

import random
import numpy
import operator

NBR_ITEMS = 100     # 物品的总数量
IND_INIT_SIZE = 5   # 每个背包一开始的物品数量
MAX_ITEM = 50       # 一个背包最多可以装多少个物品
MAX_WEIGHT = 50     # 一个背包最大的重量

创建一个字典储存,名字是整数,值是元组

NBR_ITEMS

items = {}
for i in range(NBR_ITEMS):
    items[i] = (random.randint(1, 10), random.uniform(0, 100))

遗传算法

from deap import algorithms
from deap import base
from deap import creator
from deap import tools

# 如何创建请看之前的笔记
creator.create("Fitness", base.Fitness, weights=(-1.0, 1.0))
creator.create("Individual", set, fitness=creator.Fitness)
# 这里使用set可以更好的表达问题

创建toolbox

toolbox = base.Toolbox()
toolbox.register("attr_item", random.randrange, NBR_ITEMS)
toolbox.register("individual", tools.initRepeat, creator.Individual, 
    toolbox.attr_item, IND_INIT_SIZE)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

建立evaluation function

这里会返回两个fitness值(重量和数量)

# 把weight设置成10000如果超过了界限
def evalKnapsack(individual):
    weight = 0.0
    value = 0.0
    for item in individual:
        weight += items[item][0]
        value += items[item][1]
    if len(individual) > MAX_ITEM or weight > MAX_WEIGHT:
        return 10000, 0
    return weight, value

在set里面不可以使用crossover和mutation,所以我们要自己定义

def cxSet(ind1, ind2):
    temp = set(ind1)                
    ind1 &= ind2                    # Intersection (inplace)
    ind2 ^= temp                    # Abslute difference (inplace)
    return ind1, ind2

定义mutation方程

def mutSet(individual):
    if random.random() < 0.5:
        if len(individual) > 0:
            individual.remove(random.choice(sorted(tuple(individual))))
    else:
        individual.add(random.randrange(NBR_ITEMS))
    return individual,

toolbox.register("evaluate", evalKnapsack)
toolbox.register("mate", cxSet)
toolbox.register("mutate", mutSet)
# 注册选择函数,并使用selNSGA2算法
toolbox.register("select", tools.selNSGA2)
inv1 = toolbox.individual()
print(inv1)

# Individual({58, 35, 13, 39})

设置概率以及数量等

NGEN = 500
popSize = MU = 200
LAMBDA = 400
CXPB = 0.5
MUTPB = 0.2

下面使用内置算法。 在这里,我们使用 Mu + Lambda 算法。 Lambda 是繁殖到下一代的个体数量(我们只是将其设置为恒定的种群大小),Mu 是每一代要生产的孩子数量。 我们将其设置为人口规模的两倍,以便我们在选择时有选择。

def pareto_eq(ind1, ind2):
    return numpy.allclose(ind1.fitness.values, ind2.fitness.values)

pop = toolbox.population(n=popSize)
hof = tools.ParetoFront(similar=pareto_eq)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", numpy.mean, axis=0)
stats.register("std", numpy.std, axis=0)
stats.register("min", numpy.min, axis=0)
stats.register("max", numpy.max, axis=0)

pop, log = algorithms.eaMuPlusLambda(pop, toolbox, MU, LAMBDA, CXPB, MUTPB, NGEN, stats, halloffame=hof)

结果

import matplotlib.pyplot as plt
%matplotlib inline

gen = log.select("gen")
avgs = log.select("avg")
stds = log.select("std")

avgs_weight = [item[0] for item in avgs]
avgs_value = [item[1] for item in avgs]

avgs

画个图看一下结果

plt.rc('axes', labelsize=14)
plt.rc('xtick', labelsize=14)
plt.rc('ytick', labelsize=14) 
plt.rc('legend', fontsize=14)

fig, ax1 = plt.subplots()
line1 = ax1.plot(gen, avgs_weight)
ax1.set_xlabel("Generation")
ax1.set_ylabel("Fitness (weight)")

# weight
fig2, ax2 = plt.subplots()
line2 = ax2.plot(gen, avgs_value)
ax2.set_xlabel("Generation")
ax2.set_ylabel("Fitness (value)")

# value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值