2013-09-26 66 views
19

Vì vậy, tôi có một đối tượng ngẫu nhiên:Vary loạt các uniform_int_distribution

typedef unsigned int uint32; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 

private: 
    uint32 DrawNumber(); 
    std::mt19937 eng{std::random_device{}()}; 
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX}; 
}; 

uint32 Random::DrawNumber() 
{ 
    return uniform_dist(eng); 
} 

cách tốt nhất mà tôi có thể thay đổi là gì (thông qua chức năng khác hay cách khác) trên ràng buộc của sự phân bố?

(cũng sẵn sàng tư vấn về các vấn đề kiểu khác)

+0

Bạn không thể thay đổi giới hạn của 'phân phối' sau lần khởi tạo đầu tiên. Làm thế nào bạn nên tiến hành phụ thuộc rất nhiều vào những gì bạn sử dụng số ngẫu nhiên của bạn cho và tại sao bạn cần phải thay đổi giới hạn. – us2012

Trả lời

32

Đối tượng phân phối có trọng lượng nhẹ. Chỉ cần xây dựng một bản phân phối mới khi bạn cần một số ngẫu nhiên. Tôi sử dụng cách tiếp cận này trong một công cụ trò chơi, và, sau khi điểm chuẩn, nó có thể so sánh với việc sử dụng cũ rand(). Ngoài ra, tôi đã hỏi làm thế nào để thay đổi phạm vi phân phối trên luồng trực tiếp GoingNative 2013 và Stephen T. Lavavej, một thành viên của ủy ban tiêu chuẩn, đề xuất chỉ cần tạo các bản phân phối mới, vì nó không phải là một vấn đề hiệu suất.

Đây là cách tôi sẽ viết mã của bạn:

using uint32 = unsigned int; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 
    uint32 DrawNumber(uint32 min, uint32 max); 

private:   
    std::mt19937 eng{std::random_device{}()}; 
}; 

uint32 Random::DrawNumber(uint32 min, uint32 max) 
{ 
    return std::uniform_int_distribution<uint32>{min, max}(eng); 
} 
+0

Tôi nghĩ rằng tôi chỉ xem rằng dòng Native Native :) Mặc dù, tôi (một chút) mới với C++ (đặc biệt là C++ 11) và một số tiền hợp lý của nó đã đi qua đầu của tôi: L Nếu bạn chắc chắn mà không có chi phí đáng kể trong việc tạo ra một phân phối mới mỗi lần, tôi có lẽ sẽ đi với điều này – LordAro

+0

Tôi đã đánh giá nó. Overhead là tối thiểu và có thể bỏ qua. (Điều này đang được nói bởi một nazi tối ưu hóa vi mô). Ngoài ra, không có cách nào khác * thay đổi giới hạn của phân phối. –

+0

Ok, tuyệt vời, cảm ơn rất nhiều :) Tôi có thể sẽ đi với hằng số 0 là min và UINT32_MAX làm giá trị mặc định cho CPC – LordAro

5

Tôi đang làm cho DrawNumber chức năng public ví dụ của tôi. Bạn có thể cung cấp tình trạng quá tải có giới hạn trên và sau đó vượt qua một uniform_int_distribution::param_type mới đến uniform_int_distribution::operator()

Có thể xây dựng param_type bằng cùng một đối số với phân phối tương ứng.

Từ N3337, §26.5.1.6/9 [rand.req.dist]

Đối với mỗi nhà thầu của D dùng đối số tương ứng với các thông số của phân phối, P có trách nhiệm một phương thức khởi tạo tương ứng tuân theo các yêu cầu tương tự và lấy đối số giống hệt nhau về số, loại và giá trị mặc định. Hơn nữa, đối với mỗi hàm thành viên của D trả về giá trị tương ứng với tham số của phân phối, P phải có hàm thành viên tương ứng với tên, loại và ngữ nghĩa giống hệt nhau.

nơi D là loại một số ngẫu nhiên đối tượng chức năng phân phối và P là loại được đặt tên bởi D 's liên param_type

#include <iostream> 
#include <random> 

typedef unsigned int uint32; 

class Random { 
public: 
    Random() = default; 
    Random(std::mt19937::result_type seed) : eng(seed) {} 

    uint32 DrawNumber(); 
    uint32 DrawNumber(uint32 ub); 

private: 
    std::mt19937 eng{std::random_device{}()}; 
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX}; 
}; 

uint32 Random::DrawNumber() 
{ 
    return uniform_dist(eng); 
} 

uint32 Random::DrawNumber(uint32 ub) 
{ 
    return uniform_dist(eng, decltype(uniform_dist)::param_type(0, ub)); 
} 

int main() 
{ 
    Random r; 
    std::cout << r.DrawNumber() << std::endl; 
    std::cout << r.DrawNumber(42) << std::endl; 
} 
8

Bạn chỉ có thể tạo ra một std::uniform_int_distribution<uint32>::param_type và sửa đổi phạm vi sử dụng param() phương pháp. Bạn có thể cắt giảm nhiễu mẫu bằng decltype:

decltype(uniform_dist.param()) new_range (0, upper); 
uniform_dist.param(new_range); 
Các vấn đề liên quan