Véletlenszerűen generál Letters szerint azok használatának gyakorisága?

szavazat
10

Hogyan véletlenszerűen generál levelek szerint a használati gyakoriság közös beszédet?

Bármilyen pszeudo-kód értékelik, de egy implementációt Java fantasztikus lenne. Ellenkező esetben csak a döfés a helyes irányba hasznos lenne.

Megjegyzés: Nem kell, hogy létrehoz a frekvenciák használati - Biztos vagyok benne, lehet nézni, hogy ki elég könnyen.

A kérdést 27/01/2010 21:11
a forrás felhasználó
Más nyelveken...                            


5 válasz

szavazat
11

Egy gyors módja az lenne, hogy létrehoz egy listát a levelek, ahol minden betű szerepelt a listán összhangban frekvencia. Mondjuk, ha „e” használták 25,6% -a az időt, és a listát kellett hossza 1000, akkor 256 „e” s.

Akkor is csak véletlenszerűen válasszon foltok a listából segítségével (int) (Math.random() * 1000)generál véletlen számokat 0 és 999.

Válaszolt 27/01/2010 21:14
a forrás felhasználó

szavazat
18

Én feltételezve, hogy tárolja a frekvenciákat lebegőpontos számok 0 és 1 között, hogy a teljes, hogy 1.

Először meg kell készítenie egy táblázat kumulatív gyakoriság, azaz az összeget a frekvencia, hogy a levél, és a betűket, mielőtt.

Leegyszerűsítve, ha elkezd ezzel a gyakorisági eloszlását:

A  0.1
B  0.3
C  0.4
D  0.2

A kumulatív gyakorisági táblázat a következő lenne:

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)

Most generál egy véletlen számot 0 és 1 között, és hol ebben a listában azt a számot fekszik. Válassza ki a levelet, hogy a legkisebb összegzett gyakoriság nagyobb, mint a véletlen számot. Néhány példa:

Mondja el, hogy véletlenszerűen választanak 0,612. Ez fekszik 0,4 és 0,8 közötti, azaz a B és C, így azt választani C.

Ha a véletlen szám volt 0,039, ami előtt 0,1, vagyis még egy, úgy döntenek, A.

Remélem, hogy van értelme, különben nyugodtan felvilágosítást kérni!

Válaszolt 27/01/2010 21:20
a forrás felhasználó

szavazat
4

Még egy pszeudo-kódot, de egy lehetséges megoldás az alábbiak szerint:

Hagyja, p1, p2, ..., pk az frekvenciákat szeretne egyeztetni.

  1. Számítsuk ki a kumulált frekvenciák: p1, P1 + P2, P1 + P2 + P3, ..., 1
  2. Generál egy véletlen egységes (0,1) x számot
  3. Ellenőrizze, hogy mely intervallum a kumulatív frekvencia x tartozik: ha, mondjuk, p1 + .. + pi és p1 + ... + pi + p (i + 1), majd a kimeneti (i + 1) -edik levél

Attól függően, hogy hogyan hajtsák végre az intervallum-megállapítás, az eljárás általában hatékonyabb, ha a p1, p2, ... vannak rendezve csökkenő sorrendben, mert akkor általában találni az intervallumot, amely x hamarabb.

Válaszolt 27/01/2010 21:20
a forrás felhasználó

szavazat
5

Én mit tennék a skála a relatív gyakoriságát a lebegőpontos számok, hogy összegük 1,0. Aztán lenne létrehozni egy tömböt a kumulatív összegek betűnként, vagyis azt a számot, után kell tölteni, hogy ez a levél és az összes ilyen „lent” is. Mondjuk a frekvenciáját egy 10%, b értéke 2% és z értéke 1%; akkor a táblázat a következőképpen néz ki:

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

Akkor generál magának egy véletlen számot 0,0 és 1,0 közötti, és nem egy bináris keresést a tömbben az első szám kisebb, mint a véletlen számot. Ezután vedd a levelet ebben a pozícióban. Kész.

Válaszolt 27/01/2010 21:23
a forrás felhasználó

szavazat
2

Egy bináris fa ad egy szép, tiszta módja, hogy megtalálják a megfelelő bejegyzést. Itt kezdődik a frequencytérképen, hol vannak a kulcsok a szimbólumok (angol betűk), és az értékek gyakorisága előfordulásuk. Ez lesz fordított, és NavigableMapjön létre, ahol a kulcsok halmozott valószínűsége, és az értékek szimbólumok. Ez teszi a keresést könnyű.

  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();
  }
Válaszolt 27/01/2010 22:10
a forrás felhasználó

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