Partage
  • Partager sur Facebook
  • Partager sur Twitter

Définir la taille d'un tableau de manière aléatoir

Sujet résolu
    24 mai 2020 à 3:46:48

    Bonjour, 

    Débutant en c++, je ne trouve pas le moyen de définir la taille de mon tableau de manière aléatoire.

    Voici mon code :

    srand (time(NULL));
        //génère un nombre aléatoire compris entre 1 et 10
        const int nbrAleatoire = rand() % 10 + 1;
        int sommeTotal=0;
        array<int,nbrAleatoire>tab;

    A chaque fois cela m'affiche : 

    error : the value of 'nbrAleatoire' is not usable in a constant expression 

    J'aimerais qu'à chaque fois que j'exécute mon programme, que la taille de mon tableau tab soit défini aléatoirement entre 1 et 10.

    Merci d'avance pour votre aide :D

    • Partager sur Facebook
    • Partager sur Twitter
      24 mai 2020 à 4:02:44

      Une expression constante ne peut prendre que des valeurs connues à la compilation. rand ne donne pas une valeur connue à la compilation.

      Utilise std::vector avec le constructeur qui va bien (3).

      Note: srand et rand ne devrait pas être utlisés en C++: uniform_int_distribution

      • Partager sur Facebook
      • Partager sur Twitter
        24 mai 2020 à 7:36:29

        jo_link_noir a écrit:

        Une expression constante ne peut prendre que des valeurs connues à la compilation. rand ne donne pas une valeur connue à la compilation.

        Utilise std::vector avec le constructeur qui va bien (3).

        Note: srand et rand ne devrait pas être utlisés en C++: uniform_int_distribution

        J'ai fait des tests avec rand() et la distribution n'est pas uniforme et même pas constante d'une exécution à l'autre.

        Une distribution est constante si on retourne toujours à la valeur de départ après le même nombre d'appels.

        • Partager sur Facebook
        • Partager sur Twitter

        Le Tout est souvent plus grand que la somme de ses parties.

          24 mai 2020 à 11:49:47

          PierrotLeFou a écrit:

          Une distribution est constante si on retourne toujours à la valeur de départ après le même nombre d'appels.

          Je suis très surpris par ta phrase. En gros tu veux dire que si je demande une valeur a une fonction aléatoire R constante, au bout de x appels, 2x appels 3x appels, n*x appels, j'aurais toujours la même valeur que la toute première que j'ai demandé ?

          Si c'est le cas, on peut prédire quelques valeurs d'avance, ce qui va à l'encontre du concept d'aléatoire non ?

          • Partager sur Facebook
          • Partager sur Twitter

          Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

            24 mai 2020 à 14:44:02

            Une fonction même aléatoire retourne un nombre fini de valeurs, surtout si elles sont entières.
            Forcément si tu dépasses ce nombre fini, tu vas retourner sur une valeur déjà rencontrée.
            À partir de là, tu recommences le cycle, à moins que la méthode soit assez tordue pour que tu suives un autre cycle.
            Par exemple, si j'utilise les modulo pour trouver le nombre suivant, en choisissant un bon nombre premier et un bon multiplicateur, je suis toujours le mème cycle.
            Par exemple: s = (s * 75) % 65537 va cycler sur 65536 valeurs.
            Je ne dis pas que c'est la meilleure méthode, mais elle est uniforme et constante.
            Je ne voyais pas ça avec rand()
            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              24 mai 2020 à 17:01:02

              Dans un générateur aléatoire, on essaye d'éviter les cycles, car ce n'est pas un comportement intéressant. Du coup, les cycles sont généralement très très grands ; bien plus que la plage de valeur de l'entier.

              Concernant std::uniform_int_distribution, ce n'est pas un générateur de nombre aléatoire, mais une loi de distribution dont la valeur de sortie est toujours la même pour une entrée donnée. Parler de cycle pour cette classe n'a aucun sens.

              Quant à rand(), son implémentation n'est pas définie par le standard, chacun est libre de faire comme il l'entend, que se soit dans la distribution ou le rng utilisé. La seule contrainte est que RAND_MAX qui doit être au moins de 32767. Même une fonction rand() qui retourne toujours 0 respecte les prérequis. Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux).

              -
              Edité par jo_link_noir 24 mai 2020 à 17:01:47

              • Partager sur Facebook
              • Partager sur Twitter
                24 mai 2020 à 17:34:08

                Connais-tu un endroit où je pourrais trouver la description d'un tel générateur de nombres aléatoires qui ne fasse pas de cycle et qui soit à distribution uniforme?
                Ma définition de distribution uniforme dans le contexte des ordinateurs est que la fréquence où chaque valeur apparait est la même pour tous les nombres de l'intervalle, à condition que le nombre d'appels à la fonction soit suffisamment grand (pas forcément facile à évaluer).
                Si on accepte le type long long, J'ai trouvé un nombre premier et un multiplicateur intéressants:
                long long p = 3037000493;
                long long m = 28276;
                Avec les modulo, je cycle sur 3037000492 valeurs.
                Un cycle ne donne pas forcément une distribution uniforme.
                Je pense qu'avec 28278, j'avais un cycle constant, mais avec seulement la moitié des nombres, donc ce n'était pas uniforme.
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  24 mai 2020 à 17:34:46

                  jo_link_noir a écrit:

                  Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux).

                  Tu veux dire que ça dépend du système et pas du compilateur (bibliothèque fourni avec le compilateur) ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    24 mai 2020 à 17:43:58

                    rouloude a écrit:

                    jo_link_noir a écrit:

                    Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux).

                    Tu veux dire que ça dépend du système et pas du compilateur (bibliothèque fourni avec le compilateur) ?

                    Ça dépend plus du processeur, s'il peut accepter de l'arithmétique 64-bits ou pas pour les entiers.

                    Et je ne suis toujours pas convaincu que rand() donne une distribution uniforme. Ça prend combien d'échantillons pour avoir un résultat satisfaisant?

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Le Tout est souvent plus grand que la somme de ses parties.

                      24 mai 2020 à 18:09:19

                      Heu, les gars, c'est des générateurs de nombres PSEUDO-aléatoire, et c'est bien marqué PSEUDO.

                      Donc, il y a toujours des artefacts.

                      Mais bon, avec des générateurs de qualités cryptographique, faut s'accrocher pour les trouver.

                      Sinon, il y a des services online qui donne des nombres aléatoires basés sur des récepteurs radiofréquence dans l'atmosphère, des anales de compteur de désintégration atomique ou encore, il y a une société dont je ne me rappelle plus du nom qui utiliser une centaine de "lava lamp" pour générer ces nombres aléatoires.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        24 mai 2020 à 18:49:35

                        Avec le confinement, je n'ai plus accès à mon uranium. :)
                        Si j'utilise le modulo avec les nombres que j'ai mentionnés et que je fais un masque à 32767, je suis bien près de rand.
                        On peut fonctionner à plus de 15 bits sur une machine qui ne fait pas d'arithmétique 64 bits.
                        Il suffit que le produit du nombre premier et du multiplicateur ne dépasse pas 32 bits.
                        On fonctionnera avec l'arithmétique sans signe.
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Le Tout est souvent plus grand que la somme de ses parties.

                          24 mai 2020 à 19:00:08

                          > > Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux). > Tu veux dire que ça dépend du système et pas du compilateur (bibliothèque fourni avec le compilateur) ?

                          Ça dépend de libc, les compilateurs ne la distribuent pas toujours directement et rien n'empêche d'en utiliser une autre. Ce que je dis s'applique dans le cas qu'on rencontre habituellement.

                          > Ça dépend plus du processeur, s'il peut accepter de l'arithmétique 64-bits ou pas pour les entiers.

                          Non, de l'implémentation. Qui peut très bien supporter des nombres de 128bits, 256bits ou plus sans pour autant avoir une implémentation native de l'entier. GNU libc supporte plusieurs modes simultanément par exemple (voir le manuel de random()).

                          > Connais-tu un endroit où je pourrais trouver la description d'un tel générateur de nombres aléatoires qui ne fasse pas de cycle et qui soit à distribution uniforme?

                          https://www.pcg-random.org/ -> colonne période et les pages wikipédia sur le sujet: c'est des maths.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            24 mai 2020 à 19:40:41

                            jo_link_noir a écrit:

                            > > Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux). > Tu veux dire que ça dépend du système et pas du compilateur (bibliothèque fourni avec le compilateur) ?

                            Ça dépend de libc, les compilateurs ne la distribuent pas toujours directement et rien n'empêche d'en utiliser une autre. Ce que je dis s'applique dans le cas qu'on rencontre habituellement.

                            C'est bien ce qui me semblais, mais comme tu faisais une distinction entre Windows et Linux. J'ai loupé le "Dans la pratique".

                            • Partager sur Facebook
                            • Partager sur Twitter
                              25 mai 2020 à 1:37:10

                              jo_link_noir a écrit:

                              > > Dans la pratique, rand() est une distribution uniforme avec une valeur sur 15bits (windows) ou 31bits (linux). > Tu veux dire que ça dépend du système et pas du compilateur (bibliothèque fourni avec le compilateur) ?

                              Ça dépend de libc, les compilateurs ne la distribuent pas toujours directement et rien n'empêche d'en utiliser une autre. Ce que je dis s'applique dans le cas qu'on rencontre habituellement.

                              > Ça dépend plus du processeur, s'il peut accepter de l'arithmétique 64-bits ou pas pour les entiers.

                              Non, de l'implémentation. Qui peut très bien supporter des nombres de 128bits, 256bits ou plus sans pour autant avoir une implémentation native de l'entier. GNU libc supporte plusieurs modes simultanément par exemple (voir le manuel de random()).

                              > Connais-tu un endroit où je pourrais trouver la description d'un tel générateur de nombres aléatoires qui ne fasse pas de cycle et qui soit à distribution uniforme?

                              https://www.pcg-random.org/ -> colonne période et les pages wikipédia sur le sujet: c'est des maths.

                              J'avais en effet oublié le calcul multiple précision.

                              J'ai commencé à regarder le lien que tu proposes, et il y a plusieurs choses sur wikipedia. Merci.

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Le Tout est souvent plus grand que la somme de ses parties.

                              Définir la taille d'un tableau de manière aléatoir

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown