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

NetLogo六边形细胞聚合森林火灾模型点火功能故障求助

六边形森林火灾模型Ignite函数失效排查与修复方案

核心排查方向

针对ignite函数无效、火灾无法传播的问题,优先从以下关键环节排查:

1. 六边形邻居坐标计算错误

六边形网格的邻居逻辑和矩形网格完全不同,若邻居索引计算错误,会导致火灾无法找到可传播的目标细胞,甚至初始点火的细胞状态更新无法被感知:

  • 若使用轴向坐标,6个邻居的偏移应为(1,0), (1,-1), (0,-1), (-1,0), (-1,1), (0,1)(满足q+r+s=0的约束);
  • 若使用偏移坐标(如偶行偏移),需区分奇偶行的列偏移:偶行邻居列偏移为-1,0,1,奇行邻居列偏移为0,1,-1(行偏移均为-1,0,1,排除自身);
  • 务必检查邻居坐标是否在网格有效范围内,避免访问空细胞。

2. 细胞状态判断与更新逻辑漏洞

ignite函数的核心是状态切换,若状态判断或更新逻辑错误,会直接导致点火失效:

  • 确认状态枚举值是否统一:比如定义STATE_FOREST=0, STATE_BURNING=1, STATE_ASH=2,ignite函数仅能将STATE_FOREST的细胞切换为STATE_BURNING;
  • 检查状态更新是否作用于全局网格:若仅修改了局部变量而非网格中的实际细胞对象,状态变化不会被保存。

3. 初始点火的范围与有效性问题

随机初始点火若选中无效细胞,会出现“看似没点火”的假象:

  • 随机生成的细胞坐标必须在网格的行列范围内(如行索引0 <= r < rows,列索引0 <= c < cols);
  • 初始点火前需筛选出状态为“森林”的细胞,避免选中已燃烧或灰烬状态的细胞。

4. 主循环(Go函数)的执行顺序错误

若主循环中实时修改细胞状态,会导致同一帧内的状态干扰,引发传播逻辑混乱:

  • 正确流程:先遍历所有燃烧细胞,收集所有可点燃的邻居;再统一将这些邻居点燃;最后将燃烧细胞转为灰烬。禁止在遍历过程中直接修改细胞状态。

修复示例代码

以下是基于轴向坐标的六边形火灾模型核心实现,可直接参考调整你的代码:

细胞结构定义

class HexCell:
    def __init__(self, q, r):
        self.q = q  # 轴向坐标q
        self.r = r  # 轴向坐标r
        self.s = -q - r  # 轴向坐标s(满足q+r+s=0)
        self.state = 0  # 0: 未燃烧森林, 1: 燃烧中, 2: 灰烬

邻居获取函数

def get_neighbors(cell, grid):
    # 六边形6个方向的轴向偏移
    directions = [(1,0), (1,-1), (0,-1), (-1,0), (-1,1), (0,1)]
    neighbors = []
    for dq, dr in directions:
        nq = cell.q + dq
        nr = cell.r + dr
        # 检查邻居是否在网格内
        if (nq, nr) in grid:
            neighbors.append(grid[(nq, nr)])
    return neighbors

Ignite函数实现

def ignite(cell):
    # 仅未燃烧的森林可被点燃
    if cell.state == 0:
        cell.state = 1

主循环(Go函数)

def go(grid):
    to_ignite = []
    # 第一步:收集所有待点燃的邻居
    for cell in grid.values():
        if cell.state == 1:
            # 遍历燃烧细胞的所有邻居
            for neighbor in get_neighbors(cell, grid):
                if neighbor.state == 0:
                    to_ignite.append(neighbor)
            # 燃烧细胞转为灰烬
            cell.state = 2
    # 第二步:统一点燃待燃烧细胞
    for cell in to_ignite:
        ignite(cell)

初始点火逻辑

def init_fire(grid):
    # 筛选所有未燃烧的森林细胞
    forest_cells = [cell for cell in grid.values() if cell.state == 0]
    if not forest_cells:
        return
    # 随机选一个点火
    import random
    target_cell = random.choice(forest_cells)
    ignite(target_cell)

额外调试技巧

  • 加日志输出:在ignite函数中添加print(f"Ignited cell ({cell.q}, {cell.r}) | 状态从 {cell.state-1} 转为 1"),确认函数是否被调用、状态是否正确修改;
  • 可视化网格状态:每执行一次go函数后,打印网格中所有细胞的状态,直观查看火灾传播情况;
  • 检查主循环调用:确保模拟过程中每一步都执行了go函数,而非仅执行一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:55:15