Netlogo 中的轮盘赌选择使用代理变量,而不是常量

Roulette Wheel Selection in Netlogo using Agent Variables, not Constants

我希望这是一个简单的解决方案,但我遇到了困难。


问题:

我想用一个变量而不是一个常数来衡量某件事发生的概率

设置

  1. 我的代理是一个农场。

  2. 农场拥有四个变量,代表 牛、山羊、猪和绵羊的数量。

  3. 当一个农场想要 删除一个动物,我想删除一个成员的可能性 特定物种与每个物种的数量成正比 农场上的物种(即如果有 7 只山羊、2 头牛和 1 头猪, 取山羊的概率为 70%,概率为零 羊的概率)

当您知道每个值的确切数值权重时,我找到了这样的公式:

to-report random-weighted [values weights]        
  let selector (random-float sum weights) 
  let running-sum 0 
    (foreach values weights [ 
      set running-sum (running-sum + ?2)    ; Random-Weighted Created by NickBenn
      if (running-sum > selector) [ 
        report ?1 
      ] 
    ]) 
end 

以及 rnd 扩展中描述的方法。但是,当我将 "Cow" 而不是常量放入时,这两个都会抛出 "expected a constant" 错误。

类似于:

 to example1
  let values ["Cow" "Sheep" "Goat" "Pig"]
  let probabilities [2 0 7 1]
  let indices n-values length values [ ? ]               ; Made by Nicolas Payette
  let index rnd:weighted-one-of indices [ item ? probabilities ]
  let loca item index values
end

效果很好,但如果我将其替换为:

to example1
      let values ["Cow" "Sheep" "Goat" "Pig"]
      let probabilities [Num-Cows Num-Sheep Num-Goats Num-Pigs]
      let indices n-values length values [ ? ]               ; Made by Nicolas Payette
      let index rnd:weighted-one-of indices [ item ? probabilities ]
      let loca item index values
    end

它失败了。

Alan 是对的:当你想从常量以外的任何东西构造一个列表时,你需要使用 list 原语(而不是仅仅括号)。

我要补充两点:

你也可以有这样的东西:

to example1
  let values ["Cow" "Sheep" "Goat" "Pig"]
  let probabilities (list Num-Cows Num-Sheep Num-Goats Num-Pigs)
  let loca first rnd:weighted-one-of-list (map list values probabilities) last
end

这可能有点难以理解,但这是它的要点:

  • (map list values probabilities) 表达式将您的 values 列表和 probabilities 列表和 "zips" 它们一起使用 list 原语,结果是一个对列表:[["Cow" 2] ["Sheep" 0] ["Goat" 7] ["Pig" 1]].

  • 我们将 last 报告器传递给 rnd:weighted-one-of-list 原语,告诉它每对中的最后一个(即第二个)项目应该用作概率.

  • 由于 rnd:weighted-one-of-list 对一个对列表进行操作,因此它 returns 的项目将是一个对(例如,["Goat" 7])。我们只对这对中的第一项感兴趣,所以我们用 first 报告器提取它。

请注意,在将 list 作为参数传递给 map 并将 last 作为参数传递给 rnd:weighted-n-of 时,我们使用 NetLogo 的简洁任务语法。您可以将 list 替换为 [ (list ?1 ?2) ],将 last 替换为 [ last ? ],但这样会更难看。