C#,码海拾贝(50)——求“非线性方程”一个实根的“蒙特卡洛法”之C#源代码

using System;

namespace Zhou.CSharp.Algorithm
{
    public delegate double delFunction_x(double x);
    public delegate double delFunction_xa(double[] x);
    public delegate double delFunction_x_y(double x, double y);
    public delegate double delFunction_x_ya(double x, double[] y);
    public delegate double delFunction_xa_ya(double[] x, double[] y);

    /// <summary>
    /// 求解非线性方程组的类 NLEquations
    /// 原作 周长发
    /// 改编 深度混淆
    /// </summary>
    public static partial class NLEquations
    {

        /// <summary>
        /// 求非线性方程一个实根的蒙特卡洛法
        /// 计算方程左端函数f(x) double Func(double x)
        /// </summary>
        /// <param name="Func">计算方程左端函数</param>
        /// <param name="x">传入初值(猜测解),返回求得的实根</param>
        /// <param name="xStart">均匀分布的端点初值</param>
        /// <param name="nControlB">控制参数</param>
        /// <param name="eps">控制精度</param>
        public static void GetRootMonteCarlo(delFunction_x Func, ref double x, double xStart, int nControlB, double eps)
        {
            int k;
            double xx, a, y, x1, y1, r;

            // 求解条件
            a = xStart;
            k = 1;
            r = 1.0;

            // 初值
            xx = x;
            y = Func(xx);

            // 精度控制求解
            while (a >= eps)
            {
                x1 = rnd(ref r);

                x1 = -a + 2.0 * a * x1;
                x1 = xx + x1;
                y1 = Func(x1);

                k = k + 1;
                if (Math.Abs(y1) >= Math.Abs(y))
                {
                    if (k > nControlB)
                    {
                        k = 1;
                        a = a / 2.0;
                    }
                }
                else
                {
                    k = 1;
                    xx = x1;
                    y = y1;
                    if (Math.Abs(y) < eps)
                    {
                        x = xx;
                        return;
                    }
                }
            }

            x = xx;
        }

        /// <summary>
        /// 内部函数
        /// </summary>
        private static double rnd(ref double r)
        {
            double s = 65536.0;
            double u = 2053.0;
            double v = 13849.0;
            int m = (int)(r / s);
            r = r - m * s;
            r = u * r + v;
            m = (int)(r / s);
            r = r - m * s;
            double p = r / s;
            return (p);
        }
 

}

}

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/131233958