Estou criando um conjunto de dados pseudo-aleatórios para os usuários do aplicativo treinarem.
Estou surpreso que se eu semear a função RAND() com 1, 2, 3, etc., recebo quase o mesmo resultado da função propagada. No entanto, isso parece ser seguido por valores "apropriadamente aleatórios", mas repetíveis, quando uma semente não é fornecida.
SELECT RAND(1) AS R1A, RAND() AS R1B, RAND(2) AS R2A, RAND() AS R2B,
RAND(3) AS R3A, RAND() AS R3B, RAND(4) AS R4A, RAND() AS R4B
0.713591993212924
0.472241415009636
0.713610626184182
0.217821139260039
0.71362925915544
0.963400850719992
0.713647892126698
0.708980575436056
À primeira vista, parece que posso avaliar RAND(@seed) e descartar o resultado, depois avaliar RAND() para obter vários números realmente "aleatórios" para meus dados de treinamento - até agora planejei usar quatro por registro; Eu posso precisar de um pouco mais.
Esse plano vai funcionar corretamente? E, o que estou olhando, aqui? E, deveria estar na documentação? Eu não encontrei.
A documentação diz isso, o que pode ser uma pista:
A função RAND é um gerador de números pseudoaleatórios que opera de maneira semelhante à função rand da biblioteca de tempo de execução C. Se nenhuma semente for fornecida, o sistema gerará seus próprios números de semente variáveis.
A função rand em C produz saída semelhante para entrada de semente semelhante?
Eu acho que a documentação também poderia declarar mais claramente que RAND(@number) seguido por RAND() sempre gera os mesmos números. Mas era isso que eu queria e o que qualquer programador de computador experiente espera.
Suponho que poderia preencher uma tabela com chaves de dados aleatórias obtidas em https://www.random.org/ para usar com esse propósito - mas isso tem desvantagens.
Atualização, conclusão provisória
Tenho as seguintes conclusões sobre RAND() e por enquanto acho que vou continuar com isso, mas mantendo as alternativas em mente.
RAND(@int) define a semente do gerador de números aleatórios usando o valor inteiro fornecido e retorna um resultado float que não é estatisticamente independente, visto que RAND(@int) e RAND(@int+1) produzem quase exatamente o mesmo resultado.
Claro, RAND(@int) sempre produz o mesmo resultado.
RAND(-@int) e RAND(@int) produzem o mesmo resultado.
RAND(0) é uma exceção: pode haver outras exceções. RAND(0) sempre produz o resultado 0,943597390424144, mas não é semelhante ao resultado de RAND(1).
RAND() chamado n vezes depois de RAND(@int) sempre produz os mesmos n números. Se chamarmos o enésimo número "rand(@int, @n)" -
CREATE PROCEDURE sproc_rand(@seed int, @nth int, @rand float OUTPUT) AS
SET @rand = RAND(@seed);
WHILE ( @nth > 0 ) BEGIN SET @rand = RAND(); SET @nth = @nth - 1; END
A diferença entre rand(@int, @n) e rand(@int+1, @n) "módulo 1" -
(1.0 + rand(@int, @n) - rand(@int+1, @n) % 1
É uma constante ou quase constante; para @n = 1 é aproximadamente 0,75. Para @n = 5 é 0,991. Para @n = 6 é 0,91. Para @n = 100 é 0,83.
Portanto, não, esses não são bons números "aleatórios" quando uma semente incrementada simples é usada - embora eles saltem muito bem para @n IN (1, 2, 3, 4).
O que estou considerando agora como mitigação é não usar RAND(row_id), mas,
RAND(row_id * @factor_1 + @factor_2)
onde @factor1 e @factor2 são termos constantes e @factor_1 é aproximadamente 10.000. E para projetos diferentes, fatores diferentes.
Até agora, se eu quiser resultados repetíveis, o outro método disponível (além do Inverso Multiplicativo, que eu ainda não entendi) é criar uma tabela e preenchê-la com números aleatórios não repetidos de um dos outros métodos, em seguida, desenhe os números dessa tabela, quando necessário.