Netlogo & Levelspace: как передавать строки между двумя дочерними моделями? - PullRequest
0 голосов
/ 23 января 2019

У меня есть три модели: Parent, Child1, Child2.

Child1 генерирует строки, которые затем должны быть переданы Child2 для дальнейшей обработки. Строки генерируются на лету, когда выполняется Child1. Всякий раз, когда генерируется новая строка, она должна быть немедленно отправлена ​​в Child2. Иногда 2 или более строк генерируются одновременно (разными агентами), и затем эти 2 или более строк должны отправляться одновременно (т. Е. В пределах одного тика).

Одно из решений состоит в том, чтобы пропустить родительскую модель и позволить Child1 стать Parent-моделью, которая затем получит доступ к Child 2. Однако это усложнит Child1, поскольку будет включать весь необходимый код LevelSpace. Кроме того, две детские модели должны использоваться самостоятельно. Две модели используются в образовательных целях, и студенты не должны видеть код LevelSpace. Отсюда Родительская модель.

Другое решение состоит в том, чтобы позволить родительской модели непрерывно опрашивать модель Child 1, чтобы запрашивать новые строки. Не очень красиво. Не очень эффективно.

Так что в основном я ищу некоторую совместную память и / или функциональность событий в LevelSpace: -)

Кстати, строки представляют собой ДНК, РНК и т. Д., И мы иллюстрируем транскрипцию и трансляцию строк и т. Д.

Есть идеи?

Спасибо, Палла

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Джаспер написал действительно хорошее решение, хотя оно полагается на поведение, которое не должно работать.Другой способ сделать это - child1 собрать строки, когда они запускаются в глобальной переменной.например,

Код дочернего элемента 1:

globals [ strings ]

to go
  set strings []
  ask turtles [
    set strings lput (word "hello from turtle " who) strings
  ]
  tick
end

Затем пусть child2 принимает список строк в своем методе go

Код дочернего элемента 2:

to go [ strings ]
  ; do stuff with the strings
end

Затем родитель передает список между ними:

Код родителя:

to go
  ls:ask child1 [ go ]
  ls:let child1-strings [ strings ] ls:of child1
  ls:ask child2 [ go child1-strings ]
  tick
end
0 голосов
/ 25 января 2019

Это определенно не обычный код 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 увеличивает глобальный some-val в child2.

...