Não consigo entender isso, o que é mais aleatório?
rand()
OU :
rand() * rand()
Estou achando um verdadeiro quebra-cabeças, você poderia me ajudar?
EDITAR:
Intuitivamente, sei que a resposta matemática será que eles são igualmente aleatórios, mas não posso deixar de pensar que se você "executar o algoritmo de número aleatório" duas vezes ao multiplicar os dois, criará algo mais aleatório do que apenas fazer uma vez.
math
language-agnostic
random
Trufa
fonte
fonte
Respostas:
Apenas um esclarecimento
Embora as respostas anteriores estejam corretas sempre que você tentar identificar a aleatoriedade de uma variável pseudo-aleatória ou sua multiplicação, você deve estar ciente de que enquanto Random () geralmente é distribuído uniformemente, Random () * Random () não é.
Exemplo
Esta é uma amostra uniforme de distribuição aleatória simulada através de uma variável pseudo-aleatória:
Embora essa seja a distribuição que você obtém após multiplicar duas variáveis aleatórias:
Então, ambos são "aleatórios", mas sua distribuição é muito diferente.
Outro exemplo
Enquanto 2 * Random () é distribuído uniformemente:
Random () + Random () não é!
Teorema do Limite Central
O Teorema do Limite Central afirma que a soma de Random () tende a uma distribuição normal à medida que os termos aumentam.
Com apenas quatro termos, você obtém:
E aqui você pode ver o caminho de uma distribuição uniforme para uma normal adicionando 1, 2, 4, 6, 10 e 20 variáveis aleatórias distribuídas uniformemente:
Editar
Alguns créditos
Agradecemos a Thomas Ahle por apontar nos comentários que as distribuições de probabilidade mostradas nas duas últimas imagens são conhecidas como distribuição de Irwin-Hall
Agradecimentos a Heike por sua maravilhosa função rasgada []
fonte
rand()+rand()
, você terminaria com uma distribuição do tipo "2d6" com um centro de gordura.Eu acho que os dois métodos são tão aleatórios, embora meu sentimento diria que isso
rand() * rand()
é menos aleatório porque geraria mais zeros. Assim que alguémrand()
é0
, o total se torna0
fonte
Nem é 'mais aleatório'.
rand()
gera um conjunto previsível de números com base em uma semente aleatória psuedo (geralmente com base no horário atual, que está sempre mudando). A multiplicação de dois números consecutivos na sequência gera uma sequência de números diferente, mas igualmente previsível.Respondendo se isso reduzirá colisões, a resposta é não. Na verdade, aumentará as colisões devido ao efeito de multiplicar dois números em que
0 < n < 1
. O resultado será uma fração menor, causando um viés no resultado em direção à extremidade inferior do espectro.Algumas explicações adicionais. A seguir, 'imprevisível' e 'aleatório' se referem à capacidade de alguém adivinhar qual será o próximo número com base nos números anteriores, ou seja. um oráculo.
Dada semente
x
que gera a seguinte lista de valores:rand()
irá gerar a lista acima erand() * rand()
irá gerar:Ambos os métodos sempre produzirão a mesma lista de números para a mesma semente e, portanto, são igualmente previsíveis por um oráculo. Mas se você olhar para os resultados da multiplicação das duas chamadas, verá que todas elas estão abaixo,
0.3
apesar de uma distribuição decente na sequência original. Os números são tendenciosos devido ao efeito da multiplicação de duas frações. O número resultante é sempre menor, portanto, é muito mais provável que seja uma colisão, apesar de ainda ser imprevisível.fonte
rand()+rand()+rand()...
fica cada vez mais "menos aleatório" (se por acaso você quer dizer distribuído uniformemente).rand()
para ser aleatório e não tente 'aprimorar' sua aleatoriedade. Não defina a semente várias vezes. Qualquer semente individual é perfeitamente boa, desde que seja semi-aleatória. Muitas implementações que eu já vi usam a época do UNIX como a semente, que muda a cada segundo e é única toda vez que muda.Oversimplification para ilustrar um ponto.
Suponha que sua função aleatória apenas produza
0
ou1
.random()
é um dos(0,1)
, masrandom()*random()
é um dos(0,0,0,1)
Você pode ver claramente que as chances de obter um
0
no segundo caso não são iguais às chances de obter um1
.Quando publiquei esta resposta, eu queria mantê-la o mais curta possível, para que uma pessoa que a lê entenda de relance a diferença entre
random()
erandom()*random()
, mas não consigo me impedir de responder à pergunta original ad litteram:Qual é mais aleatório?
Sendo que
random()
,random()*random()
,random()+random()
,(random()+1)/2
ou qualquer outra combinação que não conduz a um resultado fixo tem a mesma fonte de entropia (ou mesmo o estado inicial, no caso de geradores de pseudo-aleatórios), a resposta seria a de que eles são igualmente aleatório (A diferença está em sua distribuição). Um exemplo perfeito que podemos observar é o jogo de dados. O número que você recebe seriarandom(1,6)+random(1,6)
e todos sabemos que obter 7 tem a maior chance, mas isso não significa que o resultado de rolar dois dados é mais ou menos aleatório do que o resultado de rolar um.fonte
Aqui está uma resposta simples. Considere o monopólio. Você joga dois dados de seis lados (ou 2d6 para aqueles que preferem a notação de jogo) e recebe a soma deles. O resultado mais comum é 7, porque existem 6 maneiras possíveis de rolar um 7 (1,6 2,5 3,4 4,3 5,2 e 6,1). Considerando que um 2 só pode ser rolado em 1,1. É fácil ver que a rolagem 2d6 é diferente da rolagem 1d12, mesmo que o intervalo seja o mesmo (ignorando que você pode obter 1 em 1d12, o ponto permanece o mesmo). Multiplicar seus resultados em vez de adicioná-los vai distorcê-los de maneira semelhante, com a maioria dos resultados chegando no meio do intervalo. Se você está tentando reduzir valores discrepantes, esse é um bom método, mas não ajuda em uma distribuição uniforme.
(E, por incrível que pareça, ele também aumentará as jogadas baixas. Supondo que sua aleatoriedade comece em 0, você verá um pico em 0 porque transformará qualquer que seja a outra rolagem em 0. Considere dois números aleatórios entre 0 e 1 (inclusive ) e multiplicar.Se um resultado for 0, a coisa toda se tornará 0, não importa o outro resultado.A única maneira de obter um 1 é que ambos os rolos sejam 1. Na prática, isso provavelmente não importaria mas cria um gráfico estranho.)
fonte
O xkcd obrigatório ...
fonte
Pode ajudar a pensar nisso em números mais discretos. Considere querer gerar números aleatórios entre 1 e 36, para que você decida a maneira mais fácil de jogar dois dados justos de 6 lados. Você obtém isto:
Portanto, temos 36 números, mas nem todos estão bem representados, e alguns nem sequer ocorrem. Os números próximos à diagonal central (canto inferior esquerdo para canto superior direito) ocorrerão com a frequência mais alta.
Os mesmos princípios que descrevem a distribuição injusta entre dados se aplicam igualmente a números de ponto flutuante entre 0,0 e 1,0.
fonte
Algumas coisas sobre "aleatoriedade" são contra-intuitivas.
Assumindo uma distribuição plana de
rand()
, você terá distribuições não planas:sqrt(rand(range^2))
(rand(range) + rand(range))/2
range - sqrt(rand(range^2))
Existem muitas outras maneiras de criar curvas de polarização específicas. Fiz um teste rápido
rand() * rand()
e você obtém uma distribuição muito não linear.fonte
A maioria das implementações rand () tem algum período. Ou seja, após um número enorme de chamadas, a sequência se repete. A sequência de saídas se
rand() * rand()
repete na metade do tempo, portanto é "menos aleatória" nesse sentido.Além disso, sem uma construção cuidadosa, executar aritmética em valores aleatórios tende a causar menos aleatoriedade. Um pôster acima citado "
rand()
+rand()
+rand()
..." (k vezes, digamos) que de fato tende a k vezes o valor médio do intervalo de valoresrand()
retornado. (É uma caminhada aleatória com etapas simétricas sobre essa média.)Suponha, por concretude, que sua função rand () retorne um número real aleatório distribuído uniformemente no intervalo [0,1). (Sim, este exemplo permite precisão infinita. Isso não mudará o resultado.) Você não escolheu um idioma específico e idiomas diferentes podem fazer coisas diferentes, mas a análise a seguir é válida com modificações para qualquer implementação não perversa de rand ( ) O produto
rand() * rand()
também está na faixa [0,1), mas não está mais distribuído uniformemente. De fato, é mais provável que o produto esteja no intervalo [0,1 / 4) como no intervalo [1 / 4,1). Mais multiplicação inclina o resultado ainda mais para zero. Isso torna o resultado mais previsível. Em linhas gerais, mais previsível == menos aleatório.Praticamente qualquer sequência de operações com entrada aleatória uniforme será aleatoriamente não uniforme, levando a maior previsibilidade. Com cuidado, é possível superar essa propriedade, mas seria mais fácil gerar um número aleatório distribuído uniformemente no intervalo que você realmente queria, em vez de perder tempo com aritmética.
fonte
"aleatório" vs. "mais aleatório" é um pouco como perguntar qual Zero é mais zero'y.
Nesse caso,
rand
é um PRNG, portanto não totalmente aleatório. (de fato, bastante previsível se a semente for conhecida). Multiplicá-lo por outro valor não o torna mais ou menos aleatório.Um verdadeiro RNG do tipo criptográfico será realmente aleatório. E a execução de valores através de qualquer tipo de função não pode adicionar mais entropia a ela e pode muito bem remover a entropia, tornando-a não mais aleatória.
fonte
O conceito que você procura é "entropia", o "grau" de desordem de uma sequência de bits. A idéia é mais fácil de entender em termos do conceito de "entropia máxima".
Uma definição aproximada de uma sequência de bits com entropia máxima é que ela não pode ser expressa exatamente em termos de uma sequência mais curta de bits (isto é, usando algum algoritmo para expandir a sequência menor de volta à sequência original).
A relevância da entropia máxima para a aleatoriedade deriva do fato de que, se você escolher um número "aleatoriamente", quase certamente escolherá um número cuja sequência de bits esteja próxima de ter entropia máxima, ou seja, ela não poderá ser compactada. Esta é a nossa melhor compreensão do que caracteriza um número "aleatório".
Portanto, se você quiser criar um número aleatório com duas amostras aleatórias que são "duas vezes" aleatórias, concatenará as duas cadeias de bits juntas. Praticamente, você apenas colocaria as amostras nas metades alta e baixa de uma palavra de comprimento duplo.
Em uma nota mais prática, se você se deparar com um rand de baixa qualidade (), às vezes pode ajudar a compor algumas amostras juntas - embora, se ele estiver realmente quebrado, mesmo esse procedimento não ajudará.
fonte
4
ou binário do xkcd0100
pode ser compactado para zero bits. O programa de descompressão simplesmente retornaria '4'. Não é menos aleatório que isso. O problema com dilbert é que não sabemos se podemos compactá-lo para zero bits (descompactando sempre retornando 'nove'). Pode retornar oito também, então podemos compactar para 1 bit. Descomprimir por: 0-> nove, 1-> oito. Teríamos 1 bit aleatório.A resposta aceita é bastante agradável, mas há outra maneira de responder sua pergunta. A resposta do PachydermPuncher já adota essa abordagem alternativa e vou expandi-la um pouco.
A maneira mais fácil de pensar sobre a teoria da informação é em termos da menor unidade de informação, um único bit.
Na biblioteca padrão C,
rand()
retorna um número inteiro no intervalo de 0 aRAND_MAX
, um limite que pode ser definido de maneira diferente, dependendo da plataforma. SuponhaRAND_MAX
que seja definido como2^n - 1
onden
está um número inteiro (isso acontece na implementação da Microsoft, onden
é 15). Então diríamos que uma boa implementação retornarian
bits de informação.Imagine que
rand()
construa números aleatórios lançando uma moeda para encontrar o valor de um bit e depois repetindo até obter um lote de 15 bits. Então os bits são independentes (o valor de um bit não influencia a probabilidade de outros bits no mesmo lote terem um determinado valor). Portanto, cada bit considerado independentemente é como um número aleatório entre 0 e 1, inclusive, e é "distribuído uniformemente" nesse intervalo (com probabilidade de ser 0 como 1).A independência dos bits garante que os números representados por lotes de bits também sejam distribuídos igualmente em seu intervalo. Isso é intuitivamente óbvio: se houver 15 bits, o intervalo permitido é de zero a
2^15 - 1
= 32767. Cada número nesse intervalo é um padrão único de bits, como:e se os bits forem independentes, é mais provável que nenhum padrão ocorra do que qualquer outro padrão. Portanto, todos os números possíveis no intervalo são igualmente prováveis. E o inverso é verdadeiro: se
rand()
produz números inteiros distribuídos uniformemente, esses números são feitos de bits independentes.Então, pense
rand()
como uma linha de produção para a produção de bits, que por acaso os serve em lotes de tamanho arbitrário. Se você não gostar do tamanho, divida os lotes em bits individuais e, em seguida, reinstale-os nas quantidades que desejar (embora se você precisar de um intervalo específico que não seja 2), será necessário reduzir seus números e, de longe, a maneira mais fácil de fazer isso é converter para ponto flutuante).Retornando à sua sugestão original, suponha que você queira ir de lotes de 15 para lotes de 30, solicite
rand()
o primeiro número, mude-o em 15 lugares e adicione outrorand()
. Essa é uma maneira de combinar duas chamadasrand()
sem atrapalhar uma distribuição uniforme. Funciona simplesmente porque não há sobreposição entre os locais onde você coloca os bits de informação.Isso é muito diferente de "esticar" o intervalo
rand()
multiplicando por uma constante. Por exemplo, se você quisesse dobrar o intervalo,rand()
poderia multiplicar por dois - mas agora você só obteria números pares e nunca números ímpares! Isso não é exatamente uma distribuição suave e pode ser um problema sério, dependendo da aplicação, por exemplo, um jogo de roleta que supostamente permite apostas ímpares / pares. (Ao pensar em termos de bits, você evitaria esse erro intuitivamente, porque perceberia que multiplicar por dois é o mesmo que deslocar os bits para a esquerda (maior significado) por um lugar e preencher a lacuna com zero. Então, obviamente, a quantidade de informações é a mesma - apenas mudou um pouco.)Essas lacunas nos intervalos de números não podem ser atendidas em aplicativos de números de ponto flutuante, porque os intervalos de pontos flutuantes inerentemente possuem lacunas que simplesmente não podem ser representadas: existe um número infinito de números reais ausentes na lacuna entre cada dois flutuantes representáveis. números de ponto! Então, nós apenas temos que aprender a viver com lacunas de qualquer maneira.
Como outros avisaram, a intuição é arriscada nessa área, principalmente porque os matemáticos não conseguem resistir ao fascínio de números reais, que são coisas terrivelmente confusas, cheias de infinitos macabros e aparentes paradoxos.
Mas pelo menos se você pensa em termos de bits, sua intuição pode levá-lo um pouco mais longe. Os bits são realmente fáceis - até os computadores podem entendê-los.
fonte
Como outros já disseram, a resposta curta e fácil é: Não, não é mais aleatória, mas muda a distribuição.
Suponha que você estivesse jogando um jogo de dados. Você tem alguns dados completamente justos e aleatórios. As rolagens dos dados seriam "mais aleatórias" se, antes de cada rolagem, você primeiro colocasse dois dados em uma tigela, sacudisse ao redor, pegasse um dos dados aleatoriamente e depois rolasse aquele? Claramente não faria diferença. Se os dois dados derem números aleatórios, a escolha aleatória de um dos dois dados não fará diferença. De qualquer forma, você obterá um número aleatório entre 1 e 6 com distribuição uniforme em um número suficiente de jogadas.
Suponho que na vida real esse procedimento possa ser útil se você suspeitar que os dados NÃO podem ser justos. Se, digamos, os dados estiverem um pouco desequilibrados, então um tende a dar 1 com mais frequência que 1/6 do tempo, e outro tende a dar 6 com frequência incomum, então a escolha aleatória entre os dois tenderia a obscurecer o viés. (Embora neste caso, 1 e 6 ainda aumentem mais que 2, 3, 4 e 5. Bem, acho que dependendo da natureza do desequilíbrio.)
Existem muitas definições de aleatoriedade. Uma definição de uma série aleatória é que é uma série de números produzidos por um processo aleatório. Por essa definição, se eu rolar um dado justo 5 vezes e obter os números 2, 4, 3, 2, 5, é uma série aleatória. Se eu rolar o mesmo dado justo mais 5 vezes e receber 1, 1, 1, 1, 1, então isso também será uma série aleatória.
Vários pôsteres apontaram que funções aleatórias em um computador não são verdadeiramente aleatórias, mas sim pseudo-aleatórias, e que, se você conhece o algoritmo e a semente, elas são completamente previsíveis. Isso é verdade, mas na maioria das vezes completamente irrelevante. Se embaralhar um baralho de cartas e depois entregá-las uma por vez, deve ser uma série aleatória. Se alguém espiar as cartas, o resultado será completamente previsível, mas, na maioria das definições de aleatoriedade, isso não a tornará menos aleatória. Se a série passar nos testes estatísticos de aleatoriedade, o fato de eu ter espiado as cartas não mudará esse fato. Na prática, se estivermos apostando grandes somas de dinheiro em sua capacidade de adivinhar a próxima carta, o fato de você ter espiado as cartas é altamente relevante. Se estivermos usando a série para simular as opções dos visitantes do nosso site, a fim de testar o desempenho do sistema, o fato de que você espiou não fará nenhuma diferença. (Desde que você não modifique o programa para aproveitar esse conhecimento.)
EDITAR
Eu não acho que eu poderia responder minha resposta ao problema de Monty Hall em um comentário, então atualizarei minha resposta.
Para quem não leu o link Belisarius, o essencial é: Um participante de um game show pode escolher 3 portas. Atrás de um é um prêmio valioso, atrás dos outros algo sem valor. Ele pega a porta # 1. Antes de revelar se é um vencedor ou um perdedor, o anfitrião abre a porta nº 3 para revelar que é um perdedor. Ele então dá ao competidor a oportunidade de mudar para a porta 2. O competidor deve fazer isso ou não?
A resposta, que ofende a intuição de muitas pessoas, é que ele deveria mudar. A probabilidade de sua escolha original ter sido a vencedora é de 1/3, de que a outra porta seja a vencedora, de 2/3. Minha intuição inicial, juntamente com a de muitas outras pessoas, é que não haveria ganho na troca, que as probabilidades foram alteradas para 50:50.
Afinal, suponha que alguém ligou a TV logo após o anfitrião abrir a porta perdida. Essa pessoa veria duas portas fechadas restantes. Supondo que ele conheça a natureza do jogo, ele diria que há uma chance de 1/2 de cada porta para ocultar o prêmio. Como as chances do espectador podem ser de 1/2: 1/2, enquanto as chances do competidor são de 1/3: 2/3?
Eu realmente tive que pensar sobre isso para moldar minha intuição. Para entender isso, entenda que, quando falamos de probabilidades em um problema como esse, queremos dizer a probabilidade que você atribui, dada a informação disponível. Para um membro da equipe que colocou o prêmio para trás, digamos, porta 1, a probabilidade de que o prêmio esteja atrás da porta 1 é 100% e a probabilidade de estar atrás de qualquer uma das outras duas portas é zero.
As probabilidades do membro da tripulação são diferentes das probabilidades do competidor porque ele sabe algo que o competidor não sabe, a saber, qual porta ele colocou para trás o prêmio. Da mesma forma, as chances do competidor são diferentes das chances do espectador, porque ele sabe algo que o espectador não sabe, a saber, qual porta ele escolheu inicialmente. Isso não é irrelevante, porque a escolha do host de qual porta abrir não é aleatória. Ele não abrirá a porta escolhida pelo competidor e não abrirá a porta que oculta o prêmio. Se estas são a mesma porta, isso lhe deixa duas opções. Se são portas diferentes, isso deixa apenas uma.
Então, como criamos 1/3 e 2/3? Quando o competidor originalmente escolheu uma porta, ele tinha 1/3 de chance de escolher o vencedor. Eu acho que isso é óbvio. Isso significa que havia 2/3 de chance de uma das outras portas ser a vencedora. Se o anfitrião jogar com ele a oportunidade de trocar sem fornecer nenhuma informação adicional, não haverá ganho. Novamente, isso deve ser óbvio. Mas uma maneira de ver isso é dizer que há uma chance de 2/3 de que ele ganhe trocando. Mas ele tem 2 alternativas. Portanto, cada um tem apenas 2/3 dividido por 2 = 1/3 de chance de ser o vencedor, o que não é melhor do que sua escolha original. Claro que já sabíamos o resultado final, isso apenas o calcula de uma maneira diferente.
Mas agora o anfitrião revela que uma dessas duas opções não é a vencedora. Portanto, da chance de 2/3 de uma porta que ele não escolher é a vencedora, ele agora sabe que 1 das 2 alternativas não é. O outro pode ou não ser. Portanto, ele não tem mais 2/3 dividido por 2. Ele tem zero para a porta aberta e 2/3 para a porta fechada.
fonte
Considere que você tem um problema simples de troca de moeda, em que o par é considerado cara e o ímpar é considerado coroa. A implementação lógica é:
Em uma distribuição grande o suficiente, o número de números pares deve ser igual ao número de números ímpares.
Agora considere um pequeno ajuste:
Se um dos resultados for par, o resultado inteiro deverá ser par. Considere os 4 resultados possíveis (par * par = par, par * ímpar = par, ímpar * par = par, ímpar * ímpar = ímpar). Agora, em uma distribuição suficientemente grande, a resposta deve ser 75% do tempo.
Eu apostaria cabeças se eu fosse você.
Esse comentário é realmente mais uma explicação de por que você não deve implementar uma função aleatória personalizada com base no seu método do que uma discussão sobre as propriedades matemáticas da aleatoriedade.
fonte
rand()%2
pode não ser muito aleatório; isso realmente depende da aleatoriedade do bit baixo, e alguns PRNGs não são muito bons assim. (É claro que, em algumas línguas você começa resultar uma de ponto flutuante derand()
modo que você não pode fazê-lo dessa maneira em tudo ...)Em caso de dúvida sobre o que acontecerá com as combinações de seus números aleatórios, você pode usar as lições aprendidas em teoria estatística.
Na situação do OP, ele quer saber qual é o resultado de X * X = X ^ 2, onde X é uma variável aleatória distribuída ao longo de Uniforme [0,1]. Usaremos a técnica CDF, pois é apenas um mapeamento individual.
Como X ~ Uniforme [0,1] é cdf é: f X (x) = 1 Queremos a transformação Y <- X ^ 2 assim y = x ^ 2 Encontre a inversa x (y): sqrt (y) = x isso nos dá x em função de y. Em seguida, encontre a derivada dx / dy: d / dy (sqrt (y)) = 1 / (2 sqrt (y))
A distribuição de Y é dada como: f Y (y) = f X (x (y)) | dx / dy | = 1 / (2 sqrt (y))
Ainda não terminamos, temos que obter o domínio de Y. como 0 <= x <1, 0 <= x ^ 2 <1, para que Y esteja no intervalo [0, 1). Se você quiser verificar se o pdf de Y é realmente um pdf, integre-o ao domínio: Integre 1 / (2 sqrt (y)) de 0 a 1 e, de fato, ele será exibido como 1. Além disso, observe a forma do a referida função se parece com o que foi publicado.
Quanto a coisas como X 1 + X 2 + ... + X n , (onde X i ~ Uniform [0,1]), podemos apenas apelar para o Teorema do Limite Central que funciona para qualquer distribuição, cujos momentos existe. É por isso que o teste Z existe realmente.
Outras técnicas para determinar o pdf resultante incluem a transformação jacobiana (que é a versão generalizada da técnica cdf) e a técnica MGF.
EDIT: Como um esclarecimento, observe que estou falando da distribuição da transformação resultante e não de sua aleatoriedade . Isso é realmente para uma discussão separada. Também o que eu realmente deduzi foi para (rand ()) ^ 2. Para rand () * rand () é muito mais complicado, o que, em qualquer caso, não resultará em uma distribuição uniforme de qualquer tipo.
fonte
Não é exatamente óbvio, mas
rand()
geralmente é mais aleatório querand()*rand()
. O importante é que isso não seja realmente muito importante para a maioria dos usos.Mas, primeiro, eles produzem distribuições diferentes. Isso não é um problema, se é isso que você deseja, mas importa. Se você precisar de uma distribuição específica, ignore toda a questão "que é mais aleatória". Então, por que é
rand()
mais aleatório?O núcleo do porquê
rand()
é mais aleatório (sob a suposição de que ele está produzindo números aleatórios de ponto flutuante com o intervalo [0..1], o que é muito comum) é que quando você multiplica dois números FP juntamente com muita informação na mantissa, obtém alguma perda de informações no final; simplesmente não há bit suficiente em um flutuador de precisão dupla IEEE para armazenar todas as informações que estavam em dois flutuadores de precisão dupla IEEE selecionados aleatoriamente uniformemente de [0..1], e esses bits extras de informação são perdidos. Claro, isso não importa muito, já que você (provavelmente) não usaria essas informações, mas a perda é real. Também não importa realmente qual distribuição você produz (ou seja, qual operação você usa para fazer a combinação). Cada um desses números aleatórios possui (na melhor das hipóteses) 52 bits de informações aleatórias - isso 'A maioria dos usos de números aleatórios não usa nem a aleatoriedade que está realmente disponível na fonte aleatória. Obtenha um bom PRNG e não se preocupe muito com isso. (O nível de "bondade" depende do que você está fazendo com ele; você deve ter cuidado ao fazer a simulação ou criptografia de Monte Carlo, mas, caso contrário, provavelmente poderá usar o PRNG padrão, pois geralmente é muito mais rápido.)
fonte
Os randoms flutuantes são baseados, em geral, em um algoritmo que produz um número inteiro entre zero e um determinado intervalo. Como tal, usando rand () * rand (), você está essencialmente dizendo int_rand () * int_rand () / rand_max ^ 2 - o que significa que você está excluindo qualquer número primo / rand_max ^ 2.
Isso altera significativamente a distribuição aleatória.
rand () é distribuído uniformemente na maioria dos sistemas e difícil de prever se propriamente propagado. Use isso, a menos que você tenha um motivo específico para fazer contas (ou seja, moldar a distribuição para uma curva necessária).
fonte
rand()*rand()
é menor que o espaço de resultado derand()
- uma vez que exclui números primos. Obtém o meu voto ...A multiplicação de números acabaria em um intervalo menor de solução, dependendo da arquitetura do computador.
Se a tela do seu computador mostrar 16 dígitos
rand()
, digamos 0,1234567890123 multiplicado por segundorand()
, 0,1234567890123, daria 0,0152415 algo que você definitivamente encontrará menos soluções se repetir o experimento 10 ^ 14 vezes.fonte
A maioria dessas distribuições ocorre porque você precisa limitar ou normalizar o número aleatório.
Normalizamos que tudo seja positivo, ajuste dentro de um intervalo e até mesmo dentro das restrições do tamanho da memória para o tipo de variável atribuído.
Em outras palavras, como temos que limitar a chamada aleatória entre 0 e X (X é o limite de tamanho de nossa variável), teremos um grupo de números "aleatórios" entre 0 e X.
Agora, quando você adiciona o número aleatório a outro número aleatório, a soma fica entre 0 e 2X ... isso distorce os valores dos pontos extremos (a probabilidade de adicionar dois números pequenos juntos e dois grandes números juntos é muito pequena quando você tem dois números aleatórios em um grande intervalo).
Pense no caso em que você tinha um número que é próximo de zero e o adiciona com outro número aleatório, ele certamente aumentará e se afastará de 0 (isso acontecerá com números grandes e é improvável que tenha dois números grandes (números próximos a X) retornados pela função Aleatória duas vezes.
Agora, se você configurasse o método aleatório com números negativos e números positivos (abrangendo igualmente o eixo zero), esse não seria mais o caso.
Digamos, por exemplo
RandomReal({-x, x}, 50000, .01)
, que você obteria uma distribuição uniforme dos números no lado negativo e positivo e, se você adicionar os números aleatórios, eles manterão sua "aleatoriedade".Agora não tenho certeza do que aconteceria com o
Random() * Random()
intervalo de negativo para positivo ... seria um gráfico interessante de ver ... mas tenho que voltar a escrever código agora. :-Pfonte
Não existe algo mais aleatório. É aleatório ou não. Aleatório significa "difícil de prever". Isso não significa não determinístico. Random () e random () * random () são igualmente aleatórios se random () for aleatório. A distribuição é irrelevante no que diz respeito à aleatoriedade. Se ocorrer uma distribuição não uniforme, isso significa apenas que alguns valores são mais prováveis que outros; eles ainda são imprevisíveis.
Como a pseudo-aleatoriedade está envolvida, os números são muito determinísticos. No entanto, a pseudo-aleatoriedade é frequentemente suficiente em modelos e simulações de probabilidade. É bem sabido que complicar um gerador de números pseudo-aleatórios dificulta a análise. É improvável melhorar a aleatoriedade; geralmente causa falhas nos testes estatísticos.
As propriedades desejadas dos números aleatórios são importantes: repetibilidade e reprodutibilidade, aleatoriedade estatística, (geralmente) uniformemente distribuídas e um grande período são poucas.
Sobre transformações em números aleatórios: Como alguém disse, a soma de dois ou mais distribuídos uniformemente resulta em uma distribuição normal. Este é o teorema do limite central aditivo . Aplica-se independentemente da distribuição de origem, desde que todas as distribuições sejam independentes e idênticas. O multiplicativoO teorema do limite central diz que o produto de duas ou mais variáveis aleatórias independentes e distribuídas indenticamente é lognormal. O gráfico criado por alguém parece exponencial, mas é realmente anormal. Então random () * random () é lognormalmente distribuído (embora possa não ser independente, pois os números são extraídos do mesmo fluxo). Isso pode ser desejável em algumas aplicações. No entanto, geralmente é melhor gerar um número aleatório e transformá-lo em um número log-distribuído normalmente. Aleatório () * aleatório () pode ser difícil de analisar.
Para mais informações, consulte meu livro em www.performorama.org. O livro está em construção, mas o material relevante está lá. Observe que os números de capítulos e seções podem mudar com o tempo. Capítulo 8 (teoria da probabilidade) - seções 8.3.1 e 8.3.3, capítulo 10 (números aleatórios).
fonte
Podemos comparar duas matrizes de números com relação à aleatoriedade usando a complexidade de Kolmogorov. Se a sequência de números não puder ser compactada, é a mais aleatória que podemos alcançar com esse comprimento ... Eu sei que esse tipo de medição é mais teórico opção...
fonte
Na verdade, quando você pensa sobre isso,
rand() * rand()
é menos aleatório do querand()
. Aqui está o porquê.Essencialmente, há o mesmo número de números ímpares que os números pares. E dizer que 0,04325 é ímpar, e como 0,388 é par, e 0,4 é par e 0,15 é ímpar,
Isso significa que
rand()
tem uma chance igual de ser um decimal par ou ímpar .Por outro lado,
rand() * rand()
as probabilidades estão um pouco diferentes. Digamos:a
eb
ambos têm 50% de chance de ser par ou ímpar. Sabendo quesignifica que há uma chance de 75% que
c
é par, enquanto apenas uma chance de 25% é ímpar, tornando o valor derand() * rand()
mais previsível do querand()
, portanto, menos aleatório.fonte
rand()
geralmente fornece um número entre 0 e 1. Falar sobre se é par ou ímpar faz sentido?0.2*0.2=0.04
que sugere uma falha fundamental com essa abordagem: multiplicar os 53 bits de dois duplos resultará em cerca de 100 bits no resultado. Mas a última metade desses bits será descartada. Portanto, quando você toma duas duplas com 1 como o bit menos significativo, não pode dizer nada sobre o bit menos significativo do produto.rand()
são as mesmas que as definições de "par" e "ímpar" que fazem sentido para a distribuição derand()*rand()
. Se não for esse o caso, esse argumento falhará. Isso é verdade para números inteiros, mas estes não são números inteiros.Use um registro de deslocamento de realimentação linear (LFSR) que implemente um polinômio primitivo.
O resultado será uma sequência de 2 ^ n números pseudo-aleatórios, ou seja, nenhum repetido na sequência em que n é o número de bits no LFSR .... resultando em uma distribuição uniforme.
http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
Use uma semente "aleatória" baseada em microssegundos do relógio do computador ou talvez um subconjunto do resultado do MD5 em alguns dados que mudam continuamente no sistema de arquivos.
Por exemplo, um LFSR de 32 bits gerará 2 ^ 32 números únicos em sequência (não há 2 iguais) começando com uma determinada semente. A sequência sempre estará na mesma ordem, mas o ponto de partida será diferente (obviamente) para sementes diferentes. Portanto, se uma sequência possível de repetição entre as sementes não for um problema, essa pode ser uma boa escolha.
Eu usei LFSRs de 128 bits para gerar testes aleatórios em simuladores de hardware usando uma semente que é o resultado do MD5 na alteração contínua dos dados do sistema.
fonte
Supondo que
rand()
retorne um número entre[0, 1)
, é óbvio querand() * rand()
será enviesado em direção a 0. Isso ocorre porque a multiplicaçãox
por um número entre[0, 1)
resultará em um número menor quex
. Aqui está a distribuição de mais 10000 números aleatórios:Mostrar snippet de código
Se
rand()
retornar um número inteiro entre[x, y]
, você terá a seguinte distribuição. Observe o número de valores ímpares vs pares:Mostrar snippet de código
fonte
OK, então tentarei adicionar algum valor para complementar as respostas de outras pessoas dizendo que você está criando e usando um gerador de números aleatórios.
Geradores de números aleatórios são dispositivos (em um sentido muito geral) que possuem várias características que podem ser modificadas para se adequar a uma finalidade. Alguns deles (de mim) são:
Na maioria das respostas aqui, a distribuição é o principal ponto de interesse, mas, combinando funções e parâmetros, você cria novas formas de gerar números aleatórios que terão características diferentes para algumas das quais a avaliação pode não ser óbvia à primeira vista.
fonte
É fácil mostrar que a soma dos dois números aleatórios não é necessariamente aleatória. Imagine que você tem um dado e um rolo de 6 lados. Cada número tem 1/6 de chance de aparecer. Agora diga que você tinha 2 dados e resumiu o resultado. A distribuição dessas somas não é 1/12. Por quê? Porque certos números aparecem mais que outros. Existem várias partições deles. Por exemplo, o número 2 é a soma de 1 + 1 apenas, mas 7 pode ser formado por 3 + 4 ou 4 + 3 ou 5 + 2, etc.
Portanto, aplicando uma transformação, nesse caso, a adição a uma função aleatória não a torna mais aleatória ou preserva necessariamente a aleatoriedade. No caso dos dados acima, a distribuição é inclinada para 7 e, portanto, menos aleatória.
fonte
Como outros já apontaram, é difícil responder a essa pergunta, já que todos nós temos sua própria imagem de aleatoriedade em sua cabeça.
Por isso, eu recomendo que você reserve um tempo e leia este site para ter uma idéia melhor da aleatoriedade:
Para voltar à questão real. Não há mais ou menos aleatório neste termo:
ambos parecem aleatórios !
Nos dois casos - apenas rand () ou rand () * rand () - a situação é a mesma: após alguns bilhões de números, a sequência será repetida (!) . Ele aparece aleatoriamente para o observador, porque ele não sabe toda a sequência, mas o computador tem nenhuma verdadeira fonte aleatória - para que ele não pode produzir aleatoriedade também.
por exemplo: o tempo é aleatório? Não temos sensores ou conhecimentos suficientes para determinar se o tempo é aleatório ou não.
fonte
A resposta seria: depende, espero que o rand () * rand () seja mais aleatório que o rand (), mas como:
Bem, se você verificar qualquer uma dessas opções acima, sugiro que escolha o "rand ()" simples. Como seu código seria mais legível (não se pergunte por que você escreveu isso, por ... bem ... mais de 2 segundos), fácil de manter (se você quiser substituir sua função rand por um super_rand).
Se você quiser um aleatório melhor, recomendo que você o transmita de qualquer fonte que forneça ruído suficiente ( rádio estático ) e, em seguida, um simples
rand()
deve ser suficiente.fonte