How to get an array of randomly ordered numbers fr

2019-05-29 05:35发布

问题:

The code below generates an array of N integer random numbers and stores the result in random_int_array

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

The problem is that I might generates duplicates in random_int_array and I don't want that. How can I remove the duplicate from this array or, equivalently, how can I generate a set of unique random numbers?

Note that array has a dimension N/2. So the problem is basically extract N/2 numbers, without duplicates, out of N.

回答1:

It sounds like you want the integers from 1 to 19 in random order. This would be a shuffle of those integers. See, e.g., http://tekpool.wordpress.com/2006/10/06/shuffling-shuffle-a-deck-of-cards-knuth-shuffle/ or http://en.wikipedia.org/wiki/Fisher-Yates_shuffle



回答2:

So you're trying to generate one of the possible combinations of size 10 from a set of size 20 ? There are 184756 such combinations. You could generate a single random integer in the range [1..184756] and use that as input to a function to create the n-th combination.

This latter problem is regularly raised on SO, for example Calculate Combination based on position contains a solution.

I make no claims that this approach is better in any general way than repeatedly generating random numbers in the right range and throwing away duplicates until you have a set that satisfies your requirements.



回答3:

Define the following function outside your main program

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

Then inside the main function, use this function to generate random array:

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

Note that all the integers are of double precision type (*8). This is must for this function to work properly. Also, to avoid integer division to get random_uniform, we have converted denominator into real (from integer*8)