public override Result Run(Params p) { if (MethodsUsed == null) { throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; int n = p.Y.Vars.Count; Vector g; do { g = Functions.Math.GF(f, cP.X0); if (NormalizationDirections && g.Norma > 1.0) { g = g.Rationing(); } if (result.K % n == 1) { cP.P = -g; } else { /// получаем сопряженный коэф направления result.Betas.Push(ConjugateDirection.MethodPolakRibiere(g, -cP.P)); cP.P = -g + result.Betas.Last * cP.P; } result.ListP.Add(cP.P); Result resultMethods = MethodsUsed.Run(cP); /// поиск alfa_ result.Alfas.Push(resultMethods.AlfaMin); // сохранение коэф. для направления минимизации cP.X0 = X(cP.X0, result.Alfas.Last, cP.P); result.ListX.Add(cP.X0); result.K++; /// проверяем критерий Пауэлла if (!(g * cP.P <= 0.2 * g.Norma) || Lim.CheckMinEps(g * g) || Lim.CheckMinEps(result.ListX[result.ListX.Count - 1], result.ListX[result.ListX.Count - 2])) { break; } } while (result.K < Lim.K); result.XMin = result.ListX[result.ListX.Count - 1]; return(result); }
/// <summary> /// Запуск на исполнение метода /// </summary> /// <param name="p"></param> /// <returns></returns> override public Result Run(Params p) { if (MethodsUsed == null) { throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; // параметры для поиска минимума на k-ом шаге Params pSerch = (Params)p.Clone(); while (result.K <= Lim.K) { pSerch.X0 = result.ListX[result.ListX.Count - 1]; pSerch.H = cP.H; // получаю направление pSerch.P = -Functions.Math.GF(cP.Y, pSerch.X0); if (NormalizationDirections && pSerch.P.Norma > 1.0) { pSerch.P = pSerch.P.Rationing(); } result.ListP.Add(pSerch.P); // получаю шаг до минимума Result resultMethods = MethodsUsed?.Run(pSerch); result.Alfas.Push(resultMethods.AlfaMin); // получаю следующий вектор result.ListX.Add(pSerch.X0 + result.Alfas.Last * pSerch.P); // проверяю коп if (Lim.CheckMinEps(result.ListX[result.ListX.Count - 1], result.ListX[result.ListX.Count - 2]) && Lim.CheckNorma(pSerch.P) && Lim.CheckMinEps(f.Parse(result.ListX[result.ListX.Count - 1]), f.Parse(result.ListX[result.ListX.Count - 2]))) { break; } result.K++; } result.XMin = result.ListX[result.ListX.Count - 1]; return(result); }
public override Result Run(Params p) { if (MethodsUsed == null) { throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; int n = p.Y.Vars.Count; Vector mu = new Vector(); // множество направлений пи и мю for (int i = 0; i < n; i++) { result.ListP.Add(Vector.GetZeroBeside(n, i)); mu.Push(0); result.Alfas.Push(0); result.ListX.Add(null); } Params usesParam = (Params)cP.Clone(); while (result.K <= Lim.K) { // формируем массив альфа, мю, иксов for (int i = 0; i < n; i++) { usesParam.P = result.ListP[i]; usesParam.X0 = result.ListX[i]; usesParam.H = cP.H; result.Alfas[i] = (MethodsUsed.Run(usesParam).AlfaMin); result.ListX[i + 1] = X(usesParam.X0, result.Alfas[i], usesParam.P); mu[i] = f.Parse(result.ListX[i]) - f.Parse(result.ListX[i + 1]); } // получаем направляющий вектор Vector dk = result.ListX[n] - result.ListX[0]; // нормируем dk = dk.Rationing(); usesParam.P = dk; usesParam.X0 = result.ListX[n]; usesParam.H = cP.H; // вычисляю следующую точку double alfa = MethodsUsed.Run(usesParam).AlfaMin; Vector xnpp = result.GetLastX() + alfa * dk; double y1 = f.Parse(result.ListX[0]), ynp = f.Parse(result.ListX[n]), ynpp = f.Parse(xnpp); if (Lim.CheckNorma(dk) || Lim.CheckMinEps(alfa) || Lim.CheckNorma(Functions.Math.GF(f, xnpp)) || Lim.CheckMinEps((ynp - ynpp) / ynp)) { result.ListX.Add(xnpp); break; } // получаем индекс максимального мю int indexMax = mu.GetIndexMaxElem(); // Меняем систему направлений if (4 * mu[indexMax] * (ynp - ynpp) >= (y1 - ynp - mu[indexMax]) * (y1 - ynp - mu[indexMax])) { // если условие перспективности выполнелось, то сдвигаем начиная с i-ого for (int i = indexMax; i < n - 1; i++) { result.ListP[i] = result.ListP[i + 1]; } result.ListP[indexMax] = dk; } else { for (int i = 0; i < n - 1; i++) { result.ListP[i] = result.ListP[i + 1]; } result.ListP[n - 1] = dk; } result.K++; } result.XMin = result.GetLastX(); return(result); }
public override Result Run(Params p) { // проверка переданных методов if (MethodsUsed == null) { throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } // клонирование входных параметров в выходные Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; int n = cP.Y.Vars.Count; // количество переменных Params parMet = (Params)cP.Clone(); result.ListX = new System.Collections.Generic.List <Vector>() { null, null, null, null }; result.ListP = new System.Collections.Generic.List <Vector>() { null, null, null, null }; result.Alfas = new Vector(new double[4]); // получаем x1 result.ListX[0] = cP.X0; do { int i = 0; //Шаг 1 получаем x2 parMet.X0 = result.ListX[0]; result.ListP[0] = -Math.GF(f, result.ListX[0]); if (NormalizationDirections && result.ListP[0].Norma > 1.0) { result.ListP[0] = result.ListP[0].Rationing(); } parMet.P = result.ListP[0]; parMet.H = p.H; Result resultMethods = MethodsUsed.Run(parMet); result.Alfas[0] = resultMethods.AlfaMin; result.ListX[1] = X(result.ListX[0], result.Alfas[0], parMet.P); //Шаг 2 получаем x3, x4 do { // x3 parMet.X0 = result.ListX[1]; result.ListP[1] = -Math.GF(f, result.ListX[1]); if (NormalizationDirections && result.ListP[1].Norma > 1.0) { result.ListP[1] = result.ListP[1].Rationing(); } parMet.P = result.ListP[1]; parMet.H = p.H; resultMethods = MethodsUsed.Run(parMet); result.Alfas[1] = resultMethods.AlfaMin; result.ListX[2] = X(result.ListX[1], result.Alfas[1], parMet.P); // x4 Vector d1 = result.ListX[2] - result.ListX[0]; result.Betas.Push(ConjugateDirection.MethodPolakRibiere(Math.GF(f, result.ListX[1]), Math.GF(f, result.ListX[0]))); result.ListX[3] = result.ListX[2] + result.Betas.Last * d1; i++; // Шаг 3 if (i < n - 1) { result.ListX[0] = result.ListX[1]; result.ListX[1] = result.ListX[3]; } } while (i < n - 1); if (Lim.CheckMinEps(result.ListX[3], cP.X0) || Lim.CheckMinEps(f.Parse(result.ListX[3]), f.Parse(cP.X0))) { break; } cP.X0 = result.ListX[0] = result.ListX[3]; result.K++; } while (result.K < Lim.K); result.XMin = cP.X0; //cP.X0 = xs[3]; return(result); }
public override Result Run(Params p) { // проверка переданных методов if (MethodsUsed == null) { throw new Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } // клонирование входных параметров в выходные Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; int n = cP.Y.Vars.Count; // количество переменных Params parMet = (Params)cP.Clone(); do { for (int i = 1; i <= n; i++) { if (result.ListX.Count != n + 1) { result.ListP.Add(-Functions.Math.GF(f, result.ListX[i - 1])[i - 1] * Vector.GetZeroBeside(n, i - 1)); } else { result.ListP[i - 1] = -Functions.Math.GF(f, result.ListX[i - 1])[i - 1] * Vector.GetZeroBeside(n, i - 1); } if (NormalizationDirections && result.ListP[i - 1].Norma > 1.0) { result.ListP[i - 1] = result.ListP[i - 1].Rationing(); } parMet.X0 = result.ListX[i - 1]; parMet.P = result.ListP[i - 1]; parMet.H = cP.H; Result resultMethods = MethodsUsed?.Run(parMet); result.Alfas.Push(resultMethods.AlfaMin); if (result.ListX.Count != n + 1) { result.ListX.Add(parMet.X0 + resultMethods.AlfaMin * parMet.P); } else { result.ListX[i] = parMet.X0 + resultMethods.AlfaMin * parMet.P; } } Vector d = result.ListX[n] - result.ListX[0]; if (Lim.CheckMinEps(f.Parse(result.ListX[0]), f.Parse(result.ListX[n])) || Lim.CheckMinEps(result.ListX[0], result.ListX[n]) || Lim.CheckNorma(d)) { break; } result.ListX[0] = result.ListX[n]; result.K++; } while (result.K < Lim.K); result.XMin = result.ListX[result.ListX.Count - 1]; return(result); }
public override Result Run(Params p) { if (MethodsUsed == null) { throw new System.Exception("Ошибка метода " + Name + ": не определены методы, которые будет использованны"); } Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; Params usesParams = (Params)cP.Clone(); Matrix A = null; int n = f.Vars.Count; Vector gk = null, gkm = null; do { // Шаг 1 найти матрицу переменной метрики gk = Functions.Math.GF(f, result.GetLastX()); if (result.K % n == 1) { // единичная матрица A = Matrix.GetIdentity(n); } else { Vector gammak = gk - gkm; Vector skm = A * gammak; Vector deltaxkm = result.GetLastX() - result.ListX[result.ListX.Count - 2]; A = Metrics.RunMetric?.Invoke(A, gammak, skm, deltaxkm); } // Шаг 2 поиск направления поиска Vector P = -A * gk; if (NormalizationDirections && P.Norma > 1.0) { P = P.Rationing(); } result.ListP.Add(P); usesParams.X0 = result.GetLastX(); usesParams.P = result.GetLastP(); usesParams.H = cP.H; //Шаг 3 получение альфа result.Alfas.Push(MethodsUsed.Run(usesParams).AlfaMin); // Шаг 4 получение новой точки result.ListX.Add(X(result.GetLastX(), result.Alfas.Last, result.GetLastP())); // Шаг 3 Vector gkmprev = gkm; gkm = Functions.Math.GF(f, result.GetLastX()); if (Lim.CheckNorma(result.GetLastP()) || Lim.CheckNorma(gkm) || Lim.CheckNorma(gkm) || Lim.CheckMinEps(result.GetLastX(), result.ListX[result.ListX.Count - 2]) || Lim.CheckMinEps(result.GetLastX(), result.ListX[0])) { break; } gkm = gk; result.K++; } while (result.K < Lim.K); result.XMin = result.GetLastX(); return(result); }