2 votes

Comment obtenir un tableau de nombres aléatoires de 1 à N ?

Le code ci-dessous génère un tableau de N des nombres aléatoires entiers et stocke le résultat dans random_int_array

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

Le problème, c'est que je risque de générer des doublons en random_int_array et je ne veux pas de ça. Comment puis-je supprimer les doublons de ce tableau ou, de manière équivalente, comment puis-je générer un ensemble de nombres aléatoires uniques ?

Notez que array a une dimension N/2. Le problème consiste donc essentiellement à extraire N/2 nombres, sans doublons, parmi N.

3voto

M. S. B. Points 19509

On dirait que vous voulez les entiers de 1 à 19 dans un ordre aléatoire. Ce serait un mélange de ces entiers. Voir, par exemple, http://tekpool.wordpress.com/2006/10/06/shuffling-shuffle-a-deck-of-cards-knuth-shuffle/ o http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

0voto

Vous essayez donc de générer une des combinaisons possibles de taille 10 à partir d'un ensemble de taille 20 ? Il y a 184756 combinaisons possibles. Vous pourriez générer un seul entier aléatoire dans l'intervalle [1..184756] et l'utiliser comme entrée d'une fonction pour créer la nième combinaison.

Ce dernier problème est régulièrement soulevé sur SO, par exemple Calculer la combinaison en fonction de la position contient une solution.

Je ne prétends pas que cette approche soit meilleure, d'une manière générale, que la génération répétée de nombres aléatoires dans la bonne fourchette et l'élimination des doublons jusqu'à ce que vous obteniez un ensemble qui réponde à vos besoins.

0voto

Peaceful Points 1162

Définissez la fonction suivante en dehors de votre programme principal

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

Ensuite, dans la fonction principale, utilisez cette fonction pour générer un tableau aléatoire :

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

Notez que tous les entiers sont de type double précision (*8). C'est indispensable pour que cette fonction fonctionne correctement. De plus, pour éviter la division des entiers pour obtenir random_uniform, nous avons converti le dénominateur en réel (de integer*8)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X