Vou tentar, já que estou suficientemente perturbado com os conselhos dados em algumas das outras respostas.
Sejam sequências de bits infinitas geradas por dois RNGs (não necessariamente PRNGs que são determinísticos quando o estado inicial é conhecido), e estamos considerando a possibilidade de usar a sequência com a esperança de melhorar o comportamento em algum sentido. Existem várias maneiras pelas quais podem ser considerados melhores ou piores em comparação com cada um dos e ; aqui estão algumas pequenas que considero significativas, úteis e consistentes com o uso normal das palavras "melhor" e "pior":X⃗ ,Y⃗ X⃗ ⊕Y⃗ X⃗ ⊕Y⃗ X⃗ Y⃗
- (0) A probabilidade de aleatoriedade verdadeira da sequência aumenta ou diminui
- (1) A probabilidade de não aleatoriedade observável aumenta ou diminui (com respeito a algum observador que aplica uma certa quantidade de exame, presumivelmente)
- (2) A severidade / obviedade da não aleatoriedade observável aumenta ou diminui.
Primeiro, vamos pensar em (0), que é o único dos três que tem alguma esperança de ser preciso. Observe que, se, de fato, qualquer um dos dois RNGs de entrada realmente for verdadeiramente aleatório, imparcial e independente do outro, o resultado do XOR também será verdadeiramente aleatório e imparcial. Com isso em mente, considere o caso em que você acredita que são fluxos de bits isolados e não-aleatórios verdadeiramente aleatórios, mas não tem certeza. Se são as probabilidades respectivas de que você está errado em relação a cada uma delas, então a probabilidade de não ser verdadeiramente aleatória é
, de fato muito menos desdeX⃗ ,Y⃗ εX,εYX⃗ ⊕Y⃗ ≤εXεY<min{εX,εY}εX,εY são assumidos muito próximos de 0 ("você acredita que sejam verdadeiramente aleatórios"). E, de fato, é ainda melhor que isso, quando também levamos em conta a possibilidade de ser verdadeiramente independente, mesmo quando nenhum deles é verdadeiramente aleatório:
Portanto, podemos concluir que, no sentido (0), o XOR não pode prejudicar e pode ajudar muito.X⃗ ,Y⃗
Pr(X⃗ ⊕Y⃗ not truly random)≤min{Pr(X⃗ not truly random),Pr(Y⃗ not truly random),Pr(X⃗ ,Y⃗ dependent)}.
No entanto, (0) não é interessante para PRNGs, pois no caso de PRNGs nenhuma das seqüências em questão tem chance de ser verdadeiramente aleatória.
Portanto, para esta questão, que é de fato sobre PRNGs, devemos estar falando sobre algo como (1) ou (2). Como essas são em termos de propriedades e quantidades como "observável", "severo", "óbvio", "aparente", agora estamos falando sobre a complexidade de Kolmogorov, e não vou tentar fazer isso com precisão. Mas irei até o ponto de fazer a afirmação esperançosamente incontroversa de que, por essa medida, "01100110 ..." (período = 4) é pior que "01010101 ..." (período = 2) que é pior que " 00000000 ... "(constante).
Agora, pode-se adivinhar que (1) e (2) seguirão a mesma tendência que (0), e que, portanto, a conclusão "XOR não pode prejudicar" ainda pode se manter. No entanto, observe a possibilidade significativa de que nem nem foram observáveis não aleatórios, mas que as correlações entre eles fazem com que sejam observáveis não aleatórios. O caso mais grave disso, é claro, é quando (ou ); nesse caso, é constante, o pior de todos os resultados possíveis; em geral, é fácil ver isso, independentemente de quão bom e sejam,X⃗ Y⃗ X⃗ ⊕Y⃗ X⃗ =Y⃗ X⃗ =not(Y⃗ )X⃗ ⊕Y⃗ X⃗ Y⃗ X⃗ e precisa estar "próximo" do independente para que seu xor seja não-notavelmente não-aleatório. De fato, ser não-observável-dependente pode ser razoavelmente definido como sendo não-observável-não-aleatório.Y⃗ X⃗ ⊕Y⃗
Essa dependência surpresa acaba sendo um grande problema.
Um exemplo do que dá errado
A pergunta afirma: "Estou excluindo o exemplo comum de vários registros de troca de feedback linear trabalhando juntos, pois são da mesma família". Mas vou excluir essa exclusão por enquanto, para dar um exemplo claro e simples da vida real do tipo de coisa que pode dar errado com o XORing.
Meu exemplo será uma implementação antiga de rand () que estava em alguma versão do Unix por volta de 1983. IIRC, essa implementação da função rand () tinha as seguintes propriedades:
- o valor de cada chamada para rand () era de 15 bits pseudo-aleatórios, ou seja, um número inteiro no intervalo [0, 32767).
- valores de retorno sucessivos alternados par-ímpar-ímpar-par; ou seja, o bit menos significativo alternado 0-1-0-1 ...
- o bit do menos para o menos significativo teve o período 4, o seguinte depois do período 8, ... então o bit de ordem mais alta teve o período .215
- portanto, a sequência dos valores de retorno de 15 bits de rand () era periódica com o período .215
Eu fui incapaz de localizar o código-fonte original, mas eu estou supondo que a partir de juntar um par de mensagens de em https://groups.google.com/forum/#!topic/comp.os.vms/9k4W6KrRV3A que fez exatamente o seguinte (código C), que concorda com a minha memória das propriedades acima:
#define RAND_MAX 32767
static unsigned int next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return (next & RAND_MAX);
}
void srand(seed)
unsigned int seed;
{
next = seed;
}
Como se pode imaginar, tentar usar esse rand () de várias maneiras levou a uma variedade de decepções.
Por exemplo, em um ponto, tentei simular uma sequência de lançamentos aleatórios de moedas, repetidamente:
rand() & 1
ou seja, o bit menos significativo. O resultado foi simples alternância cara-coroa-cara-coroa. Isso foi difícil de acreditar no começo (deve ser um bug no meu programa!), Mas depois que me convenci de que era verdade, tentei usar o próximo bit menos significativo. Isso não é muito melhor, como observado anteriormente - esse bit é periódico com o período 4. Continuando a explorar bits sucessivamente mais altos, revelou o padrão que observei anteriormente: ou seja, cada próximo bit de ordem superior tinha o dobro do período do anterior. Nesse aspecto, o bit de mais alta ordem foi o mais útil de todos eles. Observe, no entanto, que não havia um limite em preto e branco "o bit é útil, o bit não é útil" aqui; tudo o que podemos dizer é que as posições de bits numeradas tinham graus variados de utilidade / inutilidade.ii−1
Eu também tentei coisas como embaralhar os resultados ainda mais, ou juntar valores retornados de várias chamadas para rand (). XORing pares de valores sucessivos de rand () foi um desastre, é claro - resultou em todos os números ímpares! Para meus propósitos (ou seja, produzir uma sequência "aparentemente aleatória" de troca de moedas), o resultado de paridade constante do XOR foi ainda pior do que o comportamento alternativo par e ímpar do original.
Uma leve variação coloca isso na estrutura original: ou seja, seja a sequência de valores de 15 bits retornados por rand () com uma determinada semente e a sequência de uma semente diferente . Novamente, será uma sequência de números pares ou ímpares, o que é pior que o comportamento par / ímpar alternativo original.X⃗ sXY⃗ sYX⃗ ⊕Y⃗
Em outras palavras, este é um exemplo em que o XOR piorou as coisas no sentido de (1) e (2), por qualquer interpretação razoável. Também é pior de várias outras maneiras:
- (3) O bit menos significativo do XOR é obviamente tendencioso, ou seja, possui frequências desiguais de 0 e 1, diferente de qualquer posição de bit numerada em qualquer uma das entradas que são todas imparciais.
- (4) De fato, para cada posição de bit, existem pares de sementes para os quais essa posição de bit é tendenciosa no resultado XOR, e para cada par de sementes, existem (pelo menos 5) posições de bit tendenciosas no XOR resultado.
- (5) O período de toda a sequência de valores de 15 bits no resultado XOR é 1 ou , comparado a para os originais. 2 15214215
Nenhum de (3), (4), (5) é óbvio, mas todos são facilmente verificáveis.
Finalmente, vamos considerar a reintrodução da proibição de PRNGs da mesma família. O problema aqui, eu acho, é que nunca fica realmente claro se dois PRNGs são "da mesma família", até / a menos que alguém comece a usar o XOR e observe (ou um invasor perceba) que as coisas pioraram no sentido de (1) e (2), ou seja, até que padrões não aleatórios na saída ultrapassem o limite de não notado para notado / embaraçoso / desastroso, e nesse ponto é tarde demais.
Estou alarmado com outras respostas aqui que dão conselhos não qualificados "O XOR não pode prejudicar" com base em medidas teóricas que me parecem fazer um péssimo trabalho de modelar o que a maioria das pessoas considera "bom" e "ruim" sobre PRNGs na vida real. Esse conselho é contradito por exemplos claros e flagrantes nos quais o XOR piora as coisas, como o exemplo rand () dado acima. Embora seja concebível que PRNGs relativamente "fortes" possam exibir consistentemente o comportamento oposto ao XOR em relação ao PRNG de brinquedo que era rand (), tornando o XOR uma boa idéia para eles, não vi nenhuma evidência nessa direção, teórica ou empírico, então não me parece razoável supor que isso aconteça.
Pessoalmente, tendo sido mordido de surpresa por XORing rand () na minha juventude e por inúmeras outras correlações de surpresa ao longo da minha vida, tenho poucas razões para pensar que o resultado será diferente se eu tentar táticas semelhantes novamente. É por isso que eu, pessoalmente, ficaria muito relutante em reunir vários PRNGs com XOR, a menos que análises e verificações muito extensas tenham sido feitas para me dar alguma confiança de que talvez seja seguro fazê-lo para os RNGs em questão. Como uma cura potencial para quando eu tenho pouca confiança em um ou mais PRNGs individuais, é improvável que o XORing os aumente minha confiança, portanto, é improvável que eu o use para esse fim. Imagino que a resposta para sua pergunta é que esse é um sentimento amplamente aceito.