generating random tuples in python

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Apr 21 03:53:29 EDT 2009


On Mon, 20 Apr 2009 21:04:25 -0700, per wrote:

> i realize my example in the original post was misleading. i dont want to
> maximize the difference between individual members of a single tuple --
> i want to maximize the difference between distinct tuples. in other
> words, it's ok to have (.332, .334, .38), as long as the other tuple is,
> say, (.52, .6, .9) which is very difference from (.332, . 334, .38).  i
> want the member of a given tuple to be arbitrary, e.g. something like
> (rand(), rand(), rand()) but that the tuples be very different from each
> other.
> 
> to be more formal by very different, i would be happy if they were
> maximally distant in ordinary euclidean space... so if you just plot the
> 3-tuples on x, y, z i want them to all be very different from each
> other.  i realize this is obviously biased and that the tuples are not
> uniformly distributed -- that's exactly what i want...


If you *really* mean "maximally distant", the maximal distance in a 1x1x1 
cube is sqrt(3). Clearly you can't move sqrt(3) away in an arbitrary 
direction from an arbitrary point and remain inside the cube, but you 
could probably do something like this:

* generate a random point (a, b, c);
* work out what's the furthest you can go from there and still remain 
inside the cube;
* return that point as the second point.

Problem is that one out of every two points will be on the edge of the 
cube. This will be *seriously* biase, and obviously so.


Here's another strategy: given the first point, generated randomly, 
reflect it around the centre point (0.5, 0.5, 0.5) in some plane to give 
the second point. You'll need to do some geometry to determine what plane 
to use. Disadvantage: the points will have a very strong symmetry.


Third strategy: divide the cube into eight half-cubes. Label then A 
through H:

A: 0.0 <= x <= 0.5, 0.0 <= y <= 0.5, 0.0 <= z <= 0.5
B: 0.5 <  x <= 1.0, 0.0 <= y <= 0.5, 0.0 <= z <= 0.5
C: 0.0 <= x <= 0.5, 0.5 <  y <= 1.0, 0.0 <= z <= 0.5
D: 0.5 <  x <= 1.0, 0.5 <  y <= 1.0, 0.0 <= z <= 0.5

(E, F, G, H are the same but with 0.5 < z <= 1.0)

Generate a point in one half of the cube, A-D. If the point is in A, then 
the second point needs to be in H; if the first point is in B, the second 
should be in G; if the first point is in C, then generate your second 
point in F, and if in D, generate a point in E.

This will give you points which are still random-ish, but on average they 
should be sqrt(3)/2 apart, which is probably about as far as you can 
reasonably expect. There will be some symmetry, *on average*, but 
individual points shouldn't have a mirror image (except by some fluke).



-- 
Steven



More information about the Python-list mailing list