You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

遗传算法——无序变长染色体的交叉策略咨询

嘿,针对你开发的这款带有无序、可变长度且允许重复染色体的遗传算法,我整理了一些Python实现的关键思路和代码示例,帮你搞定核心环节:

核心需求回顾
  • 染色体为无序结构:个体内染色体的排列顺序不影响适应度得分
  • 染色体长度不固定:个体的染色体数量从1条到100+不等
  • 允许染色体重复存在
  • 用Python实现,染色体以列表形式存储

简化版个体示例

# 示例个体Ea(含重复染色体)
individual_ea = ["gene_Alpha", "gene_Beta", "gene_Alpha", "gene_Gamma"]

# 示例个体Eb(仅1条染色体)
individual_eb = ["gene_Delta"]
关键实现要点

1. 适应度计算(核心:忽略顺序,关注组成与数量)

因为染色体无序,计算适应度时要完全抛开列表顺序,只统计基因的类型和出现次数。可以用collections.Counter来快速处理:

from collections import Counter

def calculate_fitness(individual):
    # 统计每个基因的出现次数
    gene_counts = Counter(individual)
    # 示例:根据基因权重计算适应度(可根据你的业务逻辑调整)
    fitness = gene_counts.get("gene_Alpha", 0) * 2 + gene_counts.get("gene_Gamma", 0) * 3
    return fitness

2. 选择操作(无需特殊调整,复用经典策略)

常规的选择方法(轮盘赌、锦标赛选择等)依然适用,只要确保传入的是基于基因组成计算出的正确适应度值即可,不需要因为染色体的无序/可变长度做额外修改。

3. 交叉操作(难点:设计不依赖顺序的融合逻辑)

针对无序+可变长度的特点,推荐两种实用的交叉策略:

随机子集交叉

从两个父代中按随机比例选取基因(允许重复),直接合并成子代:

import random

def crossover(parent1, parent2):
    # 随机分配从两个父代取基因的比例(避免极端比例)
    take_ratio_p1 = random.uniform(0.3, 0.7)
    take_ratio_p2 = 1 - take_ratio_p1
    
    # 从父代中随机采样对应数量的基因(允许重复采样)
    child_part1 = random.choices(parent1, k=int(len(parent1)*take_ratio_p1))
    child_part2 = random.choices(parent2, k=int(len(parent2)*take_ratio_p2))
    
    # 合并得到子代
    return child_part1 + child_part2

基因计数融合

先统计两个父代的基因出现次数,按比例融合计数后,再生成子代列表:

def crossover_by_count(parent1, parent2):
    count_p1 = Counter(parent1)
    count_p2 = Counter(parent2)
    child_counts = {}
    
    # 融合两个父代的基因计数(按50%比例示例)
    for gene in set(count_p1.keys()).union(count_p2.keys()):
        count_p1_val = count_p1.get(gene, 0)
        count_p2_val = count_p2.get(gene, 0)
        child_counts[gene] = int((count_p1_val + count_p2_val) * 0.5)
    
    # 根据计数生成子代列表
    child = []
    for gene, cnt in child_counts.items():
        child.extend([gene]*cnt)
    # 确保子代至少有1条染色体
    return child if child else [random.choice(list(count_p1.keys()) + list(count_p2.keys()))]

4. 变异操作(适配可变长度特性)

设计三种变异类型,覆盖替换、添加、删除场景:

def mutate(individual, gene_pool):
    mutation_type = random.choice(["replace", "add", "delete"])
    
    if mutation_type == "replace" and len(individual) > 0:
        # 随机替换一个基因
        idx = random.randint(0, len(individual)-1)
        individual[idx] = random.choice(gene_pool)
    elif mutation_type == "add":
        # 随机添加一个新基因
        individual.append(random.choice(gene_pool))
    elif mutation_type == "delete" and len(individual) > 1:
        # 随机删除一个基因(保证个体至少有1条染色体)
        idx = random.randint(0, len(individual)-1)
        del individual[idx]
    
    return individual

内容的提问来源于stack exchange,提问作者Wayne Workman

火山引擎 最新活动