int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Faisons fonctionner le registre cinq fois. */ int i ;
AfficherRegistre() ; for(i = 0 ; i < 5 ; i++)
{
printf("Bit renvoye : %d\n", ProchainBit()) ;
AfficherRegistre() ;
}
return 0 ;
}
1001011000110110010101101111100101110101010011101011011001110101110110100101100110100001110101110100
Bit renvoye : 0
0010110001101100101011011111001011101010100111010110110011101011101101001011001101000011101011101000
Bit renvoye : 0
0101100011011001010110111110010111010101001110101101100111010111011010010110011010000111010111010000
Bit renvoye : 0
1011000110110010101101111100101110101010011101011011001110101110110100101100110100001110101110100000
Bit renvoye : 1
0110001101100101011011111001011101010100111010110110011101011101101001011001101000011101011101000001
Bit renvoye : 0
1100011011001010110111110010111010101001110101101100111010111011010010110011010000111010111010000010
#include <stdio.h> #include <stdlib.h>
/* Registres à décalage et rétro-action linéaire (R.À.D.E.R.A.L.) */ struct _raderal
{ int nb_Bits ; int nb_Cases ; /* égal à 1 + (nb_Bits - 1) / (8 * sizeof(unsigned int)) */ int PositionEntrante ; /* égal à (nb_Bits - 1) % (8 * sizeof(unsigned int)) */ unsigned int *Bits ; int nb_PositionsSpeciales ; /* doit être au moins égal à 2 */ int *PositionsSpeciales ;
} ; typedefstruct _raderal raderal ;
/* On définit un générateur pseudo-aléatoire global. */
raderal GPA ;
/* Calcul des positions dans le registre */ void CalculerPosition(int p, int *IndiceCase, int *BitCase)
{
*IndiceCase = p / (8 * sizeof(unsigned int)) ;
*BitCase = p % (8 * sizeof(unsigned int)) ;
}
/* Le fonctionnement : génération du prochain bit sur un ràderal */ int ProchainBit()
{ /* Calcul du nouveau bit */ int IndiceCase, BitCase ;
CalculerPosition(GPA.PositionsSpeciales[0], &IndiceCase, &BitCase) ; int bit = (GPA.Bits[IndiceCase] & (1 << BitCase)) >> BitCase ;
int i ; for(i = 1 ; i < GPA.nb_PositionsSpeciales ; i++)
{
CalculerPosition(GPA.PositionsSpeciales[i], &IndiceCase, &BitCase) ;
bit ^= (GPA.Bits[IndiceCase] & (1 << BitCase)) >> BitCase ;
}
/* Initialisation */ int i ; for(i = 0 ; i < GPA.nb_Cases ; i++)
{ /* On met alternativement 000....0 ou 111....1 dans les cases */
GPA.Bits[i] = -(i % 2) ;
}
GPA.Bits[0] = Graine ;
/* On fait « tourner » le générateur trois fois sur tous ses bits */ for(i = 0 ; i < 3 * nb_Bits ; i++) {ProchainBit() ;}
}
/* Initialisation du ràderal */ void InitialiserGenerateur(int nb_Bits, int nb_PositionsSpeciales, int *PositionsSpeciales, unsigned int Graine)
{
...
for(i = 0 ; i < GPA.nb_Cases ; i++)
{ /* On met alternativement 000....0 ou 111....1 dans les cases */
GPA.Bits[i] = -(i % 2) ;
}
AfficherRegistre() ;
GPA.Bits[0] = Graine ;
AfficherRegistre() ;
...
}
int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Entier aléatoire entre 0 et 2**K - 1 */ int EntierPleinAlea(int K)
{ int i, x = 0 ; for(i = 0 ; i < K ; i++)
{
x <<= 1 ;
x |= ProchainBit() ;
} return x ;
}
/* Entier aléatoire dans {a, ..., b} */ int EntierAlea(int a, int b)
{ /* On cherche la plus petite puissance de deux */ au moins égale au nombre de valeurs distinctes possibles */ int d = b - a + 1 ; int K = 0, p = 1 ; /* p représente 2**K */ while(p < d) {K++ ; p *= 2 ;}
/* Méthode de rejet : par le choix de K, on « rate » en moyenne au plus une fois. */ int x = EntierPleinAlea(K) ; while(x >= d) {x = EntierPleinAlea(K) ;}
return a + x ;
}
int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Test visuel pour des entiers */ int i ; for(i = 0 ; i < 10 ; i++)
{
printf("%d ", EntierAlea(1, 6)) ;
}
int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Test statistique pour des entiers */ int i ; int Effectifs[7] = {-1, 0, 0, 0, 0, 0, 0} ; for(i = 0 ; i < 10000000 ; i++)
{
Effectifs[EntierAlea(1, 6)]++ ;
}
printf("Repartition statistique des valeurs de 1 a 6\n") ; for(i = 1 ; i <= 6 ; i++)
{
printf("%d : %d\n", i, Effectifs[i]) ;
}
return 0 ;
}
Repartition statistique des valeurs de 1 a 6
1 : 1665765
2 : 1667844
3 : 1665744
4 : 1667611
5 : 1664795
6 : 1668241
/* Réel aléatoire dans [0 ; 1[ */ #define DEUX_PUISSANCE_CINQUANTE_DEUX 4.503599627370496e+15 double Alea()
{ /* On génère un entier long sur 52 bits */ long int X = 0L ; int i ; for(i = 0 ; i < 52 ; i++)
{
X <<= 1 ;
X |= ProchainBit() ;
}
/* Puis on le divise par 2**52 */ double x = (double)X ;
x /= DEUX_PUISSANCE_CINQUANTE_DEUX ; return x ;
}
int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Test visuel pour des flottants */ int i ; for(i = 0 ; i < 10 ; i++)
{
printf("%.15g\n", Alea()) ;
}
int main()
{ /* Il faut initialiser le générateur */ int nb_Bits = 100 ; int PositionsSpeciales[] = {3, 4, 19, 25, 82} ; int nb_PositionsSpeciales = 5 ; int Graine = 42 ;
InitialiserGenerateur(nb_Bits,
nb_PositionsSpeciales, PositionsSpeciales,
Graine) ;
/* Test de mélange d'un tableau */ int i, nb_elts = 20 ; void *T[nb_elts] ; int *x = NULL ; for(i = 0 ; i < nb_elts ; i++)
{
x = malloc(sizeof(int)) ; *x = i + 1 ; T[i] = x ;
}
/* Affichage avant */ for(i = 0 ; i < nb_elts ; i++)
{
x = T[i] ;
printf("%d ; ", *x) ;
}
printf("\n") ;
Melanger(nb_elts, T) ;
/* Affichage après */ for(i = 0 ; i < nb_elts ; i++)
{
x = T[i] ;
printf("%d ; ", *x) ;
}
printf("\n") ;