# How do I generate n random numbers with an extra condition [duplicate]

I need to generate n random numbers that would sum into a. And I can't find an elegant solution here: https://reference.wolfram.com/language/tutorial/RandomNumberGeneration.html .

The only solution I have in my head is to generate random numbers and than include IF sentence. But it would take years before Mathematica would find the n random numbers whose sum is exactly a. Any other ideas on how to do this here?

• mathematica.stackexchange.com/q/69707/5478 – Kuba Jul 20 '15 at 9:53
• Generate n reals (0,1), normalize them, multiply a by that, done. – ciao Jul 20 '15 at 9:59
• Differences@Append[NestList[# + RandomReal[{0, 60 - #}] &, 0, 4], 60] – Simon Rochester Jul 20 '15 at 10:07
• One way to do @ciao's idea: a Normalize[RandomReal[1, n], Total]. – J. M.'s torpor Jul 20 '15 at 10:10
• It's kind of like Bertrand's paradox: we really need to agree in what "random" means here precisely. – Szabolcs Jul 20 '15 at 10:20

To be able to answer this question, we need to agree what "random" means precisely. To me, the most reasonable interpretation is to require a uniform distribution on the $\sum_i x_i = a$ simplex.

This will be satisfied by Praan's solution once we filter tuples containing negative numbers. Let's illustrate using $a=1$ and $n=3$.

Praan's method:

pts = Select[
Append[#, 1 - Total[#]] & /@ RandomReal[1, {10000, 2}],
Positive[Times @@ #] &
];

ListPointPlot3D[
pts,
BoxRatios -> {1, 1, 1}
]


Or let's just project down to 2D to make things easier to see:

Appropriate basis vectors:

a = Normalize[{-1, 1, 0}];
b = Normalize[{-1, -1, 1}];

ListPlot[
{a.#, b.#} & /@ pts,
AspectRatio -> Automatic,
Axes -> False, Frame -> True
]


The fact that the distribution will be uniform is also clear from the fact that this method is effectively doing a linear transformation on points of the form $(x,y,0)$, which are already uniformly distributed within a plane.

ciao's idea (comments) gives a very different distribution:

pts = Table[
Normalize[RandomReal[{0, 1}, 3], Total],
{10000}
];


And Simon Rochester's method (comments) produces a distribution that's different from both:

pts = Table[
Differences@Append[NestList[# + RandomReal[{0, 1 - #}] &, 0, 2], 1],
{10000}
];


To decide which one is right, we need to agree on the interpretation of random. To me, the most reasonable interpretation is this: a "random triplet of numbers" means uniform distribution in 3D Euclidean space. Adding a constraint (i.e they must sum to $a$) should not modify this requirement, i.e. that we need to have uniform distribution in 3D Euclidean space.

This is only satisfied by Praan's method.

• Wouldn't this be a dupe of the one you linked to, then? – J. M.'s torpor Jul 20 '15 at 10:54
• @Guesswhoitis. Yes, it is. I asked Mr.Wizard to reopen because I was just finishing up typing the answer when it got closed ... and also because I thought that DirichletDistribution is not a viable choice for large $n$. But that doesn't seem to be the case: it's fast even for $n$ as large as 10000. – Szabolcs Jul 20 '15 at 11:01
• Nice experimental setup. – chris Jul 20 '15 at 11:10
• +1, nice analysis, I concur: poorly defined question, lacking the definition of "random" for the desired result, and with your conclusion in any case. – ciao Jul 20 '15 at 12:10

Generate $n-1$ random numbers first. Then the $n$th number is given by $a$ minus the sum of the $n-1$ randomly generated numbers. Your code could look like this, for example,

rTable = RandomReal[{rmin, rmax}, n-1]
AppendTo[rTable, a-Total@rTable]
a == Total@rTable


Edit

As pointed out by Szabolcs in the comments of this answer, this method fails when the $n$-th number is negative since the OP requested positive numbers (for suitable $a$ and $n$). This can be remedied by selecting only those lists of random numbers where the $n$-th number is positive.

For a nice implementation, see the answer of Szabolcs, in which the question is reformulated in terms of a uniform distribution on the $(n-1)$-simplex defined by $\sum_{i=0}^{n-1}x_i/a=1$.

• Might want to rethink that re: distribution of the elements themselves... these are not as "random" as you seem to think... – ciao Jul 20 '15 at 10:10
• To comply with the OP's requirements, you need to ensure additionally that all numbers are positive (e.g. filter out tuples containing negative ones). – Szabolcs Jul 20 '15 at 10:23
• @ciao Could you elaborate? Thanks. – Praan Jul 20 '15 at 10:39
• @Szabolcs Yup, you're right. Sorry about that. I can't delete my answer though.. – Praan Jul 20 '15 at 10:39
• @Praan You can edit it and add the filtering. No need to delete, just a small correction needed. – Szabolcs Jul 20 '15 at 10:42