// // This source code is property of the Computer Graphics and Visualization // chair of the TU Dresden. Do not distribute! // Copyright (C) 2015-2017 CGV TU Dresden - All Rights Reserved // #pragma once #include #include #include /* Usage: //C++0x Random Engine Mersenne Twister std::mt19937 eng; //a set data structure with amortize constant time insertion, removal, and uniform random sampling from its elements sample_set my_set; my_set.reserve(3); my_set.insert(1); my_set.insert(2); my_set.insert(6); int rand_elem1 = my_set.sample(eng);//1,2 or 6 my_set.remove(2); int rand_elem2 = my_set.sample(eng); //1 or 6 */ template struct sample_set { typedef int element_index; std::vector elements; std::unordered_map index_lut; //create empty set sample_set(){} //reserve memory for n elements void reserve(size_t n) { elements.reserve(n); index_lut.rehash(n); } //insert element elem into set void insert(const T& elem) { //guard against duplicates if (index_lut.find(elem) == index_lut.end()) { element_index idx = (element_index)elements.size(); elements.push_back(elem); index_lut[elem]=idx; } } //remove element elem from set bool remove(const T& elem) { auto it = index_lut.find(elem); if(it == index_lut.end()) { return false; } int i = it->second; std::swap(elements[i],elements.back()); elements.pop_back(); index_lut.erase(it); if(unsigned(i) < elements.size()) { index_lut[elements[i]]=i; } return true; } //draw a sample from set template const T& sample(Engine& eng) { int b = (element_index)(elements.size()-1); std::uniform_int_distribution uniform_dist(0,b); element_index idx = uniform_dist(eng); return elements[idx]; } //returns number of elements in set size_t size() const { return elements.size(); } //returns true if set is empty bool empty() const { return elements.empty(); } };