问题描述
首先,让我描述一下我在做什么以及为什么问这个问题。
我有74个城市包含在模型中,我想模拟它们之间的运动。我有一个OD概率矩阵,其中行是起点,而列是终点。矩阵看起来像这样:
0 1 ..... 73
----------------------
0 |0.5 0.1 .... 0.0
...| . . .. . .
73 | 0.1 0.2 .. 0.3
请注意:如果我们看第一行,则意味着来自索引为0的城市的特工有可能留在索引中0.5,移动到idx = 1 0.1的城市中,依此类推。我想做的是以最好的统计学方法分配代理商的目的地。对于起源于城市0的座席,我想保留大约50%的座席(而不是准确的50%),但我也想给几率为0%的城市一些机会,例如0-73对。 我已经根据以下问题的答案对随机性进行了编码:Netlogo: How can send agents from "area x" to "area y" using an O/D matrix? 但是在这个问题上对我来说答案是不合逻辑的,具体来说,这部分是:
ask turtles with [residency = "nw"]
[ let myrandom random-float 1
ifelse myrandom <= 0.5 [ set destination "nw" ] [
ifelse myrandom <= 0.8 [ set destination "ne" ] [
ifelse myrandom <= 0.0 [ set destination "sw" ] [
set destination "se" ]]]
如果我很好理解,随机性将采用0-1范围内的值,然后将逐个检查其值是否小于或等于该常数。 从这个意义上说,随机分布的伤口永远不会到达“ sw”部分(0始终小于0.5),并且更有可能获得概率为0.5的“ nw”部分而不是概率较高的“ ne”部分-0.8。只是因为它不在第一位。我不确定这是正确的方法,也不确定是哪一种(我无法对我的概率进行排序,因为它们的位置代表了城市编号(见下文))。还是我理解错了?
此处显示了我的代码的一部分。我导入的矩阵没有标题/城市ID,因为它们等效于Netlogo索引。 ID为ID的城市已导入到模型中。另外,在每个点/城市中,我创建了从CSV文件中为每个城市读取的相应数量的座席。在创建代理程序的过程中,我使用矩阵中与当前城市/起源相对应的行,并像JenB在上面的回答中所做的那样遍历了概率。
breed [city cities]
breed [inhabitant inhabitants]
;; part of the setup
;; open the csv file that contains population per city
file-open path
while [ not file-at-end? ] [
let data csv:from-row file-read-line
let city-id item 0 data
let population item 1 data
to add-inhabitants
create-inhabitants population [
set city-home one-of cities with [id = city-id] ;; set the origin
move-to city-home
set-destination(city-id) ;; for this origin chose the destination
]
]
to set-destination [row] ;; row from the matrix which represent the movement from the current city/origin to other cities
let row-probabilities matrix:get-row od-matrix row ;; use the row that correspondents to the city
let random-value random-float 1
let i 0 ;; index counter
foreach row-probabilities [ ;; for each probability in row
p ->
if random-value <= p ;; this part is coded as in the JenB's answer
[
set destination one-of cities with [id = i] ;; i is column index which is actually index of destination city
stop ;; if you set city -> stop
]
if i = 73 [set destination one-of cities with [id = i]
stop] ;; the last city -> there is no more option/reason to check
set i i + 1
]
end
我知道它会更长一些,但是我想清楚地解释一下。一些指导和解释将不胜感激!
解决方法
您的问题表明您不了解该部分中的代码在做什么。这是该位的更正代码:
ask turtles with [residency = "nw"]
[ let myrandom random-float 1
ifelse myrandom <= 0.5 [ set destination "nw" ] [
ifelse myrandom <= 0.8 [ set destination "ne" ] [
ifelse myrandom <= 0.9 [ set destination "sw" ] [
set destination "se" ]]]
是的,该块中的第一行绘制了一个0到1范围内的随机数。想象一下,绘制得出0.4。然后第一个ifelse
将为true,并且目的地将设置为“ nw”。现在假设抽奖是0.6,那么第一个ifelse
将是错误的,代码将继续测试else
部分,这是正确的,因为0.6
该代码有效,因为初始绘制是均匀的。即,平均有10%的时间返回0到0.1范围内的数字,而在0.1到0.2范围内则返回10%,依此类推。因此,有50%的时间会返回0到0.5范围内的数字,第一行返回true。在30%的时间内,它返回范围在0.5到0.8之间的数字,这对于第一次测试是错误的,而对于第二次测试则为true。它有10%的时间返回0.8到0.9范围内的数字,有10%的时间返回0.9到1范围内的数字。
因此,以0.5、0.8、0.9(其余为1)的检查点打破间隔,可以得到0.5、0.3(= 0.8-0.5),0.1(= 0.9-0.8)和0.1(= 1)的部分= 0.9)的长度。并且一个统一的随机数将落入概率分布分别为抽奖的50%,30%,10%和10%的那些部分。