3 Stimmen

Wie erstellt man eine ungleichmäßige Bereichsnummer-Zufallsfunktion?

Wir wissen, dass die klassische Bereichs-Zufallsfunktion wie folgt aussieht:

public static final int random(final int min, final int max) {
    Random rand = new Random();
    return min + rand.nextInt(max - min + 1);  // +1 für die Einbeziehung des Maximums
}

Ich möchte einen Algorithmus erstellen, um eine Zahl im Bereich von 1..10 zufällig zu generieren, aber mit ungleichen Wahrscheinlichkeiten wie folgt:
1) 1,2,3 -> 3/6 (1/2)
2) 4,5,6,7 -> 1/6
3) 8,9,10 -> 2/6 (1/3)

Dies bedeutet, dass die Funktion eine 1/2-Chance hat, eine Zahl zwischen 1 und 3 zurückzugeben, eine 1/6-Chance, eine Zahl zwischen 4 und 7 zurückzugeben, und eine 1/3-Chance, eine Zahl zwischen 8 und 10 zurückzugeben.

Weiß jemand den Algorithmus?

UPDATE:
Eigentlich dient der Bereich von 1..10 nur als Beispiel. Die Funktion, die ich erstellen möchte, würde für beliebige Zahlenbereiche gelten, wie z.B. 1..10000, aber die Regel bleibt dieselbe: 3/6 für den oberen Bereich (30% Anteil), 1/6 für den mittleren Bereich (nächste 40% Anteil) und 2/6 für den unteren Bereich (letzten 30% Anteil).

5voto

Ivaylo Strandjev Punkte 67241

Verwenden Sie den Algorithmus:

int temp = random(0,5);
if (temp <= 2) {
  return random(1,3);
} else if (temp <= 3) {
 return random(4,7);
} else  {
 return random(8,10);
}

Das sollte funktionieren.

BEARBEITEN: Wie in Ihrem Kommentar angefordert:

int first_lo = 1, first_hi = 3000; // 1/2 Chance, eine Zahl in [first_lo, first_hi] zu wählen
int second_lo = 3001, second_hi = 7000; // 1/6 Chance, eine Zahl in [second_lo, second_hi] zu wählen 
int third_lo = 7001, third_hi = 10000;// 1/3 Chance, eine Zahl in [third_lo, third_hi] zu wählen 
int second
int temp = random(0,5);
if (temp <= 2) {
  return random(first_lo,first_hi);
} else if (temp <= 3) {
 return random(second_lo,second_hi);
} else  {
 return random(third_lo,third_hi);
}

3voto

Matzi Punkte 13600

Sie können ein Array der gewünschten Zahlen mit der gewünschten Dichte füllen und dann einen zufälligen Index generieren und das entsprechende Element nehmen. Ich denke, es ist etwas schneller, aber wahrscheinlich ist es nicht so wichtig. So ähnlich, es ist nicht die korrekte Lösung, nur ein Beispiel:

1,1,1,2,2,2,3,3,3,4,5,6 ...

Oder Sie können zuerst Bereiche mit if-Anweisungen definieren und dann eine einfache Zahl aus diesem Bereich generieren.

int x = zufällig(1,6)
if (x < 4) return zufällig(1, 3);
if (x < 5) return zufällig(4, 7);
return zufällig(8, 10);

2voto

Marcelo Cantos Punkte 173498

Würfeln Sie mit einem 72-seitigen Würfel, um aus dem folgenden Array auszuwählen:

// Jede Zeile repräsentiert 1/6 des Raums
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7,
 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10]

0voto

CAFxX Punkte 23026
final int lut[] = [
  1, 1, 1,
  2, 2, 2,
  3, 3, 3,
  4,
  5,
  6,
  7,
  8, 8,
  9, 9,
  10, 10
];

int unabänderlich_zufällig = lut[zufall.nextInt(lut.länge)];

Oder so ähnlich...

0voto

Cristian Toader Punkte 96

Dies könnte Ihnen helfen, wenn Sie Ganzzahlen verwenden:

Sie müssen die folgende Funktion verwenden:

f : A -> B

B = [b0, b1] repräsentiert den Wertebereich, den Sie von Ihrem Zufallszahlengenerator möchten

A = [b0, 2 * b1], damit der letzte Zweig von f tatsächlich b1 erreicht

f(x) = step((x / 3) , 
    f(x) gehört zum Intervall [b0, Länge(B)/3]
f(x) = step(x)  + E,   
    f(x) gehört zum Intervall [Länge(B) / 3, 2 * Länge(B) / 3],
    E ist eine Konstante, die sicherstellt, dass die Funktion stetig ist
f(x) = step(x / 2) + F,   
    f(x) gehört zum Intervall [2 * Länge(B) / 3, Länge(B)]
    F ist eine Konstante, die sicherstellt, dass die Funktion stetig ist

Erklärung: Es werden 3 Mal mehr Zahlen benötigt, um den gleichen Wert im ersten Zweig zu erhalten als im zweiten. Daher ist die Wahrscheinlichkeit, eine Zahl im ersten Zweig zu erhalten, 3 Mal höher als im zweiten, mit gleichmäßig verteilten Werten von einem Zufallszahlengenerator. Das Gleiche gilt für den dritten Zweig.

Ich hoffe, das hilft!

EDIT: Die Intervalle wurden geändert, Sie müssen es etwas anpassen, aber das ist meine allgemeine Idee.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X