Are there any STL functions that allow one to create a vector with random numbers that add up to 1? Ideally, this would be dependent on the size of the vector, so that I can make the vector size, say, 23 and this function will populate those 23 elements with random numbers between 0 and 1 that all add up to 1.
-
I don't know a specific function that does exactly this, but it sounds quite easy to implement. – Jan 16 '14 at 23:09
-
Note: The original I have proposed is for Java, but I expect there is no direct C++ STL solution for this, so the literal answer is “No”, and the effective answer is “You have to do it yourself”, in which case the Java question becomes relevant because it is essentially about algorithms, not Java. – Eric Postpischil Jan 16 '14 at 23:26
-
Worth nothing that due to how floating point math works most of the answers below will result in numbers that add to somewhere very close to 1 (like +/- 0.000001), but (sometimes) it might be not **exactly** 1. – user2802841 Jan 16 '14 at 23:30
-
@user2802841: That is a good point, and there is [a related question](http://stackoverflow.com/questions/20078921/normalized-double-vector-not-unit-length-to-machine-precision) about adjusting a vector, although it wants the Euclidean norm adjusted to be exactly one. Of course, not only might the sum not be exactly one, but the sum might be different when calculated in different ways (front to back, back to front, adding pairs and then pairs of pairs and so on until reduced to a single sum, et cetera). – Eric Postpischil Jan 16 '14 at 23:36
4 Answers
One option would be to use generate
to fill the vector with random numbers, then using accumulate
to sum up the values, and finally dividing all the values in the vector by the sum to normalize the sum to one. This is shown here:
std::vector<double> vec(23);
std::generate(vec.begin(), vec.end(), /* some random source */);
const double total = std::accumulate(vec.begin(), vec.end(), 0.0);
for (double& value: vec) value /= total;
Hope this helps!

- 362,284
- 104
- 897
- 1,065
-
+1 for saying in code what I said in words, in about the same amount of time. – Matt Jan 16 '14 at 23:12
No, but you can do this easily with the following steps:
- Fill the vector with random float values, say 0 to 100.
- Calculate the sum.
- Divide each value by the sum.

- 20,108
- 1
- 57
- 70
There are certainly lots of standard functions to generate random numbers. To get the normalization to happen, you'll want to do that after you've generated all the numbers. (For instance, you might generate the numbers, then divide them all by their sum.) Note that you probably won't have uniformly-distributed numbers at that point, if it matters.

- 1,751
- 11
- 10
This depends on the kind of distribution of random numbers that you want. One approach (which has been suggested in another answer) is to just generate some random numbers, then divide them each by their total sum.
Another approach is to make a list of random numbers from the interval [0, 1), then sort them. You can then take the differences between consecutive numbers (adding 0 and 1 to the beginning and end of your list respectively). These differences will naturally sum up to 1. So, for example, let's say you picked 3 random numbers and they were: {0.38, 0.05, 0.96}
. Let's add 0 and 1 to this list and then sort it:
{0, 0.05, 0.38, 0.96, 1}
Now let's take the differences:
{0.05, 0.33, 0.58, 0.04}
If you add these up, they sum to 1. If you don't understand why this works, imagine you have a piece of rope of length 1 and you use a knife to cut it some random distance from the end (without moving the pieces apart as you cut it). Naturally all the pieces will add up to the original length. That's exactly what's happening here.
Now, like I said, this approach will give you a different distribution of random numbers than the divide by sum method, so don't consider them to be the same!

- 6,500
- 2
- 31
- 41