Jesteś blisko, ale problem z twoją odpowiedzią jest taki, że istnieje więcej niż jeden sposób, aby napisać liczbę jako sumę dwóch innych liczb.
Jeśli m<n
, to działa, ponieważ numery 0,1,...,m-1
pojawiają się z równym prawdopodobieństwem, a algorytm kończy się prawie na pewno.
Ta odpowiedź nie działa ogólnie, ponieważ istnieje więcej niż jeden sposób, aby wpisać liczbę jako sumę dwóch innych liczb. Na przykład istnieje tylko jeden sposób uzyskania 0
, ale istnieje wiele sposobów uzyskania m/2
, więc prawdopodobieństwa nie będą równe.
Przykład: n = 2
i m=3
0 = 0+0
1 = 1+0 or 0+1
2 = 1+1
więc rozkład prawdopodobieństwa od sposobu jest
P(0)=1/4
P(1)=1/2
P(2)=1/4
która nie jest jednolita.
Aby to naprawić, można użyć unikalnej faktoryzacji. Napisz m
w bazie n
, śledząc największy potrzebny wykładnik, na przykład e
. Następnie znajdź największą wielokrotność m
, która jest mniejsza niż n^e
, nazwij ją k
. Na koniec wygeneruj numery e
z randn()
, pobierz je jako rozszerzenie bazy n
o numerze x
, jeśli x < k*m
, zwrócony x
, w przeciwnym razie spróbuj ponownie.
Zakładając, że m < n^2
, następnie
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);
}
}
Czy masz jakieś dodatkowe informacje na temat 'n' i' m'? – PengOne
Częściowe pytanie brzmiało, co muszę założyć, że n i m sprawiają, że to działa, ale myślę, że działa dla dowolnych liczb. – WisaF
Przyjmujesz kilka rzeczy o n, m: 1) obie są liczbami całkowitymi, 2) obie są pozytywne – RHSeeger