예제 #1
0
        /// <summary>
        /// Finds minimum of given function using the Gradient Descent algorithm.
        /// </summary>
        /// <param name="function">Function used in algorithm.</param>
        /// <param name="e">Precision.</param>
        /// <param name="startingPoint">Starting point of algorithm.</param>
        /// <param name="usingGoldenSection">Flag used for tracking whether user wants to use Golden Section algorithm or not.</param>
        /// <returns>Minimum of function.</returns>

        public static Matrica FindMinimum(Function function, double e, Matrica startingPoint, bool usingGoldenSection)
        {
            Matrica x = new Matrica();

            x.Equals(startingPoint);
            function.SetParametersSize(x.NoOfRows);
            Matrica v      = new Matrica();
            int     brojac = 0;
            Matrica xs     = new Matrica();

            if (usingGoldenSection == false)
            {
                do
                {
                    xs.Equals(x);
                    v = function.CalculateGradientValue(x.VectorToArray());
                    function.IncreaseCounterGradientValue(algorithmName);
                    v.MultiplyByScalar(-1);
                    x.AddValue(v);
                    brojac++;
                    function.IncreaseCounterValue(algorithmName);
                    function.IncreaseCounterValue(algorithmName);
                } while (brojac < 10000);
            }
            else
            {
                do
                {
                    xs.Equals(x);
                    v = function.CalculateGradientValue(x.VectorToArray());
                    function.IncreaseCounterGradientValue(algorithmName);
                    v.MultiplyByScalar(-1);
                    v.MultiplyByScalar(1.0 / function.GetGradientNorm());
                    for (int i = 0; i < x.NoOfRows; i++)
                    {
                        double     value       = x.LoadedMatrix[i][0];
                        double     vectorValue = v.LoadedMatrix[i][0];
                        Expression expression  = lambda => value + lambda * vectorValue;
                        function.SetParameters(i, expression);
                    }

                    UnimodalInterval interval       = UnimodalInterval.FindUnimodalInterval(function, 0, 1, algorithmName);
                    UnimodalInterval lambdaInterval = GoldenSection.FindMinimum(function, interval.Minimum, interval.Maximum, e, algorithmName);

                    double lambdaMin = (lambdaInterval.Minimum + lambdaInterval.Maximum) / 2;
                    v.MultiplyByScalar(lambdaMin);
                    x.AddValue(v);

                    function.IncreaseCounterValue(algorithmName);
                    function.IncreaseCounterValue(algorithmName);
                } while (function.GetGradientNorm() >= e);
            }

            function.DeleteParameters();
            return(x);
        }
예제 #2
0
        /// <summary>
        /// Finds minimum of function using Box optimization method.
        /// </summary>
        /// <param name="function">Function used to optimize.</param>
        /// <param name="implicitRestrictions">List of implicit restrictions used in Box method.</param>
        /// <param name="explicitRestriction">List of explicit restrictions used in Box method.</param>
        /// <param name="startingPoint">Starting point of algorithm.</param>
        /// <param name="alfa">Constant alpha used in algorithm.</param>
        /// <param name="iterations">Number of iterations of algorithm.</param>
        /// <returns></returns>

        public static Matrica FindMinimum(Function function, List <RestrictionExpression> implicitRestrictions, ExplicitRestriction explicitRestriction, Matrica startingPoint, double alfa, int iterations)
        {
            if (OptimizationUtils.CheckIfExplicitConstraintsAreMet(explicitRestriction, startingPoint) == false ||
                OptimizationUtils.CheckIfImplicitConstraintsAreMet(implicitRestrictions, startingPoint) == false)
            {
                throw new ArgumentException("Starting point does not meet explicit and/or implicit conditions!");
            }

            int iter = 0;

            function.SetParametersSize(startingPoint.NoOfRows);
            Matrica centroid = new Matrica();

            centroid.Equals(startingPoint);
            int              n      = startingPoint.NoOfRows;
            Random           random = new Random();
            double           R;
            List <Matrica>   simplex  = new List <Matrica>();
            UnimodalInterval interval = explicitRestriction.GetInterval();

            for (int t = 0; t < 2 * n; t++)
            {
                double[] point = new double[n];
                for (int i = 0; i < n; i++)
                {
                    R        = random.NextDouble() * (maximumForRandom - minimumForRandom) + minimumForRandom;
                    point[i] = interval.Minimum + R * (interval.Maximum - interval.Minimum);
                }

                simplex.Insert(t, Matrica.ArrayToVector(point));

                bool[] simplexPointMeetsImplicitRestrictions = new bool[implicitRestrictions.Count];
                for (int i = 0; i < implicitRestrictions.Count; i++)
                {
                    simplexPointMeetsImplicitRestrictions[i] = false;
                }

                while (true)
                {
                    for (int i = 0; i < implicitRestrictions.Count; i++)
                    {
                        simplexPointMeetsImplicitRestrictions[i] = implicitRestrictions[i].CheckIfMet(simplex[t].VectorToArray());
                        if (simplexPointMeetsImplicitRestrictions[i] == false)
                        {
                            simplex[t].AddValue(centroid);
                            simplex[t].MultiplyByScalar(1.0 / 2);
                            break;
                        }
                    }

                    if (!simplexPointMeetsImplicitRestrictions.Contains(false))
                    {
                        break;
                    }
                }

                centroid = GetCentroidPoint(simplex);
            }

            List <double> functionValues = GetSimplexPointsFunctionValues(simplex, function);
            Matrica       xr             = new Matrica();

            do
            {
                int h  = GetIndexOfWorstPoint(functionValues);
                int h2 = GetIndexOfSecondWorstPoint(functionValues, h);
                centroid = GetCentroidPoint(simplex, h);
                xr       = Reflection(centroid, simplex[h], alfa);

                for (int i = 0; i < xr.NoOfRows; i++)
                {
                    if (xr.LoadedMatrix[i][0] < interval.Minimum)
                    {
                        xr.LoadedMatrix[i][0] = interval.Minimum;
                    }
                    else if (xr.LoadedMatrix[i][0] > interval.Maximum)
                    {
                        xr.LoadedMatrix[i][0] = interval.Maximum;
                    }
                }

                bool[] reflectionMeetsImplicitRestrictions = new bool[implicitRestrictions.Count];
                for (int i = 0; i < implicitRestrictions.Count; i++)
                {
                    reflectionMeetsImplicitRestrictions[i] = false;
                }

                while (true)
                {
                    for (int i = 0; i < implicitRestrictions.Count; i++)
                    {
                        reflectionMeetsImplicitRestrictions[i] = implicitRestrictions[i].CheckIfMet(xr.VectorToArray());
                        if (reflectionMeetsImplicitRestrictions[i] == false)
                        {
                            xr.AddValue(centroid);
                            xr.MultiplyByScalar(1.0 / 2);
                            break;
                        }
                    }

                    if (!reflectionMeetsImplicitRestrictions.Contains(false))
                    {
                        break;
                    }
                }

                double xrFunctionValue = function.CalculateValue(xr.VectorToArray());
                function.IncreaseCounterValue(algorithmName);
                if (xrFunctionValue > functionValues[h2])
                {
                    xr.AddValue(centroid);
                    xr.MultiplyByScalar(1.0 / 2);
                }

                simplex[h]        = xr;
                functionValues[h] = xrFunctionValue;
                iter++;
            } while (iter < iterations);

            function.DeleteParameters();
            return(simplex.ElementAt(functionValues.IndexOf(functionValues.Min())));
        }
예제 #3
0
        /// <summary>
        /// Finds minimum of function using Newton-Raphson algorithm.
        /// </summary>
        /// <param name="function">Function used in algorithm.</param>
        /// <param name="e">Precision</param>
        /// <param name="startingPoint">Starting point of algorithm.</param>
        /// <param name="usingGoldenSection">Flag used for tracking whether user wants to use Golden Section algorithm or not.</param>
        /// <returns>Minimum of function.</returns>

        public static Matrica FindMinimum(Function function, double e, Matrica startingPoint, bool usingGoldenSection)
        {
            Matrica x = new Matrica();

            x.Equals(startingPoint);
            function.SetParametersSize(x.NoOfRows);
            Matrica gradient      = new Matrica();
            Matrica hessianMatrix = new Matrica();
            int     brojac        = 0;
            Matrica xs            = new Matrica();

            if (usingGoldenSection == false)
            {
                do
                {
                    xs.Equals(x);
                    gradient = function.CalculateGradientValue(x.VectorToArray());
                    function.IncreaseCounterGradientValue(algorithmName);
                    hessianMatrix = function.CalculateHessianMatrix(x.VectorToArray());
                    function.IncreaseCounterHessian(algorithmName);
                    Matrica LU     = hessianMatrix.LUPDecomposition(e, gradient);
                    Matrica y      = Matrica.ForwardSubstitution(LU, gradient);
                    Matrica deltaX = Matrica.BackwardSubstitution(LU, gradient, e);
                    x.AddValue(deltaX);
                    brojac++;

                    function.IncreaseCounterValue(algorithmName);
                    function.IncreaseCounterValue(algorithmName);
                } while (brojac < 100);
            }
            else
            {
                do
                {
                    xs.Equals(x);
                    gradient = function.CalculateGradientValue(x.VectorToArray());
                    function.IncreaseCounterGradientValue(algorithmName);
                    hessianMatrix = function.CalculateHessianMatrix(x.VectorToArray());
                    function.IncreaseCounterHessian(algorithmName);
                    Matrica LU     = hessianMatrix.LUPDecomposition(e, gradient);
                    Matrica y      = Matrica.ForwardSubstitution(LU, gradient);
                    Matrica deltaX = Matrica.BackwardSubstitution(LU, gradient, e);
                    x.AddValue(deltaX);

                    for (int i = 0; i < x.NoOfRows; i++)
                    {
                        double     value       = x.LoadedMatrix[i][0];
                        double     vectorValue = deltaX.LoadedMatrix[i][0];
                        Expression expression  = lambda => value + lambda * vectorValue;
                        function.SetParameters(i, expression);
                    }

                    UnimodalInterval interval       = UnimodalInterval.FindUnimodalInterval(function, 0, 1, algorithmName);
                    UnimodalInterval lambdaInterval = GoldenSection.FindMinimum(function, interval.Minimum, interval.Maximum, e, algorithmName);

                    double lambdaMin = (lambdaInterval.Minimum + lambdaInterval.Maximum) / 2;
                    deltaX.MultiplyByScalar(lambdaMin);
                    x.AddValue(deltaX);

                    function.IncreaseCounterValue(algorithmName);
                    function.IncreaseCounterValue(algorithmName);
                } while (function.GetGradientNorm() >= e);
            }

            function.DeleteParameters();
            return(x);
        }