Criar uma função que gere números aleatórios distintos

1. Criar uma função que gere números aleatórios distintos

Paulo Souza
paulosouza

(usa Ubuntu)

Enviado em 30/06/2013 - 15:42h

Será que alguém poderia fazer uma função que retorne um número aleatório distinto entre 0 e 20 (fazendo comparação com o array de tamanho 10, armazenando os números gerados) ?

att,


  


2. Re: Criar uma função que gere números aleatórios distintos

Augusto
LinuxMH

(usa BackTrack)

Enviado em 01/07/2013 - 09:36h

Posso te ajuda-lo, sabe usar função rand ?


3. Re: Criar uma função que gere números aleatórios distintos

Paulo Souza
paulosouza

(usa Ubuntu)

Enviado em 01/07/2013 - 09:50h

Eu sei usar, mas eu não conseguindo. Você poderia fazer e depois explicar para mim?


4. Re: Criar uma função que gere números aleatórios distintos

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/07/2013 - 14:15h

paulosouza escreveu:

Eu sei usar, mas eu não conseguindo. Você poderia fazer e depois explicar para mim?


Desculpe pela franqueza, mas se você não está conseguindo, é porque não sabe usar.

Vamos lá: rand() devolve um valor inteiro longo na faixa [0, RAND_MAX]. Se você quiser que esse valor fique na faixa [M, N], então você terá de usar uma expressão a*x+b. x é o valor devolvido por rand(), e a e b devem ser escolhidos de modo tal que quando x for zero, a expressão produza o valor mínimo (M) da faixa desejada, e que quando x valer RAND_MAX, o valor produzido seja N.

Você terá, então, um sistema de duas equações e duas incógnitas, a saber:

a*0+b=M
a*RAND_MAX+b=N


De cara se vê que b=M, e, portanto, a=(N-M)/RAND_MAX.

Cuidado, porém, com a ordem em que você faz as contas e com os tipos de dados envolvidos, que podem ter limites facilmente extrapolados. Se você trabalhar só com inteiros, se fizer primeiro rand()/RAND_MAX, para depois multiplicar por N-M, vai ter quase sempre um valor 0 (exceto quando rand() devolver exatamente RAND_MAX, quando então essa divisão dará 1). Por outro lado, se você multiplicar primeiro, e RAND_MAX for de uma ordem de grandeza comparável a INT_MAX, é possível que um valor muito grande devolvido por rand() produza um overflow ao ser multiplicado por (N-M). Por isso mesmo, eu recomendo trabalhar com a e b como double, da seguinte forma.

const double scale_factor=(double)(UPPER_LIMIT-LOWER_LIMIT)/(double)RAND_MAX;
const double offset=(double)LOWER_LIMIT;

double random_var;
int random_int_var;

random_var=scale_factor*(double)rand()+offset;
random_int_var=(int)(scale_factor*(double)rand()+offset+0.5); /* usa arredondamento */


Algumas pessoas podem recomendar que você use outra forma de calcular, usando a formula x%(N-M+1)+M. Isso, no entanto, tem alguns problemas -- que eu mesmo já vivi na prática e posso atestar que existem --, porque alguns geradores de números pseudo-aleatórios de uso mais comum, usados internamente por rand(), não variam de modo equilibrado os bits de mais baixa ordem e os de mais alta ordem, e a operação de extrair o resto da divisão de x por N-M+1 acaba ficando "viciada", com ciclos de repetição mais curtos, pois pega somente os bits de mais baixa ordem. A primeira forma que eu sugeri, usando números de ponto flutuante, é mais segura nesse sentido.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts