pub fn par_iter_shuffled_range<Item>(
    range: Range<Item>
) -> impl ParallelIterator<Item = <Range<Item> as IntoParallelIterator>::Item>where
    Range<Item>: ExactSizeIterator + IntoParallelIterator,
    usize: Add<Item, Output = Item>,
    Item: Ord + Sync + Send + Copy,
Expand description

Returns a parallel iterator on the range where items are pseudo-shuffled

When running an operation on all nodes of the graph, the naive approach is to use (0..graph.num_nodes()).into_par_iter().map(f).

However, nodes are not uniformly distributed over the range of ids, meaning that some sections of the range of ids can be harder for f than others. This can be an issue when some instances are harder than others, or simply because it makes ETAs unreliable.

Instead, this function returns the same set of nodes as the naive approach would, but in a somewhat-random order.

Example

use rayon::prelude::*;
use swh_graph::utils::shuffle::par_iter_shuffled_range;

let mut integers: Vec<usize> = par_iter_shuffled_range(0..10000).collect();
assert_ne!(integers, (0..10000).collect::<Vec<_>>(), "integers are still sorted");
integers.sort();
assert_eq!(integers, (0..10000).collect::<Vec<_>>(), "integers do not match the input range");