public static int Minimize5(this DfaState start, bool showProgress) { var startTime = DateTime.Now; if (showProgress) Console.WriteLine("Minimize DFA v.5"); var states = new List<DfaState>(3000000); start.ForEachNR((state) => { states.Add(state); }); var sets = new IntSet(states); if (showProgress) Console.WriteLine("Create list: {0}", DateTime.Now - startTime); if (showProgress) Console.Write("Proccessing marks...\r"); var startTime2 = DateTime.Now; foreach (var state in sets.GetSet(0)) { if (state.Value.AllMarks.Count > 0) { for (int i = 1; i < sets.Count; i++) { var state2 = sets.GetFirst(i); if (state.Value.IsSame(state2)) { sets.MoveToSet(state, state2.SetId); break; } } if (state.Value.SetId == 0) sets.MoveToNewSet(state); } } sets.RemoveEmpty(); if (showProgress) { Console.WriteLine("Marks: {0}\t\t", DateTime.Now - startTime2); Console.WriteLine("Splitted by marks to {0} sets", sets.Count); } for (int oldCount = -1; oldCount < sets.Count; ) { oldCount = sets.Count; for (int i = 0; i < sets.Count; i++) { DfaState first = sets.GetFirst(i); bool splitted = false; foreach (var state in sets.GetSet(i)) { if (IsTransitedToSameSets4(first, state.Value) == false) { state.Value.NewSetId = sets.NewSetId; splitted = true; } } if (splitted) { foreach (var state in sets.GetSet(i)) sets.MoveToSet(state, state.Value.NewSetId); Console.Write("{0}\r", sets.Count); } } } if (showProgress) Console.Write("Create MiniDFA\r"); CreateMiniDfa4(start, states, sets); if (showProgress) Console.WriteLine("Done ({0}, {1})\t\t\t\t", sets.Count, DateTime.Now - startTime); return sets.Count; }
private static void CreateMiniDfa4(DfaState start, List<DfaState> states, IntSet sets) { var miniStates = new DfaState[sets.Count]; for (int i = 0; i < sets.Count; i++) { if (i == start.SetId) miniStates[i] = start; else miniStates[i] = sets.GetFirst(i); } foreach (var state in miniStates) { for (int ch = 0; ch <= byte.MaxValue; ch++) { int transitedSetId = state.GetTransitedSetId(ch); if (transitedSetId >= 0) state.SetTransition((byte)ch, miniStates[transitedSetId]); else if (state.Transition[ch] != null) throw new InvalidProgramException(); } } }