using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Viterbi { class Program { //Weather states static String HEALTHY = "Healthy"; static String FEVER = "Fever"; //Dependable actions (observations) static String DIZZY = "dizzy"; static String COLD = "cold"; static String NORMAL = "normal"; static void Main(string[] args) { //initialize our arrays of states and observations String[] states = { HEALTHY, FEVER }; String[] observations = { DIZZY, COLD, NORMAL }; var start_probability = new Dictionary<String, float>(); start_probability.Add(HEALTHY, 0.6f); start_probability.Add(FEVER, 0.4f); //Transition probability var transition_probability = new Dictionary<String, Dictionary<String, float>>(); var t1 = new Dictionary<String, float>(); t1.Add(HEALTHY, 0.7f); t1.Add(FEVER, 0.3f); Dictionary<String, float> t2 = new Dictionary<String, float>(); t2.Add(HEALTHY, 0.4f); t2.Add(FEVER, 0.6f); transition_probability.Add(HEALTHY, t1); transition_probability.Add(FEVER, t2); //emission_probability var emission_probability = new Dictionary<String, Dictionary<String, float>>(); var e1 = new Dictionary<String, float>(); e1.Add(DIZZY, 0.1f); e1.Add(COLD, 0.4f); e1.Add(NORMAL, 0.5f); Dictionary<String, float> e2 = new Dictionary<String, float>(); e2.Add(DIZZY, 0.6f); e2.Add(COLD, 0.3f); e2.Add(NORMAL, 0.1f); emission_probability.Add(HEALTHY, e1); emission_probability.Add(FEVER, 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 }; } } }