Generieren Sie eine Zufallszahl mit gegebener Wahrscheinlichkeit matlab

Ich möchte eine Zufallszahl mit einer bestimmten Wahrscheinlichkeit generieren, aber ich bin nicht sicher, wie:

Ich brauche eine Nummer zwischen 1 und 3

num = ceil(rand*3); 

aber ich brauche verschiedene Werte um verschiedene Wahrscheinlichkeiten zu haben zB zu erzeugen.

 0.5 chance of 1 0.1 chance of 2 0.4 chance of 3 

Ich bin mir sicher, dass das unkompliziert ist, aber ich kann mir nicht vorstellen, wie ich es machen soll.

   

Die einfache Lösung besteht darin, eine Zahl mit einer gleichmäßigen Verteilung (mit rand ) zu erzeugen und sie ein wenig zu manipulieren:

 r = rand; prob = [0.5, 0.1, 0.4]; x = sum(r >= cumsum([0, prob])); 

oder in einem Einzeiler:

 x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4])); 

Erläuterung

Hier ist r eine gleichmäßig verteilte Zufallszahl zwischen 0 und 1. Um eine ganze Zahl zwischen 1 und 3 zu erzeugen, besteht der Trick darin, den [0, 1] -Bereich in 3 Segmente zu unterteilen, wobei die Länge jedes Segments proportional zu seinem entsprechenden ist Wahrscheinlichkeit. In Ihrem Fall hätten Sie:

  • Segment [0, 0.5), entspricht der Nummer 1.
  • Segment [0.5, 0.6), entsprechend Nummer 2.
  • Segment [0.6, 1], entsprechend Nummer 3.

Die Wahrscheinlichkeit, dass r in eines der Segmente fällt, ist proportional zu den Wahrscheinlichkeiten, die Sie für jede Zahl haben möchten. sum(r >= cumsum([0, prob])) ist nur eine einfache Möglichkeit, eine ganze Zahl einem der Segmente sum(r >= cumsum([0, prob])) .

Erweiterung

Wenn Sie an der Erstellung eines Vektors / einer Matrix von Zufallszahlen interessiert sind, können Sie eine Schleife oder eine arrayfun :

 r = rand(3); % # Any size you want x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r); 

Natürlich gibt es auch eine vektorisierte Lösung, ich bin einfach zu faul, um es zu schreiben.

Die bisherigen Antworten sind korrekt, aber für große Eingaben langsam: O (m * n), wobei n die Anzahl der Werte und m die Anzahl der Stichproben ist. Hier ist eine O (m * log (n)) Version, die die Monotonie des cumsum Ergebnisses und die in histc verwendete binäre Suche histc :

 % assume n = numel(prob) is large and sum(prob) == 1 r = rand(m,1); [~,x] = histc(r,cumsum([0,prob])); 

Relevanter Matlab Central Forum-Thread

 >> c = cumsum([0.5, 0.1, 0.4]); >> r = rand(1e5, 1); >> x = arrayfun(@(x) find(x < = c, 1, 'first'), r); >> h = hist(x, 1:3) h = 49953 10047 40000 

x wie gewünscht verteilt.

Eine etwas allgemeinere Lösung wäre:

 r=rand; prob=[.5,.1,.4]; prob=cumsum(prob); value=[1,2,3]; %values corresponding to the probabilities ind=find(r< =prob,1,'first'); x=value(ind) 

Mit der randsample function von Statistics and Machine Learning Toolbox können Sie Zufallszahlen mit der angegebenen Wahrscheinlichkeits-Massenfunktion (PMF) erzeugen:

 pmf = [0.5, 0.1, 0.4]; population = 1:3; sample_size = 1; random_number = randsample(population,sample_size,true,pmf); 

Ich denke, das ist die einfachste Methode.