# How to generate random vectors without repetition?

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?

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

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]

• 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} Jan 14, 2021 at 10:50
• {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}. Jan 14, 2021 at 11:17
• 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. Jan 14, 2021 at 16:32

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  *)