예제 #1
0
        private void minimize(/* ref List<List<double>> pp */)  // pp -> Vertices
        {
            const double TINY = 1.0e-10;
            int          ihi, ilo, inhi;

            List <double> psum = new List <double>();
            List <double> pmin = new List <double>();

            p = new List <List <double> >(Vertices); // is a working copy of the simplex
            FunctionValues = new List <double>();    // values of the objective function at each vertex

            // construct the working simplex
            for (int i = 0; i < nVertices; i++)
            {
                List <double> x = new List <double>();
                for (int j = 0; j < ndim; j++)
                {
                    x.Add(p[i][j]);
                }
                double f = function(x);
                if (double.IsNaN(f))
                {
                    f = double.MaxValue;
                }
                FunctionValues.Add(f);
            }

            NumIterations = 0;
            psum          = get_psum(p);

            while (true)
            {
                ilo = 0;
                if (FunctionValues[0] > FunctionValues[1])
                {
                    inhi = 1;
                    ihi  = 0;
                }
                else
                {
                    inhi = 0;
                    ihi  = 1;
                }

                for (int i = 0; i < nVertices; i++)
                {
                    // find vertex with lowest function value
                    if (FunctionValues[i] <= FunctionValues[ilo])
                    {
                        ilo = i;
                    }

                    // find vertices with greatest (ihi) and next-greatest (inhi) function values
                    if (FunctionValues[i] > FunctionValues[ihi])
                    {
                        inhi = ihi;
                        ihi  = i;
                    }
                    else if (FunctionValues[i] > FunctionValues[inhi] && i != ihi)
                    {
                        inhi = i;
                    }
                }

                // see if we have achieved requested tolerance.  If so, make final adjustments and return
                ToleranceAchieved = 2.0 * Math.Abs(FunctionValues[ihi] - FunctionValues[ilo]) /
                                    (Math.Abs(FunctionValues[ihi]) + Math.Abs(FunctionValues[ilo]) + TINY);

                if (ToleranceAchieved < ToleranceRequested)
                {
                    Swap(0, ilo, FunctionValues);
                    for (int i = 0; i < ndim; i++)
                    {
                        Swap(p[0][i], p[ilo][i]);

                        pmin.Add(p[0][i]);
                    }

                    fmin  = FunctionValues[0];
                    Point = pmin;
                    if (verbose == true)
                    {
                        HF.AppendData(fmin, Point);
                    }
                    return;
                }

                if (NumIterations >= MaxNumIterations)
                {
                    // TO DO: throw exception
                    return;
                }

                NumIterations += 2;

                // take the next step in the process
                double yTry = amoTry(ref psum, ihi, -1.0);
                if (yTry <= FunctionValues[ilo])
                {
                    // if it was successful, try again
                    yTry = amoTry(ref psum, ihi, 2.0);
                }

                else if (yTry >= FunctionValues[inhi])
                {
                    double ysave = FunctionValues[ihi];
                    yTry = amoTry(ref psum, ihi, 0.5);
                    if (yTry >= ysave)
                    {
                        for (int i = 0; i < nVertices; i++)
                        {
                            if (i != ilo)
                            {
                                for (int j = 0; j < ndim; j++)
                                {
                                    p[i][j] = psum[j] = 0.5 * (p[i][j] + p[ilo][j]);
                                }
                                double f = function(psum);
                                if (double.IsNaN(f))
                                {
                                    f = double.MaxValue;
                                }
                                FunctionValues[i] = f;
                            }
                        }
                        NumIterations += ndim;
                        psum           = get_psum(p);
                    }
                }
                else
                {
                    --NumIterations;
                }

                if (verbose)
                {
                    HF.AppendData(FunctionValues[ilo], p[ilo]);
                }
            }
        }