Skip to main content

random_hash_maps

Function random_hash_maps 

Source
pub fn random_hash_maps<I: Iterator, J: Iterator>(
    seed: Seed,
    keys_gen: &dyn Fn(Seed) -> I,
    values_gen: &dyn Fn(Seed) -> J,
    mean_size_numerator: u64,
    mean_size_denominator: u64,
) -> RandomHashMaps<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J> ⓘ
where I::Item: Eq + Hash,
Expand description

Generates random HashMaps with keys from one iterator and values from another.

The sizes of the maps are sampled from a geometric distribution with a specified mean $m$, equal to mean_size_numerator / mean_size_denominator. $m$ must be greater than 0.

The key iterator must generate at least as many distinct elements as any size that is requested; otherwise, this iterator will hang. The value iterator has no such requirement, since values may repeat.

$$ P(\{(k_i, v_i)\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i). $$

The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$ counts the orders in which the keys can be drawn; the values are drawn in the same order, so each key order pairs with exactly one value order that produces the map.

keys_gen and values_gen must produce infinite iterators.

§Expected complexity per iteration

$T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$

$M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$

where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and $M^\prime$ are the time and memory functions of the iterators produced by keys_gen, $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by values_gen, and $m$ is the mean size.

§Panics

Panics if mean_size_numerator or mean_size_denominator are zero, or, if after being reduced to lowest terms, their sum is greater than or equal to $2^{64}$.

§Examples

use itertools::Itertools;
use malachite_base::bools::random::random_bools;
use malachite_base::maps::random::random_hash_maps;
use malachite_base::num::random::random_unsigned_inclusive_range;
use malachite_base::random::EXAMPLE_SEED;
use maplit::hashmap;

let xs = random_hash_maps(
    EXAMPLE_SEED,
    &|seed| random_unsigned_inclusive_range::<u32>(seed, 1, 100),
    &random_bools,
    1,
    1,
);
let values = xs.take(20).collect_vec();
assert_eq!(
    values,
    &[
        hashmap! {},
        hashmap! {},
        hashmap! {33 => false, 78 => true, 80 => false, 82 => false},
        hashmap! {},
        hashmap! {40 => true, 49 => false},
        hashmap! {33 => false, 64 => false},
        hashmap! {88 => false},
        hashmap! {43 => false, 100 => false},
        hashmap! {},
        hashmap! {},
        hashmap! {},
        hashmap! {},
        hashmap! {70 => false},
        hashmap! {},
        hashmap! {6 => false, 74 => true},
        hashmap! {94 => false},
        hashmap! {},
        hashmap! {79 => false},
        hashmap! {},
        hashmap! {18 => false, 34 => false}
    ]
);