Netlogo & Levelspace:如何在两个子模型之间传递字符串?
Netlogo & Levelspace: how to pass strings between two child-models?
我有三个模型:Parent、Child1、Child2。
Child1 生成的字符串必须随后传递给 Child2 以进行进一步处理。这些字符串是在 Child1 执行时即时生成的。每当生成一个新字符串时,它必须立即发送给 Child2。有时会同时生成 2 个或更多的字符串(由不同的代理),然后必须同时发送这 2 个或更多的字符串(即在同一个 tick 内)。
一种解决方案是跳过父模型,让 Child1 成为父模型,然后父模型可以访问子模型 2。但是,这会使 Child1 复杂化,因为它会包含所有必需的 LevelSpace 代码。此外,这两个子模型必须可以单独使用。这两个模型用于教育目的,学生应该看不到 LevelSpace 代码。因此父模型。
另一种方案是让Parent 模型不断轮询Child 1 模型以请求新的字符串。不是很漂亮。效率不高。
所以基本上我在 LevelSpace 中寻找一些共享内存 and/or 事件功能:-)
顺便说一下,字符串代表 DNA、RNA 等,我们正在说明字符串等的转录和翻译。
有什么想法吗?
谢谢,
托盘
这绝对不是传统的 NetLogo 代码,但回调方法似乎工作正常,至少对于这个简单的例子来说是这样。您确实需要使子模型稍微复杂一些以添加 run callback
语句,但它 可能 导致整体代码比轮询方法更清晰,具体取决于用例。
父模型:
extensions [ ls ]
globals [ child1 child2 ]
to setup
ls:reset
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child1 id ])
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child2 id ])
ls:ask ls:models [
child-setup
]
; here we set the callback for the child models
; we could set the callback for just `child1` instead of all `ls:models`
ls:assign ls:models callback [ [id message] -> alert id message ]
ls:assign child1 id child1
ls:assign child2 id child2
end
to go
ls:ask ls:models [
child-go
]
end
; In this case our callback is simple, just taking the caller id
; and a message. We could add more parameters for it if we want to
to alert [id message]
show (word id ": " message)
; this is just to show that we can use the callback to update
; the state of one of the other models
if id = 0 [
ls:ask child2 [ set some-val (some-val + 1) ]
]
end
童模:
globals [ id callback some-val ]
to child-setup
set some-val 0
; set the callback to an "empty" procedure so we don't have to check
; if it is set while we run the go method.
set callback [ [model-id message] -> ]
end
to child-go
if random 10 < 3 [
(run callback id (word "child alert: " some-val))
]
end
示例输出:
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "0: child alert: 0"
observer: "1: child alert: 1"
observer: "0: child alert: 0"
observer: "1: child alert: 2"
observer: "1: child alert: 2"
observer: "0: child alert: 0"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "0: child alert: 0"
observer: "1: child alert: 4"
observer: "0: child alert: 0"
observer: "1: child alert: 5"
observer: "1: child alert: 5"
observer: "0: child alert: 0"
observer: "1: child alert: 6"
每次 child1
模型运行回调时,alert
过程都会在 child2
中递增 some-val
全局值。
Jasper 写了一个非常好的解决方案,尽管它确实依赖于不应该工作的行为。另一种方法是让 child1
在全局变量中运行时收集字符串。例如
Child 1 个代码:
globals [ strings ]
to go
set strings []
ask turtles [
set strings lput (word "hello from turtle " who) strings
]
tick
end
然后让 child2
在其 go
方法中接受一个字符串列表
Child2个代码:
to go [ strings ]
; do stuff with the strings
end
然后 parent 在它们之间传递列表:
Parent代码:
to go
ls:ask child1 [ go ]
ls:let child1-strings [ strings ] ls:of child1
ls:ask child2 [ go child1-strings ]
tick
end
我有三个模型:Parent、Child1、Child2。
Child1 生成的字符串必须随后传递给 Child2 以进行进一步处理。这些字符串是在 Child1 执行时即时生成的。每当生成一个新字符串时,它必须立即发送给 Child2。有时会同时生成 2 个或更多的字符串(由不同的代理),然后必须同时发送这 2 个或更多的字符串(即在同一个 tick 内)。
一种解决方案是跳过父模型,让 Child1 成为父模型,然后父模型可以访问子模型 2。但是,这会使 Child1 复杂化,因为它会包含所有必需的 LevelSpace 代码。此外,这两个子模型必须可以单独使用。这两个模型用于教育目的,学生应该看不到 LevelSpace 代码。因此父模型。
另一种方案是让Parent 模型不断轮询Child 1 模型以请求新的字符串。不是很漂亮。效率不高。
所以基本上我在 LevelSpace 中寻找一些共享内存 and/or 事件功能:-)
顺便说一下,字符串代表 DNA、RNA 等,我们正在说明字符串等的转录和翻译。
有什么想法吗?
谢谢, 托盘
这绝对不是传统的 NetLogo 代码,但回调方法似乎工作正常,至少对于这个简单的例子来说是这样。您确实需要使子模型稍微复杂一些以添加 run callback
语句,但它 可能 导致整体代码比轮询方法更清晰,具体取决于用例。
父模型:
extensions [ ls ]
globals [ child1 child2 ]
to setup
ls:reset
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child1 id ])
(ls:create-models 1 "LS callback child.nlogo" [ [id] -> set child2 id ])
ls:ask ls:models [
child-setup
]
; here we set the callback for the child models
; we could set the callback for just `child1` instead of all `ls:models`
ls:assign ls:models callback [ [id message] -> alert id message ]
ls:assign child1 id child1
ls:assign child2 id child2
end
to go
ls:ask ls:models [
child-go
]
end
; In this case our callback is simple, just taking the caller id
; and a message. We could add more parameters for it if we want to
to alert [id message]
show (word id ": " message)
; this is just to show that we can use the callback to update
; the state of one of the other models
if id = 0 [
ls:ask child2 [ set some-val (some-val + 1) ]
]
end
童模:
globals [ id callback some-val ]
to child-setup
set some-val 0
; set the callback to an "empty" procedure so we don't have to check
; if it is set while we run the go method.
set callback [ [model-id message] -> ]
end
to child-go
if random 10 < 3 [
(run callback id (word "child alert: " some-val))
]
end
示例输出:
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "1: child alert: 0"
observer: "0: child alert: 0"
observer: "1: child alert: 1"
observer: "0: child alert: 0"
observer: "1: child alert: 2"
observer: "1: child alert: 2"
observer: "0: child alert: 0"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "1: child alert: 3"
observer: "0: child alert: 0"
observer: "1: child alert: 4"
observer: "0: child alert: 0"
observer: "1: child alert: 5"
observer: "1: child alert: 5"
observer: "0: child alert: 0"
observer: "1: child alert: 6"
每次 child1
模型运行回调时,alert
过程都会在 child2
中递增 some-val
全局值。
Jasper 写了一个非常好的解决方案,尽管它确实依赖于不应该工作的行为。另一种方法是让 child1
在全局变量中运行时收集字符串。例如
Child 1 个代码:
globals [ strings ]
to go
set strings []
ask turtles [
set strings lput (word "hello from turtle " who) strings
]
tick
end
然后让 child2
在其 go
方法中接受一个字符串列表
Child2个代码:
to go [ strings ]
; do stuff with the strings
end
然后 parent 在它们之间传递列表:
Parent代码:
to go
ls:ask child1 [ go ]
ls:let child1-strings [ strings ] ls:of child1
ls:ask child2 [ go child1-strings ]
tick
end