为什么 Netlogo 中的 n-of 在我的代码中选择了相同的海龟?

Why does n-of in Netlogo selectes the same turtles in my code?

我有一群海龟,我正在尝试 select 两个随机的海龟一起玩游戏。我在海龟上使用 n-of,但有时 n-of selects 同一只海龟两次,我不知道为什么,因为它应该无需重复即可工作。谁能帮我理解我做错了什么?这是代码的摘录:

to go
  if ticks < cycleTime
  [
    playGame n-of 2 members
    tick
  ]

  if ticks = cycleTime
  [

    reset-ticks
  ]

end

to playGame[players]

  let player1 item 0 [self] of players
  let player2 item 1 [self] of players
  
  ;;sometimes it prints the exact member twice for player1 and player2
  print(player1)
  print(player2)

end

问题不在于 n-of 选择同一个海龟两次。 相反,[self] of players 是一个始终以随机顺序生成的列表。由于您两次生成此列表,因此两个列表的顺序不一定相同。以下应说明这一点:

to playGame[players]

  let thePlayers0 [self] of players
  let thePlayers1 [self] of players
  let thePlayers2 [self] of players
  print(thePlayers0)
  print(thePlayers1)
  print(thePlayers2)

end

生成一次名人名单解决了您的问题:

to playGame[players]

  let thePlayers [self] of players
  
  let player1 item 0 thePlayers
  let player2 item 1 thePlayers
  
  print(player1)
  print(player2)

end

检查这个使用更易于监控的全局变量的可重现示例:

globals [
  players
  player1
  player2
]

to setup
  clear-all
  reset-ticks
  create-turtles 100
end

to go
  set players n-of 2 turtles
  playGame players
  tick
end

to playGame [plrs]
  set player1 item 0 [self] of plrs
  set player2 item 1 [self] of plrs
end

如果您将此代码粘贴到代码选项卡中,请在界面中为 [self] of players 报告者创建一个监视器,然后点击 setup+go(否则 运行 repeat 10 [show [self] of players]在指挥中心),你会看到两只海龟的标识符在波动,交换了它们的位置。

这让我想起了一些我记得在 NetLogo 文档中读过的东西,但我找不到:NetLogo 不断 re-evaluates 它的变量,即使模型不是运行宁。 当这样的变量是一个代理集(例如 players - 因为注意 n-of reports an agentset if you pass it an agentset as input),或者因此取决于代理集(例如 [self] of players),这意味着内部变量的顺序将不断打乱。

发生这种情况是因为代理集是对其相关代理的随机排序,这种可变性对 NetLogo 来说不是问题:相反,它是其机制的核心。

但在您的情况下,这意味着有时 players 代理集的顺序(因此 plrs 参数的顺序,以及 [self] of plrs 列表的顺序)在这样的情况下发生了变化在评估 item 1 时,评估为 item 0 的内容变为 item 1 的那一刻。

如何解决这个问题?不改变其内部排序的是列表,因此您可以将 players 保存为列表:

set players sort n-of 2 turtles

看到 sort always reports a list

这意味着您可以:

set player1 item 0 players
set player2 item 1 players

并且总是有两个不同的玩家。

如果出于某种原因你不想让player1永远是最老的乌龟,直接设置players作为self的列表(这样会阻止排序) :

set players [self] of n-of 2 turtles