2016-03-28 4 views
1

Ich habe Hidden-Markov-Modelle der 1., 2. und 3. Ordnung mit HashMaps im Gegensatz zu einer Übergangsmatrix implementiert. Ich benutze diese HMMs, um die Anzahl der Vorkommen von Noten zu zählen (modelliert als ganze Zahlen 0-128) nach 1 Note/2 Noten/3 Noten, abhängig von der Reihenfolge.Layered HashMap Nth Order HMM-Implementierung

Zum Beispiel die Implementierung für die 2. Ordnung ist:

public void updateWeigths(ArrayList<Note> notes, HashMap<Integer, HashMap<Integer, HashMap<Integer, Double>>> hm) { 
    for (int i=0; i<notes.size()-2; i++) { 
     int prevPitch1 = notes.get(i).getPitch(); 
     int prevPitch2 = notes.get(i+1).getPitch(); 
     int nextPitch = notes.get(i+2).getPitch(); 
     if (prevPitch1 > 0 && prevPitch2 > 0 && nextPitch > 0) { 
      if (hm.containsKey(prevPitch1)) { 
       HashMap<Integer, HashMap<Integer, Double>> nextMapping1 = hm.get(prevPitch1); 
       if (nextMapping1.containsKey(prevPitch2)){ 
        HashMap<Integer, Double> nextMapping2 = nextMapping1.get(prevPitch2); 
        if (nextMapping2.containsKey(nextPitch)) { 
         double prob = nextMapping2.get(nextPitch); 
         nextMapping2.put(nextPitch, prob+1); 
        } 
        else { 
         nextMapping2.put(nextPitch, 1.0); 
        } 
       } 
       else { 
        nextMapping1.put(prevPitch2, new HashMap<Integer, Double>()); 
       } 
      } 
      else { 
       hm.put(prevPitch1, new HashMap<Integer,HashMap<Integer,Double>>()); 
      } 
     } 
    } 
} 

ich eine beliebige Reihenfolge HMM mit dem gleichen Muster implementieren möchten. Ich habe versucht, Polymorphie zu verwenden, aber ich bekomme jedesmal ClassCastException. Nicht ganz sicher, wie man Generics dazu benutzt. Der Trick, den ich vermute, ist zu wissen, wann Sie auf der letzten HashMap sind, damit Sie den Zählwert Double aktualisieren können.

Alle Vorschläge wären großartig!

Antwort

0

Ich habe das Problem mit Object Vererbung und Rekursion gelöst. Die Gewichte werden nun aktualisiert, indem die Notizen aus den Lerndaten durchlaufen werden und diese Funktion für jede Note aufgerufen wird.

Um die Funktion übergeben Sie eine HashMap<HashMap<Integer, Object> Instanz, die die Datenstruktur ist, die die Übergangswahrscheinlichkeiten enthält, die Reihenfolge der HMM und ein Notenindex aus dem Array von Lernnoten.

public void updateTransitionProb(Object mapping, int ord, int noteIndex) { 
    int note = notesList.get(noteIndex).getPitch(); 
    HashMap<Integer, Object> hm = (HashMap<Integer, Object>) mapping; 

    if (ord == 0) { 
     hm.put(note, (hm.get(note) != null) ? ((Double) hm.get(note)) + 1.0 : new Double(1.0)); 
    } 
    else { 
     if (hm.containsKey(note)) { 
      this.updateTransitionProb(hm.get(note), --ord, ++noteIndex); 
     } 
     else { 
      hm.put(note, new HashMap<Integer, Object>()); 
      this.updateTransitionProb(hm.get(note), --ord, ++noteIndex); 
     } 
    } 
}