Schelling隔离模型Python实现问题:迁移数值异常排查
谢林隔离模型问题排查与解答
1. 迁移数值正确性判断与总数统计方法
正常情况下,实际迁移数应该小于等于不开心智能体数——因为部分不开心的智能体可能找不到可迁移的空位(比如网格接近填满时)。如果你的迁移数和不开心数完全一致,大概率存在逻辑问题。
统计相关数值的标准方法:
- 总智能体数:遍历网格统计非空位(即智能体)的数量,假设用
0表示空位,1、2表示两组智能体:total_agents = sum(row.count(1) + row.count(2) for row in grid) - 不开心智能体数:遍历所有智能体,调用你的
is_unhappy()方法逐个判定,计数得到unhappy_count - 实际迁移数:在
update方法中单独维护计数器,仅当智能体成功找到空位并完成迁移时才递增:moved_count = 0 # 处理迁移逻辑... if 成功找到空位并完成迁移: moved_count += 1
2. update方法循环的常见问题排查
迁移数与不开心数完全一致,通常是update循环的逻辑错误导致所有不开心智能体都能“强制”找到空位,常见问题包括:
问题1:遍历过程中直接修改原网格
如果你的循环是边遍历网格、边修改网格(比如迁移智能体),会导致后续遍历的单元格状态被提前改变——比如刚迁移出的位置变成空位,被后续的不开心智能体重复利用,最终让所有不开心的智能体都能找到空位。
错误示例:
for i in range(grid_size): for j in range(grid_size): if is_unhappy(i, j): # 直接在遍历中修改网格 empty_pos = find_empty_cell() grid[empty_pos[0]][empty_pos[1]] = grid[i][j] grid[i][j] = 0 moved_count += 1
修正方案:先收集所有不开心智能体的位置,再批量处理迁移:
# 先一次性收集所有不开心智能体的坐标 unhappy_agents = [ (i, j) for i in range(grid_size) for j in range(grid_size) if grid[i][j] != 0 and is_unhappy(i, j) ] moved_count = 0 for (x, y) in unhappy_agents: empty_pos = find_empty_cell() if empty_pos: # 仅当找到空位时才迁移 grid[empty_pos[0]][empty_pos[1]] = grid[x][y] grid[x][y] = 0 moved_count += 1
问题2:空位查找逻辑错误
如果你的find_empty_cell()方法总是能返回空位(比如网格永远有空位,或者方法错误地返回已被占用的位置),也会导致所有不开心智能体都能迁移。检查该方法:
- 是否正确遍历网格寻找值为
0的单元格 - 当网格没有空位时,是否返回
None或其他标识,避免强制迁移
问题3:不开心判定未排除已迁移的智能体
如果在迁移后没有重新判定剩余智能体的状态(不过这种情况更多导致重复计数,而非迁移数完全等于不开心数),但可以验证:在收集不开心智能体时,确保只统计当前未迁移的智能体。
验证步骤
- 用极小网格(如5x5)手动构造测试场景:设置部分不开心智能体,且仅留1个空位,运行代码看迁移数是否为1,而非等于不开心数
- 在
update方法中打印中间变量:迁移前打印unhappy_count,迁移过程中打印每次是否找到空位,迁移后打印moved_count,对比数值差异
内容的提问来源于stack exchange,提问作者Pranas Ciziunas
相关产品推荐
相关产品推荐

