Números aleatórios em shell script

Publicado por Perfil removido em 04/07/2012

[ Hits: 18.082 ]

 


Números aleatórios em shell script



Esta dica fala de uma pequena irregularidade que passa desapercebida quando se usa a variável interna "$RANDOM" do bash para trabalhar com números aleatórios.

A variável interna "$RANDOM" gera aleatórios apenas no intervalo 0 a 32767, que compreende 15 bits, na prática, 2 bytes.

Por ser uma potência de 2, o espaço de probabilidade, quando calcula-se em módulo para outros valores, não é uniforme.

Por exemplo, quero trabalhar com números no espaço amostral de 100 números, 0 a 99 no caso.

Geralmente, o que é feito é algo do tipo: [$RANDOM%100] (0-99)

Ou então: [1+($RANDOM%100)] (para 0-100)

Acontece que o número máximo gerado por $RANDOM é 32767, e que 32767 dividido por 100 dá 327, e sobram 67.

67? E daí?

Daí que para ter uma probabilidade uniforme, estaria faltando os números entre 32768 e 32799.

Os números de final 00 a 67 (os restos da divisão por 100) repetem-se 328 vezes no intervalo de 0 a 32767. Os números de final 68 a 99 (os restos da divisão por 100) repetem-se apenas 327 vezes no intervalo de 0 a 32767.

Como não existem os números do intervalo 32768 a 32799, rigorosamente esta probabilidade fica distorcida.

Uma das alternativas possíveis, a que encontrei no momento, seria este cálculo:

Numero = ($RANDOM * "tamanho do intervalo desejado") / 32767

Isto seria um "cálculo de porcentagem". Não é apenas por trabalhar com o número 100.

O valor de $RANDOM representa uma pequena fração no intervalo de 0 a 32767. Fazendo a conta $RANDOM/32767, encontra-se sempre um número entre 0 e 1. Sempre.

Sendo que o bash não trabalha com fracionários, antes desta divisão, multiplica-se pelo valor da faixa com que se quer trabalhar. Seja 10, 20, 50 ou 100, conforme este caso.

* Lembrando que pode ser melhorado.

No caso do valor da faixa ser uma potência de 2, menos que 32768, que 2 elevado à 15, ou um dos seguintes valores:
  • 2
  • 4
  • 8
  • 16
  • 32
  • 64
  • 128
  • 256
  • 512
  • 1024
  • 2048
  • 4096
  • 8192
  • 16384
  • 32768

Então, a probabilidade funciona por igual, apenas calculando-se o resto do valor de $RANDOM por este trabalhar numa faixa de uma potência de 2.

Bem, é isto.

Outras dicas deste autor

PHP orientado a objeto com MySQL e AJAX - Seleção de estado e cidade

Gerenciador de discos para o Biglinux e Ubuntu

Como desmontar unidades removíveis com segurança no elementary OS

Ubuntu Linux - os bons tempos do "inittab" estão de volta

Compilando o libquicktime SlackBuild no Slackware 64 bits

Leitura recomendada

Operações matemáticas diretamente pelo bash

Trabalhando com parâmetros em Shell Script

Iniciando Script com o Sistema - Configuração no Debian Wheezy

Script IP Válidos na rede interna

Como lidar com variáveis retornadas pelo Expect - removendo CR do fim de linha

  

Comentários
[1] Comentário enviado por tn4ehi em 04/08/2012 - 16:42h

Genial! Eu lembro de ter um problema com um script exatamente por isso, mas só agora é que posso ver. Parabéns!



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts