1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    janvier 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2014
    Messages : 5
    Points : 0
    Points
    0

    Par défaut appel au générateur des nombres aleatoire dans un programme c++

    Bonjour tout les monde

    j'ai un programme qui consiste a générer 4000 nombre aleatoire entre 1 et 10 000 et pour chaque nombre aleatoire(n) il faut que j'exécute le P1, P2, P3. bien evidement P1 P2 et P3 vont me donner des résultats(x,y) mais pas tout ces résultats satisfaites ma condition qui exige que n(le nombre aleatoire) =x2-y2 et 0<=y<=x. et sur chaque nombre aléatoire bien sur. par la suite si la résultat fourni par chaque programme sur chaque nombre aléatoire satisfait ma condition je fais un compteur sur chaque programme qui s’incrémente a chaque fois que les sorties de programme satisfaites condition . le but de ce compteur c'est pour calculer la fiabilité a la fin qui est égale au nombre des résultats qui satisfait ma condition/ le nombre totale des nombres aleatoire(4000).

    donc vue que je vais faire d'autres travaux pareil(avec d'autres programmes et d'autres condition ) donc l'idée été de faire quelque chose plus générique. mon problème ici c'est que le générateur des nombres aléatoires m'affiche toujours le même nombre aléatoire (ici c'est le n) pour chaque exécution de P1, P2, P3. ci-joint mon code et j’espère que quelqu'un peut m'aider a le corriger

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
     
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #include <iostream>
    using namespace std;
    //#include <iostream.h> //pour cout
    typedef struct  {
                         int  n,  x, y;
                    }statetype;  // définir ma propre type de variable
    bool domR (statetype s) // faire un test sur le nombre aléatoire (n) 
    {
        if  (!((s.n/2) % 2) ==1)
            return(true);
        else
            return(false);
    }
    bool R (statetype s, statetype sprime) // Le sprime est un nom de variable de type statetype . ici j'ai ecrit dans ce procédure la condition que les sorties(x,y) de chaque programme sur chaque n doit la verifier.
    {
        if   ( s.n== pow(sprime.x,2)- pow(sprime.y,2) && 0<= sprime.y <= sprime.x)
    {
     
            return(true);
    }
        else
            return(false);
    }
     
    bool oracle (statetype s,  statetype sprime)
              {  return ! domR(s) || R(s,sprime) ;
     }                                       
     
     
     
    void p1()
    {unsigned int n, x, y; 
    {unsigned int r;
    x=0; y=0; r=0; 
    while (r<n) {r=r+2*x+1; x=x+1;}}}
     
     
    void p2() 
    {unsigned  int n, x, y; // input/output variables
    {unsigned  int r; x=0; r=0;
    while (r<n) {r=r+2*x+1; x=x+1;}
       if (r>n) {y=0; while (r>n) {r=r-2*y-1; y=y+1;}}}}
     
     
     
    void p3() 
    {unsigned int n, x, y; // input/output variables
    {unsigned int r; x=0; r=0; 
    while (r<n) {r=r+2*x+1; x=x+1;}
    while (r>n) {int rsave; y=0; rsave=r;
    while (r>n) {r=r-2*y-1; y=y+1;}
       if (r<n) {r=rsave+2*x+1; x=x+1;}}}}
     
     
       //------------------------------------------------------------------
    int randomgeneration(int n)
    {
        int partSize   = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1));
        int maxUsefull = partSize * n + (partSize - 1);
        int draw;
     
        do {
            draw = rand();
        } while (draw > maxUsefull);
     
        return draw / partSize;
    }
    //---------------------------------------------------------------------
    void tesdriver(int testdatasize)
    {int c1=0; // compteur qui s'incrémente chaque fois que les résultats fourni par le programme satisfait la condition qui est exprimée dans le procedure bool R(N=x2-y2)et (0<=y<x)
    int c2=0;
    int c3=0;
     
    int testindex=1; 
     
    while (testindex <= testdatasize)
    {
     
    statetype inits,s, sprime;  
     
    inits.n=randomgeneration(10000);
     
    //P1 
     
    s=inits;
    p1();
    if (oracle(inits,s)) {c1=c1+1;}
    printf("n : %d \t" , inits);
    printf("counter p1 : %d \t" , c1);
     
     
    // P2
     
    s=inits;
    p2();
    if (oracle(inits,s)) {c2=c2+1;}
    printf("n : %d \t" , inits);                                    
    printf("counter p2 : %d \t" , c2);
     
     
    //P3
    s=inits;
    p3();
    if (oracle(inits,s)) {c3=c3+1;}
    printf("n : %d \t" , inits);                                
    printf("counter p3 : %d \t" , c3);
     
    testindex ++;
     
    }
     
    //printf("\nc1=%d\t",c1);
    //printf("c2=%d\t",c2);
    //printf("c3=%d\t",c3);
    //printf("reliability of p1 : %f \t" , float (c1)/float (testdatasize));
    cout << "reliability of p1 : " << float (c1)/ float(testdatasize) << endl ; // calcul de realiabilité 
    //printf("reliability of p2 : %f \t" , float (c2)/float (testdatasize));
    cout << " reliability of p2 : " << float (c2)/ float(testdatasize) << endl ;
    //printf("reliability of p3 : %f \t" , float (c3)/float (testdatasize));
    cout << " reliability of p3 : " << float (c3)/ float(testdatasize)  << endl ;
    }
    int main()
    {
        tesdriver(4000);
    }

  2. #2
    Membre chevronné
    Avatar de Daïmanu
    Homme Profil pro
    Étudiant
    Inscrit en
    janvier 2011
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : janvier 2011
    Messages : 495
    Points : 1 752
    Points
    1 752

    Par défaut

    Bonjour, bienvenue sur le forum

    Déjà, je t'invite à toujours mettre ton code dans une vue prévue à cet effet (le bouton # quand tu écris un message) pour avoir la coloration syntaxique.

    Avant d'utiliser la fonction rand(), il faut impérativement faire un appel à la fonction srand(), cf. la faq : Pourquoi rand() me renvoie toujours la même valeur ?, visiblement cet appel n'y est pas.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le soucis en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 982
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 982
    Points : 16 602
    Points
    16 602

    Par défaut

    Avant toute chose, pense à utiliser la balise [code ] (le bouton #), qui mettrait en forme ton code sur le forum.

    Ton code est un mélange infame de C et de C++.
    En C++, aucun entête système ne se nomme en .h (ils existent encore pour des raisons de compatibilité avec l'ancien code).

    Plein de remarques:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef struct {
      int n, x, y;
    }statetype; // définir ma propre type de variable
    1. Il vaut mieux commenter avant la déclaration.
    2. Il vaut mieux commenter de manière utile: que ce soit ton propre type, on s'en doute, vu que tu le définis. Par contre, définir sa signification serait utile.
    3. En C++, il n'est pas nécessaire de procéder à un typedef, puisque le nom est introduit automatiquement.
    4. Les trois variables sont-elles de même nature? J'entends par là: les instructions suivantes sont elles logique: s.n = s.x, s.x = s.n, s.n = s.y, s.y = s.n, s.x = s.y, s.y = s.x. Je ne pense pas. C'est donc qu'il faudrait introduire des noms de types utiles.
      A la simple lecture de cette structure, je ne sais pas ce que sont ces trois variables.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    using random_value_type = int;
    using coord_type = int;
     
    struct state {
      random_value_type n;
      coord_type x;
      coord_type y;
    };
    fragment suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool domR (statetype s) // faire un test sur le nombre aléatoire (n)
    {
      if (!((s.n/2) % 2) ==1)
      return(true);
      else
      return(false);
    }
    l'opérateur ternaire est "magique", il permet de condenser ce code de manière plus lisible: bool domR (statetype s) { return (!((s.n/2) % 2) ==1) ? true : false; }.
    Cela dit, il est inutile de tester une condition puis de retourner vrai si elle est vrai, et faux si elle est fausse. Autant retourner directement la condition. bool domR (statetype s) { return !((s.n/2) % 2) == 1; }.
    Et là, a priori, tu as un bug, parce que tu applique le ! à un entier, et non un booléen. tu voulais probablement écrire !( (s.n/2)%2 == 1). Ce en quoi, je t'invite à écrire (s.n/2)%2 == 0 (ou (s.n/2)%2 != 1)
    Pourquoi copier le statetype? Le C++ fournit des références (sur constantes) qui permettent de l'éviter.
    Tu peux aussi faire de cette fonction une fonction membre du statetype. A toi de voir si cela a du sens: est-ce que cela a toujours un sens de calculer le domR d'un statetype, ou est-ce uniquement à l'usage qui en est fait dans ce programme?

    J'en suis donc à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    using random_value_type = int;
    using coord_type = int;
     
    struct state {
      random_value_type n;
      coord_type x;
      coord_type y;
     
      bool domR() const { return (n/2)% 2 == 0; }
    };
    Le const après les parenthèses signifie que cette fonction ne modifie pas l'objet sur lequel elle est appelée, donc elle peut être appelée sur une constante de type state.
    Rendre les fonctions "const compatibles" permet de gagner en souplesse.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    bool R (statetype s, statetype sprime) // Le sprime est un nom de variable de type statetype . ici j'ai ecrit dans ce procédure la condition que les sorties(x,y) de chaque programme sur chaque n doit la verifier.
    {
      if ( s.n== pow(sprime.x,2)- pow(sprime.y,2) && 0<= sprime.y <= sprime.x)
      {
     
        return(true);
      }
      else
      return(false);
    }
    La fonction pow est très lente, parce quelle utilise un algorithme adapté à des puissances non entières. pow(bidule, 2) est toujours plus vite calculée par bidule * bidule. Et c'est souvent aussi lisible.
    les comparaisons ne se chainent pas ainsi. 0<= sprime.y <= sprime.x est équivalent à (0<= sprime.y) <= sprime.x, ce qui n'est pas du tout ton souhait.
    Même remarque sur le retour d'un booléen et sur les références
    [code]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    using random_value_type = int;
    using coord_type = int;
     
    struct state {
      random_value_type n;
      coord_type x;
      coord_type y;
     
      bool domR() const { return (n/2)% 2 == 0; }
    };
     
    bool R(state const& s1, state const& s2) {
      return (s1.n == s2.x * s2.x - s2.y * s2.y) && 0<= s2.y && s2.y <= s2.x;
    }
    A noter que d'un point de vue logique, tu compare le n d'un state avec les x et y d'un autre. Pourquoi?

    Es-tu sur certaine que ce not s'applique seulement à s.domR()? mets une parenthèse pour le confirmer
    bool oracle (state const& s1, state const& s2) { return (! s1.domR()) || R(s1, s2) ; } ou bool oracle (state const& s1, state const& s2) { return (! s1.domR() || R(s1, s2)) ; }A présent, plus conséquent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void p1()
    {unsigned int n, x, y;
    {unsigned int r;
    x=0; y=0; r=0;
    while (r<n) {r=r+2*x+1; x=x+1;}}}
    Un code doit être indenté et parenthésé de manière claire et consistente. J'opte personnellement pour les ouvertures d'accolade en fin de ligne (plutot qu'a la ligne suivante)
    Il convient de séparer les instructions dans une boucle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void p1() {
      unsigned int n, x, y;
      {
        unsigned int r;
        x=0; y=0; r=0;
        while (r<n) {
          r=r+2*x+1;
          x=x+1;
        }
      }
    }
    Tu dois suivre un très vieux cours, qui utilisait la notation K&R (d'il y a trente ou quarante ans).
    A l'époque on aurait écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void p1(n, x, y)
      unsigned int n, x, y;
      {
        unsigned int r;
        x=0; y=0; r=0;
        while (r<n) {r=r+2*x+1; x=x+1;}
    }
    • Ton intention est probablement de prendre n, x et y et argument, modifiable.
    • r = r + bidule peut s'écrire r += bidule.
    • x = x + 1 devrait s'écrire ++x.
    • ce while pourrait etre reformulée par une boucle for, mais je te le laisse en exercice.
    • d'un point de vue mathématique, est-ce r += (2 * x) + 1 ou r += 2 * (x+1)? L'absence de parenthèse dans ton code n'indique pas ta volonté explicite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void p1(random_value_type n, coord_type& x, coord_type& y) {
        x=0;
        y=0;
       <quel type> r = 0;
        while (r<n) {r = r+ 2*x+1; x=x+1;}
    }
    Je suis prète à parier qu'en fait, la fonction voudrait générer un state à partir d'un n donné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    state p1(random_value_type n) {
      coord_type x = 0;
      <quel type> r = 0;
      while (r<n) {
        r = r+ 2*x+1;
        x=x+1;
      }
      return state {n, x, 0};
    }
    Pour p2 et p3, j'ai sensiblement les mêmes remarques.
    Attention aux variables non initialisées (comme y dans p2, si r==n)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    state p2(random_value_type n) {
      coord_type x=0, y=0;
      unsigned int r=0;
      while (r<n) {
        r=r+2*x+1; 
        x=x+1;
      }
      if (r>n) {
        while (r>n) [
          r=r-2*y-1;
          y=y+1;
        }
      }
      return state {r, x, y};
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    state p3(random_value_type n) {
      coord_type x = 0, y=0;
      unsigned int r=0;
      while (r<n) {
        r=r+2*x+1;
        x=x+1;
      }
      while (r>n) {
        int rsave = r;
        y=0;
        while (r>n) {
          r=r-2*y-1;
          y=y+1;
        }
        if (r<n) {
          r=rsave+2*x+1;
          x=x+1;
        }
      }
      return state {r, x, y};
    }
    fonction randomgeneration:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int randomgeneration(int n) {
      int partSize = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1));
      int maxUsefull = partSize * n + (partSize - 1);
      int draw;
     
      do {
        draw = rand();
      } while (draw > maxUsefull);
     
      return draw / partSize;
    }
    Comme dit précédemment, tu n'as pas appelée srand une seule fois. Cela dit, tu devrais utiliser le contenu de <random> à savoir un générateur et une distribution.
    Je ne comprends pas bien le fonctionnement de cette fonction.

    Ta fonctiontestdriver n'est pas utile, car main ne fait rien d'autre que l'appeler, fusionne les deux fonctions.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    int main() {
      auto const testdatasize = 4000;
     // compteur qui s'incrémente chaque fois que les résultats fourni par le programme satisfait la condition qui est exprimée dans le procedure bool R(N=x2-y2)et (0<=y<x)
      int c1=0;
      int c2=0;
      int c3=0;
     
      for(int testindex=1; testindex <= testdatasize; ++testindex) {
        // pas de déclaration sans initialiseur, il faut définir une variable quand on sait que mettre dedans.
     
        // inutile de créer un inits intermédiaire juste pour stocker un n sans le x et le y correspondant.
        auto const n = randomgeneration(10000);
        std::cout << "n : " << n << '\t';
     
        state s_p1 = p1(n);
        if (oracle(s_p1, s_p1)) ++c1;
        printf("counter p1 : " << c1 << '\t';
     
        state s_p2 = p2(n);
        if (oracle(s_p2, s_p2)) ++c2;
        printf("counter p2 : " << c2 << '\t';
     
        state s_p3 = p3(n);
        if (oracle(s_p3, s_p3)) ++c3;
        printf("counter p3 : " << c3 << '\t';
      }
     
      std::cout << "reliability of p1 : " << (c1 / static_cast<double>(testdatasize)) << std::endl;
      std::cout << " reliability of p2 : " << (c2 / static_cast<double>(testdatasize)) << std::endl;
      std::cout << " reliability of p3 : " << (c3 / static_cast<double>(testdatasize)) << std::endl;
    }
    Comme je le suspectais, la seule utilisation de oracle, c'est avec deux state ayant le même n (pour cause de copie).
    Du coup, on peut revoir toute la copie en enlevant cette distinction.
    Et puis autant partager du code entre les fonctions p1, p2 et p3:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    include <iostream>
     
    using value_type = int;
     
    struct state {
      value_type n;
      value_type x;
      value_type y;
     
      bool domR() const { return (n/2)% 2 == 0; }
     
      bool R() const { return (n == x * x - y * y) && 0 <= y && y <= x; }
    };
     
    bool oracle (state const& s) { return (! s.domR()) || s.R() ; }
     
    //je veux réutiliser du code entre les fonctions p1, p2 et p3
    value_type set_x(state & s) {
      s.x = 0;
      while (r < s.n) {
        r += 2*s.x+1;
        ++s.x;
      }
      return r;
    }
     
    set_y(state & s, value_type & r) {
      //pas besoin d'entourer un while (condition) par un if(condition), car while teste la condition.
      while (r > s.n) {
        r -= 2*s.y +1;
        ++s.y;
      }
      return r;
    }
     
    state p1(value_type n) {
      state s {n, 0, 0};
      set_x(s);
    }
     
    state p2(random_value_type n) {
      state s {n, 0, 0};
      auto r = set_x(s);
      set_y(s, r);
      return s;
    }
     
    state p3(random_value_type n) {
      state s {n, 0, 0};
      auto r = set_x(s);
     
      while (r > s.n) {
        const auto rsave = r;
        r = set_y(s, r);
        if (r < s.n) {
          s.r = rsave + 2*s.x+1;
          ++s.x;
        }
      }
      return s;
    }
     
    int randomgeneration(int n) {
      const auto partSize = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1));
      const auto maxUsefull = partSize * n + (partSize - 1);
     
      int draw;
     
      do {
        draw = rand();
      } while (draw > maxUsefull);
     
      return draw / partSize;
    }
     
    int main() {
      auto const testdatasize = 4000;
     // compteurs qui s'incrémente chaque fois que les résultats fourni par le programme satisfait la condition qui est exprimée dans le procedure bool R(N=x2-y2)et (0<=y<x)
      std::array<int, 3> counters;
     
      for(int testindex=1; testindex <= testdatasize; ++testindex) {
        // pas de déclaration sans initialiseur, il faut définir une variable quand on sait que mettre dedans.
     
        // inutile de créer un inits intermédiaire juste pour stocker un n sans le x et le y correspondant.
        auto const n = randomgeneration(10000);
        std::cout << "n : " << n << '\t';
     
        if (oracle(p1(n))) ++counters[0];
        printf("counter p1 : " << counters[0] << '\t';
     
        if (oracle(p2(n))) ++counters[1];
        printf("counter p2 : " << counters[1] << '\t';
     
        if (oracle(p3(n))) ++counters[2];
        printf("counter p3 : " << counters[2] << '\t';
      }
     
      std::cout << "reliability of p1 : " << (counters[0] / static_cast<double>(testdatasize)) << std::endl;
      std::cout << "reliability of p2 : " << (counters[1] / static_cast<double>(testdatasize)) << std::endl;
      std::cout << "reliability of p3 : " << (counters[2] / static_cast<double>(testdatasize)) << std::endl;
    }
    On constate que les trois fonctions pi ont la même signature, a savoir: state (value_type). On peut faire quelque chose de plus intéressant, en rendant la fonction principale aveugle au nombre de possibilités:
    L'oracle est la manière de vérifier le résultat d'une de ces fonctions testées.
    On pourrait avoir quelque chose comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    struct test {
    public:
        using oracle_type = std::function<bool(state const&)>;
        using generator_type = std::function<state(value_type)>;
        usint counter_type = unsigned long;
     
        test(oracle_type oracle, generator_type g, std::string const& name): oracle(oracle), generator(g), name(name), counter(0) {}
     
        test& operator() (value_type n) {
            if ( oracle(g(n)) ) ++ compteur;
            return *this; //permet le chainage, par exemple pour l'affichage.
        }
     
        auto mean(counter_type total_executions) const { return counter / static_cast<double>(total_executions); }
    private:
        oracle_type oracle;
        generator g;
        std::string name;
        counter_type counter;
     
        friend inline std::ostream& operator << (std::ostream& stream, test const& t) {
            return stream << "counter for " << t.name << ": " << t.counter;
        }
    };
     
    int main() {
      std::vector<test> tests;
      tests.emplace_back(&oracle, &p1, "p1");
      tests.emplace_back(&oracle, &p2, "p2");
      tests.emplace_back(&oracle, &p3, "p3");
     
     
      auto const testdatasize = 4000;
      for(int testindex=1; testindex <= testdatasize; ++testindex) {
        auto const n = randomgeneration(10000);
        std::cout << "n : " << n << '\t';
        for(auto & p : tests) {
          std::cout << p(n) << '\t';
        }
      }
      for(auto & p : tests) {
        std::cout << p << ",\treliability: " << p.mean(testdatasize) << std::endl;
      }
      return 0;
    }
    On peut améliorer un peu en constatant que finalement, l'oracle est partagé entre tous les tests.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    janvier 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2014
    Messages : 5
    Points : 0
    Points
    0

    Par défaut

    Merci bien pour votre réponse. mon problème est d’exécuter P1, P2, et P3 avec 4000 nombre aléatoire(ici le n) entre 1 et 10 000. mon code traite les 3 programmes avec le même nombre aléatoire

  5. #5
    Expert éminent
    Homme Profil pro
    Développeur informatique
    Inscrit en
    février 2005
    Messages
    4 377
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : février 2005
    Messages : 4 377
    Points : 9 729
    Points
    9 729

    Par défaut

    mon problème est d’exécuter P1, P2, et P3 avec 4000 nombre aléatoire(ici le n)
    Moi, je dirais plus que vous ne voulez pas lire attentivement les réponses qu'on vous donne.
    Vous ne tirez même pas des nombres aléatoires, donc commencez par le début.
    p1, p2 et p3 ne sont pas des programmes mais des fonctions.
    Ces fonctions n'utilisant pas de paramètres mais toujours des variables locales non-initialisées, c'est un peu des générateurs pseudo-pseudo-aléatoire de résultats.
    Indentation de code complètement abscons, utilisation de variables non initialisé, utilisation d'API bugué comme rand, etc....
    Il fonctionnera jamais correctement votre machin.

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 982
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 982
    Points : 16 602
    Points
    16 602

    Par défaut

    Bon, j'ai finis mon gros pavé.
    maintenant, va lire la documentation de <random>, et les exemples qui y sont décrits.
    Par exemple: uniform_int_distribution
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    janvier 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2014
    Messages : 5
    Points : 0
    Points
    0

    Par défaut

    Merci bien pour votre aide car je suis encore débutante en c et c++ mais lors de la compilation il m'affiche des erreurs comme:
    9 [Error] expected nested-name-specifier before 'value_type'
    12[Error] 'value_type' does not name a type
    13[Error] 'value_type' does not name a type
    14 [Error] 'value_type' does not name a type
    16[Error] 'n' was not declared in this scope
    18[Error] 'n' was not declared in this scope

    18 [Error] 'x' was not declared in this scope
    18[Error] 'y' was not declared in this scope
    24[Error] 'value_type' does not name a type
    33[Error] 'value_type' has not been declared
    35[Error] 'struct state' has no member named 'n'
    36[Error] 'struct state' has no member named 'y'
    37[Error] 'struct state' has no member named 'y'
    42[Error] 'value_type' was not declared in this scope
    42[Error] expected ',' or ';' before '{' token

  8. #8
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 982
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 982
    Points : 16 602
    Points
    16 602

    Par défaut

    A priori, c'est parce que tu compiles avec un vieux compilateur, ou avec la vieille version du C++.

    Outre mettre à jour le compilateur si c'est possible, il faut activer le C++14, ou à la rigueur le C++11.
    Quel est ton outil de travail (code::blocs? Visual Studio? Eclipse?)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  9. #9
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    janvier 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2014
    Messages : 5
    Points : 0
    Points
    0

    Par défaut

    merci encore une fois. j’utilise le dev-c++ 5.11

  10. #10
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 982
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 982
    Points : 16 602
    Points
    16 602

    Par défaut

    Je n'avais pas compilé. En corrigeant les quelques erreurs que j'ai commises, ca donne ceci:
    Cela doit compiler proprement en C++11 (g++ --std=c++11 -Wall -Wextra)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #include <iostream>
    #include <iomanip>
    #include <array>
    #include <vector>
     
    using value_type = int;
     
    struct state {
      value_type n;
      value_type x;
      value_type y;
     
      bool domR() const { return (n/2)% 2 == 0; }
     
      bool R() const { return (n == x * x - y * y) && 0 <= y && y <= x; }
    };
     
    bool oracle (state const& s) { return (! s.domR()) || s.R() ; }
     
    //je veux réutiliser du code entre les fonctions p1, p2 et p3
    value_type set_x(state & s) {
      s.x = 0;
      value_type r = 0;
      while (r < s.n) {
        r += 2*s.x+1;
        ++s.x;
      }
      return r;
    }
     
    value_type set_y(state & s, value_type & r) {
      //pas besoin d'entourer un while (condition) par un if(condition), car while teste la condition.
      while (r > s.n) {
        r -= 2*s.y +1;
        ++s.y;
      }
      return r;
    }
     
    state p1(value_type n) {
      state s {n, 0, 0};
      set_x(s);
      return s;
    }
     
    state p2(value_type n) {
      state s {n, 0, 0};
      auto r = set_x(s);
      set_y(s, r);
      return s;
    }
     
    state p3(value_type n) {
      state s {n, 0, 0};
      auto r = set_x(s);
     
      while (r > s.n) {
        const auto rsave = r;
        r = set_y(s, r);
        if (r < s.n) {
          r = rsave + 2*s.x+1;
          ++s.x;
        }
      }
      return s;
    }
     
    int randomgeneration(int n) {
      const auto partSize = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1));
      const auto maxUsefull = partSize * n + (partSize - 1);
     
      int draw;
     
      do {
        draw = rand();
      } while (draw > maxUsefull);
     
      return draw / partSize;
    }
     
    int main() {
      auto const testdatasize = 4000;
     // compteurs qui s'incrémente chaque fois que les résultats fourni par le programme satisfait la condition qui est exprimée dans le procedure bool R(N=x2-y2)et (0<=y<x)
      std::array<int, 3> counters;
     
      for(int testindex=1; testindex <= testdatasize; ++testindex) {
        // pas de déclaration sans initialiseur, il faut définir une variable quand on sait que mettre dedans.
     
        // inutile de créer un inits intermédiaire juste pour stocker un n sans le x et le y correspondant.
        auto const n = randomgeneration(10000);
        if (oracle(p1(n))) ++counters[0];
        if (oracle(p2(n))) ++counters[1];
        if (oracle(p3(n))) ++counters[2];
      }
     
      std::cout << "p1: " << std::setw(8) << (counters[0]) << ", reliability: " << (counters[0] / static_cast<double>(testdatasize)) << std::endl;
      std::cout << "p2: " << std::setw(8) << (counters[1]) << ", reliability: " << (counters[1] / static_cast<double>(testdatasize)) << std::endl;
      std::cout << "p3: " << std::setw(8) << (counters[2]) << ", reliability: " << (counters[2] / static_cast<double>(testdatasize)) << std::endl;
    }
    Je note toutefois que je ne vois pas l'intérêt de tester 4000 nombres aléatoires, autant tout essayer, non?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  11. #11
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    janvier 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2014
    Messages : 5
    Points : 0
    Points
    0

    Par défaut

    ça marche maintenant . merciii

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/12/2016, 16h07
  2. Réponses: 6
    Dernier message: 26/05/2008, 21h08
  3. Réponses: 14
    Dernier message: 06/05/2008, 16h16
  4. ecrire des nombres decimaux dans EDIT Control
    Par craryb dans le forum MFC
    Réponses: 1
    Dernier message: 22/03/2007, 20h28
  5. total des nombres générés dans un fichier.xls?
    Par loukoulouk dans le forum Modules
    Réponses: 4
    Dernier message: 22/06/2006, 12h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo