Generieren Randomly Letters Nach ihrer Häufigkeit der Nutzung?

stimmen
10

Wie kann ich Briefe zufällig gemeinsam Rede nach ihrer Häufigkeit der Verwendung generieren?

Jeder Pseudo-Code geschätzt, aber eine Implementierung in Java wäre fantastisch. Ansonsten nur ein Stoß in die richtige Richtung wäre hilfreich.

Anmerkung: Ich habe nicht die Frequenzen der Nutzung erzeugen müssen - ich bin sicher, dass ich das einfach genug nach oben schauen.

Veröffentlicht am 27/01/2010 um 21:11
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
11

Eine schnelle Möglichkeit, es zu tun wäre, um eine Liste der Buchstaben zu erzeugen, wobei jeder Buchstabe erschien in der Liste entsprechend seiner Frequenz. Sprich, wenn „e“ 25,6% der Zeit verwendet wurde, und die Liste hatte Länge 1000, müßte es 256 „e“ s.

Dann könnten Sie nur zufällig Flecke aus der Liste auswählen , indem Sie (int) (Math.random() * 1000)Zufallszahl zwischen 0 und 999 zu erzeugen.

Beantwortet am 27/01/2010 um 21:14
quelle vom benutzer

stimmen
18

Ich gehe davon aus, dass Sie die Frequenzen speichern als Punktzahl zwischen 0 und 1 schwimmend, die 1 machen insgesamt.

Zuerst sollten Sie eine Tabelle kumulativer Frequenzen, dh die Summe der Frequenz des Schreibens und alle Buchstaben, bevor sie vorzubereiten.

Zur Vereinfachung, wenn Sie mit dieser Häufigkeitsverteilung starten:

A  0.1
B  0.3
C  0.4
D  0.2

Ihre kumulative Häufigkeitstabelle wäre:

A  0.1
B  0.4 (= 0.1 + 0.3)
C  0.8 (= 0.1 + 0.3 + 0.4)
D  1.0 (= 0.1 + 0.3 + 0.4 + 0.2)

Nun erzeugt eine Zufallszahl zwischen 0 und 1 und sieht, wo in dieser Liste, die Zahl liegt. Wählen Sie die Buchstaben, den die kleinste Summenhäufigkeit größer als Ihre Zufallszahl hat. Einige Beispiele:

Sagen Sie zufällig 0,612 holen. Dieser liegt zwischen 0,4 und 0,8, dh zwischen B und C, so würden Sie wählen C.

Wenn Ihre Zufallszahl 0,039 war, kommt, dass vor 0,1, vor A, dh, so A. wählen

Ich hoffe, das macht Sinn, sonst fühlen sich frei, um Klärung zu bitten!

Beantwortet am 27/01/2010 um 21:20
quelle vom benutzer

stimmen
4

Nicht einmal ein Pseudo-Code, sondern ein möglicher Ansatz ist wie folgt:

Lassen p1, p2, ..., pk die Frequenzen, die Sie anpassen möchten.

  1. Berechnen Sie die kumulativen Frequenzen: p1, p1 + p2, p1 + p2 + p3, ..., 1
  2. Generieren eines Zufalls uniform (0,1) Zahl x
  3. Überprüfen Sie, welche Intervall der kumulativen Frequenzen x gehört zu: wenn sie zwischen, sagen wir, p1 + .. + pi und p1 + ... + pi + p (i + 1), dann geben die (i + 1) -te Brief

Je nachdem, wie Sie das Intervall-Feststellung implementieren, ist das Verfahren in der Regel effizienter, wenn die p1, p2, ... sortiert sind in absteigender Reihenfolge, weil Sie in der Regel das Intervall enthält x früher finden.

Beantwortet am 27/01/2010 um 21:20
quelle vom benutzer

stimmen
5

Was ich tun würde , ist die relativen Häufigkeiten als Gleitkommazahlen so skalieren , dass ihre Summe 1,0. Dann würde ich ein Array der erstellen kumulativen Summen pro Buchstaben, dh die Zahl , die nachgefüllt werden muss diesen Brief zu bekommen und all jene , „unten“ es. Angenommen , die Frequenz eines 10% beträgt, b 2% ist und z 1%; dann würde Ihre Tabelle wie folgt aussehen:

0.000 A ; from 0% to 10% gets you an A
0.100 B ; above 10% is at least a B
0.120 C ; 12% for C...
...
0.990 Z ; if your number is >= 99% then you get a Z

Dann erzeugen Sie sich selbst eine Zufallszahl zwischen 0,0 und 1,0 und tun eine binäre Suche in dem Feld für die erste Nummer kleiner als Ihre Zufallszahl. Dann nehmen Sie den Brief an dieser Position. Erledigt.

Beantwortet am 27/01/2010 um 21:23
quelle vom benutzer

stimmen
2

Einen binären Baum mit Hilfe gibt Ihnen eine schöne, saubere Art und Weise den richtigen Eintrag zu finden. Hier starten Sie mit einer frequencyKarte, wo die Schlüssel sind die Symbole (englische Buchstaben), und die Werte sind die Häufigkeit ihres Auftretens. Dies wird invertiert und ein NavigableMaperstellt wird , wo die Tasten sind kumulative Wahrscheinlichkeit, und die Werte sind Symbole. Das macht die Suche einfach.

  private final Random generator = new Random();

  private final NavigableMap<Float, Integer> table = 
    new TreeMap<Float, Integer>();

  private final float max;

  public Frequency(Map<Integer, Float> frequency)
  {
    float total = 0;
    for (Map.Entry<Integer, Float> e : frequency.entrySet()) {
      total += e.getValue();
      table.put(total, e.getKey());
    }
    max = total;
  }

  /** 
   * Choose a random symbol. The choices are weighted by frequency.
   */ 
  public int roll()
  {
    Float key = generator.nextFloat() * max;
    return table.higherEntry(key).getValue();
  }
Beantwortet am 27/01/2010 um 22:10
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more