在fortran中无需更换的抽样

时间:2012-08-09 16:09:39

标签: 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

提前致谢

1 个答案:

答案 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=1minloc的规范,以确保它返回一个标量:我认为这是Fortran 2003语义,而早期的实现可能会返回一个带有1个元素的rank-1数组,所以请检查你的编译器文档。

如果minloc在数组中找到2个(或更多)元素具有相同的值,由于它们是real s,它相对不太可能,它只返回它找到的第一个元素的索引,这是对我们来说没问题。

接下来,为了确保我们在下一次迭代中不选择相同的索引,请执行以下操作:

random_array(j1) = huge(1.0)

注意确保调用huge的参数与real中的random_array号码的类型和种类相同。

这应该随机列举人口的元素,而不是替换。