0
点赞
收藏
分享

微信扫一扫

netlogo笔记(4):森林火灾模拟与模型改进

老罗话编程 2022-03-31 阅读 416

目录

森林火灾模拟

1.to setup:建立一个森林和起火线

2.to go:燃烧

模型改进

改进(一):考虑树木的可燃性

改进(二):考虑风的影响

改进(三):考虑火苗的远距离传播


森林火灾模拟

森林火灾模拟来自netlogo模型库。主要思路是通过让turtles随机改变周围turtles的颜色模拟火灾发生,并探索森林密度与烧毁比例之间的关系。

1.to setup:建立一个森林和起火线

代码如下:

globals [
initial-trees ;; 声明新的全局变量:原本的树
burned-trees ;; 被烧毁的树
]

breed [fires fire] ;; 声明新的海龟种类:fires fire(火)
breed [embers ember] ;; embers ember(余烬)

to setup
clear-all
set-default-shape turtles "square"
;; 将海龟默认形状设置为方形
ask patches with [(random-float 100) < density]
[ set pcolor green ]
;; 用random-float命令让patch生成<100的随机数,该数字若小于density,则patch变绿
ask patches with [pxcor = min-pxcor]
[ ignite ]
;; 让坐标系中最左边的一条线点燃
set initial-trees count patches with [pcolor = green]
;;设置变量原本的树为:绿色patch的数量
set burned-trees 0
reset-ticks
end

注意点:

(1)在最前面声明新的全局变量:initial-trees、burned-trees和新的海龟种类:fire、fires、ember、embers;

(2)用random-float的命令使得patch与森林密度density关联起来,即:使patch生成随机数,若设置density为30(界面已设置density滑块),则随机数<30的patch变为绿色;

(3)用count命令使initial-trees取值等于绿色patch的数量。,

设置完毕如下图:

森林模拟(密度:33%)

森林模拟(密度:60%)

2.to go:燃烧

令fires随机点燃4个邻居,点燃即:使fire变红,之后pcolor变黑,烧毁数量加1。点燃后生成灰烬,最后灰烬死亡。

代码如下:

to go
if not any? turtles ;; 条件语句not any?,若为真,则停止
[ stop ]
ask fires
[ ask neighbors4 with [pcolor = green] ;;随机选择上下左右的绿色patch点燃
[ ignite ] ;;嵌套命令ignite
set breed embers ] ;;设置种类embers
fade-embers ;;嵌套命令fade-embers
tick
end


to ignite
sprout-fires 1 ;;使fires涌现,数量为1
[ set color red ] ;;颜色变为红色
set pcolor black ;;瓦片颜色变为黑色
set burned-trees burned-trees + 1 ;;烧毁的数数量加1
end


to fade-embers
ask embers
[ set color color - 0.3 ;; embers颜色变为暗红
if color < red - 3.5 ;; 如果颜色<red-3.5,则pcolor和color都消失
[ set pcolor color
die ] ]
end

注意点:

(1)嵌套了两个命令:ignite和fade-embers,让fire涌现(红色),瓦片变黑;然后再生成ember,再让ember变暗至die。我尝试不加入ember,直接让fires变暗至die,这样做的后果是火线ignite后就die了,火苗没法传播出去。(p.s.:不知道解释的对不对);

(2)之所以在ignite中要让pcolor变黑,是因为如果不变黑,红色就会以绿色为背景出现,视觉效果不好。

效果如图:

森林火灾燃烧模拟

模型改进

改进(一):考虑树木的可燃性

在现实的森林大火中,出于各种原因(下雨、天气湿度、树木本身特性),树木也许并不都是可燃的,所以火苗的传播可能不是畅通无阻的。可以在模型中增加变量:probability-of-spread。原代码变为:

ask fires
[ ask neighbors4 with [pcolor = green]
[ if random 100 < probability-of-spread
[ ignite ] ]
set breed embers ]

注意点:

与命令random-float不同,random命令生成的是整数,random-float生成的是floating point number(浮点数,即小数)。

效果如图

改进(一):考虑树木可燃性的森林火灾

改进(二):考虑风的影响

风可能是影响火势的重要因素。因此,在模型中继续加入风速。考虑风的方向,主要把风分解为:南风速度、西风速度这两个变量。在火苗传播的过程中,如果没点燃的patch位于上风向,则令probability-of-spread减去风速;如果位于下风向,则令probability-of-spread加上风速,以计算总的被点燃可能性。原代码变为:

ask fires [
ask neighbors4 with [pcolor = green] [
let probability probability-of-spread
let direction towards myself
if direction = 0 [
set probability probability - south-wind-speed
]
if direction = 90 [
set probability probability - west-wind-speed
]
if direction = 180 [
set probability probability + south-wind-speed
]
if direction = 270 [
set probability probability + west-wind-speed
]
if random 100 < probability
[ ignite ] ]
set breed embers ]

注意点:

(1)myself指的是命令的发出者(netlogo词典官方解释:"the turtle, patch or link who asked me to do what I'm doing right now"),此句命令的发出者是:fire,所以指的是:令direction等于neighbors4和fire之间的角度。

(2)这里的probability和direction都是局部变量,不需要像全局变量那样在命令的最开始提前声明,但局部变量只在所属的这一段代码中有用。

效果如图:

改进(二):考虑树木可燃性、风的森林火灾

改进(三):考虑火苗的远距离传播

在真实的森林火灾中,火苗不止仅燃烧到neighbor的patch,还有可能会进行远距离的传播。因此加上big-jumps开关。原代码变为:

if random 100 < probability 
[ ignite ] ]
if big-jumps? [
let target patch-at (west-wind-speed / 5) (south-wind-speed / 5)
if target != nobody and [ pcolor ] of target = green [
ask target [
ignite ]]]
set breed embers ]

注意点:

(1)开关名为big-jumps?,if big-jumps?(如果打开);

(2)target为局部变量,只在该命令行有效;

(3)nobody指的是一个主体都没有(netlogo词典:no agent was found),与not any有所不同。any?指主体集合(netlogo词典:the given agentset is non-empty),not any?指没有agentset;

(4)嵌套的命令较多,注意结尾方括号。

效果如图

改进(三):考虑树木可燃性、风、火苗远距离传播的森林火灾

加入以上这些变量以后,可以用行动空间模拟不同参数设置下,森林火灾的燃烧情况。实验数据可以用来进一步研究变量与森林火灾燃烧的关系。

(2022.3.31)

举报

相关推荐

0 条评论