Sensible distributed random seeding

This PR provides support for setting the random seed sensibly over the distributed engines.

Specifically, it provides a client-side `seed()` function, which sends the supplied seed to the generators on each engine, and then (optionally) makes a change to the state on each engine, based on the rank value, so that each engine's generator is in a different state (but still completely determined by the seed and rank).

If a seed of `None` is passed (or the seeding is omitted), then each generator will have a state based on whatever physical randomness the system supplied. This would give each engine a different state, but one not reproducible.

If another seed is passed (anything allowed by the usual `numpy.random.seed` is ok), then this seed is set on each engine. If `make_distinct=True`, the default, then each engine has its state scrambled in a way determined from the rank, so that each engine will be in a deterministic but different state. If a seed is passed, and `make_distinct=False`, then each engine is left in the same state, and so would generate the same sequence of numbers.

Tests for the above claims are included in the PR.

This resolves issue #149.