分层HashMap第N阶HMM实现

时间:2016-03-28 10:15:18

标签: java generics hashmap polymorphism hidden-markov-models

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

例如,第二个订单的实现是:

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,这样你就可以更新计数Double值。

任何建议都会很棒!

1 个答案:

答案 0 :(得分:0)

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

传递给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);
        }
    }
}