12
votes

Algorithme d'imprimer une liste mélangée, sur place et avec O (1) mémoire

Après avoir lu Cette question j'ai commencé à me demander: est-il possible de avoir un algorithme de mélange qui ne modifie pas ou ne copie pas la liste d'origine?

Pour préciser:

Imaginez que vous avez reçu une liste d'objets. La taille de la liste peut être arbitraire, mais suppose qu'il est assez grand (par exemple, 10 000 000 articles). Vous devez imprimer les éléments de la liste dans un ordre aléatoire et vous devez le faire aussi vite que possible. Cependant, vous ne devriez pas:

  • Copiez la liste d'origine, car c'est très grand et la copie perdrait beaucoup de mémoire (frapper probablement les limites de la RAM disponible);
  • Modifiez la liste d'origine, car il est trié d'une manière ou d'une autre et une autre partie plus tard dépend de son tri.
  • Créer une liste d'index, car, encore une fois, la liste est très grande et la copie prend trop de temps et de mémoire. (Clarification: Ceci est signifié à toute autre liste, qui a le même nombre d'éléments que la liste d'origine).

    est-ce possible?

    ajouté: plus de clarifications.

    1. Je veux que la liste soit mélangée de manière aussi aléatoire de toutes les permutations également probables (bien sûr, en supposant que nous ayons une fonction de rand () appropriée pour commencer).
    2. Suggestions que je fais une liste de points d'ouverture, ou une liste d'indices, ou toute autre liste qui aurait le même nombre d'éléments que la liste d'origine, est explicitement jugée comme inefficace par la question initiale. Vous pouvez créer des listes supplémentaires si vous le souhaitez, mais ils devraient être des ordres de grandeur graves plus petites que la liste d'origine.
    3. La liste d'origine est comme un tableau et vous pouvez récupérer n'importe quel article par son index dans O (1). (Donc, pas de choses de liste doublement liées, où vous devez itération à travers la liste pour vous rendre à l'article souhaité.)

      ajouté 2 : OK, mettons-la comme ça: Vous avez un disque dur de 1 ToB rempli d'éléments de données, chacun de 512 octets (un seul secteur). Vous souhaitez copier toutes ces données sur un autre disque dur de 1 ToB tout en mélangeant tous les éléments. Vous voulez le faire aussi vite que possible (passer une seule passe sur les données, etc.). Vous avez 512 Mo de RAM disponible et ne comptez pas sur Swap. (Ceci est un scénario théorique, je n'ai rien comme ça dans la pratique. Je veux juste trouver l'algorithme parfait.Item.)


9 commentaires

Je pense que la réponse à cela peut dépendre de la mise en œuvre interne de la liste. Juste pour être clair, cela serait probablement une liste doublement liée?


Paxdiablo discute du shuffle de Knuth dans ce message Stackoverflow.com/Questtions/1858610/... Je pense que c'est ce que vous êtes après.


Sur une seconde pensée, bien qu'elle fonctionne à O (n), vous devrez créer un ensemble INT de cette longueur - mais je pense que c'est le meilleur que vous puissiez atteindre - vous devez en quelque sorte suivre les éléments sélectionnés.


La réponse est "non", mais il n'y a pas assez de place dans cette marge pour expliquer pourquoi :-)


N'hésitez pas à ajouter une longue réponse. :) Je pense aussi que la réponse est "non", mais je ne peux pas le prouver, c'est pourquoi je l'ai demandé. :)


@ Vilx-, maintenant, vous causez simplement des problèmes :-) Allez acheter un troisième lecteur de 1 To et utilisez-le comme une liste de shuffle ou un masque de bits pour les secteurs :-)


Oh, allez! Je veux juste trouver l'algorithme parfait! :)


Si vous êtes cassé, vous avez des choses plus importantes à vous inquiéter que des enregistrements de mélange. Aller chercher un homme d'emploi :-)


Hahaha! : D +1 pour ce commentaire! :RÉ


11 Réponses :


13
votes

Eh bien, cela dépend un peu sur quel type de hasard vous sauf pour le mélangeur, c'est-à-dire que tous les shufflings soient aussi probables, ou la distribution peut être asymétrique.

Il existe des moyens mathématiques de produire des permutations "à la recherche aléatoire" de N entiers, donc si p est une telle permutation de 0..n-1 à 0..n-1, vous pouvez simplement itérer x de 0 à N-1 et l'élément de la liste de sortie L (p (x)) au lieu de l (x) Et vous avez obtenu un mélangeur. Ces permutations peuvent être obtenues par ex. en utilisant des arithmétiques modulaires. Par exemple, si n est préféré, p (x) = (x * k) mod n est une permutation pour tout 0

Il devrait être a noté que l'exponentiation modulaire est la base de nombreux algorithmes cryptographiques (par exemple, RSA, Diffie-Hellman) et est considérée comme une opération fortement pseudorandom par les experts sur le terrain. p>

Un autre moyen facile (ne nécessitant pas de numéros premiers) d'abord pour élargir le domaine afin que, au lieu de n, vous considérez que m où m est le moins de pouvoir de deux au-dessus de N. Donc, par exemple. Si n = 12, vous définissez m = 16. Ensuite, vous utilisez des opérations de bits BIJECTIVE, par exemple P>

AES(k, 0), AES(k, 1), ...


7 commentaires

Eh bien, j'aimerais vrai aléatoire impartial. Je suis au courant de la solution principale, mais ce n'est pas vraiment aléatoire.


Le problème avec un PRNT fort est que vous obtiendrez des répétitions. Cela nécessite un bitmap pour empêcher «cueillir» un élément de la liste d'origine plus d'une fois.


Eh bien, comme je l'ai signalé ci-dessus, il existe des séquences non répétitives qui, à mesure que les permutations sont considérées comme fortement aléatoires, par exemple. Exponciation modulaire ou chiffres de bloc modernes.


Je pense que cette réponse est la plus proche que vous puissiez obtenir. Toute algorithme vraiment aléatoire va nécessiter de garder une trace de laquelle l'élément a déjà été sélectionné puisqu'il sera, par définition, ne pas être prévisible. Cela signifie soit modifier la liste d'origine ou créer une structure de données distincte.


Qu'entendez-vous par «sauf aléatoire»?


Aimer cette réponse. Je ne les utiliserais pas pour quelque chose de cryptographique, mais pour les jeux, cette idée va travailler un régal.


Corrigez-moi si je me trompe, mais je pense que le p (x) = (x ^ 3) mod n n'est pas une permutation. Par exemple, 1 ^ 3 mod 7 = 1 MOD 7 = 1, mais aussi 2 ^ 3 mod 7 = 8 mod 7 = 1. Je pense que la réponse allait pour quelque chose comme ça, ce qui est plus compliqué: Stackoverflow.com / Questions / 10054732 / ...



4
votes

Vous n'êtes pas autorisé à effectuer une copie, de le modifier ou de garder une trace de laquelle des éléments que vous avez visités? Je vais dire que ce n'est pas possible. Sauf si j'ai mal compris votre troisième critère.

Je suppose que vous voulez dire que vous n'êtes pas autorisé à dire, faites une matrice de 10 000 000 booléens correspondants, défini sur true lorsque vous avez imprimé l'élément correspondant. Et vous n'êtes pas autorisé à faire une liste des 10 000 000 indices, mélangez la liste et imprimez les éléments de cet ordre.


1 commentaires

Oui, vous me comprenez correctement. Eh bien, vous pouvez garder une trace de laquelle les articles que vous avez visités, si vous découvrez un moyen de le faire sans faire une autre liste de la même taille que son entrée. Si vous faites une liste de taille quelque chose comme Log (n), alors je serais satisfait.



2
votes

Ces 10 000 000 articles ne sont que des références (ou des pointeurs) aux éléments réels, de sorte que votre liste ne sera pas aussi grande. Seulement ~ 40 Mo sur une architecture 32 bits pour toutes les références + taille des variables internes de cette liste. Si lorsque vos articles sont plus petits que la taille de référence, vous ne copiez simplement que la liste complète.


0 commentaires

1
votes

Cela semble impossible.

mais 10 000 000 pointeurs 64 bits ne sont que d'environ 76 Mo.


3 commentaires

Ok, j'ai un peu augmenté les enjeux. :)


@Vilx et vous n'avez dit que les articles Poids 1 To, pas qu'il y ait 1T de pointeurs. Tout dépend du nombre de vos articles, pas de la taille de tous ces éléments.


Dans mon exemple ci-dessus, il y a 1 g de pointeurs, beaucoup trop pour 512 Mo de Ram quand même.



0
votes

S'il y a suffisamment d'espace, vous pouvez stocker les pointeurs de nœud dans un tableau, créer un bitmap et obtenir des INT au hasard qui pointent sur l'élément choisi suivant. Si déjà choisi (vous stockez cela dans votre bitmap), alors soyez le plus proche (à gauche ou à droite, vous pouvez randomiser cela), jusqu'à ce que aucun produit ne soit laissé.

S'il n'y a pas assez d'espace, vous pourriez faire la même chose sans stocker les pointeurs de nœud, mais le temps souffrira (c'est le compromis de l'espace horaire).


1 commentaires

L'OP a déjà dit qu'ils ne voulaient pas avoir à créer un réseau d'indices de même taille, qu'un éventail de pointeurs équivaut à. Ensuite, s'ils sont le permettent, je ne comprends pas pourquoi vous auriez besoin de ce vague «bitmap d'intensions aléatoires» quand, si vous étiez autorisé à avoir un 2e conteneur, vous pouvez simplement utiliser STD :: shuffle sur cela puis itérer, ce qui serait beaucoup plus simple et (je présume) plus rapidement.



2
votes

Il n'est pas possible de le faire avec un générateur de nombres aléatoires véritable que vous devez soit:

  • N'oubliez pas quels numéros ont déjà été choisis et les sauter (qui nécessitent une liste O (n) de booléens et qui aggravent progressivement les temps d'exécution lorsque vous sautez de plus en plus de chiffres); ou
  • Réduisez la piscine après chaque sélection (qui nécessite soit des modifications à la liste d'origine, une liste séparée O (n) à modifier).

    Aucun de ceux-ci ne sont pas des possibilités dans votre question, donc je vais avoir à dire "non, tu ne peux pas le faire".

    Ce que j'aurais tendance à faire dans ce cas est un masque de bits de valeurs utilisées mais pas avec le saut depuis, comme mentionné, les temps d'exécution s'aggravent lorsque les valeurs utilisées s'accumulent.

    Un masque de bits sera sensiblement meilleur que la liste d'origine de 39 Go (10 millions de bits ne correspond que d'environ 1,2 m), beaucoup d'ordre de grandeur moins que vous avez demandé, même si c'est toujours O (n).

    Pour contourner le problème d'exécution, générez un nombre aléatoire à chaque fois et, si le bit «utilisé» correspondant est déjà défini, balayez vers l'avant dans le masque de bits jusqu'à ce que vous en trouviez un pas < / em> ensemble.

    Cela signifie que vous ne serez pas suspendu, désespérément pour le générateur de nombres aléatoires de vous donner un numéro qui n'a pas encore été utilisé. Les temps d'exécution ne seront jamais aussi mauvais que le temps nécessaire pour numériser 1,2 m de données.

    Bien sûr, cela signifie que le nombre spécifique choisi à tout moment est asymétrique en fonction des chiffres déjà choisis, mais que ces chiffres étaient de toute façon aléatoire, l'asymétrie est aléatoire (et si les chiffres n'étaient pas vraiment aléatoire de commencer, puis la biaiser auront d'importer).

    Et vous pouvez même alterner le sens de la recherche (numérisation de haut ou bas) si vous voulez un peu plus de variété.

    En bas de la ligne: je ne crois pas ce que vous demandez est faisable, mais gardez à l'esprit que je me suis trompé auparavant, car ma femme attestera, rapidement et fréquemment :-) Mais avec toutes choses, il y a Habituellement des moyens de contourner de tels problèmes.


3 commentaires

Eh bien, je suis d'accord sur votre point sur le générateur de nombres vraiment aléatoires. Je pensais quelque chose à propos d'une fonction de PRNG étrange qui générerait une liste non répétée d'entiers pouvant servir de indices dans la liste d'origine. Eh bien, sans répétition uniquement aussi grande que la taille de la matrice. Après cela, ils commencent à répéter, naturellement, peut-être même dans la même séquence.


Bien sûr, chaque PRNG a besoin d'une graine, une entropie originale à baser. Au cas où j'ai 1 000 000 000 articles, il y a 1 000 000 000 000! permutations possibles qui sont beaucoup. Je ne sais même pas combien, mais la graine de PRNG aurait besoin d'avoir au moins que de nombreuses variations, ou la distribution seraient sérieusement biaisées. Un nombre binaire de cette taille serait-il plus petit qu'une liste d'indices entier 32 bits?


Si oui, cette graine pourrait être générée par le générateur de nombres vraiment aléatoires, puis le PRNG prendrait soin du reste.



0
votes

Vous pouvez créer un pseudorandom, «sécuriser» permutation à l'aide d'un chiffrement de bloc - voir ici . Ils ont une perspicacité clé, c'est que, étant donné un chiffrement à bloc de N bits de longueur, vous pouvez utiliser «pliage» pour raccourcir à M


0 commentaires

1
votes

Un registre à décalage de retour linéaire peut faire à peu près à peu ce que vous voulez - générer une liste de chiffres jusqu'à une limite, mais dans un ordre aléatoire (raisonnablement). Les modèles qu'il produit sont statistiquement similaires à ce que vous attendez d'essayer du hasard, mais ce n'est même pas proche de la sécurité cryptographique. L'algorithme Berlekamp-Massey vous permet d'inverser l'ingénieur d'un LFSR équivalent basé sur une séquence de sortie.

Compte tenu de votre condition d'une liste d'environ 10 000 000 articles, vous souhaiteriez une LFSR de longueur maximale 24 bits, et simplement supprimer les sorties supérieures à la taille de votre liste.

Pour ce que cela vaut, un LFSR est généralement assez rapide que d'un PRN de la même période typique de la même période. Dans le matériel, une LFSR est extrêmement simple, consistant en un registre N-bits et M 2-INPUT XOR's (où M est le nombre de robinets - parfois seulement un couple, et rarement plus qu'un demi-douzaine).


1 commentaires

C'est une très bonne idée aussi - certains programmeurs de jeu vous remercieront de l'avoir signalé.



2
votes

Voici une preuve très simple qu'aucun système de PRNG ne peut fonctionner:

L'idée PRNG a deux phases: d'abord, sélectionnez un PRNG et son état initial; Deuxièmement, utilisez le PRNG pour mélanger la sortie. Eh bien, il y a n! permutations possibles, vous avez donc besoin d'au moins n! différents états de démarrage possibles, entrant la phase 2. Cela signifie qu'au début de la phase 2, vous devez avoir au moins journal 2 n! bits d'état, qui n'est pas autorisé.

Cependant, cela n'exclut pas les schémas où l'algorithme reçoit de nouveaux bits aléatoires de l'environnement. Il pourrait y avoir, disons, un PRNG qui lit son état initial paresseusement et est garanti de ne pas répéter. Pouvons-nous prouver qu'il n'y a pas?

Supposons que nous ayons un algorithme de mélange parfait. Imaginez que nous commençons à courir, et quand c'est à mi-chemin, nous mettons l'ordinateur dormir. Maintenant, l'état complet du programme a été sauvé quelque part. Laissez s est l'ensemble de tous les états possibles que le programme pourrait être dans cette marque à mi-chemin.

Étant donné que l'algorithme est correct et garanti de se terminer, il existe une fonction f qui compte tenu de l'état de programme enregistré plus une chaîne de bits suffisamment longue, produit une séquence valide de lecture de disque et écrit le shuffle. L'ordinateur lui-même implémente cette fonction. Mais considérez-le comme une fonction mathématique:

f : (s × bits) → séquence de lecture et écrit

Puis, de manière triviale, il existe une fonction g qui, étant donné seul l'état du programme enregistré, produit l'ensemble des emplacements de disque à lire et à écrire. (Laissez simplement passer une ficelle arbitraire de bits à f , puis regardez les résultats.)

g : s jeu d'emplacements pour lire et écrire

Le bit restant de la preuve consiste à montrer que le domaine de g contient au moins n c n / 2 < / em> différents ensembles quel que soit le choix de l'algorithme. Si tel est vrai, il doit y avoir au moins que de nombreux éléments de s , et l'état du programme doit donc contenir au moins journal 2 N < / SUB> C N / 2 Les bits à mi-chemin, en violation des exigences.

Je ne sais pas comment prouver que le dernier bit, cependant, depuis l'ensemble des emplacements-lecture ou les installations -L'écrire peut être faible entraplopy, en fonction de l'algorithme. Je soupçonne qu'il y a un principe évident de la théorie de l'information pouvant couper le nœud. Marquant ce wiki communautaire dans l'espoir que quelqu'un le fournira.


8 commentaires

Wow cool. En fait, je ne vous suivez pas à travers la seconde moitié, mais cela semble assez grave que je ne doute pas de vous.


Il est vrai que si toutes les permutations doivent être aussi probables que vous ne pouvez utiliser aucun standard, hors-la-auto-prng car lorsque N devient grand, n! >> 2 ** k où k = taille en bits de l'état interne de la PRNG. Cependant, je pense qu'il est erroné d'interpréter le «vrai aléatoire» du poste d'origine de cette manière stricte, car elle ferait même une solution qui pourrait utiliser une quantité arbitraire d'espace très difficile. Je pensais que la question initiale était davantage sur l'utilisation de l'espace et "véritable aléatoire" signifiait "vrai pseudorandom" comme étant la norme en informatique.


Eh bien, l'astucieux a dit plusieurs fois ce qu'il voulait dire par "vrai aléatoire". Et il ou elle vérifie cette réponse. Alors.


@ antti.huima: Notez également que la deuxième partie de cette réponse tente de faire valoir que la tâche spécifiée est impossible même si nous prenons pour acquis une source parfaite de randomneur (c.-à-d. "L'algorithme reçoit de nouveau bits aléatoires de l'environnement comme ça va ").


D'un point de vue théorique, je pense que une question raisonnable peut être une question raisonnable: supposons que l'on reçoive une fonction supposée prendre une durée constante et laquelle pour toute paire arbitraire d'entiers x et y produira un entier vraiment aléatoire également réparti entre 0 et ( X-1) inclus. Quelle est la courbe de compromis optimale / spatiale pour produire un shuffle parfait de n cartes N, si la magnitude d'entier maximale est une puissance constante du nombre de cartes? Il pourrait être fait dans O (1) espace et o (n ^ 2) temps, en cueillant des nombres de 0 à N-1, puis de 0 à N-2, etc. Mais augmenter chaque nombre par le nombre de ...


... des numéros précédents inférieurs ou égaux à celui-ci. Il peut être fait dans O (n) espace et o (n) temps en utilisant des méthodes de mélange existantes. Je vais conjecturer que o (n ^ 0.5) espace et o (n ^ (1.5)) le temps ne serait probablement pas trop difficile, mais je me demande s'il y a des approches qui seraient O (lg (n)) dans l'espace et o (NLGN) à temps?


Je suis à peu près sûr que cette réponse manque le point de la question. Oui, aucun PRNA raisonnable ne peut rendre toutes les sorties possibles également probables, mais qui s'appliquent également au cas où vous êtes autorisé à modifier l'entrée. Il s'applique à la plupart des applications d'un PRNG. Nous ne nous soucions tout simplement pas. Bien que la question dit «avec toutes les permutations également probables», cela ne devrait pas. Les vrais problèmes sont en train de s'assurer que la sortie ne contient pas de répétitions et de s'assurer que la sortie est suffisamment indiscernable du hasard.


@ user2357112: Antti Huima a posté un commentaire très similaire en 2009. J'ai répondu alors. La question posée, après plusieurs mises à jour, est extrêmement claire sur ce que l'on entend par "vrai aléatoire". Je vais accorder que c'est peut-être une mauvaise question, mais à l'époque, je m'opposais à "Peut-être que vous vouliez dire cette question totalement autre question" réponses.



0
votes

essentiellement ce dont vous avez besoin est un générateur de nombres aléatoires qui produit les chiffres 0..n-1 exactement une fois chacun.

Voici une idée à moitié cuit au four: vous pouvez faire assez bien en cueillant un premier p légèrement plus grand que N, puis choisissez un X aléatoire entre 1 et P-1 dont l'ordre dans le groupe multiplicatif MOD P est P-1 (choix XS et test aléatoires que ceux qui satisfont x ^ i! = 1 pour i = n et cela vous donne une séquence d'index à imprimer.

Ce n'est pas terriblement aléatoire, mais vous pouvez utiliser la même technique à plusieurs reprises, en suivant les index ci-dessus (+1) et les utiliser comme des exposants d'un autre générateur X2 Modulo Authore P2 (vous aurez besoin de n


0 commentaires

0
votes

Ma solution dépend des propriétés mathématiques de certains numéros intelligemment calculés xxx pré>

avec cette configuration, nous pouvons calculer les suivants à plusieurs reprises et il ira tous les éléments de la matrice exactement une fois dans un apparemment aléatoire. ordre, après quoi il se bougera de traverser la matrice dans la même commande exacte à nouveau. p> xxx pré>

J'ai mis en œuvre et testé cela dans Java, j'ai donc décidé de coller mon code ici pour Référence future. P>

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

public class PseudoRandomSequence {

    private long            state;
    private final long  range;
    private final long  root;
    private final long  prime;
    //Debugging counter
    private int             dropped = 0;

    public PseudoRandomSequence(int r) {
        range = r;
        prime = closestPrimeAfter(range);
        root = modPow(generator(prime), closestPrimeTo(prime / 2), prime);
        reset();
        System.out.println("-- r:" + range);
        System.out.println("   p:" + prime);
        System.out.println("   k:" + root);
        System.out.println("   s:" + state);
    }

    // https://en.wikipedia.org/wiki/Primitive_root_modulo_n
    private static long modPow(long base, long exp, long mod) {
        return BigInteger.valueOf(base).modPow(BigInteger.valueOf(exp), BigInteger.valueOf(mod)).intValue();
    }

    //http://e-maxx-eng.github.io/algebra/primitive-root.html
    private static long generator(long p) {
        ArrayList<Long> fact = new ArrayList<Long>();
        long phi = p - 1, n = phi;
        for (long i = 2; i * i <= n; ++i) {
            if (n % i == 0) {
                fact.add(i);
                while (n % i == 0) {
                    n /= i;
                }
            }
        }
        if (n > 1) fact.add(n);
        for (long res = 2; res <= p; ++res) {
            boolean ok = true;
            for (long i = 0; i < fact.size() && ok; ++i) {
                ok &= modPow(res, phi / fact.get((int) i), p) != 1;
            }
            if (ok) {
                return res;
            }
        }
        return -1;
    }

    public long get() {
        return state - 1;
    }

    public void advance() {
        //This loop simply skips all results that overshoot the range, which should never happen if range is a prime number.
        dropped--;
        do {
            state = (state * root) % prime;
            dropped++;
        } while (state > range);
    }

    public void reset() {
        state = root;
        dropped = 0;
    }

    private static boolean isPrime(long num) {
        if (num == 2) return true;
        if (num % 2 == 0) return false;
        for (int i = 3; i * i <= num; i += 2) {
            if (num % i == 0) return false;
        }
        return true;
    }

    private static long closestPrimeAfter(long n) {
        long up;
        for (up = n + 1; !isPrime(up); ++up)
            ;
        return up;
    }

    private static long closestPrimeBefore(long n) {
        long dn;
        for (dn = n - 1; !isPrime(dn); --dn)
            ;
        return dn;
    }

    private static long closestPrimeTo(long n) {
        final long dn = closestPrimeBefore(n);
        final long up = closestPrimeAfter(n);
        return (n - dn) > (up - n) ? up : dn;
    }

    private static boolean test(int r, int loops) {
        final int array[] = new int[r];
        Arrays.fill(array, 0);
        System.out.println("TESTING: array size: " + r + ", loops: " + loops + "\n");
        PseudoRandomSequence prs = new PseudoRandomSequence(r);
        final long ct = loops * r;
        //Iterate the array 'loops' times, incrementing the value for each cell for every visit. 
        for (int i = 0; i < ct; ++i) {
            prs.advance();
            final long index = prs.get();
            array[(int) index]++;
        }
        //Verify that each cell was visited exactly 'loops' times, confirming the validity of the sequence
        for (int i = 0; i < r; ++i) {
            final int c = array[i];
            if (loops != c) {
                System.err.println("ERROR: array element @" + i + " was " + c + " instead of " + loops + " as expected\n");
                return false;
            }
        }
        //TODO: Verify the "randomness" of the sequence
        System.out.println("OK:  Sequence checked out with " + prs.dropped + " drops (" + prs.dropped / loops + " per loop vs. diff " + (prs.prime - r) + ") \n");
        return true;
    }

    //Run lots of random tests
    public static void main(String[] args) {
        Random r = new Random();
        r.setSeed(1337);
        for (int i = 0; i < 100; ++i) {
            PseudoRandomSequence.test(r.nextInt(1000000) + 1, r.nextInt(9) + 1);
        }
    }

}


1 commentaires

Je pense que cela échoue sur le "Je veux que la liste soit mélangée de manière réelle de manière aléatoire avec toutes les permutations, des critères également probables". Mais cela pourrait être suffisant pour de nombreuses fins pratiques.