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

Python羊兔种群模拟问题:指数增长及物种未正确死亡排查

羊(S)与兔(R)种群模拟模型问题修复

模型规则

  • 不同物种的两只动物在nsides网格的同一方格相遇时,存在无死亡、两者都死亡或其一死亡的概率
  • 同一物种的两只动物在同一方格相遇时,有概率诞生新个体
  • 下一时间步,存活动物可向上下左右移动(网格边界采用循环处理)

现存问题

  • 两物种种群均呈无限制指数增长,未体现种间竞争的抑制作用
  • 不同物种相遇时,部分动物未被正确标记为死亡

代码问题定位

  1. 死亡状态赋值错误:标记动物死亡时误用比较运算符==,而非赋值运算符=,导致死亡状态从未被正确设置
  2. 种群更新逻辑错误:原代码将存活动物追加到旧的self.people列表后,而非替换原列表,导致死亡动物仍保留在种群中,叠加新繁殖个体后必然指数增长
  3. 缺失依赖导入:使用itertools.combinations但未导入itertools模块,运行会触发报错
  4. 重复处理风险:原逻辑中通过set去重存活动物,但People2实例不可哈希,set(not_killed)会触发错误

修复后的完整代码

import numpy as np
import itertools  # 补充缺失的导入

class People2:  # 动物类,保留原命名
    def __init__(self, status, species, nsides=40):
        self.nsides = nsides
        self.location = np.random.randint(0, self.nsides, [2])
        self.status = status  # 1=存活,0=死亡
        self.species = species

    def move(self):  # 随机上下左右移动,循环边界
        moves = np.random.randint(-1, 2, [2])
        self.location[0] = (self.location[0] + moves[0]) % self.nsides
        self.location[1] = (self.location[1] + moves[1]) % self.nsides


class World2:
    def __init__(self, time=0, maxtime=1000, nsides=40, npeople=2, nprob=0.9):
        self.npeople = npeople
        self.nprob = nprob  # 死亡/繁殖概率参数
        self.nsides = nsides
        self.time = time
        self.maxtime = maxtime
        
        # 初始化种群:交替生成兔(R)和羊(S)
        self.people = []
        for i in range(self.npeople):
            species = 'R' if i % 2 == 0 else 'S'
            self.people.append(People2(status=1, species=species, nsides=nsides))
        
    def step(self):  # 重命名movement为step,更贴合模拟逻辑
        new_individuals = []
        # 生成所有存活动物的两两组合
        alive_animals = [animal for animal in self.people if animal.status == 1]
        animal_pairs = itertools.combinations(alive_animals, 2)
        
        for a1, a2 in animal_pairs:
            # 仅处理同一位置的动物对
            if np.all(a1.location == a2.location):
                if a1.species != a2.species:
                    # 不同物种相遇:判断死亡概率
                    # nprob是存活概率,1-nprob是死亡概率
                    a1_survive = np.random.choice([True, False], p=[self.nprob, 1-self.nprob])
                    a2_survive = np.random.choice([True, False], p=[self.nprob, 1-self.nprob])
                    if not a1_survive:
                        a1.status = 0
                    if not a2_survive:
                        a2.status = 0
                else:
                    # 同一物种相遇:判断繁殖概率
                    reproduce = np.random.choice([True, False], p=[self.nprob, 1-self.nprob])
                    if reproduce:
                        new_individuals.append(People2(status=1, species=a1.species, nsides=self.nsides))
        
        # 更新种群:保留存活个体 + 添加新繁殖个体
        self.people = [animal for animal in self.people if animal.status == 1] + new_individuals
        
        # 所有存活动物移动
        for animal in self.people:
            animal.move()
        
        self.time += 1
        return self.people


# 模拟运行
anim_world = World2(npeople=10, nprob=0.7)  # 调整初始种群和概率便于观察
rabbit_counts = []
sheep_counts = []

for _ in range(20):  # 模拟20步
    current_pop = anim_world.step()
    r_count = sum(1 for animal in current_pop if animal.species == 'R')
    s_count = sum(1 for animal in current_pop if animal.species == 'S')
    rabbit_counts.append(r_count)
    sheep_counts.append(s_count)

print("兔种群数量变化:", rabbit_counts)
print("羊种群数量变化:", sheep_counts)

修复说明

  1. 修正死亡状态赋值:将r[1].status==0改为a1.status = 0,确保死亡状态被正确设置
  2. 重构种群更新逻辑:每次模拟步后,直接筛选存活个体并添加新繁殖个体,替换原self.people列表,避免旧个体残留
  3. 补充itertools导入,修复运行报错
  4. 优化动物对处理逻辑:先筛选存活动物再生成组合,减少无效计算
  5. 重命名movement方法为step,更符合模拟步骤的语义
  6. 调整概率逻辑的可读性:用布尔值替代0/1,代码更直观

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:22:34