Estás cerca, pero el problema con tu respuesta es que hay más de una forma de escribir un número como suma de otros dos números.
Si m<n
, entonces esto funciona porque los números 0,1,...,m-1
aparecen con la misma probabilidad, y el algoritmo termina casi seguramente.
Esta respuesta no funciona en general porque hay más de una forma de escribir un número como suma de otros dos números. Por ejemplo, solo hay una forma de obtener 0
, pero hay muchas maneras de obtener m/2
, por lo que las probabilidades no serán iguales.
Ejemplo: n = 2
y m=3
0 = 0+0
1 = 1+0 or 0+1
2 = 1+1
por lo que la distribución de probabilidad de su método es
P(0)=1/4
P(1)=1/2
P(2)=1/4
que no es uniforme.
Para solucionar esto, puede utilizar factorización única. Escriba m
en la base n
, siguiendo el mayor exponente necesario, digamos e
. Luego, encuentre el mayor múltiplo de m
que sea menor que n^e
, llámelo k
. Finalmente, genere e
números con randn()
, tómelos como la expansión base n
de algún número x
, si x < k*m
, devuelva x
, de lo contrario intente de nuevo.
Suponiendo que m < n^2
, entonces
int randm() {
// find largest power of n needed to write m in base n
int e=0;
while (m > n^e) {
++e;
}
// find largest multiple of m less than n^e
int k=1;
while (k*m < n^2) {
++k
}
--k; // we went one too far
while (1) {
// generate a random number in base n
int x = 0;
for (int i=0; i<e; ++i) {
x = x*n + randn();
}
// if x isn't too large, return it x modulo m
if (x < m*k)
return (x % m);
}
}
¿Usted tiene alguna información adicional sobre 'n' y' m'? – PengOne
Parte de la pregunta era qué debo asumir sobre nym para hacer que esto funcione, pero creo que funciona para cualquier número. – WisaF
Estás asumiendo una cantidad de cosas sobre n, m: 1) ambos son enteros, 2) ambos son positivos – RHSeeger