NetLogo是一个用来对自然和社会现象进行仿真的可编程建模环境。NetLogo特别适合对随时间演化的复杂系统进行建模。建模人员能够向成百上千的独立运行的“主体”(agent)发出指令。这就使得探究微观层面上的个体行为与宏观模式之间的联系成为可能,这些宏观模式是由许多个体之间的交互涌现出来的。NetLogo足够简单,可以非常容易的进行仿真,或者创建自己的模型。并且它也足够先进,在许多领域都可以做为一个强大的研究工具。
更多了解请见 http://ccl.northwestern.edu/netlogo/,注意页面左边用户手册中,有中文手册的链接。
只要有一点点编程基础的人,就可以尝试学一学这这个有用的工具,其编程语言较比C、JAVA等简单得多。
近几年利用NetLogo做过几个仿真实验,有一些随手写下来的小技巧,发布在本文中。特别提醒,此文仅是些雕虫小技,但阅读需要有Netlogo的编程经历。条件不具备者,省些时间,先打基础去。
一、集合运算的实现
仿真中常涉及到集合的操作。集合用list实现,List中能包含多个数据。
在下面的例子中,集合A对应list-a,集合B对应list-b,二元运算的结果放在list-a
1、并运算
(1)用List的运算实现
;合并列表
;例a:[[1] [4] [7]] b: [[2] [5]],Merge-list a b: a:[[2] [5] [1] [4] [7]]
;例a:[1 4 7] b: [2 5],Merge-list a b: a:[2 5 1 4 7]
to-report Merge-list [list-a list-b] ;
let cur-result list-a
foreach list-b
[
let an-element ?
set cur-result (lput an-element cur-result)
]
set cur-result (remove-duplicates cur-result)
report cur-result
end
(2)用netlogo自身的原语
最简单的是,用netlogo中的sentence原语可以直接完成合并。
Set list-a (sentence list-a list-b)
2、交运算
类似并运算,可以自编例程,也可以用netlogo自身的原语实现。
3、差运算
(1)用List的运算实现
;列表相减
;例a:[1 2 7] b: [2 5],minus-list a b: a:[1 7]
to-report Minus-list [list-a list-b] ;filter [not member? value list-b ] list-a
let cur-result list-a
foreach list-b
[
let an-element ?
set cur-result (remove an-element cur-result)
]
report cur-result
end
(2)用netlogo自身的原语
Set list-a (filter [not member? ? list-b ] list-a)
二、调试技术
在netlogo中没有提供传统IDE中的单步跟踪。实际上,因为是多个主体同时运行,也无法一一跟踪。在并行程序设计中,调试手段本身就是一个比较难的问题。
可以采用的技巧是:
1、设置一个go on step按钮,功能与具有forever性质的go按钮相同,但不勾选forever选项,以此来实现按tick执行。将需要观察的值设置为海龟的变量(该变量可能仅只为观察而设,调试完后可以删除),选择其中的一个海龟进行inspect去发现问题。文本框太小不容易阅读,可以将其值复制到word中观察。如果被观察的海龟die了,立即在who处输入另一个新号,重新开始观察。
2、在适当的地方加入show显示局部变量的值,最好将tick也加入。这种方法有缺点,尤其是Agent数量特别多时:(1)由于show严重地影响了运行速度;(2)每一个海龟都输出,信息太多不易找出问题。解决办法:只显示其中的有限几个用于观察,如显示编号为100的倍数的海龟的有关信息:
to show-test-message [msg]
if (who mod 100) = 0
[
show msg
]
End
这样,观察有限的几个海龟的信息,能够给排错提供启发。
3、快速停止模型的运行
当模型中Agent数目特别多,尤其是其功能逻辑也相当复杂的时候,运行每一轮需要花费很长的时间。假设运行模型用“forever”型的”go”按钮,需要停止模型运行时,点击”go”按钮需要很长时间,等到所有海龟都停止才能结束。
技巧是,打开“procedures”页,在任意一行代码后输入空格,然后“check”,系统检查代码,模型也马上结束运行了。
三、用Edit-plus编辑代码
在NetLogo中,编辑器的功能相对简单,有语法着色,却不能修改字体、字号等,对中文支持不好。更加不能容忍的是,在NetLogo4.1.2版本中,中文无法输入和显示,非常不便使用。
我用的办法是在Edit-plus编辑。利用Netlogo中对多个源文件(Multiple source files)的支持(见手册),主程序只写一段很短的代码,完成全局变量的设置,提供对其他例程的调用。而其他例程另建在.nls文件中保存,用关键词__includes引入到主例程中,从而能在Netlogo中编译和运行。代码多时甚至可以在一个模型里使用多个源文件。
为了在Edit-plus中也能进行语法着色,需要引入语法文件。我自制了一份,下载链接为: http://download.csdn.net/detail/sxhelijian/3925173。请先将此文件copy到editplus目录中去。在editplus中,在tools->preferences->Setting & syntax下,首先新建一个文件类型,命名为netlogo,扩展名(file extensions)栏里填入nls。在syntax file栏里找到刚才下载的netlogo.stx文件即可。
为了在Edit-plus中也能快速定位例程,在函数模板的正则表达式处设置为"to "和"to-report "。