我必须从人口中抽取一定数量的对象。下面的代码给出了替换的采样。在没有更换的情况下,我可以使用什么条件进行取样?
do while(j .lt. w)
call random_number(u1)
j1 = 1 + int(population*u1)
Z = inftime(j1)
Z1 = X(j1)
Z2 = Y(j1)
do t = 1, 10
if(Z.gt.0 .and. Z.le.10)then
if(t==Z .and.( my_cnt(t) .lt. k1(t)))then
my_cnt(t) = my_cnt(t) + 1
j = j+1
inftime1(j)= Z
X1(j) = Z1
Y1(j) = z2
endif
endif
enddo
enddo
提前致谢
答案 0 :(得分:5)
如果我理解正确,你可以使用这些陈述
call random_number(u1)
j1 = 1 + int(population*u1)
生成整数索引(j1
)以选择总体的 j1-th 元素。我将在 n 的群体中调用 i-th 元素。在循环的每次迭代中,您都会生成一个新的随机数并选择一个新的 i-th 元素,并且它与您在一个(或多个)先前迭代中选择的元素相同。您宁愿采用一种避免重新选择已经选择的 i 的方法。我认为你至少有3种方法。
一个:保留您已经使用的 i 的列表。如果随机数生成器在稍后的迭代中抛出相同的 i ,则再次掷骰子直到获得新的骰子。这需要一点点直接的簿记。如果您需要帮助编程,请编辑您的问题。随着已经选择的 i 的比例变大,这种方法开始失去吸引力。你已经选择了50%的人口成员,你必须为每个新的 i 掷骰子两次(平均)。您可以决定这是否是一个严重的问题。
二:创建群体的随机排列;在第一次迭代中,选择第一个种群(按其新的随机顺序),在第二次,第二次,依此类推。当然,你不会真正地对人群进行置换,你可以在人群中创建指数的随机排列。 This Wikipedia article建议您如何创建这样的随机排列。同样,如果您在编写此代码时遇到问题,请编辑您的问题或提出新问题。
三:这是两个的变体,我会这样做。首先,在循环外部,创建一个 n 随机数的数组:
real, dimension(n) :: random_array
.
.
call random_number(random_array)
接下来,在循环内部,找到数组中最小值的索引:
j1 = minloc(random_array, dim=1)
请注意,我已经回到了您的符号并使用j1
作为人口的索引。还要注意调用dim=1
时minloc
的规范,以确保它返回一个标量:我认为这是Fortran 2003语义,而早期的实现可能会返回一个带有1个元素的rank-1数组,所以请检查你的编译器文档。
如果minloc
在数组中找到2个(或更多)元素具有相同的值,由于它们是real
s,它相对不太可能,它只返回它找到的第一个元素的索引,这是对我们来说没问题。
接下来,为了确保我们在下一次迭代中不选择相同的索引,请执行以下操作:
random_array(j1) = huge(1.0)
注意确保调用huge
的参数与real
中的random_array
号码的类型和种类相同。
这应该随机列举人口的元素,而不是替换。