/// <summary> /// Konstruktor /// </summary> /// <param name="automata">Automat do obliczeń.</param> /// <param name="personalBest">Najlepszy znaleziony automat dla cząsteczki.</param> public Particle(Automata automata, Automata personalBest) { Automata = automata; PersonalBestAutomata = personalBest; PersonalBest = int.MaxValue; Velocity = new double[Automata.MaxNumberOfStates * Automata.NumberOfSymbols]; }
/// <summary> /// Metoda oblicza funkcję błędu. /// </summary> /// <param name="words">Zbiór słów</param> /// <param name="current">Cząsteczka, której automat będzie porównywany</param> /// <param name="best">Najlepszy znaleziony automat</param> /// <param name="alphabet">Alfabet</param> /// <returns>Zwraca wartość funkcji błędu</returns> private static int CalculateErrorFunction(ref string[] words, Particle current, Automata best, char[] alphabet) { int sum = 0; for (int i = 0; i < words.Length; i++) for (int j = i + 1; j < words.Length; j++) if (!Utils.CompareAutomats(current.Automata.StateTable, best.StateTable, words[i], words[j], alphabet)) sum++; return sum; }
public void DetectUnreachableStatesTest() { Automata automata = new Automata(); automata.NumberOfStates = 5; automata.NumberOfSymbols = 3; automata.StateTable = new int[automata.NumberOfStates * automata.NumberOfSymbols]; automata.StateTable[0] = 1; automata.StateTable[1] = 3; automata.StateTable[2] = 5; automata.StateTable[3] = 1; automata.StateTable[4] = 2; automata.StateTable[5] = 4; automata.StateTable[6] = 3; automata.StateTable[7] = 5; automata.StateTable[8] = 1; automata.StateTable[9] = 1; automata.StateTable[10] = 1; automata.StateTable[11] = 5; automata.StateTable[12] = 5; automata.StateTable[13] = 1; automata.StateTable[14] = 3; bool[] expected = new bool[automata.NumberOfStates]; bool[] actual = new bool[automata.NumberOfStates]; expected[0] = true; expected[1] = false; expected[2] = true; expected[3] = false; expected[4] = true; Utils.DetectUnreachableStates(ref actual, ref automata); CollectionAssert.AreEqual(expected, actual); }
public void ReduceUnreachableStatesTest() { Automata actual = new Automata(); Automata expected = new Automata(); expected.NumberOfStates = 3; expected.NumberOfSymbols = 3; expected.StateTable = new int[expected.NumberOfStates * expected.NumberOfSymbols]; expected.StateTable[0] = 1; expected.StateTable[1] = 2; expected.StateTable[2] = 3; expected.StateTable[3] = 2; expected.StateTable[4] = 3; expected.StateTable[5] = 1; expected.StateTable[6] = 3; expected.StateTable[7] = 1; expected.StateTable[8] = 2; actual.NumberOfStates = 5; actual.NumberOfSymbols = 3; actual.StateTable = new int[actual.NumberOfStates * actual.NumberOfSymbols]; actual.StateTable[0] = 1; actual.StateTable[1] = 3; actual.StateTable[2] = 5; actual.StateTable[3] = 1; actual.StateTable[4] = 2; actual.StateTable[5] = 4; actual.StateTable[6] = 3; actual.StateTable[7] = 5; actual.StateTable[8] = 1; actual.StateTable[9] = 1; actual.StateTable[10] = 1; actual.StateTable[11] = 5; actual.StateTable[12] = 5; actual.StateTable[13] = 1; actual.StateTable[14] = 3; Utils.ReduceUnreachableStates(ref actual); Assert.AreEqual(expected, actual); }
/// <summary> /// Algorytm aproksymujacy automat. /// </summary> /// <param name="swarm">Rój cząsteczek.</param> /// <param name="globalBest">Cząsteczka, dla której znaleziono najlepsze dopasowanie. Początkowo ma największy możliwy rozmiar.</param> /// <param name="givenAutomaton">Automat, który próbujemy przybliżyć</param> /// <param name="maxSpeed">Maksymalna liczba stanów.</param> /// <param name="calculationsTime">Czas obliczeń podany w godzinach.</param> /// <param name="error">Zadowalająca wartość błędu.</param> /// <param name="words">Słowa do testowania.</param> /// <param name="alphabet">Alfabet.</param> /// <param name="bg">Wątek do obliczeń</param> /// <param name="maxIterationsNoChange">Ilość iteracji, po których zostaje wygenerowany nowy rój</param> /// <param name="c1">Pierwszy współczynnik akceleracji</param> /// <param name="c2">Drugi współczynnik akceleracji</param> /// <param name="c3">Trzeci współczynnik akceleracji</param> /// <returns></returns> public static Particle ApproximateAutomaton(Particle[] swarm, Particle globalBest, Automata givenAutomaton, int maxSpeed, int calculationsTime, int error, string[] words, char[] alphabet, ref BackgroundWorker bg, int maxIterationsNoChange, double c1, double c2, double c3) { globalBest.Automata.MaxNumberOfStates = maxSpeed; InitTimer(calculationsTime); _bestError = CalculateErrorFunction(ref words, globalBest, givenAutomaton, alphabet, ref bg); globalBest.PersonalBest = _bestError; foreach (var s in swarm) for (int i = 0; i < s.Automata.MaxNumberOfStates * s.Automata.NumberOfSymbols; i++) { _r = new Random(i * DateTime.Now.Millisecond); s.Velocity[i] = _r.NextDouble() * maxSpeed; } _iterationsNoChange = 0; while (_minutes > 0 && _bestError > error) { if (_iterationsNoChange++ > maxIterationsNoChange) { _iterationsNoChange = 0; swarm = Utils.GenerateRandomSwarm(swarm.Length, givenAutomaton.NumberOfSymbols, givenAutomaton.MaxNumberOfStates); } foreach (var s in swarm) { _currentError = CalculateErrorFunction(ref words, s, givenAutomaton, alphabet, ref bg); if (s.PersonalBest > _currentError) { s.PersonalBest = _currentError; s.PersonalBestAutomata = s.Automata; } if (globalBest.PersonalBest > _currentError) { globalBest.PersonalBest = _currentError; int size = s.Automata.NumberOfStates * s.Automata.NumberOfSymbols; globalBest.Automata.StateTable = new int[size]; for (int i = 0; i < size; i++) globalBest.Automata.StateTable[i] = s.Automata.StateTable[i]; globalBest.Automata.NumberOfStates = s.Automata.NumberOfStates; _iterationsNoChange = 0; } if (_currentError < _bestError) { _bestError = _currentError; double errorsPercent = Math.Round(((double)_bestError / (double)(words.Length * (words.Length - 1))) * 100, 2); bg.ReportProgress(-1, errorsPercent); } } foreach (var s in swarm) { #region making vectors equal int max = globalBest.Automata.MaxNumberOfStates * globalBest.Automata.NumberOfSymbols; var pb = s.PersonalBestAutomata.StateTable; var gb = globalBest.Automata.StateTable; var posOld = s.Automata.StateTable; Array.Resize(ref posOld, max); Array.Resize(ref pb, max); Array.Resize(ref gb, max); #endregion #region updating velocity for (int i = 0; i < s.Velocity.Length; i++) { _r = new Random(i * DateTime.Now.Millisecond); Random r1 = new Random(i * DateTime.Now.Millisecond + 1); Random r2 = new Random(i * DateTime.Now.Millisecond + 2); Random r3 = new Random(i * DateTime.Now.Millisecond + 3); s.Velocity[i] = c1 * r1.NextDouble() * s.Velocity[i] + c2 * r2.NextDouble() * (pb[i] - s.Velocity[i]) + c3 * r3.NextDouble() * (gb[i] - s.Velocity[i]); if (s.Velocity[i] > maxSpeed || s.Velocity[i] < -maxSpeed) s.Velocity[i] = _r.Next(-maxSpeed, maxSpeed); } #endregion #region updating position int[] pos = new int[max]; for (int i = 0; i < max; i++) pos[i] = Math.Round(posOld[i] + s.Velocity[i]) > s.Automata.MaxNumberOfStates ? _r.Next(1, s.Automata.MaxNumberOfStates + 1) : (int)Math.Round((double)posOld[i] + (int)s.Velocity[i]); int[] npos = null; for (int i = 0; i < max; i++) { if (pos[i] < 1) { if (i < s.Automata.NumberOfSymbols) { npos = new int[s.Automata.NumberOfSymbols]; for (int j = 0; j < s.Automata.NumberOfSymbols; j++) npos[j] = 1; s.Automata.NumberOfStates = 1; } else { int newLength = i / s.Automata.NumberOfSymbols; npos = new int[newLength * s.Automata.NumberOfSymbols]; for (int j = 0; j < newLength * s.Automata.NumberOfSymbols; j++) npos[j] = pos[j]; s.Automata.NumberOfStates = newLength; } pos = npos; break; } npos = pos; } var posMax = pos.Max(); if (posMax > s.Automata.NumberOfStates) { if (posMax > s.Automata.MaxNumberOfStates) { posMax = s.Automata.MaxNumberOfStates; for (int i = 0; i < pos.Length; i++) if (pos[i] > s.Automata.MaxNumberOfStates) pos[i] = s.Automata.MaxNumberOfStates; } int newLength = (posMax * s.Automata.NumberOfSymbols); int[] newtab = new int[newLength]; for (int j = 0; j < npos.Length; j++) newtab[j] = pos[j]; for (int j = npos.Length; j < newLength; j++) newtab[j] = _r.Next(1, posMax + 1); pos = newtab; } s.Automata.NumberOfStates = pos.Length / s.Automata.NumberOfSymbols; for (int i = 0; i < pos.Length; i++) if (pos[i] > s.Automata.NumberOfStates) pos[i] = s.Automata.NumberOfStates; s.Automata.StateTable = pos; #endregion } } if (_minutes == 0) Console.WriteLine(@"timeout"); Automata bestAutomata = globalBest.Automata; Utils.ReduceUnreachableStates(ref bestAutomata); globalBest.Automata = bestAutomata; return globalBest; }
/// <summary> /// Metoda oblicza funkcję błędu. /// </summary> /// <param name="words">Zbiór słów</param> /// <param name="current">Cząsteczka, której automat będzie porównywany</param> /// <param name="best">Najlepszy znaleziony automat</param> /// <param name="alphabet">Alfabet</param> /// <param name="bg">Wątek do obliczeń</param> /// <returns>Zwraca wartość funkcji błędu</returns> private static int CalculateErrorFunction(ref string[] words, Particle current, Automata best, char[] alphabet, ref BackgroundWorker bg) { int sum = 0; for (int i = 0; i < words.Length; i++) for (int j = i + 1; j < words.Length; j++) if (!Utils.CompareAutomats(current.Automata.StateTable, best.StateTable, words[i], words[j], alphabet)) sum++; double errorsPercent = Math.Round(((double)_bestError / (double)(words.Length * (words.Length - 1))) * 100, 2); if (bg != null) bg.ReportProgress(-1, errorsPercent); return sum; }
private Automata OpenAutomata(string fileName) { Automata automata = new Automata(); using (StreamReader sr = new StreamReader(fileName)) { int numberOfLine = 0; string line = sr.ReadLine(); while (line != null) { var parameters = line.Split(','); if (numberOfLine == 0) { automata.StateTable = new int[int.Parse(parameters[0]) * int.Parse(parameters[1])]; automata.NumberOfSymbols = int.Parse(parameters[1]); automata.MaxNumberOfStates = int.Parse(textBoxMaxState.Text); } else { for (int i = 0; i < parameters.Length; i++) { automata.StateTable[(numberOfLine - 1) * automata.NumberOfSymbols + i] = int.Parse(parameters[i]); } } line = sr.ReadLine(); numberOfLine++; } } labelProgress.Text = "Wczytano automat!"; List<string> lista = new List<string>(); char[] alpha = Utils.GenerateAlphabeth(automata.NumberOfSymbols); Utils.GenerateTrainingDictionary(ref lista, alpha, automata.MaxNumberOfStates, _wordLength); return automata; }
private void buttonFileOpen_Click(object sender, EventArgs e) { using (var openFileDialog = new OpenFileDialog()) { if (openFileDialog.ShowDialog() == DialogResult.OK) { _fileAutomata = OpenAutomata(openFileDialog.FileName); _isFile = true; } } }