前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >遗传算法——以背包问题为例

遗传算法——以背包问题为例

作者头像
曼亚灿
发布2023-09-21 08:22:10
3900
发布2023-09-21 08:22:10
举报
文章被收录于专栏:亚灿网志

优胜略汰,自然选择

What's Genetic Algorithm?

A Genetic Algorithm (GA) is a type of optimization algorithm that is inspired by the process of natural selection and genetics. GAs are used to find approximate solutions to optimization and search problems, especially in cases where the search space is vast and complex. They are particularly useful when you have a large solution space and don't know the mathematical form of the objective function you're trying to optimize.

什么是背包问题?

假设我们有一个背包,最多只能装6件物品且物品总重量不超过80,如何才能找到一个组合,可以尽量让装进去的物品总价值最高?

物品1

物品2

物品3

物品4

物品5

物品6

重量

25

15

20

30

20

15

价值

15

5

10

20

10

10

这,就是背包问题。

GA算法解决背包问题

随机初始化种群函数

代码语言:javascript
复制
def init_population(population_size: int = 50) -> list:
    """
    Create a population of random solutions
    :param population_size: Number of organisms in a population
    :return: Randomly generated population
    """
    population = []
    for i in range(population_size):
        chromosome = []
        for j in range(num_items):
            chromosome.append(random.randint(0, 1))
        population.append(chromosome)

    return population

该函数用于初始化一个种群,该种群中具有population_size个成员。

以随机化得到的第二个成员[1, 1, 0, 1, 1, 1]为例:

表示选择1、2、4、5、6号物品装入背包的组合。

基因评价函数

代码语言:javascript
复制
def evaluate_fitness(chrom: list) -> int:
    """
    Evaluate the fitness of a solution using your objective function
    :param chrom: 基因序列
    :return: 返回该基因序列的“质量高低“
    """
    weight_sum, value_sum = 0, 0
    for i in range(len(chrom)):
        if chrom[i] == 1:
            weight_sum, value_sum = weight_sum + weights[i], value_sum + values[i]

    return 0 if weight_sum > capacity else value_sum

该函数的作用是,传入一个成员的基因(物品)组合,然后返回其基因质量评分。对应到背包问题,就是返回该种组合物品的总价值。

需要特殊说明的是,当物品总重量超过限制值时(weight_sum > capacity),则返回0,因为此时价格没有意义。

种群优质成员选择

代码语言:javascript
复制
def select_parents(population: list, selection_rate: float = 0.5) -> list:
    """
    Select parents based on their fitness
    :param population: All members of the population
    :param selection_rate: Selection ratio of high-quality members
    :return: high-quality members(Selected by function evaluate_fitness())
    """
    population_fitness_values = []
    for chrom in population:  # 遍历种群中每一个成员的基因,得到其基因”评分“
        population_fitness_values.append(evaluate_fitness(chrom))

    sorted_population = [x for _, x in
                         sorted(zip(population_fitness_values, population), reverse=True)]  # 将种群中的成员按照其基因”质量评分“升序排列
    cut_num = int(selection_rate * len(sorted_population))  # 只选择前cut_num个”优质“种群成员用于后续交配繁衍
    return sorted_population[:cut_num]  # 返回”优质“种群成员

该函数的作用是对种群中的优质成员进行筛选。反应到背包问题中,就是对当前所有物品组合的价值进行排序,过滤价值较高的组合。

父类繁衍函数

代码语言:javascript
复制
def crossover(parent_0: list, parent_1: list) -> list:
    """
    Perform crossover to create offspring
    :param parent_0: First parent class member
    :param parent_1: Second parent class member
    :return: Two offspring by exchanging information between two parents
    """
    cut_point = random.randint(0, len(parent_0) - 1)
    child = parent_0[:cut_point] + parent_1[cut_point:]
    # child_1 = parent_1[:cut_point] + parent_0[cut_point:]
    return child

该函数的作用是对两个传入父类的基因进行交叉重组,得到一个新的子类。

函数用法举例

基因突变函数

代码语言:javascript
复制
def mutate(chrom: list, mutation_rate: float = 0.01) -> list:
    """
    Apply mutation to a solution
    :param mutation_rate: Probability of gene mutations
    :param chrom: Normal chromosomes
    :return: Mutated chromosomes
    """
    for i in range(len(chrom)):
        if random.random() < mutation_rate:
            j = random.randint(0, num_items - 1)
            chrom[i], chrom[j] = chrom[j], chrom[i]

    return chrom

该函数的作用是对某个成员的基因进行突变。

函数用法举例

GA算法思路

代码语言:javascript
复制
# Main GA loop
num_iterations = 100  # 循环迭代数——即进行多少代的繁衍
population = init_population(100)  # 初始化100个种群成员

for generation in range(num_iterations):  # 开始优胜略汰循环繁衍
    # 对初始种群成员进行过滤筛选,保留“高质量”种群成员基因
    parents = select_parents(population)

    # 使用“高质量”种群成员基因交配繁衍新成员
    offspring = []
    for _ in range(len(population) - len(parents)):  # 优胜略汰淘汰了几个种群成员,那么就再在“优秀”成员中繁衍出几个新成员
        parent_0, parent_1 = random.choice(parents), random.choice(parents)  # 随机选择两个高质量成员
        child = crossover(parent_0, parent_1)  # 交换基因得到新成员
        child = mutate(child)  # 新成员进行基因变异
        offspring.append(child)

    # 将新成员补充到种群中
    population = parents + offspring

# 对经过多次迭代循环后的种群基因进行排序,选择出最好的
best_chrom = max(population, key=evaluate_fitness)
best_fitness = evaluate_fitness(best_chrom)
print('Best Solution: ', best_chrom)
print('Best Fitness: ', best_fitness)

最终解

对于该问题,最终的解为选择物品1、3、4装入背包,总重量为75(满足小于80的需求),总价值为45。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • What's Genetic Algorithm?
  • 什么是背包问题?
  • GA算法解决背包问题
    • 随机初始化种群函数
      • 基因评价函数
        • 种群优质成员选择
          • 父类繁衍函数
            • 基因突变函数
            • GA算法思路
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档