thắc mắc random lấy số nth của dẫy số pseudorandom

  • Người tạo chủ đề Người tạo chủ đề tiengdonhoarira
  • Ngày bắt đầu Ngày bắt đầu

tiengdonhoarira

Senior Member
Nếu dùng 1 seed thì số ngẫu nhiên là một dẫy số có thể lặp lại được (không thay đổi)

Mọi người biết cách lấy số nth của một dẫy số pseudorandom không? (dùng c++ thì càng tốt )

Trên stackoverflow thì tìm được bài

https://stackoverflow.com/questions...-a-pseudo-random-number-generator-in-c-that-s
https://stackoverflow.com/questions...-of-rand-directly-without-having-to-call-rand

dùng discard. Và chắc là chậm (Nếu số cần lấy nth là 1.0E+9, thì nó phải skip lâu mối lấy được số )
 
lên chatGPT hỏi cho thím nè
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
int n = 5;
int a = 0;
int b = 100;
srand(time(NULL));
for (int i = 1; i < n; i++) {
rand();
}
cout << rand() % (b - a + 1) + a << endl;
return 0;
}
Trong đoạn code trên, biến n là số thứ tự của số cần lấy (trong ví dụ này là số thứ 5), biến a và b là giới hạn của khoảng giá trị mà bạn muốn lấy số ngẫu nhiên (trong ví dụ này là từ 0 đến 100). Hàm srand(time(NULL)) được sử dụng để khởi tạo seed cho hàm rand() bằng cách sử dụng giá trị của hàm time(NULL) (thời gian hiện tại tính theo giây kể từ ngày 1/1/1970).
 
Nếu dùng 1 seed thì số ngẫu nhiên là một dẫy số có thể lặp lại được (không thay đổi)

Mọi người biết cách lấy số nth của một dẫy số pseudorandom không? (dùng c++ thì càng tốt )

Trên stackoverflow thì tìm được bài

https://stackoverflow.com/questions...-a-pseudo-random-number-generator-in-c-that-s
https://stackoverflow.com/questions...-of-rand-directly-without-having-to-call-rand

dùng discard. Và chắc là chậm (Nếu số cần lấy nth là 1.0E+9, thì nó phải skip lâu mối lấy được số )

Tùy theo thuật toán chứ, như thuật toán mersenne twister có hàm để fast forward đến step nth như thớt yêu cầu.
 
lên chatGPT hỏi cho thím nè
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
int n = 5;
int a = 0;
int b = 100;
srand(time(NULL));
for (int i = 1; i < n; i++) {
rand();
}
cout << rand() % (b - a + 1) + a << endl;
return 0;
}
Trong đoạn code trên, biến n là số thứ tự của số cần lấy (trong ví dụ này là số thứ 5), biến a và b là giới hạn của khoảng giá trị mà bạn muốn lấy số ngẫu nhiên (trong ví dụ này là từ 0 đến 100). Hàm srand(time(NULL)) được sử dụng để khởi tạo seed cho hàm rand() bằng cách sử dụng giá trị của hàm time(NULL) (thời gian hiện tại tính theo giây kể từ ngày 1/1/1970).
cái đoạn này quan trọng nè

for (int i = 1; i < n; i++) {
rand();
}
nó chạy để skip số. như thế nếu lấy số 1.0E+9, nó sẽ phải làm for để skip 1 000 000 000 lần để lấy
 
Tùy theo thuật toán chứ, như thuật toán mersenne twister có hàm để fast forward đến step nth như thớt yêu cầu.

https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine

nó dùng discard để đi qua rồi lấy . giống như câu trả lời trên stackoverflow

Yes, its possible, but it will be horribly slow.
It would involve resetting the generator back to the start with the same seed (probably by recreating it over each time) then calling discard to advance the generator by n. https://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine/discard
 
Như này được k nhỉ:
1. Nếu random nth với seed S, thì tức là random seed S' = f(n, S) rồi lấy số đầu tiên
2. Hoặc là chia khoảng ra và dùng nhiều randomizer?
 
dùng mersenne_twister_engine discard
#include <random>
#include <iostream>
void ranNum( ) {
clock_t t;
t = clock();
std::mt19937 rng;
static const size_t distance = 1.0E+9;

rng.seed(0);
rng.discard(distance);
std::cout << "after discard "<< distance <<": " << rng() << '\n';

t = clock() - t;
std::cout << "\nThis took " << ((float)t)/CLOCKS_PER_SEC << "s\n";
}


int main() {
ranNum();

return 0;
}

after discard 1000000000: 2678885099

This took 3.347s

3.347 s để lấy 1 số . nếu lấy nhiều số, chương trình sẽ chạy rất lâu
 
Sửa lần cuối:
LFSR dùng state, nên để lấy số ở vị trí n, thì nó cần số ở vị trí n-1

https://stackoverflow.com/questions...at-can-generate-nth-number-in-series-in-o1-ti
thử viết dùng CTR , dùng encryption để mã khóa input (một số bất kỳ) ra một số integer
nhưng tạm thời thì thấy CTR dùng inner counter, nên để lấy số ở thứ n, vẫn phải dùng for circle đi đến n-1

mọi người còn phương pháp nào không?
 
Sửa lần cuối:
Sửa lần cuối:
đây là cách tui implement thuật toán random của tui
mã nhị phân => random tới mức nào ví dụ: tui random 1 số trên 2^48 trường hợp thì tương đương generate 1 chuổi nhị phân dài 48 kí tự: tương ứng random 48 lần của 1 hoặc 0 thôi
ví dụ. "01010111011011...."
ở đây thì tui sẽ lấy vị trí bit nhớ của ram là chẵn hay lẻ để lấy số là 0 hay 1
ví dụ: địa chỉ vùng nhớ của tui là 13 thì nó là số nhị phân là"1"


1. tại sao tui lại lấy vị trí vùng nhớ: vì nó ko random nhưng rất khó quản lí và việc giải phóng ram trên 1 server thì khá là khó kiểm soát và nó vẫn đảm bảo đc tính khá là random theo tiêu chuẩn của tui
2. làm sao để tìm kiếm nhanh 1 số trúng
ví dụ: tui có 1 tập từ 1 đến 10 số và random vẫn dùng 2^48 random của tui thì làm sao xác định 1 người trúng với kiểu dữ liệu của tui khi thuật toán của tui thật sự ko ra 1 trong 10 số đó
 

Thống kê chủ đề

Ngày tạo
tiengdonhoarira,
Người trả lời cuối
xjaoxjao,
Trả lời
13
Lượt xem
1.041
Quay lại
Lên đầu trang