Select random element in an unordered_map

前端 未结 5 1080
北海茫月
北海茫月 2021-02-04 05:50

I define an unordered_map like this:

std::unordered_map edges;

Is there a efficient way to choose a rando

5条回答
  •  被撕碎了的回忆
    2021-02-04 06:39

    Is there a efficient way to choose a random Edge from the unordered_map edges ?

    If by efficient you mean O(1), then no, it is not possible.

    Since the iterators returned by unordered_map::begin / end are ForwardIterators, the approaches that simply use std::advance are O(n) in the number of elements.

    If your specific use allows it, you can trade some randomness for efficiency:

    You can select a random bucket (that can be accessed in O(1)), and then a random element inside that bucket.

    int bucket, bucket_size;
    do
    { 
        bucket = rnd(edges.bucket_count());
    }
    while ( (bucket_size = edges.bucket_size(bucket)) == 0 );
    
    auto element = std::next(edges.begin(bucket), rnd(bucket_size));
    

    Where rnd(n) returns a random number in the [0,n) range.

    In practice if you have a decent hash most of the buckets will contain exactly one element, otherwise this function will slightly privilege the elements that are alone in their buckets.

提交回复
热议问题