2

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


问题:

我想加权一个变量而不是常数发生某事的概率

设置

  1. 我的代理人是农场。

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

  3. 当农场想要移除动物时,我希望移除特定物种的成员的可能性与农场中每个物种的数量成正比(即,如果有 7 只山羊、2 头奶牛和 1 头猪,有 70% 的概率会抓到一只山羊,而有 0% 的概率会抓到一只绵羊)

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

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

它失败。

4

1 回答 1

4

listAlan 是对的:当您想从常量以外的任何内容构建列表时,您需要使用原语(而不仅仅是括号)。

我要补充两点:

你也可以有类似的东西:

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列表,并使用原语将它们“压缩”在一起list,从而产生一个对列表:[["Cow" 2] ["Sheep" 0] ["Goat" 7] ["Pig" 1]]

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

  • 由于rnd:weighted-one-of-list对对列表进行操作,因此它返回的项目将是一对(例如,["Goat" 7])。我们只对这对中的第一项感兴趣,因此我们与first记者一起提取它。

请注意,当list作为参数传递给maplast作为参数传递给rnd:weighted-n-of. 你可以list[ (list ?1 ?2) ]last替换[ last ? ],但它会更难看。

于 2016-08-04T22:44:11.720 回答