Gewichtete Zufallszahlen

UnkiDunki

Grünschnabel
Hi,

ich wollte gerne mal fragen, welches der beste Weg ist um gewichtete Zufallszahlen zu realisieren bzw. diese zu ermitteln...

Ich habe bis jetzt einige Methoden probiert, die aber nur bei einer kleinen Menge von Elementen wirklich geeignet sind. z.B.

Zufallszahlen von 1 - 5 mit Gewichtung in Klammern: 1(8), 2 (2), 3 (1), 4 (9), 5 (10)

Jetzt könnte ich z.B. in einer Schleife eine Zufallszahl zwischen 1 und 5 ermitteln, z.B. 1 und dann ihre Wahrscheinlichkeit, also ihre Gewichtung durch die Summe aller Gewichtungen ermitteln (für 1: 8/30) und dann bei erneuter Zufallszahl jetzt zwischen 1 und 30 überprüfen, ob diese Zahl <= 8 ist, wenn ja ist die 1 die ermittelte Zufallszahl, wenn nein, fortführen mit Schleife und erneutes Generieren einer Zufallszahl von 1 - 5 usw.

Ok... das wäre jetzt meine Herangehensweise als "Laie". Das würde vielleicht bei kleinen Spannen noch gehen, aber bei z.B. 2-3000 Elementen nicht mehr... [jedenfalls wenn man es zeitlich optimiert haben möchte]

Darüber hinaus könnte man auch gleich eine Zufallszahl von 1-30 (Summer aller Wertigkeiten) ermitteln und bei z.B. einem Ergebnis von 11 berechnen, dass damit die 3 gewählt wurde...
Das würde auch bei großen Spannen funktionieren... aber da fehlt mir irgendwie die technische Realisierung unter zeitlichem Aspekt:

Klar: Ne Schleife von 1-5 und dann jeweils die einzelnen Gewichtungen addieren und sobald die Summe größer ist als die Zufallszahl habe ich das Ergebnis mit dem aktuellen Schleifenwert...
Aber bei mehreren tausend Elementen ist das auch zeitlich wieder sehr unbefriedigend. Gibt es da vielleicht sogar ne Formel für um sich die Schleife zu sparen?

Und wie würde sich das ändern, wenn man z.B. es so festlegen möchte, dass die kleinste Gewichtung in Wirklichkeit die größte Gewichtung hat?
Das wäre ja bei z.B einer Tabelle der Fall wie "die häufigsten Haustiere":

Platz 1: Hund, Platz 2: Katze etc. also Gewichtung Hund(1), Katze(2), etc.
Die Wahrscheinlichkeiten wäre ja dann für z.B. den Hund: (Summe aller Gewichtungen-eigene Gewichtung(hier "1"))/Summe aller Gewichtungen...

Mhmm...
Wie wäre denn wirklich die beste Herangehensweise an solche "Geschichten"?
Jemand ne Idee? :)
Vielen Dank im Voraus!

P.S. Sorry, wenn sich das ein wenig wirr lesen sollte. Falls ihr Verständnisprobleme habt, fragt gerne nach :)
 
Zuletzt bearbeitet:
Moin,

ich habe zwar nicht verstanden, was Du eigentlich genau mir der Gewichtung bezwecken möchtest, aber wenn Du mal bei :google: mit "gewichtete Zufallszahlen" suchst, findest Du jede Menge Links, die Deine Fragen vermutlich klären könnten ...

Gruß
Klaus
 
Moin,

ich habe zwar nicht verstanden, was Du eigentlich genau mir der Gewichtung bezwecken möchtest, aber wenn Du mal bei :google: mit "gewichtete Zufallszahlen" suchst, findest Du jede Menge Links, die Deine Fragen vermutlich klären könnten ...

Gruß
Klaus

Moin,
Was verstehst du nicht? Den Zweck von gewichteten Zufallszahlen allgemein oder in meinem Fall? Von meinem Fall habe ich ja noch garnichts erzählt, sondern nur recht "abstrakte" Beispiele aufgeführt...
Allgemein sollte ja klar sein: Bsp wie schon angeführt. Man möchte ein zufälliges Haustier ermitteln unter der Berücksichtigung seiner auftretenden Häufigkeit... Ein Hund soll also häufiger zufällig ausgewählt werden als Königspython...
Und nein, mit Tieren hat mein realer Anwendungsfall nichts zu tun, lässt sich aber absolut darauf übertragen :)
 
Ja richtig... Habe den Anwendungsfall beim Googeln auch gefunden... aber dürfte ja jetzt klar sein, was gemeint war :)
Übrigens habe ich immer noch nichts vernünftiges gefunden... Die Lösungen, die ich so gegoogelt habe, waren ähnlich bis gleich meinen beiden...

Meine zweite Lösung wäre wirklich ne Idee, aber halt mit einer mathematischen Umsetzung und nicht wie ich das mit einer Schleife löse :) Mhm...
 
Hallo,

schau mal hier:
Java:
package de.tutorials;

import java.util.Random;

public class WeightedRandomNumberExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//10(8), 20 (2), 30 (1), 40 (9), 50 (10)
		int[] weights = {8,2,3,4,5};
		int[] values = {10,20,30,40,50};
		
		int weightSum = sum(weights);
		
		int[] histogram = new int[values.length];
		
		Random random = new Random();
		for(int i = 0; i< 100000;i++){
			int currentLimit = random.nextInt(weightSum+1);
			
			int currentSum = 0;
			for(int j = 0; j< values.length;j++){
				currentSum += weights[j];
				if(currentSum >= currentLimit){
		
					//System.out.println(values[j]);
					
					histogram[j]++;
					
					break;
				}
			}
		}
		
		for(int i = 0; i< histogram.length;i++){
			System.out.println("Got " + values[i] + " " + histogram[i] +" times, weight was " + weights[i] +" normalizedWeight: " + (weights[i] * 1./ weightSum));
		}
		
	}

	private static int sum(int[] values) {
		int result = 0;
		
		for(int value : values){
			result += value;
		}
		
		return result;
	}

}

Ausgabe:
Code:
Got 10 39182 times, weight was 8 normalizedWeight: 0.36363636363636365
Got 20 8724 times, weight was 2 normalizedWeight: 0.09090909090909091
Got 30 12931 times, weight was 3 normalizedWeight: 0.13636363636363635
Got 40 17456 times, weight was 4 normalizedWeight: 0.18181818181818182
Got 50 21707 times, weight was 5 normalizedWeight: 0.22727272727272727

Gruß Tom
 

Neue Beiträge

Zurück