Bạn thân thiết, nhưng vấn đề với câu trả lời của bạn là có nhiều cách viết một số làm tổng của hai số khác.
Nếu m<n
, thì điều này hoạt động vì các số 0,1,...,m-1
xuất hiện từng có xác suất bằng nhau và thuật toán chấm dứt gần như chắc chắn.
Câu trả lời này không có tác dụng nói chung vì có nhiều cách viết một số làm tổng của hai số khác. Ví dụ, chỉ có một cách để có được 0
nhưng có rất nhiều cách để có được m/2
, vì vậy xác suất sẽ không bằng nhau.
Ví dụ: n = 2
và m=3
0 = 0+0
1 = 1+0 or 0+1
2 = 1+1
nên phân bố xác suất từ phương pháp của bạn là
P(0)=1/4
P(1)=1/2
P(2)=1/4
mà không phải là thống nhất.
Để khắc phục điều này, bạn có thể sử dụng hệ số duy nhất. Viết m
trong cơ sở n
, theo dõi số mũ cần thiết lớn nhất, nói e
. Sau đó, tìm bội số lớn nhất của m
nhỏ hơn n^e
, gọi số đó là k
. Cuối cùng, tạo số e
với randn()
, lấy chúng làm cơ sở n
mở rộng một số số x
, nếu x < k*m
, trả lại x
, nếu không hãy thử lại.
Giả sử rằng m < n^2
, sau đó
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);
}
}
Bạn có thêm thông tin nào về 'n' và' m' không? – PengOne
Một phần của câu hỏi là những gì tôi cần phải giả định về n và m để thực hiện công việc này, nhưng tôi nghĩ rằng nó hoạt động cho bất kỳ số nào. – WisaF
Bạn giả định một số điều về n, m: 1) cả hai là số nguyên, 2) cả hai đều dương là – RHSeeger