0
votes

Fonction simple pour générer une séquence de nombres aléatoires sans connaître le nombre précédent mais connaître l'index de courant (pas d'affectation variable)?

Y a-t-il une fonction de génération aléatoire (simple) qui peut fonctionner sans affectation variable? La plupart des fonctions que j'ai lues ressemblent à ce en cours = suivant (courant) . Cependant, j'ai actuellement une restriction (de SQLite) que je ne peux utiliser aucune variable du tout.

existe-t-il un moyen de générer une séquence numérique (par exemple, de 1 à max ) avec uniquement n (index de numéro de courant dans la séquence) et graine ?

J'utilise actuellement ce:

moulage ((((1103515245 * graines * Rowid + 12345)% 2147483648) / 2147483648) / 2147483648) / 2147483648) + 1

avec max 47, rowid étant n . Cependant, pour certaines graines, le taux de répétition est trop élevé (3 unique sur 47).

Dans mes exigences, la répétition est ok aussi longtemps que ce n'est pas trop (<50%). Y a-t-il une meilleure fonction qui réponde à mon besoin?

La question a une étiquette SQLite, mais une langue / pseudo-code est OK.

PS: J'ai essayé d'utiliser Générateurs congrandentiels linéaires avec des triplets A / C / M et Semed * Rowid comme graines , mais cela ne fonctionne pas bien, c'est encore pire.

Edit: J'utilise actuellement celui-ci, mais je ne sais pas d'où il s'agit. Le taux semble mieux que le mien:

((((((graine * rangée)% 79) * 53)% "max") + 1


4 commentaires

SQLite a aléatoire () ... SQLITE.ORG/LANG_COREFUNC.HTML #random


@Shawn oui mais aussi loin que je le vois, je ne peux utiliser aucun graine , et c'est important car j'ai besoin que la séquence soit réordiable.


Votre implémentation SQL a-t-elle des fonctions hachées telles que MD5 ou SHA1? Un simple hachage du railid, modé dans la gamme de droite, devrait bien fonctionner.


@Leedanielcrocker c'est une idée intéressante, mais malheureusement non.


3 Réponses :


0
votes

a Générateur confortable linéaire avec Paramètres de choix ( a , c , et MODULUS M ) sera un générateur , de telle sorte qu'il cycle le pseudo-pseudorandommier à travers tous les nombres entiers de sa période avant de répéter. Bien que vous ayez peut-être essayé cette idée auparavant, avez-vous envisagé que m équivaut à max dans votre cas? Pour une liste de choix de paramètres pour ces générateurs, voir l'Ecuyer, P., "Tables de générateurs congruentiels linéaires de différentes tailles et une bonne structure de réseau", Mathématiques du calcul 68 (225), janvier 1999 .

Notez qu'il existe des problèmes pratiques à la mise en œuvre de cela dans la SQLite, en particulier si votre version SQLite prend en charge uniquement des entiers 32 bits et des nombres de points flottants de 64 bits (avec 52 bits de précision). À savoir, il peut y avoir un risque de -

  • Overflow Si une multiplication intermédiaire dépasse 32 bits pour les entiers et
  • perte de précision si une multiplication intermédiaire entraîne un nombre supérieur à 52 bits.

    Aussi, considérez pourquoi vous créez la séquence de numéro aléatoire:

    • est la séquence destinée à être imprévisible? Dans ce cas, un générateur congruentiellement linéaire ne suffit pas, et vous devriez générer des identifiants uniques par d'autres moyens, tels que par Combinant des numéros uniques avec des nombres aléatoires cryptographiquement .
    • Les chiffres générés de cette manière sont-ils exposés de quelque manière que ce soit pour mettre fin aux utilisateurs? Sinon, il n'est pas nécessaire de les obscurcer par "le mélanger".

      Aussi, en fonction de l'API SQLITE que vous utilisez (pour votre langage de programmation), il peut y avoir un moyen d'écrire une fonction personnalisée pour convertir la graine et Rowid à un numéro unique aléatoire. Les détails, cependant, dépendent fortement de l'API SQLite spécifique. Une autre réponse montre un exemple pour Perl.


6 commentaires

Le problème avec LCG est que je n'ai jamais vu de mise en œuvre qui n'utilise pas la variable (connaissant X (N) sans savoir x (N-1)). C'est ma limitation principale maintenant. En ce qui concerne le langage de programmation, je n'ai pas accès à celui-ci (c'est dans le contexte de la boite de sable et je ne donne que le dB)


Est max une constante dans votre application (par exemple, est-ce toujours le numéro 47)? En outre, considérons pourquoi vous devez utiliser des numéros uniques "aléatoires", par opposition à des chiffres "uniques". Ces chiffres seront-ils exposés de quelque manière que ce soit pour mettre fin aux utilisateurs? Les chiffres doivent-ils être «imprévisibles», ou simplement uniques? Pourquoi ne pouvez-vous pas utiliser de chiffres séquentiels ou le numéro Rowid à la place?


Ah désolé j'ai oublié de celles-ci. Eh bien, il ne s'agit pas de la sécurité et il devrait être facile à vivre tant que le résultat acceptable est disponible. Le max n'est pas vraiment des constantes mais devrait généralement être d'environ 43 à 50 (mais dans certains cas peut être plus élevé, mais pas beaucoup). Ils ne doivent pas nécessairement être absolument uniques ou aléatoires.


Ok, alors: n'est-ce pas suffisamment pour vos besoins? Sinon, pourquoi pas?


Eh bien ... j'en ai besoin d'être aléatoire et peut être reproductible compte tenu du même nombre de semences.


Avec un Max et vos contraintes, un générateur confortable linéaire n'est pas idéal, car une nouvelle formule doit être utilisée pour chaque valeur de max que vous anticipez. (Peut-être que le meilleur que vous puissiez faire est de choisir un m près de la valeur la plus élevée pour max que vous attendez et utilisez l'un des choix de paramètres dans L'Ecuyer 1999, ou Un choix personnalisé trouvé dans la manière suggérée dans ce document.) Je suis également au courant des registres de décalage de commentaires linéaires pour des numéros de pseudo-pseudo-pseudorandom uniques, mais ils ne fonctionnent que pour des pouvoirs de 2, pas de valeurs arbitraires pour max .



1
votes

Qu'en est-il de l'utilisation de la bonne fonction de hachage et de la carte entraîner une plage [1 ... max]?

Le long des lignes (en pseudocode). SHA1 a été ajouté à SQLite 3.17. xxx

ou utilisez n'importe quel code C externe pour hachage (murmur, chacha, ...) comme indiqué ici >


2 commentaires

Malheureusement mon sqlite_version () est 3.15.2, et je suis dans un environnement de sable de la boîte à sable et ne sont pas autorisés à mettre à jour / de modifier le moteur SQLite lui-même. Merci quand même, c'est une solution valide pour les personnes moins restrictions que les miennes.


@Lukevo peut-être qu'il y a des modules chargeux? Je ne suis pas très familier avec Sqlite. Fondamentalement, tout hachage décent avec de bonnes propriétés d'avalanche ( en.wikipedia.org/wiki/avalanche_effect ) fera le travail.



1
votes

Je ne suis pas sûr que si vous avez toujours le même problème, mais je pourrais avoir une solution pour vous. Ce que vous pourriez faire est d'utiliser des générateurs de séquence M Pseudo aléatoires basés sur des registres changeants. Là où vous devez juste prendre assez d'ordre de votre polynôme primitif et que vous n'avez pas besoin de stocker vraiment de variables. Pour plus d'informations, vous pouvez vérifier le page wiki

Qu'est-ce que vous auriez besoin de coder est juste L'équation de changement de polynôme primitif et j'ai vérifié dans un éditeur en ligne, il devrait être très facile à faire. Je pense que le moyen le plus simple est d'utiliser une base binaire et d'utiliser des séquences de PRBS et, en fonction du nombre d'éléments que vous aurez, vous pouvez choisir votre longueur de séquence. Par exemple, il s'agit de la mise en oeuvre de la longueur de 2 ^ 15 = 32768 (PRBS15), le polynôme primitif que j'ai pris de la page wiki (là, vous trouverez les polynômes primitifs tout le chemin de PRBS31 Que serait < Code> 2 ^ 31 = 2.1475E + 09 ) Fondamentalement, ce que vous devez faire est: xxx

La beauté de cette approche est si vous prenez la séquence des PRBS avec une période plus longue que votre plus grande valeur que vous aurez un hasard unique. indice. Très simple. :)

Si vous avez besoin d'aide pour rechercher des polynômes primitifs, vous pouvez voir mon Github Repo qui traite exactement de la recherche de polynômes primitifs et de séquences M unique. Il est actuellement écrit à Matlab, mais je prévois de l'écrire à Python dans les prochains jours.

acclamations!


0 commentaires