6
$\begingroup$

The problem is to generate random points on the plane that are unique (i.e. no repetition of a point). The following won't work because of repetition:

In[86]:= RandomInteger[5, {3, 2}]
Out[86]= {{1, 3}, {3, 5}, {1, 3}}

So RandomSample may be the answer. But something like the following also repeats:

In[94]:= Table[RandomSample[Range[5], 2], {3}]
Out[94]= {{3, 4}, {4, 5}, {3, 4}}

Is there a clever solution to this?

$\endgroup$

3 Answers 3

9
$\begingroup$

Better is

RandomSample[Tuples[Range[5], 2], 3]

Your formula may generate the same point two-times or more

(try, for a counterexample

Table[RandomSample[Range[2], 2], {3}]

)

$\endgroup$
2
  • $\begingroup$ Can you expand on what your method is here? Or what your thought process was? These techniques may be useful for the generation of aperiodic patterning or simulation of cell/material growth processes, and also I find it useful to expand what you’ve done here in terms of these are awesome one-liners, and are very well done :) $\endgroup$ Commented May 17, 2019 at 13:52
  • $\begingroup$ They may be useful, but this procedure is not sophisticated. Range[5] generates the list {1,2,3,4,5}, Tuples[#,2] set of 25 combinations '{{1,1}... {5,5}' and 'RandomSample[#,3]' randomly selects three of them. That's very cumbersome to the simulation. $\endgroup$ Commented May 17, 2019 at 14:32
3
$\begingroup$

Another approach...if you want 10 points in a 3D space, with no repeats of a coordinate in any dimension...

dim = 3;
numPts = 10;
Transpose@(Ordering /@ Ordering /@ RandomReal[1, {dim, numPts}])

$ \begin{array}{ccc} 8 & 6 & 4 \\ 7 & 5 & 8 \\ 2 & 4 & 1 \\ 5 & 8 & 5 \\ 9 & 3 & 2 \\ 10 & 7 & 9 \\ 1 & 2 & 10 \\ 4 & 1 & 7 \\ 6 & 9 & 6 \\ 3 & 10 & 3 \\ \end{array} $

Data sets in this form (each column is a permutation of Range[numPts]) have a bunch of interesting combinatorial properties. What is fascinating is to take the transform and apply it to random data that is distributed in unique ways, such as points on a simplex, hypersphere, etc.

Expanding a wee bit: the reason this transformation is interesting is that in algorithms to identify the Pareto frontier, you don't care about absolute values of a coordinate, just its ordinal value with respect to other values in a column. Once transformed, a bunch of shortcuts and interesting properties open up.

$\endgroup$
5
  • 1
    $\begingroup$ or Transpose@Table[RandomSample@Range@numPts, {dim}] to generate random permutations directly $\endgroup$
    – Roman
    Commented May 17, 2019 at 13:38
  • 1
    $\begingroup$ You may be interested in this performance comparison for Ordering[Ordering[list]]. $\endgroup$
    – Roman
    Commented May 17, 2019 at 13:40
  • $\begingroup$ Great expansion! Same goes for your answer, can you expand on your one-liner’s through process/methodology? :D @Roman thank you for the link, what a great combo of question and answer! $\endgroup$ Commented May 17, 2019 at 13:55
  • $\begingroup$ @Roman, I remember that post on Ordering@Ordering. $\endgroup$
    – MikeY
    Commented May 17, 2019 at 13:57
  • $\begingroup$ One interesting tidbit is with the data structured as I did, you actually can't have all of the data on a single plane if you have an even number of points. With an odd number of points, the sum of values for each point must add to 3(n+1)/2 where n is the number of points. $\endgroup$
    – MikeY
    Commented May 17, 2019 at 14:00
3
$\begingroup$

If the number of possible points is large, than enumerating them all and taking a random sample won't be feasible. For example, suppose you have integer points in a 1000 x 1000 x 1000 box. Then, the number of possible points is 10^9, and it is unlikely that your computer will be able to generate the full list. Instead, it makes sense to index the points, and take a random sample of the indices, and then convert the indices to a point. For instance, in this example, there are 10^9 indices, and we can convert any index to a point using IntegerDigits, for example:

IntegerDigits[13412343, 1000]

{13, 412, 343}

So, to find 10 random sample indices, we can do:

SeedRandom[1]
indices = RandomSample[0 ;; 10^9-1, 10]

{877665282, 101700636, 562018428, 288541214, 403280597, 238031837, 817685571, \ 339828267, 510012226, 749565074}

The key here is that RandomSample can accept a span object instead of a list of 10^9 integers. Then, convert them to points with IntegerDigits:

IntegerDigits[indices, 1000]

{{877, 665, 282}, {101, 700, 636}, {562, 18, 428}, {288, 541, 214}, {403, 280, 597}, {238, 31, 837}, {817, 685, 571}, {339, 828, 267}, {510, 12, 226}, {749, 565, 74}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.