如何从1到N获得一组随机排序的数字?

时间:2012-03-23 14:18:49

标签: random duplicates fortran

下面的代码生成一个N整数随机数的数组,并将结果存储在random_int_array

 N=20
 allocate(array(N/2))
 call random_seed
 call random_number(array)
 random_int_array=int(array*N)

问题是我可能会在random_int_array中生成重复项,但我不希望这样。如何从此数组中删除副本,或者等效地,如何生成一组唯一的随机数?

请注意,array的维度为N / 2。所以问题基本上是从N中提取N / 2个数字,没有重复。

3 个答案:

答案 0 :(得分:3)

听起来你想要随机顺序从1到19的整数。这将是那些整数的混乱。例如,请参阅http://tekpool.wordpress.com/2006/10/06/shuffling-shuffle-a-deck-of-cards-knuth-shuffle/http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

答案 1 :(得分:0)

所以你试图从一组20码中生成10号大小的可能组合之一?有184756这样的组合。您可以生成[1..184756]范围内的单个随机整数,并将其用作函数的输入以创建第n个组合。

后一个问题经常在SO上提出,例如Calculate Combination based on position包含一个解决方案。

我没有声称这种方法在任何一般方面都比在正确的范围内重复生成随机数并抛弃重复数据更好,直到你有一套满足你要求的集合。

答案 2 :(得分:0)

在主程序之外定义以下功能

function random_uniform(m)
  implicit none
  integer*8 m
  real*8 random_uniform
  m = mod(7**5*m, 2147483647)
  random_uniform = m / 2147483647.     
end function

然后在main函数内部,使用此函数生成随机数组:

m = 1067 !This is your seed which you can change to get different sequence
do i = 1,20
   array(i) = random_uniform(m)
enddo

请注意,所有整数都是双精度类型(* 8)。这个功能必须正常工作。另外,为了避免整数除法得到random_uniform,我们将分母转换为实数(从整数* 8)