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