Conditional Random number generation
Show older comments
Hello there, For example; If I want to generate 5 random integer numbers with a sum of 20, how can I do that?
" ... example = ceil(10*rand(100, 5)) ... "
1 Comment
Rik
on 20 Dec 2020
Accepted Answer
More Answers (2)
Walter Roberson
on 2 Mar 2017
1 vote
9 Comments
Roger Stafford
on 2 Mar 2017
Unfortunately, the numbers from ‘randfixedsum’ will rarely be integers. However, I can conceive of a method of rounding and sorting its results which would transform such numbers into integers with the proper sum. I’m too sleepy to work on it for now - tomorrow maybe.
Walter Roberson
on 2 Mar 2017
In the case of integers, one approach is to work with Partitions . Unfortunately the partitions routines I see at the moment are designed to list all of the possibilities rather than to choose one at random.
Jan
on 2 Mar 2017
@Roger: What about creating the numbers with the sum 20*2^53 by randfixedsum and dividing the values by 2^53? This might cause some inaccuracies in the last bit due to rounding, but this might be negligible for the OP.
Roger Stafford
on 2 Mar 2017
@syracus syr: That is not how I would do the correction.
Walter Roberson
on 2 Mar 2017
I just thought of a completely different method for the case where you have a fixed sum of a fixed number of positive integers:
random_posint_partition = @(of_what, num_rows, number_of_partitions) accumarray( [repmat((1:num_rows).',of_what, 1), randi(number_of_partitions, num_rows*of_what, 1)], 1);
Example run:
>> random_posint_partition(20,7,5)
ans =
4 3 4 5 4
5 3 3 5 4
3 6 1 6 4
3 6 4 5 2
5 3 6 2 4
4 6 8 1 1
5 1 6 4 4
>> sum(ans,2)
ans =
20
20
20
20
20
20
20
That is, the first parameter gives the number which is to be partitioned, the second parameter gives the number of different times you want the generation to be done, and the third parameter gives the number of pieces to partition into.
... I thought it would be a lot harder to come up with a fair method!
Oops, I just discovered that this can generate entries with a count of 0. :( For example,
6 5 5 4 0
The adjusted version is
random_posint_partition = @(of_what, num_rows, number_of_partitions) 1 + accumarray( [repmat((1:num_rows).',of_what-number_of_partitions, 1), randi(number_of_partitions, num_rows*(of_what-number_of_partitions), 1)], 1);
Roger Stafford
on 4 Mar 2017
Edited: Roger Stafford
on 4 Mar 2017
@Walter. The distribution of values one gets with this method you have described depends very heavily upon the assumption that is made about the underlying statistics involved. By my calculations, using your method, the probability of getting the result [4,4,4,4,4] is 305,540,235,000 times as likely as that of getting the result [20,0,0,0,0]. (I’m assuming your original method, which would allow zero integers.) It is equivalent to tossing 20 pebbles into 5 cans at random and recording the sum of pebbles in each can. In other words, the distribution is heavily weighted in favor of roughly equal values among the five integers.
However, suppose you assume instead that you are in a five dimensional “hyper-cube” of integer space, each integer of which can vary from 0 to 20, and that each integer-valued point in this cube has an equal a priori probability, namely, 1/(21^5). Then suppose, as a conditional probability, that we restrict ourselves to the subset in which the five integers must have 20 as their sum. Such a conditional probability distribution will give [4,4,4,4,4] and [20,0,0,0,0] an equal conditional probability, as opposed to the above enormous difference. This latter kind of conditional probability is analogous to the kind of conditional probability assumption that is the basis of my ‘randfixedsum’ algorithm #9700 for continuous distributions. If we were to use an integer adjustment to the results of randfixedsum, this latter is roughly the kind of integer distribution we would obtain.
Walter Roberson
on 4 Mar 2017
Ah. I don't think I know how to implement your suggestion, though, at least not without generating all of the possible choices that sum to 20 and then picking one at random.
John D'Errico's https://www.mathworks.com/matlabcentral/fileexchange/12009-partitions-of-an-integer can calculate all of the possible partitions; a question is whether we can avoid having to take that step.
Walter Roberson
on 4 Mar 2017
https://en.wikipedia.org/wiki/Partition_(number_theory)#Restricted_part_size_or_number_of_parts talks about restricted partitioning briefly, and ties it to change making problems, which does indeed sound equivalent to the approach I was taking. Those are in turn tied to knapsack problems.
Bruno Luong
on 10 Aug 2020
m = 5;
n = 3;
s = 10;
This will generate uniform distribution with sum criteria
% generate non-negative integer random (m x n) array row-sum to s
[~,r] = maxk(rand(m,s+n-1),n-1,2);
z = zeros(m,1);
r = diff([z, sort(r,2), (s+n)+z],1,2)-1;
1 Comment
Bimal Ghimire
on 4 Oct 2020
While generating conditional random numbers, how can we generate random numbers that has a limit of some maximum value and have certain specified sum value?
Categories
Find more on Random Number Generation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!