L'utilisation de qsrand, aléatoire méthode qui n'est pas aléatoire
Je vais avoir un problème étrange ici, et je n'arrive pas à trouver une bonne explication à ça, alors j'ai pensé à demander à vous les gars :
Envisager la méthode suivante :
int MathUtility::randomize(int Min, int Max)
{
qsrand(QTime::currentTime().msec());
if (Min > Max)
{
int Temp = Min;
Min = Max;
Max = Temp;
}
return ((rand()%(Max-Min+1))+Min);
}
Je ne vais pas vous expliquer ce que les gourous de cette méthode en fait, je vais plutôt vous expliquer mon problème :
Je l'ai compris quand j'ai appeler cette méthode dans une boucle, parfois, j'obtiens le même nombre aléatoire, encore et encore... Pour exemple, cet extrait...
for(int i=0; i<10; ++i)
{
int Index = MathUtility::randomize(0, 1000);
qDebug() << Index;
}
...va produire quelque chose comme :
567
567
567
567...etc...
J'ai réalisé aussi que si je ne l'appelez pas qsrand à chaque fois, mais une seule fois lors de ma demande de son vivant, il fonctionne parfaitement...
Ma question : Pourquoi ?
Vous devez vous connecter pour publier un commentaire.
Parce que si vous appelez
randomize
plus d'une fois en un millième de seconde (ce qui est plutôt probablement au courant du PROCESSEUR vitesse d'horloge), vous êtes l'amorçage de la RNG avec la même valeur. C'est garanti pour produire le même résultat à partir de la RNG.Aléatoire nombre de générateurs sont uniquement destinées à l'ensemencement des fois. L'ensemencement, à plusieurs reprises ne pas faire la sortie supplémentaire aléatoire, et en fait (comme vous l'avez trouvé) peut rendre beaucoup moins aléatoire.
qsrand(QTime::currentTime().msec());
2:int number = rand() % (100-0+1)+0;
suffit d'inverser les 100 avec votre numéro max et 0 avec votre nombre minimum.Si vous faites l'appel assez rapide de la valeur de
QTime::currentTime().msec()
ne changera pas, et vous avez l'impression de re-semisqsrand
avec la même semence, causant la prochaine nombre aléatoire généré à être le même que l'avant de l'un.Si vous appelez la qsrand Qt fonction pour initialiser la graine, vous devez appeler le qrand Qt fonction pour générer un nombre aléatoire, et non pas la fonction rand de la bibliothèque standard. la graine de l'initialisation de la fonction rand est srand.
Désolé pour le creuser.
Ce que vous voyez est l'effet de la pseudo-aléatoire. Vous la graine avec le temps une fois et il génère une séquence de nombres. Depuis que vous êtes en tirant une série de nombres aléatoires très rapidement les uns après les autres, vous êtes re-semis, l'entrant à nouveau avec le même nombre jusqu'à ce que le prochain ordre de la milliseconde. Et tout en un millième de seconde semble être un court laps de temps, pensez à la quantité de calculs que vous faites dans ce temps.
moderne Qt c++ 11
Deux problèmes:
1 Comme d'autres l'ont souligné, le générateur est en cours de semences à plusieurs reprises.
2 Ce n'est pas une très bonne méthode pour générer des nombres aléatoires à l'intérieur d'une plage donnée. (En fait, c'est très très mauvais pour la plupart des générateurs )
Vous êtes en supposant que les bits du générateur sont distribuées de manière uniforme . Ce n'est pas le cas avec la plupart des générateurs. Dans la plupart des générateurs de l'aléatoire se produit dans l'ordre élevé de bits.
En utilisant le reste après les divisions vous êtes en effet de jeter le caractère aléatoire de l'.
Vous devriez échelle à l'aide de la multiplication et de la division. Ne pas utiliser l'opérateur modulo.
par exemple
my_number= start_required + ( generator_output * range_required)/generator_maximum;
si generator_output est dans [0, generator_maximum]
my_number sera dans [start_required , start_required + range_required]
J'ai trouvé la même action et résolu par l'utilisation de la
rand()
au lieu de lasrand()
.Mais je l'utilise pour vérifier ma demande. Il vient de travailler dans la cicle, je n'ai pas besoin de chercher des mises à jour.
Mais si vous allez faire quelque roi de jeu, il n'est pas sur la bonne voie, parce que votre randomisation sera le même.