分层 HashMap N 阶 HMM 实现

Layered HashMap Nth Order HMM implementation

我已经使用 HashMap 而非转换矩阵实现了一阶、二阶和三阶隐马尔可夫模型。我使用这些 HMM 来计算音符(建模为整数 0-128)在 1 个音符/2 个音符/3 个音符之后出现的次数,具体取决于顺序。

例如二阶的实现是:

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>>());
            }
        }
    }
}

我想使用相同的模式实现任意顺序的 HMM。我尝试使用多态性,但每次都得到 ClassCastException。不完全确定如何在此使用泛型。我猜的诀窍是知道你什么时候在最后一个 HashMap 上,这样你就可以更新 count Double 值。

有什么建议就太好了!

我设法使用对象继承和递归解决了这个问题。现在通过迭代学习数据中的音符并在每个音符上调用此函数来更新权重。

向函数传入一个 HashMap<HashMap<Integer, Object> 实例,该实例是包含转换概率、HMM 顺序和学习笔记数组中的笔记索引的数据结构。

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);
        }
    }
}