Point3[,] pts = new Point3[20, 20]; //задание матрицы точек с тремя координатами для построения графика #endregion Fields #region Constructors //конструктор формы public FunctionGraph(Functions.FunctionVyb Fun, double minX, double maxX, double minY, double maxY) { InitializeComponent(); FunctionGraphik.C3DrawChart.ChartType = DrawChart.ChartTypeEnum.SurfaceFillContour; //определяем вид графика - контурный и объемный Azimuth.Text = PovorotAzimuth.Value.ToString(); //для поворота по горизонтали выводим в соответсвующую метку Elevation.Text = PovorotElevation.Value.ToString(); //для поворота по вертикали выводим в соответсвующую метку this.Fun = Fun; //присваиваем функцию переданную в конструктор полю if (minX == maxX) //присваиваем границы переданные - полям, если границы одинаковые - расширяем, чтобы график не выродился в точку { this.minX = minX-1; this.maxX = maxX+1; } else { this.minX = minX; this.maxX = maxX; } if (minY == maxY) { this.minY = minY-1; this.maxY = maxY+1; } else { this.minY = minY; this.maxY = maxY; } AddData(); //вызываем метод для построения }
//выполнение алгоритма полностью - минимум функции public static double[] FunctionMinimum(int kol, double MinIntX, double MaxIntX, double MinIntY, double MaxIntY, Functions.FunctionVyb Fun) { double[,] newpop = NewPopulation(MinIntX, MaxIntX, MinIntY, MaxIntY); //массив популяции int n = MemeplexNumber(newpop.GetLength(0)); for (int i = 0; i < kol; i++) { PopulationBadModernization(newpop, MinIntX, MaxIntX, MinIntY, MaxIntY, newpop.GetLength(0), n, Fun); //улучшение newpop = PopulationShuffle(newpop); //перемешиваем популяцию } return Minimum(newpop,Fun); }
//минимум в популяции public static double[] Minimum(double[,] newpop, Functions.FunctionVyb Fun) { double[] min = new double[2]; min[0] = newpop[0, 0]; min[1] = newpop[0, 1]; for (int i = 0; i < newpop.GetLength(0); i++) { if (Fun(min[0], min[1]) > Fun(newpop[i, 0], newpop[i, 1])) { //присваиваем, если значение меньше промежуточного минимума min[0] = newpop[i, 0]; min[1] = newpop[i, 1]; } } return min; }
//максимум в популяции public static double[] Maximum(double[,] newpop, Functions.FunctionVyb Fun) { double[] max = new double[2]; max[0] = newpop[0, 0]; max[1] = newpop[0, 1]; for (int i = 0; i < newpop.GetLength(0); i++) { if (Fun(max[0], max[1]) < Fun(newpop[i, 0], newpop[i, 1])) { //присваиваем, если значение больше промежуточного максимума max[0] = newpop[i, 0]; max[1] = newpop[i, 1]; } } return max; }
double[,] newpop; //популяция #endregion Fields #region Constructors //конструктор формы public Graphiks(int KolIt, double MiX, double MaX, double MiY, double MaY, bool MaxF, bool MinF, Functions.FunctionVyb x) { Kol = KolIt;//присваиваем переданные значения из другой формы MaxX = MaX; MinX = MiX; MaxY = MaY; MinY = MiY; Max = MaxF; Min = MinF; Fun = x; InitializeComponent(); Timer.Interval = 1000; //интервал для таймера lastiteration.Enabled = false; //начальные параметры доступа некоторых объектов Stop_button.Enabled = false; newpop = OptimizationAlgorithms.NewPopulation(MinX, MaxX, MinY, MaxY); //формируем новую популяцию lastmassiv = new double[newpop.GetLength(0), 2]; //инициализируем массив для предыдущей итерации Postroenye(); //строим график без точек zedGraph.IsShowPointValues = true;// включаем показ всплывающих подсказок при наведении курсора на график // для изменения формата представления координат обрабатываем событие для графика zedGraph.PointValueEvent += new ZedGraphControl.PointValueHandler(zedGraph_PointValueEvent); GraphSupport.SetToolTip(zedGraph, "Красным цветом обозначается лучший агент, желтым - худший агент, зеленым - остальные агенты"); //подсказка для графика }
double[,] newpop; //переменные для возможности использовать вне конструктора #endregion Fields #region Constructors public PopulationShow(int Kol, double[,] newpop, Functions.FunctionVyb Fun) { //конструктор формы InitializeComponent(); this.newpop = newpop; this.Fun = Fun; //присваивание внешним переменным Iteration.Text = Kol.ToString(); //задание количества итераций Population.RowCount = newpop.GetLength(0); Population.ColumnCount = 3; Population.Columns[0].HeaderText = "Координата Х"; //именуем столбцы Population.Columns[1].HeaderText = "Координата Y"; Population.Columns[2].HeaderText = "Значение функции"; for (int i = 0; i < newpop.GetLength(0); i++) { //заполняем таблицу switch ((int)KolZnakov.Value) { //в зависимости от выбранного количества знаков, заполняем таблицу case 0: Population[0, i].Value = string.Format("{0:f0}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f0}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f0}",Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 1: Population[0, i].Value = string.Format("{0:f1}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f1}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f1}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 2: Population[0, i].Value = string.Format("{0:f2}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f2}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f2}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 3: Population[0, i].Value = string.Format("{0:f3}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f3}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f3}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 4: Population[0, i].Value = string.Format("{0:f4}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f4}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f4}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 5: Population[0, i].Value = string.Format("{0:f5}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f5}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f5}",Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 6: Population[0, i].Value = string.Format("{0:f6}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f6}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f6}",Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 7: Population[0, i].Value = string.Format("{0:f7}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f7}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f7}",Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 8: Population[0, i].Value = string.Format("{0:f8}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f8}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f8}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 9: Population[0, i].Value = string.Format("{0:f9}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f9}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f9}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 10: Population[0, i].Value = string.Format("{0:f10}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f10}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f10}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 11: Population[0, i].Value = string.Format("{0:f11}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f11}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f11}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 12: Population[0, i].Value = string.Format("{0:f12}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f12}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f12}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 13: Population[0, i].Value = string.Format("{0:f13}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f13}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f13}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 14: Population[0, i].Value = string.Format("{0:f14}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f14}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f14}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; case 15: Population[0, i].Value = string.Format("{0:f15}",newpop[i, 0]); Population[1, i].Value = string.Format("{0:f15}", newpop[i, 1]); Population[2, i].Value = string.Format("{0:f15}", Fun(newpop[i, 0], newpop[i, 1])); Population.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1); break; } } }
//улучшения в мемеплексах для поиска минимума public static double[,] PopulationBadModernization(double[,] newpop, double MinIntX, double MaxIntX, double MinIntY, double MaxIntY, int populationsize, int n, Functions.FunctionVyb Fun) { double[, ,] memeplexes = new double[(int)populationsize / n, n, 2]; //создаем матрицу-мемеплексов Random gen = new Random(); double[] max = new double[2]; max[0] = newpop[0, 0]; max[1] = newpop[0, 1]; //глобальный максимум (минимальное значение) for (int i = 0; i < populationsize; i++) if (Fun(max[0], max[1]) > Fun(newpop[i, 0], newpop[i, 1])) { max[0] = newpop[i, 0]; //поиск агента с минимальным значением фитнесс функции max[1] = newpop[i, 1]; } for (int i = 0; i < memeplexes.GetLength(0); i++) for (int j = 0; j < n; j++) { memeplexes[i, j, 0] = newpop[i + j, 0]; memeplexes[i, j, 1] = newpop[i + j, 1]; //задание мемеплексов } for (int i = 0; i < memeplexes.GetLength(0); i++) //модернизируем популяцию { double[] Sbest = new double[2]; Sbest[0] = memeplexes[i, 0, 0]; Sbest[1] = memeplexes[i, 0, 1]; double[] Sworst = new double[2]; //задание лучшего и худшего агентов Sworst[0] = memeplexes[i, 0, 0]; Sworst[1] = memeplexes[i, 0, 1]; int SWind = 0; //индекс худшего агента for (int k = 0; k < n; k++) //проходим по мемеплексу и ищем лучшего и худшего агентов в мемеплексе { if (Fun(Sbest[0], Sworst[1]) > Fun(memeplexes[i, k, 0], memeplexes[i, k, 1])) { Sbest[0] = memeplexes[i, k, 0]; //ищем лучшего агента в мемеплексе Sbest[1] = memeplexes[i, k, 1]; } else if (Fun(Sworst[0], Sworst[1]) < Fun(memeplexes[i, k, 0], memeplexes[i, k, 1])) { Sworst[0] = memeplexes[i, k, 0]; //ищем худшего агента Sworst[1] = memeplexes[i, k, 1]; SWind = k; //задаем индекс худшего агента } } //начинаем улучшать позицию худшего агента в мемеплексе double[] Sworsttry = new double[2]; Sworsttry[0] = MinIntX; Sworsttry[1] = MinIntY; Sworsttry[0] = Sworst[0] + gen.NextDouble() * (Sbest[0] - Sworst[0]); //улучшение на локальном максимуме Sworsttry[1] = Sworst[1] + gen.NextDouble() * (Sbest[1] - Sworst[1]); if (Sworsttry[0] < MinIntX) Sworsttry[0] = MinIntX; //если агент выходит за рамки присваиваем граничные значения if (Sworsttry[1] < MinIntY) Sworsttry[1] = MinIntY; if (Sworsttry[0] > MaxIntX) Sworsttry[0] = MaxIntX; if (Sworsttry[1] > MaxIntY) Sworsttry[1] = MaxIntY; if (Fun(Sworsttry[0], Sworsttry[1]) < Fun(Sworst[0], Sworst[1])) { memeplexes[i, SWind, 0] = Sworsttry[0]; //если улучшение прошло успешно, то фиксируем улучшение memeplexes[i, SWind, 1] = Sworsttry[1]; } else //если улучшение неудачно, пробуем улучшить на глобальном максимуме { Sworsttry[0] = MinIntX; Sworsttry[1] = MinIntY; //задаем начальное значение Sworsttry[0] = Sworst[0] + gen.NextDouble() * (max[0] - Sworst[0]); //улучшение на глобальном максимуме Sworsttry[1] = Sworst[1] + gen.NextDouble() * (max[1] - Sworst[1]); if (Sworsttry[0] < MinIntX) Sworsttry[0] = MinIntX; //если агент выходит за рамки присваиваем граничные значения if (Sworsttry[1] < MinIntY) Sworsttry[1] = MinIntY; if (Sworsttry[0] > MaxIntX) Sworsttry[0] = MaxIntX; if (Sworsttry[1] > MaxIntY) Sworsttry[1] = MaxIntY; if (Fun(Sworsttry[0], Sworsttry[1]) < Fun(Sworst[0], Sworst[1])) //если улучшение помогло, фиксируем { memeplexes[i, SWind, 0] = Sworsttry[0]; memeplexes[i, SWind, 1] = Sworsttry[1]; } else //если и это улучшение не прошло, то генерируем агента по новой { memeplexes[i, SWind, 0] = MinIntX + gen.NextDouble() * (MaxIntX - MinIntX); //задаем случайно популяцию - в промежутке искомом memeplexes[i, SWind, 1] = MinIntY + gen.NextDouble() * (MaxIntY - MinIntY); } } } for (int i = 0; i < memeplexes.GetLength(0); i++) { for (int j = 0; j < n; j++) { newpop[i + j, 0] = memeplexes[i, j, 0]; //собираем популяцию воедино заново из измененного мемеплекса newpop[i + j, 1] = memeplexes[i, j, 1]; } } return newpop; }