Generating a weighted random number

125 views (last 30 days)
Adam Vilanova-Goldstein
Adam Vilanova-Goldstein on 30 Jan 2020
Answered: Steven Lord on 30 Jan 2020
I currently have a variable that looks like this
var = 1:4
which every run through the for loop it picks a random number 1 - 4.
I need it to pick 1 half of the time and 2:4 the other half. so for the 1 x 4 matrix [1 2 3 4] i need the probabilities to be [ 0.5 0.16 0.16 0.17]
How would I write this?

Answers (3)

John D'Errico
John D'Errico on 30 Jan 2020
Use randsample:
Y = randsample(N,K,true,W) or randsample(POPULATION,K,true,W) returns a
weighted sample, using positive weights W, taken with replacement. W is
often a vector of probabilities. This function does not support weighted
sampling without replacement.
So, for your problem, use it like:
var = 1:4;
W = [0.5, 1/6, 1/6, 1/6];
X = randsample(var,1,true,W);
If you don't have the stats toolbox (where randsample seems to live) this is not difficult to do.
  2 Comments
Adam Vilanova-Goldstein
Adam Vilanova-Goldstein on 30 Jan 2020
thank you so much. Is the Stats toolbox "Statistics and Machine Learning Toolbox"?
Hans Scharler
Hans Scharler on 30 Jan 2020
Yes, its the Statistics and Machine Learning Toolbox.

Sign in to comment.


Steven Lord
Steven Lord on 30 Jan 2020
Set up a vector of probabilities.
dist = [2 1 1 1 1 1];
p = normalize(dist, 'norm', 1); % sum(abs(p)) is effectively 1
Use those probabilities as bin edges.
edges = [0, cumsum(p)];
edges(end) = 1; % Make the last bin edge exactly 1, no round-off
Create some sample data.
x = rand(1, 14000);
Use discretize to bin the elements in x into bins delimited by the edges vector.
D = discretize(x, edges);
Let's see how we did.
histogram(D)
The first bin (rolling a 1) has about twice as many hits as each of the other five (rolling 2, 3, 4, 5, or 6.)

chris j
chris j on 30 Jan 2020
Did a similar problem before, essentially rolling a weighted dice.
Var = 1:4;
Odds = [ 0.5 0.16 0.16 0.17];
Odds = cumsum(Odds./sum(Odds)); % re-write as a normalised cumulative sum.
Result = Var(find(Odds>=rand,1,'first'));
% generate a random number between 0 and 1
% use the boundaries defined by Odds to check result
%To show it works:
for J=1:10000
Res(J) = Out(find(Odds>=rand,1,'first'));
end
hist(Res)

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!