using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Viterbi { class Program { //Weather states static String RAINY = "Rainy"; static String SUNNY = "Sunny"; //Dependable actions (observations) static String WALK = "walk"; static String SHOP = "shop"; static String CLEAN = "clean"; static void Main(string[] args) { //initialize our arrays of states and observations String[] states = { RAINY, SUNNY }; String[] observations = { WALK, SHOP, CLEAN }; var start_probability = new Dictionary<String, float>(); start_probability.Add(RAINY, 0.6f); start_probability.Add(SUNNY, 0.4f); //Transition probability var transition_probability = new Dictionary<String, Dictionary<String, float>>(); var t1 = new Dictionary<String, float>(); t1.Add(RAINY, 0.7f); t1.Add(SUNNY, 0.3f); Dictionary<String, float> t2 = new Dictionary<String, float>(); t2.Add(RAINY, 0.4f); t2.Add(SUNNY, 0.6f); transition_probability.Add(RAINY, t1); transition_probability.Add(SUNNY, t2); //emission_probability var emission_probability = new Dictionary<String, Dictionary<String, float>>(); var e1 = new Dictionary<String, float>(); e1.Add(WALK, 0.1f); e1.Add(SHOP, 0.4f); e1.Add(CLEAN, 0.5f); Dictionary<String, float> e2 = new Dictionary<String, float>(); e2.Add(WALK, 0.6f); e2.Add(SHOP, 0.3f); e2.Add(CLEAN, 0.1f); emission_probability.Add(RAINY, e1); emission_probability.Add(SUNNY, e2); Object[] ret = forward_viterbi(observations, states, start_probability, transition_probability, emission_probability); Console.WriteLine((float)ret[0]); Console.WriteLine((String)ret[1]); Console.WriteLine((float)ret[2]); Console.ReadLine(); } public static Object[] forward_viterbi(String[] obs, String[] states, Dictionary<String, float> start_p, Dictionary<String, Dictionary<String, float>> trans_p, Dictionary<String, Dictionary<String, float>> emit_p) { var T = new Dictionary<String, Object[]>(); foreach (String state in states) { T.Add(state, new Object[] { start_p[state], state, start_p[state] }); } foreach (String output in obs) { var U = new Dictionary<String, Object[]>(); foreach (String next_state in states) { float total = 0; String argmax = ""; float valmax = 0; float prob = 1; String v_path = ""; float v_prob = 1; foreach (String source_state in states) { Object[] objs = T[source_state]; prob = ((float)objs[0]); v_path = (String)objs[1]; v_prob = ((float)objs[2]); float p = emit_p[source_state][output] * trans_p[source_state][next_state]; prob *= p; v_prob *= p; total += prob; if (v_prob > valmax) { argmax = v_path + "," + next_state; valmax = v_prob; } } U.Add(next_state, new Object[] { total, argmax, valmax }); } T = U; } float xtotal = 0; String xargmax = ""; float xvalmax = 0; float xprob; String xv_path; float xv_prob; foreach (String state in states) { Object[] objs = T[state]; xprob = ((float)objs[0]); xv_path = ((String)objs[1]); xv_prob = ((float)objs[2]); xtotal += xprob; if (xv_prob > xvalmax) { xargmax = xv_path; xvalmax = xv_prob; } } return new Object[] { xtotal, xargmax, xvalmax }; } } }