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$ Commented Jan 14, 2021 at 9:57
  • 5
    $\begingroup$ RandomSample[Tuples[{0, 1, 2}, 7], 1000] $\endgroup$ Commented Jan 14, 2021 at 10:19
  • $\begingroup$ @cvgmt You could post this as an answer since it fits the criteria and it runs very quickly. $\endgroup$ Commented Jan 14, 2021 at 11:08

2 Answers 2

-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$ Commented Jan 14, 2021 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$ Commented Jan 14, 2021 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$ Commented Jan 14, 2021 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 and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.