-1

我必须从人群中抽取一定数量的对象。下面的一段代码给出了带替换的采样。我可以在什么条件下不更换采样?

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

提前致谢

4

1 回答 1

6

如果我理解正确,您使用这些语句

   call random_number(u1)
   j1 = 1 + int(population*u1)

生成整数索引 ( j1) 以选择总体的第 j1 个元素。我将把它称为n人口中的第 i 个元素。在循环的每次迭代中,您都会生成一个新的随机数并选择一个新的第 i 个元素,该元素很有可能与您在一次(或多次)之前的迭代中选择的元素相同。您宁愿采用一种方法来避免重新选择已选择的i。我认为您至少有3种方法。

一:保留你已经使用过的i的列表。如果随机数生成器在以后的迭代中抛出相同的i,请再次掷骰子,直到得到一个新的。这需要一些简单的簿记。如果您在编程方面需要帮助,请编辑您的问题。随着已经选择的i的比例变大,这种方法开始失去吸引力。一个你已经选择了 50% 的人口成员,你必须为每个新的i掷两次骰子(平均) 。您可以决定这对您来说是否是一个严重的问题。

二:创建种群的随机排列;在第一次迭代中选择第一个种群(以新的随机顺序),在第二次迭代中选择第二个,依此类推。当然,您不会真正排列总体,而是将索引随机排列到总体中。 这篇 Wikipedia 文章建议您如何创建这样的随机排列。同样,如果您在编码时遇到问题,请编辑您的问题,或提出一个新问题。

三:这是对的变体,也是我会做的。首先,在循环之外,创建一个包含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 个(或更多)具有相同值的元素,因为它们是reals,所以相对不太可能,它只返回它找到的第一个元素的索引,这对于我们的目的来说是可以的。

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

random_array(j1) = huge(1.0)

注意确保调用 to 的参数huge与.realrandom_array

这应该在没有替换的情况下随机枚举总体的元素。

于 2012-08-10T08:42:47.020 回答