Dav*_*vid -1 fortran random-sample
我必须从人口中抽取一定数量的对象.下面的代码给出了替换的采样.我可以使用什么条件进行取样而无需更换?
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
Run Code Online (Sandbox Code Playgroud)
提前致谢
如果我理解正确,你可以使用这些陈述
call random_number(u1)
j1 = 1 + int(population*u1)
Run Code Online (Sandbox Code Playgroud)
生成整数索引(j1)以选择总体的第j1个元素.我将把n个人口中的第i个元素称为.在循环的每次迭代中,您都会生成一个新的随机数,并选择一个新的第i个元素,它有可能与您在一个(或多个)先前迭代中选择的元素相同.你宁愿采用一种避免重新选择已经选择过的i的方法.我认为你至少有3种方法.
一:列出你已经使用过的i.如果随机数生成器在稍后的迭代中抛出相同的i,则再次掷骰子直到获得新的骰子.这需要一点点直接的簿记.如果您需要帮助编程,请编辑您的问题.随着已经选择的i的比例变大,这种方法开始失去吸引力.一个你已经选择了50%的人口成员,你必须为每个新的i掷骰子两次(平均).您可以决定这是否是一个严重的问题.
二:创建群体的随机排列; 在第一次迭代中,选择第一个种群(以新的随机顺序),在第二次,第二次,依此类推.当然,你不会真正地对人群进行置换,你可以在人群中创建指数的随机排列. 这篇维基百科的文章建议你如何创建这样一个随机排列.同样,如果您在编码时遇到问题,请编辑您的问题或提出新问题.
三:这是两个变体,是我会做的.首先,在循环外部,创建一个由n个随机数组成的数组:
real, dimension(n) :: random_array
.
.
call random_number(random_array)
Run Code Online (Sandbox Code Playgroud)
接下来,在循环内部,找到数组中最小值的索引:
j1 = minloc(random_array, dim=1)
Run Code Online (Sandbox Code Playgroud)
请注意,我已经回到了你的符号并用作j1人口的索引.还要注意dim=1调用的规范,minloc以确保它返回一个标量:我认为这是Fortran 2003语义,早期的实现可能会返回一个带有1个元素的rank-1数组,因此请检查编译器文档.
如果minloc在数组中找到具有相同值的2个(或更多)元素,由于它们是reals,它们相对不太可能,它只返回它找到的第一个元素的索引,这对于我们的目的是可以的.
接下来,为了确保我们在下一次迭代中不选择相同的索引,请执行以下操作:
random_array(j1) = huge(1.0)
Run Code Online (Sandbox Code Playgroud)
注意确保调用的参数huge与real数字中的数字类型和种类相同random_array.
这应该随机地列举人口的元素而不替换.