Genera aleatoriu scrisori în funcție de frecvența lor de utilizare?

voturi
10

Cum pot genera aleatoriu scrisori în funcție de frecvența lor de utilizare în discursul comun?

Orice pseudo-cod apreciat, dar o implementare în Java ar fi fantastic. În caz contrar, doar un ghiont în direcția corectă ar fi de ajutor.

Notă: Nu am nevoie pentru a genera frecvențele de utilizare - Sunt sigur că pot uita asta destul de ușor.

Întrebat 27/01/2010 la 21:11
sursa de către utilizator
În alte limbi...                            


5 răspunsuri

voturi
11

O modalitate rapidă de a face acest lucru ar fi pentru a genera o listă de litere, în cazul în care fiecare literă apărut în lista în conformitate cu frecvența. Spune, dacă „e“ a fost utilizat 25,6% din timp, iar lista a avut o lungime de 1000, ar avea 256 de „e“ s.

Apoi , ai putea alege aleator puncte din lista folosind (int) (Math.random() * 1000)pentru a genera numere aleatoare între 0 și 999.

Publicat 27/01/2010 la 21:14
sursa de către utilizator

voturi
18

Sunt presupunând că stocați frecvențele ca numere în virgulă mobilă între 0 și 1, care în total pentru a face 1.

În primul rând ar trebui să pregătească un tabel de frecvențe cumulative, și anume suma frecvenței acestei scrisori și toate scrisorile înainte de aceasta.

Pentru a simplifica, dacă începeți cu această distribuție de frecvență:

A  0.1
B  0.3
C  0.4
D  0.2

Tabelul de frecvență cumulativă ar fi:

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)

Acum, generează un număr aleatoriu între 0 și 1 și a vedea în cazul în care, în această listă se află numărul. Alege litera care are cea mai mică frecvență cumulată mai mare decât numărul dvs. de aleatoare. Cateva exemple:

Spuneți că ați alege aleator 0.612. Aceasta se află între 0,4 și 0,8, adică între B și C, astfel încât ai alege C.

Dacă numărul aleatoriu a fost 0,039, care vine înainte de 0,1, adică înainte, așa că alege A.

Sper că are sens, în caz contrar se simt liber pentru a cere clarificări!

Publicat 27/01/2010 la 21:20
sursa de către utilizator

voturi
4

Nici măcar un pseudo-cod, dar o posibilă abordare este după cum urmează:

Să p1, p2, ..., să fie pk frecvențele pe care doriți să se potrivească.

  1. Se calculează frecvențele cumulative: p1, p1 + p2, p1 + p2 + p3, ..., 1
  2. Generarea unei uniforme aleatoare (0,1) x numărul
  3. Verificați ce interval de frecvențe cumulate x aparține: dacă este între, să zicem, p1 + .. + pi si p1 + ... + pi + P (i + 1), apoi de ieșire (i + 1) litera st

În funcție de modul în care pune în aplicare interval de constatare, procedura este de obicei mai eficientă în cazul în care p1, p2, ... sunt sortate în ordine descrescătoare, pentru că veți găsi de obicei, intervalul care conține x mai devreme.

Publicat 27/01/2010 la 21:20
sursa de către utilizator

voturi
5

Ce mi - ar face este scala frecvențelor relative ca numere în virgulă mobilă , astfel încât suma lor este de 1,0. Apoi , aș crea o serie de cumulative totalurile pe litere, adică numărul care trebuie depășit pentru a obține acea literă și toți cei „mai jos“ ea. Spun frecvența A este de 10%, b este de 2% , iar z este de 1%; apoi masa ta ar arata ceva de genul:

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

Apoi, generați-vă un număr aleatoriu între 0,0 și 1,0 și de a face o căutare binară în matrice pentru primul număr mai mic decât numărul dvs. aleatoare. Apoi alege scrisoarea la acea poziție. Terminat.

Publicat 27/01/2010 la 21:23
sursa de către utilizator

voturi
2

Folosind un arbore binar vă oferă un mod frumos, curat pentru a găsi intrarea din dreapta. Aici, începe cu o frequencyhartă, în cazul în care cheile sunt simboluri (litere englezești), iar valorile sunt frecvența apariției lor. Acest lucru devine inversat, și NavigableMapeste creată în cazul în care cheile sunt cumulative de probabilitate, iar valorile sunt simboluri. Asta face ușor lookup.

  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();
  }
Publicat 27/01/2010 la 22:10
sursa de către utilizator

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