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

Random 如何获得从1到N的随机顺序数字数组?,random,duplicates,fortran,Random,Duplicates,Fortran,下面的代码生成一个N整数随机数数组,并将结果存储在random\u int\u数组中 N=20 allocate(array(N/2)) call random_seed call random_number(array) random_int_array=int(array*N) 问题是我可能会在随机数组中生成重复项,我不希望这样。如何从该数组中删除重复项,或者等效地,如何生成一组唯一的随机数 请注意,array的维度为N/2。因此,问题基本上是从N个数中提取N/2个数,没有重复项

下面的代码生成一个
N
整数随机数数组,并将结果存储在
random\u int\u数组中

 N=20
 allocate(array(N/2))
 call random_seed
 call random_number(array)
 random_int_array=int(array*N)
问题是我可能会在
随机数组中生成重复项,我不希望这样。如何从该数组中删除重复项,或者等效地,如何生成一组唯一的随机数


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

听起来你想要1到19之间的整数以随机顺序排列。这将是这些整数的混合。请参见,例如,或

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

后一个问题经常被提出,例如,它包含一个解决方案


我不认为这种方法在任何一般情况下都比在正确的范围内重复生成随机数并丢弃重复数更好,直到你有一个满足你要求的集合。

在你的主程序之外定义以下函数

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
然后在主函数内,使用此函数生成随机数组:

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)。这是此功能正常工作所必需的。另外,为了避免整数除法以获得随机均匀性,我们将分母转换为实数(从整数*8)

这不是我想要的。我编辑了这篇文章,现在应该更清楚了。但是你可以洗牌N个数字,只将其中的一半放入你的数组中。或者只进行一半洗牌。Wikapedia的文章指出,Fisher-Yates算法适用于只需要一部分排列的情况。这是最简单的方法,你只需跳过重复,还不够好吗?(将项目从random_int_array1移动到random_int_array2,如果它们不在第二个数组中)这就足够了,但我需要一种聪明的方法来找到重复项并消除它们。没关系,我发现这个页面对我的问题非常有用:你能描述一下它的作用吗?它如何保证不重复的值?它比随机数好吗?注意OP想要随机整数数组。事实上,@VladimirF。虽然
m
将(通常)是长周期的,但如果不仔细描述
random\u uniform
如何映射到整数,这并不能回答问题。正如您必须注意的,这是一个线性同余生成器。它是由刘易斯、古德曼和米勒在1969年提出的,并成功地通过了许多测试(尽管有更好的发电机可用)。请注意,此生成器的周期为2147483647,这对于任何实际用途都是非常好的。一旦我们有了这个函数,得到整数数组而不是实数数组就是儿戏。