Próbuję realizować następujące klasy:Z czego składa się losowa dystrybucja C++ 11?
typedef std::mt19937 Engine;
class Interval
{
public:
double upperBoundary;
double lowerBoundary;
double generateUniformRandomNumber(Engine& engine);
};
chcę klasa do pracy w środowisku wielowątkowym. Każdy wątek będzie miał własną instancję obiektu Engine
i przekaże Engine
obiektom dowolnej klasy, która ma losowe zachowanie.
W celu wygenerowania liczb losowych jednostajnie na C++ 11 sposób, realizacja generateUniformRandomNumber
musiałoby być coś takiego:
uniform_real_distribution<double> distribution_; // private member of Interval
double Interval::generateUniformRandomNumber(Engine& engine)
{
return distribution_(engine);
}
Problemem jest to, że nie rozumiem, C++ 11 dystrybucje. Wiem, że silniki liczb losowych C++ 11 mogą być bardzo dużymi obiektami (kilka kilobajtów), ale co z dystrybucjami? Początkowo myślałem, że dystrybucje są po prostu prostymi funktorami, gdzie operator()
jest funkcją pure const
, ale wydaje się, że nie jest to ani pure
ani const
. Zgodnie z reference każda instancja dystrybucji ma funkcję składową reset()
. Oznacza to, że ma potencjalnie duży wewnętrzny stan, a może pamięć podręczną.
Moje pytanie brzmi:
Czy dystrybucje mają stan wewnętrzny? Jeśli tak, dlaczego? Czy standard mówi cokolwiek o wielkości tego stanu?
Czy to dobry pomysł, aby wykonać wdrożenie tak jak ja? Czy istnieje lepszy sposób?
Jako przykład zaimplementowałem [wersję beta] (https://gist.github.com/sftrabbit/5068941), której stan to właściwie dwie dystrybucje gamma. 'reset' nic nie robi, ponieważ jedynym wymaganiem jest, aby jakiekolwiek poniższe wartości były niezależne od poprzednich zastosowań silników. –
@sftrabbit Tak więc jest 'reset()' na wypadek, gdyby ktoś dokonał dystrybucji, która kumuluje stan, gdy wywołasz 'operator()'? Na przykład każde kolejne wywołanie 'operator()' może dać ci zwiększający się zakres ... co również tłumaczy, dlaczego 'operator()' nie jest const, jak sądzę? – David
@Dave Tak, nie ma powodu, aby dystrybucja nie mogła się zmienić w trakcie wywoływania 'operator()'. Oznacza to tylko, że wynikowe wartości zależą od poprzednich inwokacji. –