模拟退火,如何规范化概率分布

Simulated Annealing, How to normalize the probability distribution

本文关键字:规范化 概率分布 模拟退火      更新时间:2023-10-16

我正在为任意非线性高阶方程求解器工作。 我想找到最低限度。我遇到的问题是如何规范化概率分布函数。 我不想对所有变量进行积分(另外,如果我只是这样做,我不妨通过蛮力找到最小值。 这是我的代码。 如何规范化指数项。

template<typename Real, int N, typename Funct>
    Vector<Real, N> simulated_anneling_solver(Funct f, const Vector<Real, N>& lower_bound, const Vector<Real, N>& upper_bound, int t_start)
    {
        static int called_count = 0;
        std::default_random_engine eng;
        eng.seed(time(0) * ++called_count);
        Vector<Real, N> x;
        for(int i = 0; i < N; i++)
            x[i] = (upper_bound[i] + lower_bound[i]) * (Real)0.5;
        Real v = f(x);
        for(int t = t_start; t > 0; t--)
        {
            Vector<Real, N> next_x;
            Real cooled_percent = (Real)t / t_start;
            for(int i = 0; i < N; i++)
            {
                Real dimw = upper_bound[i] - lower_bound[i];
                do
                {
                    next_x[i] = std::normal_distribution<Real>(x[i], dimw * cooled_percent)(eng);
                }
                while(next_x[i] < lower_bound[i] || next_x[i] > upper_bound[i]);
            }
            Real next_v = f(next_x);
            if(next_v <= v || expx((next_v - v) / t) > std::uniform_real_distribution<float>(0.0f, 1.0f)(eng))
            {
                v = next_v;
                x = next_x;
            }
        }
        return x;
    }
}

附言。 我尝试将expx((next_v - v) / t) > std::uniform_real_distribution<float>(0.0f, 1.0f)(eng)更改为 (next_v - v) / v < cooled_percent这似乎给出了一些不错的结果。 现在我知道我只是拿函数的百分比误差,并将其与它冷却的程度进行比较。 因此,一切都被规范化并限制在 0 和 1 之间。当系统冷却时,您将需要较低的误差百分比。 我想现在虽然它不是真正的模拟退火。

在模拟退火中,不需要规范化,因为程序中的 if 子句应如下所示:

if(next_v < v || 
     expx((v-next_v) / t) > std::uniform_real_distribution<float>(0.0f, 1.0f)(eng))
{
    v = next_v;
    x = next_x;
}

其中 expx 将始终产生 (0,1) 中的值。