Netlogo 中的轮盘赌选择使用代理变量,而不是常量
Roulette Wheel Selection in Netlogo using Agent Variables, not Constants
我希望这是一个简单的解决方案,但我遇到了困难。
问题:
我想用一个变量而不是一个常数来衡量某件事发生的概率
设置
我的代理是一个农场。
农场拥有四个变量,代表
牛、山羊、猪和绵羊的数量。
当一个农场想要
删除一个动物,我想删除一个成员的可能性
特定物种与每个物种的数量成正比
农场上的物种(即如果有 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
原语(而不是仅仅括号)。
我要补充两点:
最新版本的rnd
扩展有两组原语:one for agentsets, and one for lists. So you should probably update and use the rnd:weighted-one-of-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 ? ]
,但这样会更难看。
我希望这是一个简单的解决方案,但我遇到了困难。
问题:
我想用一个变量而不是一个常数来衡量某件事发生的概率
设置
我的代理是一个农场。
农场拥有四个变量,代表 牛、山羊、猪和绵羊的数量。
当一个农场想要 删除一个动物,我想删除一个成员的可能性 特定物种与每个物种的数量成正比 农场上的物种(即如果有 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
原语(而不是仅仅括号)。
我要补充两点:
最新版本的
rnd
扩展有两组原语:one for agentsets, and one for lists. So you should probably update and use thernd:weighted-one-of-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 ? ]
,但这样会更难看。