【问题标题】:Netlogo: Assign variable using probabilitiesNetlogo:使用概率分配变量
【发布时间】:2017-06-13 13:38:24
【问题描述】:

如何使用组/列表中变量的概率将字符串或整数变量分配给turtle?例如,从特定组/列表中使用一个特定变量的概率为 0.4。该函数根据概率随机选择变量。之后我需要使用相同的方法根据概率从列表中选择一个变量(字符串)。 在python中应该是:

import random
def random_value(probability_list, values):
    r = random.random()
    index = 0
    while(r >= 0 and index < len(probability_list)):
      r -= probability_list[index]
      index += 1
    value=values[index - 1]
    value_index=index-1
    return value,value_index

我在下面的 Netlogo 中尝试过(得到索引为 -1 的错误)但有更好的方法吗?

globals [random_nr probabilities some_list index]
to initialize-variables
  set some_list[]
  set probabilities[]
end
to random_pick
  set random_nr random-float 1
  set probabilities [0.1 0.2 0.4 0.3]
  set some_list ["String1" "String2" "String3" "String4"]
  set index 0
  while [(random_nr >= 0) and (length probabilities < index)] [
   set random_nr random_nr - item index probabilities
   set index index + 1 ]
  set index index - 1
end

【问题讨论】:

  • 一些一般性建议:如果你发现自己搞乱了索引和 while 循环,你可能做错了;几乎总有更好的、更类似于 NetLogo 的方式。

标签: list variables random probability netlogo


【解决方案1】:

有没有更好的方法?

是的。

NetLogo 6.0 与 rnd extension 捆绑在一起。 (您也可以download the extension separately 获取早期版本的 NetLogo。)

rnd 扩展提供了 rnd:weighted-one-of-list 原语,这正是您想要做的:

extensions [ rnd ]

to-report pick
  let probabilities [0.1 0.2 0.4 0.3]
  let some_list ["String1" "String2" "String3" "String4"]
  report first rnd:weighted-one-of-list (map list some_list probabilities) last
end

让我稍微解开最后一个表达式:

  • (map list some_list probabilities) 的作用是将两个列表“压缩”在一起,以便得到以下形式的对列表:[["String1" 0.1] ["String2" 0.2] ["String3" 0.4] ["String4" 0.3]]

  • 该对列表作为第一个参数传递给rnd:weighted-one-of-list。我们将last 作为rnd:weighted-one-of-list 的第二个参数传递给它,告诉它应该使用每对的第二项作为概率。

  • rnd:weighted-one-of-list 然后随机选择其中一对,并返回整对。但由于我们只对这对中的第一项感兴趣,所以我们使用first 来提取它。

要了解该代码的工作原理,了解Anonymous procedures 的工作原理会有所帮助。请注意我们如何使用简洁的语法将list 传递给map 以及将last 传递给rnd:weighted-one-of-list

【讨论】:

    【解决方案2】:

    不要忽视rnd 扩展: https://github.com/NetLogo/Rnd-Extension 但基本上可以按照您的建议进行。我会在这里,但最好使用显式参数。

    to-report random-pick
      let _r random-float 1
      let _ps [0.1 0.2 0.4 0.3]
      let _lst ["String1" "String2" "String3" "String4"]
      let _i 0
      while [_r >= item _i _ps] [
       set _r (_r - item _i _ps)
       set _i (_i + 1) ]
      report item _i _lst
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多