Skip to content

Instantly share code, notes, and snippets.

@sergeant-wizard
Created March 12, 2015 00:58
Show Gist options
  • Save sergeant-wizard/f2727161d38805734e25 to your computer and use it in GitHub Desktop.
Save sergeant-wizard/f2727161d38805734e25 to your computer and use it in GitHub Desktop.
Weighted Probability Lottery
double throwDice() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0, 1);
return dis(gen);
}
template<class T>
typename std::vector<T>::const_iterator lottery(
const std::vector<T>& list,
std::function<double(const T&)> probabilityAccessor)
{
double denominator = 0;
for (const auto& element : list) {
denominator += probabilityAccessor(element);
}
double dice = throwDice();
double probabilitySum = 0;
for (auto element = list.begin(); element != list.end(); ++element) {
probabilitySum += probabilityAccessor(*element) / denominator;
if (probabilitySum > dice)
return element;
}
return list.end();
}
int main() {
struct WeightedElement {
double probability;
int elementIndex;
};
std::vector<WeightedElement> list = {
{0.25, 1},
{0.75, 2},
};
auto result = lottery<WeightedElement>(
list,
[](const WeightedElement& element) {
return element.probability;
});
std::cout << result->elementIndex << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment