减少每次通过的随机统一int分布

时间:2016-04-10 23:54:48

标签: c++ random set uniform-distribution

处理块大小为256个元素的类。每次我存储任何东西之前调用我的add函数;我想在[0,255]的范围内生成一个统一的随机int。我想要做的是在此函数完成之前跟踪之前使用的值,以便下次通过函数时,uniform random int distribution将自动跳过这些值,而不必检查是否已经包含某些内容。

template<class T>
class SomeClass {
     struct Node {
         unsigned idx;
         std::shared_ptr<T> pT;

         Node() : idx(-1), pT(nullptr) {}
         Node( unsigned idx_, std::shared_ptr<T>& pT_ ) : idx(idx_), pT(pT_) {}
    }; // Node

private:
     Node m_storage[256];
     static unsigned m_elementCount;
     std::set<unsigned> m_indexesUsed; 
public:
    SomeClass(){}
    ~SomeClass(){}

    void add( T& obj );
}; // SomeClass

template<class T>
unsigned SomeClass<T>::m_elementCount = 0;    

template<class T>
void SomeClass<T>::add( T& obj ) {

    if ( m_elementCount == 256 ) {
        return; // My Code Base Is Bigger - If This Is Full This Array gets pushed into a vector, 
        // and all values get reset to default and we start over.
    }
    Node n;

    // Generate Uniform Random In Distribution In The Range of [0,255]
    // Excluding the Values from m_listIndexesUsed.
    n.idx =  std::uniform_random_int_distribution from [0,255] excluding previous selected numbers
    n.pT = std::make_shared<T>( obj );
    m_storage[n.idx] = n;
    m_indexesUsed.insert( n.idx );
    m_elementCount++;
}

可以确定一个指定范围之间的值我的情况[0,255]是否会在每次连续调用中确定另一个随机值,该随机值之前已经选择了均匀的随机int分布?如果是这样,将如何做?

修改

在考虑下面的一些评论之后,他们提出了一个很好的观点。在我的情况下真正需要的是一组256个唯一键值,范围从0到255,它们需要随机混洗或加扰。我会考虑如何尝试实现这一点,但如果有人愿意得到一个很好的例子,那是可以接受的。我不介意投入工作,但有时当我达到一个我似乎无法过去并且开始花费太多时间的时候,我只是想超越这一点所以我可以继续前进。

1 个答案:

答案 0 :(得分:0)

我们有一个标准算法来重排序列;它被称为shuffle。因此,制作一个0 ... 255的序列,将其洗牌,然后从结果列表中取出,直到耗尽它,然后重复。如果需要,将整个事物包装到类模板中:

template<size_t N>
struct index_generator {

    // seeding method for illustration purposes only
    // see http://www.pcg-random.org/posts/cpp-seeding-surprises.html
    index_generator() : rng(std::random_device()()) {
        std::iota(indices.begin(), indices.end(), size_t{});
        reset(); 
    }

    explicit operator bool() const { return current < N; }

    // use [] if you don't need the bounds checking
    size_t operator()() { return indices.at(current++); }

    void reset() {
        std::shuffle(indices.begin(), indices.end(), rng);
        current = 0;
    }
private:
    std::array<size_t, N> indices;
    size_t current;
    std::mt19937 rng;
};

用法与

一致
index_generator<256> gen; // static(?) data member

// ...
if ( !gen ) {
    // we've exhausted the 256 indices
    // do whatever you need to do
    gen.reset();
    return;
}

Node n;
n.idx =  gen();
// other stuff