public static Tuple<Function, string> FunctionVariation(Function I, double level = 1, double from = 0, double to = 1, string by = "x") { StringBuilder sb = new StringBuilder( @"<!DOCTYPE html> <?xml-stylesheet type='text/xsl' href='mathml.xsl'?> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:math='http://www.w3.org/1998/Math/MathML' > <head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head> <body> <b>Вариация функции:</b></br>" ); sb.AppendFormat("<math><mrow><mi>I</mi><mo>=</mo><mrow><msubsup><mo>∫</mo><mn>{1}</mn><mn>{2}</mn></mrow><mrow><mfenced>{0}</mfenced></mrow><mo>d</mo><mi>{3}</mi></mrow></math></br>", I.ToMathML(), from, to, by); string[] vars = I.Variables; Dictionary<string, IMatrixElement> varsValues = new Dictionary<string, IMatrixElement>(); Variable Alpha = new Variable("α"); for (int i = 0; i < vars.Length; i++) { if (vars[i] != by) { varsValues[vars[i]] = new FunctionMatrixElement(new Function(new Variable(vars[i]) + Alpha * new Variable("d" + vars[i]))); } } Function I2 = new Function(I.SetVariablesValues(varsValues)); sb.AppendFormat(@" <math><mrow> <mi>I</mi><mfenced><mrow><mi>y</mi><mo>+</mo><mi>{4}</mi><mo>d</mo><mi>y</mi></mrow></mfenced><mo>=</mo> <mrow> <mrow><msubsup><mo>∫</mo><mn>{1}</mn><mn>{2}</mn></msubsup></mrow> <mrow>{0}</mrow><mrow><mo>d</mo><mi>{3}</mi></mrow></mrow> </mrow> </mrow></math></br>", I2.ToMathML(), from, to, by, Alpha.Name); var curI = I2; for (int i = 0; i < level; i++) { sb.AppendFormat("</br></br>{0} вариация:</br>", i + 1); var dI2 = new Function(curI.Derivative(Alpha.Name)); sb.AppendFormat("<math><mrow><msup><mo>d</mo><mn>{4}</mn></msup></mrow><mi>I</mi><mo>=</mo><msubsup><mo>∫</mo><mn>{1}</mn><mn>{2}</mn></msubsup><mfenced><mrow>{0}</mrow></mfenced><mo>d</mo><mi>{3}</mi><math></br></br>", dI2.ToMathML(), from, to, by, i + 1); sb.AppendFormat("<math><mrow><msup><mo>d</mo><mn>{4}</mn></msup></mrow><mi>I</mi><mo>⁢</mo><mrow><mfenced><mrow>{5}</mrow><mo>=</mo><mi>0</mi></mfenced></mrow><mo>=</mo><msubsup><mo>∫</mo><mn>{1}</mn><mn>{2}</mn></msubsup><mfenced><mrow>{0}<mrow></mfenced><mo>d</mo><mi>{3}</mi><math>", dI2.SetVariableValue(Alpha.Name, 0).ToMathML(), from, to, by, i + 1, Alpha.Name); curI = dI2; } sb.Append("</body></html>"); return new Tuple<Function, string>(new Function(curI.SetVariableValue(Alpha.Name, 0)), sb.ToString()); }
public static Tuple<Matrix, string> NuthonMethod(Function f, Matrix x0, double e1, double e2, int M) { string matrixStartLine = "[", matrixElementsSeparator = ", ", matrixEndLine = "]"; StringBuilder sb = new StringBuilder("Метод Ньютона\n"); int k = 0; double t = 0; string[] vars = f.Variables; Matrix varsNames = new Matrix(vars.Length); int n = vars.Length; for (int i = 0; i < vars.Length; i++) { varsNames[i] = new FunctionMatrixElement(1, vars[i]); } Matrix gradF = f.Gradient(); Matrix H = f.GesseMatrix(); sb.AppendFormat("Шаг 1. Задаём: x0 = {0}, e1 = {1}, e2 = {2}, M = {3}\n", x0.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine), e1, e2, M); sb.AppendFormat(" Градиент функции: ▼f = {0}\n", gradF.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); sb.AppendFormat(" Матрица Гессе: H = {0}\n", H.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); sb.AppendFormat("Шаг 2. Положим: k = {0}\n", k); List<Matrix> gradFs = new List<Matrix>(); List<Matrix> x = new List<Matrix>(); List<Matrix> d = new List<Matrix>(); x.Add(x0); Matrix answer = x0; while (true) { sb.AppendFormat("---------------------------{0} иттерация-------------------\n", k); gradFs.Add(gradF.SetVariablesValuesWithFixedOrder(x[k], varsNames)); sb.AppendFormat("Шаг 3. Градиент: ▼f(x[{0}]) = {1}\n", k, gradFs[k].Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); double normF = gradFs[k].Norm(); sb.AppendFormat("Шаг 4. 1-ый критерий окончания: || ▼f(x[{0}]) || = {1} {2} e1 = {3}\n", k, normF, normF <= e1 ? " <= " : " > ", e1); if (normF <= e1) { answer = x[k]; sb.AppendFormat("1-ый критерий выполнен, следовательно x* = {0}", answer.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); break; } sb.AppendFormat("Шаг 5. Проверяем k >= M: {0} {1} {2}\n", k, k < M ? "<" : ">=", M); if (k >= M) { answer = x[k]; sb.AppendFormat("Следовательно x* = {0}", answer.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); break; } Matrix Hk = H.SetVariablesValuesWithFixedOrder(x[k], varsNames); sb.AppendFormat("Шаг 6. H(x[{0}]):\n{1}\n", k, Hk.ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); sb.AppendFormat("Шаг 7. Обратная матрица матрицы H(x[{0}]):\n{1}\n", k, Hk.Reverse().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); bool flag = Hk.Reverse().Silvestr(); sb.AppendFormat("Шаг 8. Проверяем условие H^-1[{0}] > 0: {1}", k, flag); if (flag) { sb.AppendFormat(" => переходим к 9 шагу.\n"); d.Add(new FunctionMatrixElement(-1) * Hk.Reverse() * gradFs[k]); sb.AppendFormat("Шаг 9. Находим d[{0}]:\n{1}\n", k, d[k].ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); t = 1; } else { d.Add(new FunctionMatrixElement(-1) * gradFs[k]); sb.AppendFormat(" => переходим к 10 шагу, положим d[{0}] = -▼f(x[{0}]):{1}\n", k, d[k].ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); Matrix tf = x[k] - new FunctionMatrixElement(1, "t#") * gradFs[k]; Function fi = new Function(f.SetVariablesValues(tf)); sb.AppendFormat("x{0} - t{0}*▼f(x{0}) = {1}\n", k, tf.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); sb.AppendFormat("f(x{0} - t{0}*▼f(x{0})) = {1}\n", k, fi); Equation et = new Function(fi.Derivative("t#")).EquationSolutionByVariable("t#", new Function(0)); sb.AppendLine(et.ToString()); t = et.RightPart.ToDouble(); } x.Add(x[k] + new FunctionMatrixElement(t) * d[k]); sb.AppendFormat("Шаг 10. x{0} = {1}\n", k + 1, x[k + 1].Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); if (k == 0) { k++; sb.AppendFormat("Шаг 11. Т.к. это первая иттерация, то увеличиваем k и возвращаемся к 3 шагу.\n\tk = {0}\n", k); continue; } double normX1 = (x[k + 1] - x[k]).Norm(), normX2 = (x[k] - x[k - 1]).Norm(); double normF1 = Math.Abs((new Function(f.SetVariablesValuesWithFixedOrder(x[k + 1], varsNames)) - f.SetVariablesValuesWithFixedOrder(x[k], varsNames)).ToDouble()), normF2 = Math.Abs((new Function(f.SetVariablesValuesWithFixedOrder(x[k], varsNames)) - f.SetVariablesValuesWithFixedOrder(x[k - 1], varsNames)).ToDouble()); sb.AppendFormat("Шаг 11. ||x{0} - x{1}|| = {2} {3} {4}\n ||f(x{0}) - f(x{1})|| = {5} {6} {4}\n", k, k + 1, normX1, normX1 < e2 ? "<" : ">", e2, normF1, normF1 < e2 ? "<" : ">"); sb.AppendFormat(" ||x{0} - x{1}|| = {2} {3} {4}\n ||f(x{0}) - f(x{1})|| = {5} {6} {4}\n", k - 1, k, normX2, normX2 < e2 ? "<" : ">", e2, normF2, normF2 < e2 ? "<" : ">"); if (normX1 < e2 && normX2 < e2 && normF1 < e2 && normF2 < e2) { answer = x[k + 1]; sb.AppendFormat("Следовательно x* = {0}", answer.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); break; } else { k++; sb.AppendFormat("Т.к. хотя бы одно условие не выполнено (не <), то увеличиваем k и возвращаемся к 3 шагу.\n\tk = {0}\n", k); continue; } } return new Tuple<Matrix, string>(answer, sb.ToString()); }
public static Tuple<Matrix, string> BarrierMethod(Function f, Equation[] q, Matrix x0, double e, double r0, double C) { List<Function> qm = new List<Function>(), qp = new List<Function>(); StringBuilder sb = new StringBuilder("<h1>Метод барьерных функций</h1></br>"); foreach (var qi in q) { if (qi.Sign == "<=") { qp.Add(qi.AllToLeft()); } if (qi.Sign == "=") { qm.Add(qi.AllToLeft()); } } sb.AppendFormat("<b>Функция</b> f = {0}</br><b>Ограничения:</b></br>", f.ToMathML()); int i = 0; qm.ForEach(qi => sb.AppendFormat("    q({0}) = {1} = 0</br>", i++, qi.ToMathML())); i = 0; qp.ForEach(qi => sb.AppendFormat("    q({0}) = {1} <= 0</br>", i++, qi.ToMathML())); int k = 0; string[] vars = f.Variables; Matrix varsNames = new Matrix(vars.Length); for (i = 0; i < vars.Length; i++) { varsNames[i] = new FunctionMatrixElement(1, vars[i]); } sb.AppendFormat("Шаг 1. Задаём: <math><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><mo>=</mo><mrow>{0}</mrow><mo></math>,штраф <math><msub><mi>r</mi><mn>0</mn></msub><mo>=</mo></math>{1}, C = {2}, e = {3}, k = {4}</br>", x0.ToMathML(), r0, C, e, k); List<Matrix> x = new List<Matrix>(); List<double> r = new List<double>(); Function Sq = new Function(); foreach(var qi in q) { Sq += qi.AllToLeft().Pow(-1); } Function P = new Variable("rk") * Sq; x.Add(x0); r.Add(r0); Matrix answer = x0; while (true) { sb.AppendFormat("---------------------------<b>{0} иттерация</b>-------------------</br>", k); Function F = f - P.SetVariableValue("rk", r[k]); sb.AppendFormat("Шаг 2. Вспомогательная функция = {0}</br>", F.ToMathML()); //Function der = F.Derivative(); //Matrix minX = SecondOrderMethods.NuthonMethod(F, x[k], e, e, 5).Item1; Matrix minX = MinimisationMethods.PenaltyMethod(F, q.ToArray(), x[k], e, r0, C).Item1; sb.AppendFormat("Шаг 3. Минимум функции F:</br>     <math><msub><mi>x</mi><mn>0</mn></msub><mo>=</mo><msub><mi>x</mi><mn>{0}</mn></msub><mo>=</mo></math>{1}</br>    X* = {2}</br>", k, x[k].ToMathML(), minX.ToMathML() ); sb.AppendFormat("Шаг 4. Условие окончания: <math><mi>P</mi><mfenced><msup><mi>x</mi><mn>*</mn></msup><mfenced><msub><mi>r</mi><mn>{0}</mn></msub></mfenced><mo>,</mo><msub><mi>r</mi><mn>{0}</mn></msub></mfenced><mo><=?</mo><mi>e</mi><mo>=</mo><mi>{1}</mi></math></br>", k, e); double p = Math.Abs(new Function(P.SetVariableValue("rk", r[k])).SetVariablesValuesWithFixedOrder(minX, varsNames).ToDouble()); sb.AppendFormat("    {0} {1} {2}</br>", p, p <= e ? "<=" : ">", e); if (p <= e) { answer = minX; sb.AppendFormat("Следовательно x* = {0}", answer.ToMathML()); break; } else { r.Add(r[k] / C); x.Add(minX); k++; } } return new Tuple<Matrix, string>(answer, sb.ToString()); }
public static Tuple<Matrix, string> PenaltyMethod(Function f, Equation[] q, Matrix x0, double e, double r0, double C) { string matrixStartLine = "[", matrixElementsSeparator = ", ", matrixEndLine = "]"; List<Function> qm = new List<Function>(), qp = new List<Function>(); StringBuilder sb = new StringBuilder("<h1>Метод штрафных функций</h1></br>"); foreach (var qi in q) { if (qi.Sign == "<=") { qp.Add(qi.AllToLeft()); } if (qi.Sign == "=") { qm.Add(qi.AllToLeft()); } } sb.AppendFormat("<b>Функция</b> f = {0}</br><b>Ограничения:</b></br>", f.ToMathML()); int i = 0; qm.ForEach(qi => sb.AppendFormat("    q({0}) = {1} = 0</br>", i++, qi.ToMathML())); i = 0; qp.ForEach(qi => sb.AppendFormat("    q({0}) = {1} <= 0</br>", i++, qi.ToMathML())); int k = 0; string[] vars = f.Variables; Matrix varsNames = new Matrix(vars.Length); for (i = 0; i < vars.Length; i++) { varsNames[i] = new FunctionMatrixElement(1, vars[i]); } sb.AppendFormat("Шаг 1. Задаём: <math><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><mo>=</mo><mrow>{0}</mrow><mo></math>,штраф <math><msub><mi>r</mi><mn>0</mn></msub><mo>=</mo></math>{1}, C = {2}, e = {3}, k = {4}</br>", x0.ToMathML(), r0, C, e, k); List<Matrix> x = new List<Matrix>(); List<double> r = new List<double>(); Function Sm = new Function(); Function Sp = new Function(); qm.ForEach(qi => Sm += qi.Pow(2)); #warning Врятли без этого оно будет работать //qp.ForEach(qi => Sp += qi.AddFunction(new SliceFunction()).Pow(2)); Function P = new Variable("rk") / 2.0 * (Sm + Sp); x.Add(x0); r.Add(r0); Matrix answer = x0; while (true) { sb.AppendFormat("---------------------------{0} иттерация-------------------\n", k); sb.AppendFormat("{0}\n", P); Function F = f + P.SetVariableValue("rk", r[k]); sb.AppendFormat("Шаг 2. Вспомогательная функция = {0}\n", F); Matrix minX = SecondOrderMethods.NuthonMethod(F, x[k], e, e, 5).Item1; sb.AppendFormat("Шаг 3. Минимум функции F:\n\tx[0] = x[{0}] = {1}\n\tX* = {2}\n", k, x[k].Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine), minX.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine) ); sb.AppendFormat("Шаг 4. Условие окончания: P(x*(r[{0}],r[{0}]) <=? e = {1}\n", k, e); double p = new Function(P.SetVariableValue("rk", r[k])).SetVariablesValuesWithFixedOrder(minX, varsNames).ToDouble(); sb.AppendFormat(" {0} {1} {2}\n", p, p <= e ? "<=" : ">", e); if (p <= e) { answer = minX; sb.AppendFormat("Следовательно x* = {0}", answer.Transposition().ToString(matrixStartLine, matrixElementsSeparator, matrixEndLine)); break; } else { r.Add(C * r[k]); x.Add(minX); k++; } } return new Tuple<Matrix, string>(answer, sb.ToString()); }
public Matrix GesseMatrix() { string[] vars = this.Variables; Matrix m = new Matrix(vars.Length, vars.Length); for (int i = 0; i < vars.Length; i++) { for (int j = 0; j < vars.Length; j++) { m[i, j] = new FunctionMatrixElement(new Function(this.Derivative(vars[i]).Derivative(vars[j]))); } } return m; }
public Matrix Gradient() { string[] vars = this.Variables; Matrix m = new Matrix(vars.Length, 1); for (int i = 0; i < vars.Length; i++) { m[i, 0] = new FunctionMatrixElement(new Function(this.Derivative(vars[i]))); } return m; }