public Vertex(XPoint x1, XPoint x2, double value = 0) { X1 = x1; X2 = x2; Value = value; }
public static List <PointF> MethodBox(out List <PointF> pts, MethodInfo mainF, MethodInfo condF, bool sMin) { CalculationsCount++; //n - кол-во независеммых переменных int n = 2; //Длинна комлекса 2 * n при n <= 5 int N = 2 * n; XPoint[,] points; Vertex[] vertices; double[] g = new double[] { Param1Min, Param2Min }; double[] h = new double[] { Param1Max, Param2Max }; do { points = new XPoint[n, N]; vertices = new Vertex[N]; Random rnd = new Random(); for (int j = 0; j < N; j++) { double r1 = Math.Abs(rnd.NextDouble()); double r2 = Math.Abs(rnd.NextDouble()); var p1 = g[0] + r1 * (h[0] - g[0]); var p2 = g[1] + r2 * (h[1] - g[1]); vertices[j] = new Vertex(new XPoint(p1), new XPoint(p2)); } } while (vertices.Count(vertex => !CheckVertex2(vertex, condF)) == N); var nonFixed = new List <Vertex>(vertices.Where(x => !CheckVertex2(x, condF))); var fixes = new List <Vertex>(vertices.Where(x => CheckVertex2(x, condF))); var count2 = 0; for (int i = 0; i < nonFixed.Count && count2 < 1000; i++) { double sum1 = 0, sum2 = 0; for (int k = 0; k < fixes.Count; k++) { sum1 += fixes[k].X1.Value; sum2 += fixes[k].X2.Value; } var temp = new Vertex(); temp.X1.Value = 0.5 * ((nonFixed[i].X1.Value + sum1) / fixes.Count); temp.X2.Value = 0.5 * ((nonFixed[i].X2.Value + sum2) / fixes.Count); if (CheckVertex2(temp, condF)) { fixes.Add(temp); } else { nonFixed[i] = temp; i--; count2++; } } vertices = fixes.ToArray(); //Вычисление значений целевой функции Fj для всех N вершин Комплекса vertices = vertices.Select(vertex => { vertex.Value = Convert.ToDouble(mainF.Invoke(null, new object[] { vertex.X1.Value, vertex.X2.Value })); return(vertex); }).ToArray(); Vertex vertexG = default; //Поиск лучшей и худшей вершины do { //vertexG = vertices.OrderBy(x => x.Value).First(); //var vertexD = vertices.OrderBy(x => x.Value).Last(); Vertex vertexD = default; int minValueInx = 0; int maxValueInx = 0; double min = double.MaxValue; double max = double.MinValue; for (int i = 0; i < vertices.Length; i++) { if (vertices[i].Value < min) { minValueInx = i; min = vertices[i].Value; } if (vertices[i].Value > max) { maxValueInx = i; max = vertices[i].Value; } } if (sMin) { vertexG = vertices[minValueInx]; vertexD = vertices[maxValueInx]; } else { vertexG = vertices[maxValueInx]; vertexD = vertices[minValueInx]; } //Определение координат Ci центра Комплекса с отброшенной "наихудшей" вершиной // Для X1 double tsum1 = 0, tsum2 = 0; for (int J = 0; J < N; J++) { tsum1 += vertices[J].X1.Value; tsum2 += vertices[J].X2.Value; } double C_X1 = (tsum1 - vertexD.X1.Value) / (N - 1); double C_X2 = (tsum2 - vertexD.X2.Value) / (N - 1); double cSum1 = Math.Abs(C_X1 - vertexD.X1.Value) + Math.Abs(C_X1 - vertexG.X1.Value); double cSum2 = Math.Abs(C_X2 - vertexD.X2.Value) + Math.Abs(C_X2 - vertexG.X2.Value); double B = (cSum1 + cSum2) / (2 * n); //Проверка условия окончания поиска if (B < FuncAccuracy / 100) { break; } //Вычисление координаты новой точки Комплекса взамен наихудшей var optVertex = new Vertex( new XPoint(2.3 * C_X1 - 1.3 * vertexD.X1.Value), new XPoint(2.3 * C_X2 - 1.3 * vertexD.X2.Value)); //Проверка выполнения ограничений 2.го рода для новой точки. while (!CheckVertex2(optVertex, condF)) { optVertex.X1.Value = 0.5 * (optVertex.X1.Value + C_X1); optVertex.X2.Value = 0.5 * (optVertex.X2.Value + C_X2); } //Вычисление значения целевой функции F0 в новой точке optVertex.Value = Convert.ToDouble(mainF.Invoke(null, new object[] { optVertex.X1.Value, optVertex.X2.Value })); //Нахождение новой вершины смещением xi0 на половину расстояния к лучшей из вершин комплекса с номером G if (sMin) { while (optVertex.Value > vertexD.Value) { optVertex.X1.Value = 0.5 * (optVertex.X1.Value + vertexG.X1.Value); optVertex.X2.Value = 0.5 * (optVertex.X2.Value + vertexG.X2.Value); optVertex.Value = Convert.ToDouble(mainF.Invoke(null, new object[] { optVertex.X1.Value, optVertex.X2.Value })) - 10; //а шоб быстрее было } } else { while (optVertex.Value < vertexD.Value) { optVertex.X1.Value = 0.5 * (optVertex.X1.Value + vertexG.X1.Value); optVertex.X2.Value = 0.5 * (optVertex.X2.Value + vertexG.X2.Value); optVertex.Value = Convert.ToDouble(mainF.Invoke(null, new object[] { optVertex.X1.Value, optVertex.X2.Value })); } } var indexD = vertices.ToList().IndexOf(vertexD); vertices[indexD] = optVertex; } while (true); //double[,] x = CalcComplex(n, N); //int P = CheckComplex(x, n, N); //x = CalcComplexStar(x, n, N, P); ////Отсюда закинуть все в отдельный метод //double[] F = new double[N]; //for (int i = 0; i < n; i++) //{ // for (int j = 0; j < N; j++) // { // F[j] = Convert.ToDouble(mainF.Invoke(null, new object[] { x[0, j], x[1, j] })); // } //} //double[,] new_coord = MainOptimMethodBox(x, mainF, n, N, F, sMin); pts = new List <PointF>(); if (sMin) { pts.Add(new PointF((float)Param1Min, (float)Param2Min)); pts.Add(new PointF((float)Param1Max, (float)Param2Max)); } else { pts.Add(new PointF((float)Param1Max, (float)Param2Max)); pts.Add(new PointF((float)Param1Min, (float)Param2Min)); } pts.Add(new PointF((float)vertexG.X1.Value, (float)vertexG.X2.Value)); return(pts); }