You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二维世界遗传算法控制的生物未实现有效学习的问题排查

遗传算法优化生物适应度:进化停滞问题排查与解决建议

我的目标

我尝试实现遗传算法,优化二维模拟世界中某类生物的适应度。该世界包含随机分布的可食用食物与怪物(基础僵尸),需算法找出让生物保持饱腹且存活的行为。

已完成的工作

  • 用NumPy生成11×9的二维数组作为染色体,填充0到1的随机浮点数;
  • 通过np.matmul将染色体每行的随机权重与所有感知器(percepts)计算得到动作(actions);
  • 适应度计算公式为:(能量 + 死亡时间×100);
  • 选择适应度高于平均值的精英个体,保留最优精英至下一代种群,剩余空位通过两种交叉方式生成新个体:每行双点交叉、交替选取父母染色体行。

遇到的核心问题

生物完全没表现出有效学习能力:75回合的模拟里,偶尔出现1个幸存者,偶尔有3-4个,但完全是随机的,看不到任何逐步进化的趋势。

核心代码片段

#!/usr/bin/env python
from cosc343world import Creature, World
import numpy as np
import time
import matplotlib.pyplot as plt
import random
import itertools

# 可配置参数
numGenerations = 2000
numTurns = 75
worldType=2
gridSize=24
repeatableMode=False

class MyCreature(Creature):
    def __init__(self, numPercepts, numActions):
        # 染色体为11×9的随机浮点数数组
        self.chromosome = np.random.rand(11,9)
        self.fitness = 0
        Creature.__init__(self)

    def AgentFunction(self, percepts, numActions):
        # 通过矩阵乘法将感知映射为动作
        actions = np.matmul(self.chromosome, percepts)
        return actions.tolist()

# 注:原始代码未完成种群更新的后续逻辑

问题排查与优化建议

我帮你梳理下几个最可能导致进化停滞的点,以及对应的修复方案:

1. 染色体与动作/感知的维度匹配问题

你用了11×9的染色体矩阵做np.matmul,这里必须满足感知器的维度是9,同时输出的动作维度是11,但代码里的numActions参数如果不是11的话,这就会出现不匹配的问题——模拟世界可能期望你输出固定维度的动作,但你给的维度不对,导致生物行为完全混乱。

修复建议:

  • 先在__init__里加print(numPercepts, numActions),确认感知器和动作的实际维度;
  • 调整染色体形状为(numActions, numPercepts),这样np.matmul(chromosome, percepts)就能得到刚好numActions维度的动作向量。

2. 适应度函数的设计偏差

当前的适应度公式(能量 + 死亡时间×100)有很大问题:死亡时间的权重太高了,会导致那些“啥也不干,躲在角落苟活更久”的个体,比“主动觅食但不小心被怪物打死”的个体适应度高得多。这种导向下,种群根本不会朝着“有效生存”的方向进化,反而会往消极避战的方向走,自然看不到进化趋势。

修复建议:
重新设计适应度公式,强化“存活到最后”和“保持高能量”的正向反馈,比如:

# 示例:能量权重2,存活回合权重5,活到最后的额外奖励100
fitness = (creature.energy * 2) + (creature.time_alive * 5) + (100 if creature.is_alive else 0)

这样既能鼓励存活,也能鼓励主动觅食获取能量。

3. 缺少变异操作,种群多样性不足

你只实现了交叉,但完全没有变异操作!遗传算法里,交叉是组合已有基因,而变异是引入新的基因多样性。如果种群一开始的基因池没有能产生有效行为的个体,交叉来交叉去还是那些无效基因,根本跳不出随机混乱的状态。

修复建议:
给新生成的个体添加高斯变异,比如:

def mutate_chromosome(chromosome, mutation_rate=0.03, sigma=0.1):
    # 遍历染色体的每个权重,以mutation_rate的概率进行变异
    for i in range(chromosome.shape[0]):
        for j in range(chromosome.shape[1]):
            if random.random() < mutation_rate:
                # 给权重加一个小的高斯噪声
                chromosome[i][j] += np.random.normal(0, sigma)
                # 把权重限制在0-1之间(和初始化的范围一致)
                chromosome[i][j] = np.clip(chromosome[i][j], 0, 1)
    return chromosome

在交叉生成新个体后,调用这个函数对其染色体进行变异,保持种群的基因多样性。

4. 动作输出未标准化

np.matmul输出的动作值可能范围非常大(比如从负几十到正几十),但模拟世界大概率期望动作是标准化后的数值(比如0-1之间的概率值,或者-1到1的方向向量)。如果动作值超出了世界能处理的范围,生物的行为就会完全随机,根本无法体现染色体的控制作用。

修复建议:
在AgentFunction里对动作进行归一化处理:

def AgentFunction(self, percepts, numActions):
    actions = np.matmul(self.chromosome, percepts)
    # 归一化到0-1范围
    if np.max(actions) != np.min(actions):
        actions = (actions - np.min(actions)) / (np.max(actions) - np.min(actions))
    else:
        actions = np.zeros_like(actions)
    return actions.tolist()

或者用sigmoid函数把值压缩到0-1之间,确保动作在合理范围内。

5. 精英保留策略的细节优化

你提到保留最优精英,但如果只保留1个最优个体,很容易导致种群被这个个体的基因垄断,失去多样性;如果精英比例太高,同样会限制进化的可能性。

修复建议:

  • 每代保留Top 10%的精英个体(比如种群规模是50的话,保留5个);
  • 精英个体直接进入下一代,不参与交叉和变异,保证优秀基因的延续;
  • 剩余的种群空位由交叉+变异的方式生成。

6. 种群规模与进化代数的匹配

2000代看起来很多,但如果你的种群规模太小(比如少于30个个体),基因多样性根本不够,进化就会陷入随机波动。

修复建议:

  • 把种群规模调整到50-100个个体,保证足够的基因多样性;
  • 先把进化代数降到500代,观察是否有明显的进化趋势,再逐步调整代数值。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:34:15