如何将项目添加到邻居的代理集列表中,该代理集孵化另一个代理集?



我当前有一个代理集(breed1)正在孵化另一个代理集中(breed2)。我想要的是编辑breed2(attribute1attribute2),然后将编辑的项目(在图案填充中称为item)添加到breed1的邻居列表中。

编辑时间:在Wade Schuette的回答之后,我编写了以下

breed [people person]
breed [items item_1]

people-own
[
my-list
attribute1
attribute2 
]
items-own
[
selected
attribute1
attribute2
]
to setup
clear-all
;; make turtles to test
create-people 1 [ set my-list [1 2 3 ] ] 
create-people 1 [ set my-list [ ] ] 
create-people 1 [ set my-list [22 33 ] ] 
create-people 1 [ set my-list ["a" "b" "c"] ] 
create-people 1 [ set my-list [3  4 5 ] ] 
;; make a network
ask people [ create-links-with other people ]

reset-ticks
end
to go
let picked nobody
let neighbours nobody
ask one-of people 
[
set attribute1 random-float 1
set attribute2 random-float 1
hatch-items 1 [
set selected picked
let this-item self 
ask myself[
print (word "turtle "  self " has item " this-item " with attribute1 " attribute1 "and attribute2 " attribute2) 
set my-list lput this-item my-list
show my-list
]
ask link-neighbors [ print (word "Person "  who " has this my-list " my-list) 
set attribute1 (attribute1 + random-float 1)
set attribute2 (attribute2 + 3)
set my-list lput this-item my-list
print (word "added item " this-item " with attribute1 " attribute1 " with attribute2 " attribute2)
show my-list
]
]
]
tick
end

正如你所看到的,我的困难在于考虑乌龟的邻居,以及更新我想添加到他们列表中的物品的信息(属性1和2)。

您只需要进行两次更改即可使代码正常工作。在您尝试询问链接邻居之前,向上移动图案填充语句的右括号(])。现在,你正在为孵化的代理请求链接邻居,而不是调用它的代理,所以它找不到任何代理,并默默失败。

如果你这样做,你会得到一个关于这个项目未定义的错误。这是因为你在填充代码中声明了它,所以当填充代码关闭时它就会消失。要解决此问题,请在调用填充代码(让此项")之前声明此项,但请确保使用let而不是SET。

然后,当更新链接的邻居时,您只需要设置它,因为您已经声明了它

我认为有了这些改变,它就会奏效。以下是我要做的工作。我给它放了很多调试xprint语句并设置全局verbose?正如我前面提到的那样。执行所有这些打印语句揭示了链接邻居突然消失的问题——这就是我定位错误的方式。

是否设置全局详细?设置为false以停用它们并获得干净的输出。

globals [ 
verbose?   ;; to turn on debugging statements
]
breed [people person]
breed [items item_1]

people-own
[
my-list
attribute1
attribute2 
]
items-own
[
selected
attribute1
attribute2
]
to setup
clear-all
set verbose? true  ;; true means printa lot of stuff
;; make turtles to test
create-people 1 [ set my-list [1 2 3 ] ] 
create-people 1 [ set my-list [ ] ] 
create-people 1 [ set my-list [22 33 ] ] 
create-people 1 [ set my-list ["a" "b" "c"] ] 
create-people 1 [ set my-list [3  4 5 ] ] 
;; make a network
ask people [ create-links-with other people ]
;; ADDED next 2 lines
xprint (word "Created this many links in setup: "  count links)  
ask person 0 [
let fastcount count link-neighbors
xprint ( word "In setup,   person " who " has this many links " fastcount ) 
]

reset-ticks
end
to go
let picked nobody
let neighbours nobody

ask one-of people with [ who = 0 ]
[ 
let fastcount count link-neighbors
xprint ( word "Entering ask-person,   person " who " has this many links " fastcount ) 
set attribute1 random-float 1
set attribute2 random-float 1
xprint ( word "Before hatch-items, we have this...")
xprint (word "turtle "  self " has no item hatched, " 
" with attribute1 " precision attribute1 2 " and attribute2 " precision attribute2 2) 
let this-item 0   ;; this was down inside hatch-items, so it evaporated when 
;; finishing hatch-items, causing a problem
;; DECLARE it up here, then SET it inside hatch-items
hatch-items 1 [
set selected picked
set this-item self   ;; this was down here inside hatch-items, move it up 4 lines
xprint ( word "confirming this-item value is: " this-item )
ask myself[
xprint ( word "inside hatch-items ,  inside ask-myself, we have this...")
xprint (word "turtle "  self " has item " this-item 
" with attribute1 " precision attribute1 2 " and attribute2 " precision attribute2 2) 
set my-list lput this-item my-list
xprint ( word  "hatched item now has my-list = "    my-list )
] ;; end of ask myself
];;; <====== you want to close context of hatch-items up here, not down below
;;; so that ask link-neighbors will work

;; ADDED THIS NEXT LINES FOR DEBUGGING  
xprint "we are done with ask myself,  but still inside hatch-items"
set fastcount count link-neighbors
xprint ( word "After ask myself, but still inside hatch-items,   person " who " has this many links " fastcount )  
xprint ( " the code posted in the revised question failed here")
xprint ( " PERSON should be person 0  , link count should be 4 ")
xprint ( " SO ASK  LINK-NEIGHBORS WIll fail !!!")

xprint " asking link-neighbors to update their lists now"
ask link-neighbors [ print (word "Person "  who " has this my-list " my-list) 
set attribute1 (attribute1 + random-float 1)
set attribute2 (attribute2 + 3)
set my-list lput this-item my-list
xprint (word "added item " this-item " with attribute1 " attribute1 " with attribute2 " attribute2)
show my-list
]
;;] ;; closes context of hatch-items,  try closing hatch-items before asking link-neighbors
]
tick
end
to xprint [ stuff ]
if verbose? [ print stuff ]
end

轻微的打字错误:您的一个方法在链接邻居中使用,另一个方法使用链接邻居。除非你想排除出站链接,否则我认为你想要链接邻居。

基本上,您要问的一个设计问题是在填充之前找到调用方的链接邻居集并将其保存在属性中更好,还是在填充时在本地找到它们并在填充后忘记列表更好。我还没有尝试过你的代码,但我认为这两种方法都可以。如果链接集是静态的,你可以找到它一次,存储它,而不用每次孵化新的代理时都麻烦再次找到它,这样可以节省一些时间。如果链接集是动态的,那么每次都需要查找它,所以将它保存在属性中是没有意义的。

您询问如何验证代码。我不知道你的任何一个建议是什么意思,所以我会回答一般情况。在这里发布之前,这些可能是你可以做的,也应该做的步骤,来修复你自己可以修复的所有问题。

规则#1:从简单开始,在增加复杂性之前先做那么多工作

您的代码已经违反了规则#1。当您可以只使用一个属性进行测试时,您可以设置两个属性。如果第二个属性代码导致一个错误,混淆了您对整个逻辑是否正常工作的检查,该怎么办。就这一点而言,从零属性开始测试。注释掉该代码,然后逐渐将其添加回来,在每一步都要再次检查。

规则#2:迈出一小步

在添加更多代理之前,请确认代码仅适用于一个代理。通过一次"开始"步骤,然后停下来进行测试。在进入第二步之前,要做到完美。等等

我们都可以梦想有一天,NetLogo有一个真正的调试器,让你一次只执行一条语句,或者设置断点。但事实并非如此。当前进的一步结束,"停止"生效时,你已经失去了上下文。局部变量已经蒸发,无法检查。嵌套调用的"堆栈"丢失。

据我所知,在上下文中查看动态细节的唯一方法是设置新的全局变量,这很混乱,或者大量使用嵌入的"打印"语句。

您还可以插入错误语句以导致运行时错误,检查调用堆栈,并有机会喘口气查看此时的输出。

error " here is the calling stack, halting execution entirely here."

或者,您可以使用用户消息语句使代码暂停,让您知道发生了什么变化,或者发生了不应该发生的情况(!)。这为您提供了"停止"或像什么都没发生一样继续运行的不错选择。

if x > 5 [ user-message " Alert -- X is over 5!! " ]

其他评论者,请点击此处并分享其他方法

我发现的最有用的print语句标记了几个感兴趣的变量,并确定了它们的执行位置,这样你就可以在输出中区分它们。查看3个变量x、y和z的示例:

print ( word "In step 3,  x = " x " y = " y " z = " z )"

如果有一种方法可以在编辑器中切换这些语句的可见性,那就太好了,但没有。您至少可以通过添加全局变量(比如"verbose?")并更改打印语句来利用它来切换语句是运行还是跳过。(见下文)

然后,您可以打开或关闭同时打印所有这些语句,而不是注释掉它们,或者更糟的是,删除它们。一般来说,不要删除它们,因为总有一天你需要修改并重新验证代码,你需要再次返回这些代码,以确认修改正在做你希望它们做的事情,并且没有破坏新的东西。好的"印刷品"声明是物有所值的,值得努力落实。

这里有一个选择性打印的好方法。声明一个名为"xprint"的新命令,该命令仅在全局变量"verbose?"为true时才打印。您可以在设置中设置一次,也可以在中途进行修改,或者设置verbose?true或false。

然后,您可以使用"xprint"而不是"print"来切换打印或不打印。

xprint ( word "In step 3,  x = " x " y = " y " z = " z )"

这确实降低了代码中有大量打印语句的成本,因此它确实简化了验证代码和稍后重新验证代码的过程

;; This shows how to use a global variable to turn on or off print statements,
;; which you might want to use while developing and testing code
globals [
verbose?   ;; true means print lots of things,  false means don't print them
]
to setup
clear-all
set verbose? true  ;; or false, whatever.  You can also use the Command Center
;; to set this true or false in the middle of a run
reset-ticks
end
to go
let x random 10         ;; just for illustrating how this works
xprint (word "At tick " ticks " x = " x )
tick
end
to xprint [ stuff ]
if  verbose? [ print stuff ]
end

你在对第一个答案的评论中说:

代码有效,但我无法打印所有邻居并查看该项目是否已添加到他们的列表。。。。然而,我的困难在于考虑并定义乌龟(我自己)的邻居。

你能解释一下你遇到了什么困难吗?我们能选择一个更简单的例子吗?你对"我自己"one_answers"自我"这两个词的含义有什么问题,这取决于你对"问谁"的嵌套程度吗?

这里有一些更容易上手的代码。你能用这个代码制造问题吗?

顺便说一句,如果你是另一个提问循环中的提问循环,关键字"我自己"将被定义,你可以使用

print (word "At point 3, self = " self ", and myself = " myself)

看看谁是谁。我不知道如何测试"我自己"是否存在,因为如果不存在,就会抛出一个错误——测试=没有人不工作,是代理?如果我不存在,那就不起作用。任何人你怎么知道我是否存在?

不管怎样,这并不重要这里有一个解决方法只要等到孵化部分完成后,当你回到第一个代理的上下文中,你就可以使用

ask link-neighbors [ print (word "turtle "  who " has this my-list " my-list) ]

它应该起作用!

turtles-own
[
my-list 
]
to setup
clear-all
;; make turtles to test
create-turtles 1 [ set my-list [1 2 3 ] ] 
create-turtles 1 [ set my-list [ ] ] 
create-turtles 1 [ set my-list [22 33 ] ] 
create-turtles 1 [ set my-list ["a" "b" "c"] ] 
create-turtles 1 [ set my-list [3  4 5 ] ] 
;; make a network
ask turtles [ create-links-with other turtles ]

reset-ticks
end
to go
ask one-of turtles 
[
ask link-neighbors [ print (word "turtle "  who " has this my-list " my-list) ]
]
tick
end

最新更新