02.NetLogo-例程学习(构建一个简单的羊吃草模型)

1、制作setup按钮

创建一个button-setup
在代码页定义例程:

to setup 
 clear-all 
 create-turtles 100 
 ask turtles [ setxy random-xcor random-ycor ] 
end

例程以to开始,以end结束。所有的例程都要用这两个词开始和结束。

to setup 开始定义一个名为"setup"的例程
clear-all 将世界重设为初始、全空状态。所有瓦片变黑,你已经创建的海龟消失。
基本上是将过去一笔勾销,为新模型运行做好准备。
create-turtles 100 创建 100 个海龟。这些海龟都在原点,即瓦片 0,0 的中心。
ask turtles [ … ] 告诉每个海龟独立地去运行方括号中的命令 (NetLogo中每条命令都是由某些主体执行的。ask 也是一条命令。在这里是observer运行这条ask 命
令,这条命令又引起海龟运行命令)
setxy random-xcor random-ycor 是一条用"reporters"的命令。reporter与命令不同,它只报告一个结果。首先每个turtle 运行reporter random-xcor,它返回 X坐标范围内的一个随机数,然后每个turtle运行 reporter random-ycor, 返回Y坐标范围的一个随机数。最后每个turtle 使用前面的两个数做输入参数运行setxy 命令,这使得turtle移动到相应的坐标处。
end 结束"setup" 例程的定义。

2、制作go按钮

步骤与 setup 按钮的一样, 除了下面几点:
• 在命令部分输入 go,而非setup.
• 在编辑对话框里勾选 “forever”(持续执行)

在代码页添加go例程:

to go 
 move-turtles 
end

move-turtles不是一个像clear-all那样的原语(NetLogo内嵌的),是一个需要你添加的例程。

至今你已经有两个自己添加的例程了:setup 和go
在go例程后面增加move-turtles 例程:

to go 
 move-turtles 
end 
to move-turtles 
 ask turtles [ 
 right random 360 
 forward 1 
 ] 
end

ask turtles [ … ] 每个turtle运行[ ]中的命令
right random 360 是使用reporter的命令。首先每个turtle 在 0 和 359 之间随机选一个整数 (random 不会返回你给它的数) ,然后turtle 右转这个度数。
forward 1 让turtle前进 1 步。

3、瓦片和变量

现在我们有 100 个海龟,它们漫无目的的移动,对周围的事物毫无知觉。下面我们给海龟一个好点的背景,让模型稍微有趣一些。

修改setup例程:

to setup 
 clear-all 
 setup-patches 
 setup-turtles 
end

新的 setup引用了两个新例程,定义 setup-patches :

to setup-patches 
 ask patches [ set pcolor green ] 
end

例程setup-patches将开始时所有瓦片颜色定义为绿色。

定义setup-turtles:

to setup-turtles 
 create-turtles 100 
 ask turtles [ setxy random-xcor random-ycor ] 
end

5、海龟变量

目前海龟在可以地表上移动,但什么都不做。现在在海龟和瓦片之间加上一些交互。
我们让海龟吃“草”(绿色瓦片),繁殖、死亡。草被吃掉后要逐渐恢复。
我们需要一种控制海龟繁殖和死亡的方式。我们通过跟踪海龟有多大能量(energy)来
决定。要这样的话需要增加一个新的海龟变量。
你已经见过一些内置的海龟变量,如color。要添加新的海龟变量,需要在例程页的顶
部加上turtles-own 声明,这个声明必须在所有例程之前,变量名为energy:

turtles-own [energy] 
to go 
 move-turtles 
 eat-grass 
end

to eat-grass 
 ask turtles [ 
 if pcolor = green [ 
 set pcolor black 
 set energy (energy + 10) 
 ] 
 ] 
end

如果瓦片是绿色则返回true,这时才执行[ ]中的命令(否则跳过)。这些命令让海龟将瓦片改为黑色,海龟能量值增加 10。瓦片变黑表明该处的草被吃掉,因为吃了草,海龟能量增加。

下面,让海龟移动时消耗一些能量:
重写move-turtles如下:

to move-turtles 
 ask turtles [ 
 right random 360 
 forward 1 
 set energy energy - 1 
 ] 
end

展示

6、监视器

在这里插入图片描述
现在有两个监视器报告有多少海龟,有多少绿色瓦片,帮助我们跟踪模型运行。模型运行时,监视器中的数字自动变化。
在这里插入图片描述

7、开关和标签

海龟不仅是将瓦片变黑,它们还获得、损失能量。模型运行时试试使用海龟监视器查看一个海龟的能量变化。

如果能在任何时候看到所有海龟的能量就更好了。现在就这样做,并且增加一个开关能控制这些额外信息显示与否。
在这里插入图片描述
重写eat-grass例程:

to eat-grass 
 ask turtles [ 
 if pcolor = green [ 
 set pcolor black 
 set energy (energy + 10) 
 ] 
 ifelse show-energy? 
 [ set label energy ] 
 [ set label "" ] 
 ] 
end

例程 eat-grass用了ifelse命令,仔细看代码。每个海龟当运行这些新命令时检查show-energy?的值(由开关决定)。

如果开关打开,比较结果为true,海龟执行第一个[ ]中的命令。这时将能量值赋给海龟标签。

如果比较结果为false(开关关闭),海龟执行第二个[ ]中的命令,这时移去文本标签(通过将海龟标签设为空)。

当开关打开时,能看到海龟的能量因吃草而增加,移动时减小:
在这里插入图片描述

8、更多例程

现在海龟在吃草,再让它们繁殖和死亡,也让草能恢复。现在增加三个例程,分别负责这三种行为。

to go 
 move-turtles 
 eat-grass
 reproduce 
 check-death 
 regrow-grass
end

to reproduce 
 ask turtles [ 
 if energy > 50 [ 
 set energy energy - 50 
 hatch 1 [ set energy 50 ] 
 ] 
 ] 
end 
to check-death 
 ask turtles [ 
 if energy <= 0 [ die ] 
 ] 
end 
to regrow-grass 
 ask patches [ 
 if random 100 < 3 [ set pcolor green ] 
 ] 
end

当繁殖时,每个海龟检查它的energy值,如果大于 50 执行第一个[ ]中的命令。在这里energy减少 50,然后孵出(hatches)一个energy为 50 的新海龟。

hatch命令是NetLogo的一个原语,形如hatch number [commands ],海龟创建number个新海龟,每个都与母体相同,并且请求这些新海龟执行commands,你可以使用commands让这些新海龟有不同的颜色、方向等。这里运行一条命令,将新海龟的energy设为 50。

当每个海龟运行check-death时,它检查energy是否小于等于 0。如果是真,则海龟被告知去死die(这是NetLogo的一个原语)。

当每个海龟运行regrow-grass 时,它检查随机产生的 0-99 之间的整数是否小于 3。如果是,瓦片颜色设为绿。对每个瓦片来说,发生的次数(平均)是 3%,因为在 100 个可能的数中,有三个数(0,1,2)小于 3。

此时,go模型,看模型的监视器,会发现 count turtles 和 green patches 监视器都有振荡。

如果有更容易的跟踪模型行为的方式就更好了。NetLogo 可以为我们画图。

9、画图

添加do-plots例程:

to setup 
 clear-all 
 setup-patches 
 setup-turtles 
 do-plots
end

to go 
 move-turtles 
 eat-grass 
 reproduce 
 check-death 
 regrow-grass 
 do-plots 
end

to do-plots 
 set-current-plot "Totals" 
 set-current-plot-pen "turtles" 
 plot count turtles 
 set-current-plot-pen "grass" 
 plot count patches with [pcolor = green] 
end

注意使用plot命令在图上增加新点。然而在这样做之前,需要告诉NetLogo两件事。

第一,需要指明要使用哪个图(因为后面的模型有多个图)。

第二,要指定使用哪支笔(pen)画图(本图使用两支笔)。

plot命令告诉画笔移动到新点,新点的X 坐标是先前的X坐标加 1,Y坐标就是plot命令中给定的值(第一种情况是海龟数量,第二种情况是绿瓦片数量)。当画笔移动时就画出线。

为了让set-current-plot "Totals"工作,必须在界面页中为你的模型增加一个图(plot),然后进行编辑,让它的名字与例程中用到的相同。即使名字中多个空格也会出错—两处必须完全相同。

在这里插入图片描述

10、时钟计数器

修改go例程:

to go 
 if ticks >= 500 [ stop ] 
 move-turtles 
 eat-grass 
 reproduce 
 check-death 
 regrow-grass 
 tick 
 do-plots 
end

注意:
在中文手册4.0里面只说了在go例程里加tick。但这样会报错:
时间步计数器尚未启动,使用 RESET-TICKS.
error while observer running TICKS
called by procedure GO
called by 按钮 ‘go’

解决方法:
不仅仅要在"go"程序中加tick,同时你需要在setup程序的clear-up语句后面加一条reset-ticks,因为每一次你setup,你把ticks中的记录被clear-up清除了

setup例程:

to setup 
 clear-all 
 reset-ticks
 setup-patches 
 setup-turtles 
 do-plots
end

当界面页工具条上的时钟计数器达到 500 时,模型自动
停止。

11、更多细节

可以有可变数量的海龟,而非总是 100 个。
增加一个滑动条改变海龟数量:

to setup-turtles 
 create-turtles number 
 ask turtles [ setxy random-xcor random-ycor ] 
end

增加滑动条energy-from-grass.
增加滑动条birth-energy

to eat-grass 
 ask turtles [ 
 if pcolor = green [ 
 set pcolor black 
 set energy (energy + energy-from-grass) 
 ] 
 ifelse show-energy? 
 [ set label energy ] 
 [ set label "" ] 
 ] 
end

to reproduce 
 ask turtles [ 
 if energy > birth-energy [ 
 set energy energy - birth-energy 
 hatch 1 [ set energy birth-energy ] 
 ] 
 ] 
end 

完整代码:

turtles-own [energy]


to setup 
 clear-all 
 reset-ticks
 setup-patches 
 setup-turtles 
 do-plots
end


to setup-patches 
 ask patches [ set pcolor green ] 
end

to setup-turtles 
  create-turtles number
 ask turtles [ setxy random-xcor random-ycor ] 
end


to go 
 if ticks >= 500 [ stop ] 
 move-turtles 
 eat-grass 
 reproduce 
 check-death 
 regrow-grass 
 tick 
 do-plots 
end

to move-turtles 
 ask turtles [ 
 right random 360 
 forward 1 
 set energy energy - 1 
 ] 
end

to eat-grass 
 ask turtles [ 
 if pcolor = green [ 
 set pcolor black 
 set energy (energy + energy-from-grass) 
 ] 
 ifelse show-energy? 
 [ set label energy ] 
 [ set label "" ] 
 ] 
end

to reproduce 
 ask turtles [ 
 if energy > birth-energy [ 
 set energy energy - birth-energy 
 hatch 1 [ set energy birth-energy ] 
 ] 
 ] 
end 
to check-death 
 ask turtles [ 
 if energy <= 0 [ die ] 
 ] 
end 
to regrow-grass 
 ask patches [ 
 if random 100 < 3 [ set pcolor green ] 
 ] 
end

to do-plots 
 set-current-plot "Totals" 
 set-current-plot-pen "turtles" 
 plot count turtles 
 set-current-plot-pen "grass" 
 plot count patches with [pcolor = green] 
end
  • 11
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值