2013-04-09 45 views
5

Tôi đã viết lớp sau để tạo các số nguyên ngẫu nhiên từ một khoảng thời gian nhất định [lower, upper].Tạo các số nguyên giả ngẫu nhiên từ một khoảng thời gian thay đổi hiệu quả

class RandomInteger { 

protected: 

    std::random_device randomDevice; 
    std::default_random_engine randomEngine; 
    std::uniform_int_distribution<> distribution; 

public: 

    RandomInteger(int64_t lower, int64_t upper); 

    virtual ~RandomInteger(); 

    virtual int64_t generate(); 
}; 


RandomInteger::RandomInteger(int64_t lower, int64_t upper) : randomEngine(this->randomDevice()), distribution(lower, upper) { 
} 

RandomInteger::~RandomInteger() { 
    // TODO Auto-generated destructor stub 
} 

int64_t RandomInteger::generate() { 
    int64_t i = this->distribution(this->randomEngine); 
    return i; 
} 

Điều này là ổn nếu khoảng thời gian vẫn giữ nguyên và nhiều cuộc gọi đến generate được thực hiện. Tuy nhiên, bây giờ trường hợp sử dụng của tôi là tạo ra các số nguyên từ một khoảng thời gian luôn luôn thay đổi (giới hạn trên tăng lên mỗi lần).

Đầu tiên và quan trọng nhất, điều này cần phải nhanh chóng. Điều này không liên quan gì tới mật mã nên các số giả ngẫu nhiên đều không sao (và có lẽ không cần đến số std::random_device). Tôi cũng muốn tránh phong cách C nếu có thể và sử dụng kiểu C++ 11 hiện đại.

Bạn có thể đề xuất các cách để thực hiện điều này một cách hiệu quả không?

+2

Việc thay đổi phân phối không đủ hiệu quả? 'uniform_int_distribution' là một trình bao bọc rất mỏng, không có bất kỳ chi phí đáng kể nào. Ngoài ra, tại sao các hàm trong lớp của bạn là 'virtual'? –

+0

@KonradRudolph Họ không cần phải ảo. Sẽ làm cho họ không kết quả ảo ở tốc độ đáng kể ở đây? Tôi đã học được rằng chi phí cho các cuộc gọi phương thức ảo là rất thấp. Đó là một tình huống kỳ lạ: C++ tuyên bố là một ngôn ngữ OOP. OOP là rất nhiều về làm cho mã của bạn mở rộng và tái sử dụng trong tương lai. Tuy nhiên, nhiều lập trình viên C++ liên tục khuyên người khác vô hiệu hóa OOP (tức là tạo các phương thức nonvirtual) trừ khi cần thiết ngay bây giờ. – clstaudt

+0

@KonradRudolph "thay đổi phân phối" có nghĩa là tạo một 'std :: uniform_int_distribution' mới với các tham số khác nhau? – clstaudt

Trả lời

2

Sử dụng sự quá tải của uniform_int_distribution::operator() chấp nhận một const param_type &:.

int64_t RandomInteger::generate(int64_t lower, int64_t upper) { 
    int64_t i = this->distribution(this->randomEngine, 
     std::uniform_int_distribution<int64_t>{lower, upper}.param()); 
    return i; 
} 

(Lưu ý rằng bạn nên đánh giá cao-khởi distribution, như bạn không quan tâm đến việc thiết param của nó Ngoài ra, distribution nên templated với int64_t, không phải int.)

Nếu uniform_int_distribution giữ nguyên trạng thái, thì điều này sẽ sử dụng hiệu quả.

Thực tế, hầu hết các lần triển khai uniform_int_distribution không giữ lại trạng thái nào; xem ví dụ libstdC++ random.tcc: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01001_source.html#l00832

Các vấn đề liên quan