예제 #1
0
 public Vertex(XPoint x1, XPoint x2, double value = 0)
 {
     X1    = x1;
     X2    = x2;
     Value = value;
 }
예제 #2
0
        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);
        }