private void worker_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < Pop_Size; i++) { Thread.Sleep((int)(Sleeper * 100)); _parameters.ListOfPoints.Add(new ObservablePoint(trandom.NextDouble(F1LeftConstraint, F1RightConstraint), trandom.NextDouble(F2LeftConstraint, F2RightConstraint) )); DomainChart.EditBSeriesCollection(_parameters.ListOfPoints); } while (_parameters.IterationNumber < _parameters.IterationLimit && !_Stop) { // inicjalizacja tablic InitializePopulation(ref PopulationAfterSelection, Pop_Size / 2); InitializePopulation(ref PopulationAfterMutation, Pop_Size / 2); InitializePopulation(ref PopulationAfterCrossing, Pop_Size / 4); InitializePopulation(ref PopulationFunctionValue, Pop_Size); InitializePopulation(ref PopulationFunctionValueAfterSelection, Pop_Size / 2); InitializePopulation(ref PopulationFunctionValueAfterCrossing, Pop_Size / 4); // czas na obserwacje popsize'a i wykresu wartosci funkcji // wszystkie operacje wykonujemy na tablicy znajdujacej sie w Parameters public double[][][] Population; // [2][popsize][popsize] FillRandomValues(ref Population); // operacja selekcji // 2 warianty i tutaj trzeba zrobic ze na zasadzie losowej jest wybierana metoda selekcji // selekcja turniejowa --> losujemy 2 punkty z populacji i wygrywa lepszy (o mniejszej wartosci), // dzielimy popsize na 2 rowne zbiory i jeden zbior jest porownywany wzgledem f1 a drugi wzgledem f2 Selection(Population, ref PopulationAfterSelection); // parametr, aby w nastepnej iteracji uzupelnic brakujace osobniki w populacji refill = true; Function2ValueCountForAllPopulation(PopulationAfterSelection, ref PopulationFunctionValueAfterSelection); // selekcja ruletkowa --> obliczamy fitness, jaki to jest procent z calosci dla danego osobnika, obliczamy dystrybuante, // generujemy liczby losowe i szeregujemy okreslajac ktore elementy maja przetrwac // mozna tutaj juz wrzucic te osobniki na wykres dziedziny _parameters.RewriteThePoints(PopulationAfterSelection); DomainChart.EditASeriesCollection(_parameters.ListOfPoints); CheckDomain(ref PopulationOutsideTheDomain, PopulationAfterSelection); _parameters.RewriteThePoints(PopulationOutsideTheDomain); DomainChart.SetPointsOutsideTheDomain(_parameters.ListOfPoints); _parameters.RewriteThePoints(PopulationFunctionValueAfterSelection); ParetoChart.EditSeriesCollection(_parameters.ListOfPoints); ParetoChart.MakeParetoFunctions(FindMinAndMax(PopulationFunctionValueAfterSelection)); CheckParetoDomain(ref PopulationOutsideTheDomain, PopulationFunctionValueAfterSelection); _parameters.RewriteThePoints(PopulationOutsideTheDomain); ParetoChart.SetPointsOutsideTheDomain(_parameters.ListOfPoints); MainChart.EditSeriesCollection(PopulationFunctionValueAfterSelection, _parameters.IterationNumber); // operacja Mutation(PopulationAfterSelection, ref PopulationAfterMutation); // losujemy ktore punkty zostana poddane mutacji (sprawdzamy wszystkie pod wzgledem prawdopodobienstwa) (prawdopodobienstwo mutacji dla kazdego osobnika) // jezeli wylosowano osobnika to losujemy kat oraz dlugosc wektora // sprawdzamy czy zmutowany osobnik znajduje sie w dziedzinie // jezeli nie wykorzystujemy funkcje kary aby zwiekszyc wartosc osobnika // mozna tutaj juz wrzucic te osobniki na wykres dziedziny // operacja krzyzowania // to jest chyba najtrudniejsza operacja, duzo pierdolenia z przeksztalceniami // ogolnie to staramy sie tak skrzyzowac aby np calkowicie odbic jeden punkt // do dyskusji jak to robimy Crossing(PopulationAfterMutation, ref PopulationAfterCrossing); // mozna tutaj juz wrzucic te osobniki na wykres dziedziny // obliczenie minimum SearchForMinValue(PopulationFunctionValueAfterSelection, ref MinF1, ref MinF2); _parameters.Minimum = $"{{{Math.Round(MinF1,2)};{Math.Round(MinF2,2)}}}"; // przepisywanie tablicy PopulationAfterCrossing do Population Array.Clear(Population, 0, Population.Length); Array.Copy(PopulationAfterCrossing, Population, PopulationAfterCrossing.Length); // przepisywanie tablicy PopulationFunctionValueAfterCrossing do PopulationFunctionValue Array.Clear(PopulationFunctionValue, 0, PopulationFunctionValue.Length); Array.Copy(PopulationFunctionValueAfterCrossing, PopulationFunctionValue, PopulationFunctionValueAfterCrossing.Length); // czyszczenie tablic Array.Clear(PopulationAfterSelection, 0, PopulationAfterSelection.Length); Array.Clear(PopulationAfterMutation, 0, PopulationAfterMutation.Length); Array.Clear(PopulationAfterCrossing, 0, PopulationAfterCrossing.Length); Array.Clear(PopulationFunctionValueAfterSelection, 0, PopulationFunctionValueAfterSelection.Length); Array.Clear(PopulationFunctionValueAfterCrossing, 0, PopulationFunctionValueAfterCrossing.Length); // finalne utworzenie wykresu dziedziny oraz pareto frontu a takze wykresu wartosci poszczegolnych funkcji // jezeli przez 5 iteracji nie ma poprawy minimum zatrzymujemy algorytm // musimy obliczyc jeszcze to spierdolone odchylenie // suma po wszystkich punktach w populacji (od i do licznosci pareto frontu) |f(f1) - f2| _parameters.IterationNumber++; e.Cancel = true; Thread.Sleep(4000); } }