2009-11-07 9 views
10

J'ai écrit cette fonction pour obtenir un pseudo flottant aléatoire entre 0 .. 1 inclus:nombre flottant au hasard

float randomFloat() 
{ 
     float r = (float)rand()/(float)RAND_MAX; 
     return r; 
} 

Cependant, il retourne toujours 0,563585. Le même nombre, peu importe combien de fois je cours mon application de console.

EDIT:

Voici mon ensemble de l'application si nécessaire:

#include <stdio.h> 
#include <stdlib.h> 

float randomFloat() 
{ 
     float r = (float)rand()/(float)RAND_MAX; 
     return r; 
} 

int main(int argc, char *argv[]) 
{ 
    float x[] = { 
     0.72, 0.91, 0.46, 0.03, 0.12, 0.96, 0.79, 0.46, 0.66, 0.72, 0.35, -0.16, 
     -0.04, -0.11, 0.31, 0.00, -0.43, 0.57, -0.47, -0.72, -0.57, -0.25, 
     0.47, -0.12, -0.58, -0.48, -0.79, -0.42, -0.76, -0.77 
    }; 

    float y[] = { 
     0.82, -0.69, 0.80, 0.93, 0.25, 0.47, -0.75, 0.98, 0.24, -0.15, 0.01, 
     0.84, 0.68, 0.10, -0.96, -0.26, -0.65, -0.97, -0.03, -0.64, 0.15, -0.43, 
     -0.88, -0.90, 0.62, 0.05, -0.92, -0.09, 0.65, -0.76  
    }; 

    int outputs[] = { 
     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 
    }; 

    int patternCount = sizeof(x)/sizeof(int); 

    float weights[2]; 
    weights[0] = randomFloat(); 
    weights[1] = randomFloat(); 

    printf("%f\n", weights[1]); 

    float learningRate = 0.1; 

    system("PAUSE"); 
    return 0; 
} 
+3

Notez que la fonction rand() ne doit pas être très « bon » générateur de nombres aléatoires. Cela n'aura probablement pas d'importance si vous n'avez besoin que de deux décimales entre 0 et 1; ce serait le cas si vous aviez besoin de 4 décimales ou plus. Si vous avez besoin de plus d'endroits, regardez la famille de fonctions 'drand48()': http://www.opengroup.org/onlinepubs/9699919799/functions/drand48.html –

Répondre

13

Vous devez appeler

srand(time(NULL)); 

avant d'utiliser rand pour la première fois. time est dans <time.h>.

EDIT: Comme le souligne Jonathan Leffler, c'est facile à prévoir, alors n'essayez pas de l'utiliser pour la cryogravure.

+2

Faites attention en utilisant time(); c'est plutôt prévisible et donc vos séquences aléatoires peuvent être prédites aussi. Ce n'est peut-être pas important dans ce cas, mais soyez prudent en général. –

10

C'est parce que le générateur aléatoire C est un générateur pseudo de -Random (et qui est, d'ailleurs, une très bonne chose, avec de nombreuses applications). (La norme ANSI C nécessite un tel générateur pseudo-aléatoire)

Essentiellement chaque fois que votre application console est redémarrée il utilise la même graine [par défaut] pour le générateur aléatoire.

en ajoutant une ligne comme

srand(time(NULL)); 

vous obtiendrez une graine distincte à chaque fois, et la séquence du nombre produit avec varier en conséquence.
Note: il suffit d'appeler srand() une fois, pas avant chaque appel de rand().

Modifier: (Test/indice temps de débogage)
[d'une remarque par Artelius] Pour des fins de test, il est préférable de srand (SOME_CONST), et modifier la valeur de la constante entre les courses. De cette façon, si un bug se manifeste à cause d'une combinaison de nombres aléatoires, vous pourrez le reproduire.

+5

À des fins de test, il est préférable de définir srand (SOME_CONST) et de modifier la valeur de la constante entre les exécutions. De cette façon, si un bug se manifeste à cause d'une combinaison de nombres aléatoires, vous pourrez le reproduire. – Artelius

+0

@artelius, excellente suggestion. J'ai ajouté ceci comme une note à la réponse elle-même! – mjv

+0

@artelius et mjv: c'est un bon point; cela peut aussi être une bonne idée de permettre à l'utilisateur de spécifier la graine sur la ligne de commande au lieu d'utiliser time(), et il peut souvent (mais pas toujours) être une bonne idée de rapporter la graine qui a été utilisée ligne de commande ou toute autre source) pour travailler avec les résultats. –

2

Vous avez d'initialiser une graine aléatoire avec

void srand (unsigned int seed); 

Vous pouvez par exemple le temps du système.

1

L'appelez-vous plus d'une fois? rand() retournera toujours le même pseudo aléatoire. Vous pourriez vouloir appeler srand() avec une belle graine, comme l'heure actuelle.

4

drand48 est parfait pour votre usage, mieux que (float)rand()/RAND_MAX, parce que

Les drand48() et erand48() fonctions renvoient non-négatif, double précision, les valeurs à virgule flottante, réparties uniformément sur l'intervalle [0.0, 1.0 ]

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
int main() { 
    int i; 

    srand48(time(NULL)); 

    for (i = 0; i < 10; i++) 
     printf("%g\n", drand48()); 

    return 0; 
}