2011-12-16 3 views
6

Tôi muốn tạo ra một số ngẫu nhiên giữa 0 và 3 và tôi đã sau trong mã của tôi:thay đổi khả năng nhận được một số ngẫu nhiên

int random = rand() % 4; 

này hoạt động tốt nhưng tôi muốn nó để tạo ra 1, 2, và 3 phần lớn thời gian và 0 chỉ thỉnh thoảng.

Cách tốt nhất để giải quyết vấn đề này là gì? Tên thuật toán phổ biến để giải quyết vấn đề này là gì?

+0

Đó không phải là số ngẫu nhiên. Đó là một phân bố xác suất, đó là loại đối diện của ngẫu nhiên (khả năng dự đoán là khủng khiếp khi bạn đang nói về một RNG). –

Trả lời

15

Đây là một cách. Giả sử bạn muốn 0, 1, 2, 3 để phân phối 5%, 20%, 30%, 45%.
Bạn có thể làm điều đó như thế này:

double val = (double)rand()/RAND_MAX; 

int random; 
if (val < 0.05)  // 5% 
    random = 0; 
else if (val < 0.25) // 5% + 20% 
    random = 1; 
else if (val < 0.55) // 5% + 20% + 30% 
    random = 2; 
else 
    random = 3; 

Tất nhiên nó không phải được thực hiện với dấu chấm động. Tôi chỉ làm theo cách này vì nó trực quan hơn.

+0

Đối với những gì nó có giá trị, đây là phương pháp tôi thực sự sử dụng khi tôi cần phải đối phó với xác suất. –

0

bạn đã thử nghiệm bao nhiêu số này? nếu nó thực sự đúng, bạn có thể tạo ra một phạm vi từ 0-> 3999 bằng cách sử dụng a = rand()%4000 và sử dụng int = a/1000 điều này sẽ loại bỏ trọng lượng của dường như dưới không được tạo ra.

+1

Tôi nghĩ bạn hiểu nhầm câu hỏi khi hỏi ngược lại câu hỏi đó là gì. OP nói rằng 'rand()% 4' phân phối đồng đều các số, nhưng (các) số đó muốn số không xuất hiện ít thường xuyên hơn. – ruakh

+1

Tôi nghĩ OP * muốn * số không được sản xuất. Nó không phải là một quan sát, đó là một yêu cầu. –

+0

ah xấu của tôi bằng cách nào đó tôi đã bỏ lỡ những từ 'Tôi muốn' trong câu đó – smitec

0

Tôi sẽ chỉ ánh xạ nhiều giá trị hơn 1,2,3 từ tập hợp lớn hơn. Ví dụ: 9 và bản đồ 1,2,3 => 1, 3,4,5 => 2, 6,7,8 => 3 và 0 cho số không. Có nhiều cách khác, nhưng tôi đang làm việc trong câu hỏi của bạn

0

Chỉ cần mã chính xác những gì bạn muốn:

int myrand(void) 
{ 
    const int percentZero = 10; 
    if ((rand()%100) < percentZero) return 0; 
    return 1 + (rand() % 3); 
} 

Bạn có thể thay đổi phần trăm của thời gian không được trả lại cho bất cứ điều gì bạn muốn.

1

Bạn không đưa ra tỷ lệ chính xác, nhưng giả sử bạn muốn 1, 2 và 3 cho mỗi xảy ra 32% thời gian và 0 để xảy ra 4% còn lại. Sau đó, bạn có thể viết:

int random = rand() % 25; 
if(random > 0) 
    random = random % 3 + 1; 

(Rõ ràng là bạn cần phải điều chỉnh mà cho tỷ lệ khác nhau Và trên chỉ là một cách tiếp cận; nhiều cách tiếp cận tương tự có thể làm việc..)

0

Bạn cần phải tìm một xác suất phân phối phù hợp với trường hợp của bạn. Vì bạn đang chỉ nói về những con số 0-3 này là khá dễ dàng, bạn có thể hoặc gọi rand() một lần nữa nếu kết quả đầu tiên là 0, hoặc bạn có thể sử dụng trọng lượng:

int random = rand() % 16; 

if(random > 10) 
{ 
    random = 3; 
} 
else if(random > 5) 
{ 
    random = 2; 
} 
else if(random > 0) 
{ 
random = 1; 
} 

Đây không phải là một đặc biệt thanh lịch, nhưng hy vọng nó cho bạn thấy làm thế nào bạn có thể tạo ra một phân phối tùy chỉnh để phù hợp với nhu cầu của bạn.

6

Bạn có thể sử dụng lớp phân bổ riêng biệt từ thư viện ngẫu nhiên.

#include <iostream> 
#include <random> 
#include <ctime> 

int main() 
{ 
    std::discrete_distribution<> dist({ 1.0, 4.0, 4.0, 4.0 }); 
    std::mt19937 eng(std::time(0)); 
    for (int i=0; i<100; ++i) 
     std::cout << dist(eng); 
} 

Demo: http://ideone.com/z8bq4

Nếu bạn không thể sử dụng C++ 11, các lớp này cũng tồn tại trong tăng.