/// <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) { Params cP = (Params)p.Clone(); Result result = cP.ToResult(); result.ListP.Clear(); // устанавливаем функцию f = p.Y; Vector gfk = Functions.Math.GF(f, result.GetLastX()); do { // Шаг 1 Matrix hessian = Functions.Math.GetMatrixHessianInPoint(f, result.GetLastX()); Vector P = Functions.Math.GetTheSolutionOfTheSystem(hessian, -gfk); if (NormalizationDirections && P.Norma > 1.0) { P = P.Rationing(); } result.ListP.Add(P); //Шаг 2 result.ListX.Add(X(result.GetLastX(), alfa, result.GetLastP())); // Шаг 3 gfk = Functions.Math.GF(f, result.GetLastX()); if (Lim.CheckNorma(result.GetLastP()) || Lim.CheckNorma(gfk)) { break; } result.K++; } while (result.K < Lim.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 = 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 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 (p.Alfa.Size != 2) { throw new Exception(Name + " вектор альф не имеет 2 элемента"); } // Скопирвоать входные параметры для изменения Params cP = (Params)p.Clone(); if (NormalizationDirections && cP.P.Norma > 1.0) { cP.P = cP.P.Rationing(); } Result result = cP.ToResult(); Vector x = result.ListX[0], P = result.ListP[0]; // утановить функцию f = p.Y; // основной этап do { // шаг 1 вычислить gamma double alfa_; Vector xalfa1 = X(x, result.Alfas[0], P); Vector xalfa2 = X(x, result.Alfas[1], P); double dfalfa1 = Functions.Math.GF(f, xalfa1, P); double dfalfa2 = Functions.Math.GF(f, xalfa2, P); double z = dfalfa1 + dfalfa2 + 3.0 * (f.Parse(xalfa1) - f.Parse(xalfa2)) / (result.Alfas[1] - result.Alfas[0]); double omega = System.Math.Sqrt(z * z - dfalfa1 * dfalfa2); double gamma = (z + omega - dfalfa1) / (dfalfa2 - dfalfa1 + 2.0 * omega); if (gamma < 0.0) { alfa_ = result.Alfas[0]; } else if (gamma > 1.0) { alfa_ = result.Alfas[1]; } else { alfa_ = result.Alfas[0] + gamma * (result.Alfas[1] - result.Alfas[0]); } // шаг 2 проверить коп Vector gfalfa_V = Functions.Math.GF(f, X(x, alfa_, P)); if (Lim.CheckMinEps(Functions.Math.GF(f, X(x, alfa_, P), P)) || Lim.CheckNorma(gfalfa_V) || alfa_ == result.Alfas[0] || alfa_ == result.Alfas[1]) { result.AlfaMin = alfa_; break; } double gfalfa_ = Functions.Math.GF(f, X(x, alfa_, P), P); if (gfalfa_ > 0.0) { result.Alfas[1] = alfa_; } else { result.Alfas[0] = alfa_; } result.K++; } while (result.K < Lim.K); if (!double.IsNaN(result.AlfaMin)) { result.XMin = X(x, result.AlfaMin, P); } 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); }