/// <summary> /// Finds minimum for function using Coordinate Descent Optimization algorithm. /// </summary> /// <param name="vector">Starting point.</param> /// <param name="e">Precision.</param> /// <param name="function">Function used in algorithm.</param> /// <param name="h">Shift used for getting unimodal interval.</param> /// <returns>Minimum of function.</returns> public static Matrica FindMinimum(Matrica vector, Matrica e, Function function, int h) { Matrica x = new Matrica(); x.Equals(vector); Matrica xs = new Matrica(); function.SetParametersSize(x.NoOfRows); do { xs = new Matrica(); xs.Equals(x); for (int i = 0; i < vector.NoOfRows; i++) { Matrica ei = new Matrica(); ei.NoOfColumns = 1; ei.NoOfRows = vector.NoOfRows; for (int j = 0; j < vector.NoOfRows; j++) { List <double> row = new List <double>(); if (i == j) { row.Insert(0, 1); } else { row.Insert(0, 0); } ei.LoadedMatrix.Add(j, row); } for (int j = 0; j < x.NoOfRows; j++) { double value = x.LoadedMatrix[j][0]; if (i == j) { Expression expression = lambda => value + lambda; function.SetParameters(j, expression); } else { Expression expression = lambda => value; function.SetParameters(j, expression); } } UnimodalInterval interval = UnimodalInterval.FindUnimodalInterval(function, 0, h); UnimodalInterval lambdaInterval = GoldenSection.FindMinimum(function, interval.Minimum, interval.Maximum, e.LoadedMatrix[i][0]); double lambdaMin = (lambdaInterval.Minimum + lambdaInterval.Maximum) / 2; ei.MultiplyByScalar(lambdaMin); x.AddValue(ei); } } while (x.SubtractMatrices(xs).IsLessThanOrEqual(e)); function.DeleteParameters(); return(x); }
/// <summary> /// Finds unimodal interval for given function and starting point. /// </summary> /// <param name="function">Function.</param> /// <param name="startingPoint">Starting point.</param> /// <param name="h">Shift.</param> /// <returns>Unimodal interval.</returns> public static UnimodalInterval FindUnimodalInterval(Function function, double startingPoint, double h, string algorithmName) { UnimodalInterval result = new UnimodalInterval(startingPoint - h, startingPoint + h); double m = startingPoint; double funcValueForMinimum, funcValueForMaximum, funcValueForM; uint step = 1; funcValueForM = function.CalculateValue(startingPoint); function.IncreaseCounterValue(algorithmName); funcValueForMinimum = function.CalculateValue(result.Minimum); function.IncreaseCounterValue(algorithmName); funcValueForMaximum = function.CalculateValue(result.Maximum); function.IncreaseCounterValue(algorithmName); if (funcValueForM < funcValueForMaximum && funcValueForM < funcValueForMinimum) { return(new UnimodalInterval(startingPoint - h, startingPoint + h)); } else if (funcValueForM > funcValueForMaximum) { do { result.Minimum = m; m = result.Maximum; funcValueForM = funcValueForMaximum; result.Maximum = startingPoint + h * (step *= 2); funcValueForMaximum = function.CalculateValue(result.Maximum); function.IncreaseCounterValue(algorithmName); } while (funcValueForM > funcValueForMaximum); } else { do { result.Maximum = m; m = result.Minimum; funcValueForM = funcValueForMinimum; result.Minimum = startingPoint - h * (step *= 2); funcValueForMinimum = function.CalculateValue(result.Minimum); function.IncreaseCounterValue(algorithmName); } while (funcValueForM > funcValueForMinimum); } return(result); }
/// <summary> /// Executes Golden Section Optimization algorithm for given function. /// </summary> /// <param name="f">Function used in algorithm.</param> public static void GoldenSectionOptimization(Function f) { Console.WriteLine("ZLATNI REZ:"); Console.WriteLine("============================================"); Console.WriteLine("Unesite 1 ako želite predati početnu točku za koju će se izračunati unimodalni interval ili 2 ako unosite unimodalni interval iz datoteke sami."); string line = Console.ReadLine(); int choice = Int32.Parse(line); if (choice == 1) { Console.WriteLine("Upišite putanju do datoteke s početnom točkom:"); string path1 = Console.ReadLine(); double startingPoint = ReadValueFromFile(path1); Console.WriteLine("Upišite putanju do datoteke s preciznosti e:"); string path2 = Console.ReadLine(); double e = ReadValueFromFile(path2); Console.WriteLine("Upišite putanju do datoteke s pomakom pretraživanja h:"); string path3 = Console.ReadLine(); double h = ReadValueFromFile(path3); UnimodalInterval interval = UnimodalInterval.FindUnimodalInterval(f, startingPoint, h); UnimodalInterval result = GoldenSection.FindMinimum(f, interval.Minimum, interval.Maximum, e); Console.WriteLine("\nRješenje:"); Console.WriteLine("============"); Console.WriteLine("[" + result.Minimum + ", " + result.Maximum + "]"); } else if (choice == 2) { Console.WriteLine("Upišite putanju do datoteke s unimodalnim intervalom:"); string path1 = Console.ReadLine(); UnimodalInterval interval = GetUnimodalIntervalFromFile(path1); Console.WriteLine("Upišite putanju do datoteke s preciznosti e:"); string path2 = Console.ReadLine(); double e = ReadValueFromFile(path2); UnimodalInterval result = GoldenSection.FindMinimum(f, interval.Minimum, interval.Maximum, e); Console.WriteLine("\nRješenje:"); Console.WriteLine("============"); Console.WriteLine("[" + result.Minimum + ", " + result.Maximum + "]"); } else { throw new ArgumentException("Niste odabrali ni 1 ni 2!"); } }