This is not simple, if you want to find a truly uniform set. In 24 dimensions, things get fairly complicated. And the domain the numbers can live in is actually pretty wide, thus the interval [5,800].
So, if you have all numbers at or near their mininum,
5*24
ans =
120
>> 800*24
ans =
19200
>> (5 + 800)/2*24
ans =
9660
The point being that it will be a quite rare event that 24 numbers, chosen randomly from that interval, will have a sum in the interval [3550,3650].
The law of large numbers tells us that the sum of that set will be effectively normally distributed. And, in fact, this gives us a solution to the problem!
Lets see. Each member of that set will be uniform, on the interval [5,800]. That means the mean of x_i will be
a = 5;
b = 800;
(a + b)/2
ans =
402.5
And the variance (of each number in the set) will be
So now the sum of 24 of them will be fairly accurately normally distributed, with mean, variance, and standard deviation:
sumMean = (a+b)/2*24
xmean =
9660
sumVar = (b-a)^2/12*24
xvar =
1264050
sumStd = sqrt(sumVar)
xstd =
1124.29978208661
So, now what are the odds that you will find a sum in the range from [3550,3650]? That would be found from a cumulative normal.
sumLimits = [3550,3650];
normcdf(sumLimits,sumMean,sumStd)
ans =
2.74761306010529e-08 4.50716095152589e-08
diff(ans)
ans =
1.7595478914206e-08
Hmm. So you will probably need to generate roughly 1e8 sets of 24 uniform numbers before you find a single set that lives in the interval [3550,3650].
But! As I said, this actually gives you a near trivial solution! How? We break the problem down into two simpler problems. Hard problems are hard. Easy problems are way easier. So lets create two simpler problems.
First, can we sample from a truncated normal distributiuon? That part is easy.
norminv(sumNormProbLimits(1) + rand()*diff(sumNormProbLimits),sumMean,sumStd)
ans =
3637.00633112408
As you can see, that is a number that has atuncated normal distribution, with the desired parameters. So now we can just use randfixedsum. I'll put it all together here:
a = 5;
b = 800;
ndim = 24;
sumMean = (a+b)/2*ndim;
sumVar = (b-a)^2/12*ndim;
sumStd = sqrt(sumVar);
sumLimits = [3550,3650];
sumNormProbLimits = normcdf(sumLimits,sumMean,sumStd);
S = norminv(sumNormProbLimits(1) + rand()*diff(sumNormProbLimits),sumMean,sumStd);
randfixedsum(24,1,S,a,b)
ans =
32.6666351919248
226.171574450247
26.4486244673284
59.5273902733376
105.140425145937
198.085619814426
313.588691531256
125.527412419838
222.108869160278
78.6355991625287
116.832965448386
25.2315920517267
10.7762636314948
295.321051677379
339.225232904641
91.7004913938697
29.5858150543207
184.827862803465
37.7525635267701
115.866539562388
512.657889835195
372.544944227602
13.6087483202661
58.868132270981
So, a set of 24 uniformly distributed random numbers that have their sum in the desired interval. The numbers really are uniformly distributed to lie in the interval [5,800], but the condition that the sum be so relatively small, makes it unlikely that any of them are near the maximum. On this random set, the max was as large as 512. That seems reasonable to me, under the conditional sampling that was required.
sum(ans)
ans =
3592.70093432559
It was really pretty easy to do. I did need randfixedsum, which you can get from the File Exchange for free download.
Best Answer