0
$\begingroup$

Say we have three elements, 0,1,2 and we want to generate 1000 random vectors of length 7 with these elements, i.e.

{2,1,0,0,0,0,2}

How can we do this without duplicates among these vectors?

$\endgroup$
3
  • $\begingroup$ Try a combination of Tuples and RandomSample. $\endgroup$ Jan 14 at 9:57
  • 5
    $\begingroup$ RandomSample[Tuples[{0, 1, 2}, 7], 1000] $\endgroup$
    – cvgmt
    Jan 14 at 10:19
  • $\begingroup$ @cvgmt You could post this as an answer since it fits the criteria and it runs very quickly. $\endgroup$ Jan 14 at 11:08
-1
$\begingroup$

First, there are $3^7=2187$ different 7-tuples, so there is indeed a considerable probability to encounter duplicates if we generate each 7-tuple independently. So, we use the following:

vectors=IntegerDigits[#, 3, 7] & /@ RandomSample[Range[3^7] - 1, 1000]
$\endgroup$
3
  • $\begingroup$ Can your answer be modified to work in case that the elements are not 3 successive numbers but a list to choose from? i.e. instead 0,1,2 to have {0,3,6} $\endgroup$
    – John Matis
    Jan 14 at 10:50
  • $\begingroup$ {0,3,6} is not so much difference, just multiply vectors by 3. More general {a,b,c} would require vectors/.{0->a,1->b,2->c}. $\endgroup$
    – Roma Lee
    Jan 14 at 11:17
  • $\begingroup$ If the sample universe is really large, it would be better to use Span instead of Range to avoid memory issues, e.g., RandomSample[Span[0, 3^7-1], 1000] instead. $\endgroup$
    – Carl Woll
    Jan 14 at 16:32
2
$\begingroup$

Here are two similar methods of generating a pseudorandom list of unique vectors. The first method uses Union. It is a little faster than the second, which uses DeleteDuplicates. The two methods are implemented as functions f and g

Clear[f]
f[nvect_, ndims_, list_] := Module[{a = {}, k},
  If[TrueQ[nvect <= Length[list]^ndims],
   While[(k = Length[a]) < nvect,
    a = Union[a, RandomChoice[list, {nvect - k, ndims}]]
    ]];
  RandomSample[a]]

Clear[g]
g[nvect_, ndims_, list_] := Module[{a = {}, k},
  If[TrueQ[nvect <= Length[list]^ndims],
   While[(k = Length[a]) < nvect,
    a = DeleteDuplicates@Join[a, RandomChoice[list, {nvect - k, ndims}]]
    ]]; a]

Since Union returns an ordered array, function f uses RandomSample to return a pseudorandom permutation of the ordered array. Both functions return an empty set if you ask for an impossibly large number of unique vectors.

Timing tests on f and g give, for 1000 unique vectors,

tf = RepeatedTiming[f[1000, 7, {0, 1, 2}], 5];
tf // First

(*  0.002  *)

tg = RepeatedTiming[g[1000, 7, {0, 1, 2}], 5];
tg // First

(*  0.003  *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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