【问题标题】:Optimize the expected payoff using a normal distribution使用正态分布优化预期收益
【发布时间】:2015-07-20 18:02:03
【问题描述】:

假设我生成一个均值为 50,标准差为 1 的正态分布。

boost::normal_distribution<> normal(50, 1);

然后我想将此正态分布乘以由下式给出的支付函数:

f(x) = 100 - x

然后求解最大 x \in [0, 100]。

特别想解决:

((最大 x /in [0,100]) 正常(x) * (100 - x)

有人可以帮我编写代码,或者引导我朝着正确的方向前进吗?

【问题讨论】:

  • 你能再解释一下这个问题吗?您是否正在寻找x(100-x) 的最大值,其中x 具有正态分布?您想从正态分布中选择几个xs 并为x 的这些值找到x(100-x) 的最大值还是想知道理论上的最大值?
  • @triple_r 请注意,正态分布 normal(x) 和 ,f(x) = 100 - x 都具有相同的自变量。我只是希望将每个 x 的两个函数相乘,然后在所有 x \in [0, 100] 上最大化。清楚吗?
  • 哦,那么normal(x) 是指x 处正态分布的概率密度函数吗?类似this?
  • @triple_r 是的。 x 是沿 x 轴变化的自变量。
  • @triple_r 通过将 normal(x) 乘以支付函数(对于每个 x),我将生成预期的支付函数。

标签: c++ optimization normal-distribution


【解决方案1】:

正态分布的 PDF(概率分布函数)有一个很好的封闭形式:

因此可以通过求解以下问题以解析方式找到最大值:

这将导致您的情况为 x=75-sqrt(626)x=49.98

但是,如果您想在代码中而不是在分析中执行此操作,则可以使用优化算法。在您的情况下,可能一个简单的算法,例如黄金分割搜索(一维)就可以正常工作(here, for example):

using boost::math::normal;

normal ndist(50.0, 1.0);

double f(const double &x)
{
    return pdf(ndist, x) * (100.0 - x);
}

double max(double (*f)(const double &), double &a, double &b, const double tol = 1e-5)
{
    static double goldenratio = 0.618034;
    double c = b - goldenratio * (b - a);
    double d = a + goldenratio * (b - a);
    while(abs(c - d) > tol)
    {
        double fc = (*f)(c); double fd = (*f)(d);
        if (fc > fd)
        {
            b = d;
            d = c;
            c = b - goldenratio * (b - a);
        } else
        {
            a = c;
            c = d;
            d = a + goldenratio * (b - a);
        }
    }
    return 0.5 * (b + a);
}

一个好的起始括号是0100

double a = 0.0;
double b = 100.0;
maximum = max(f, a, b);

【讨论】:

  • 您介意解释一下如何在 c++ 中求解该导数吗?
  • 使用黄金分割搜索,您无需计算导数。一些优化算法需要导数,对于这些算法,您可以分析(象征性地)计算导数并放入您的代码中,或者使用数值微分方法。例如,使用中心差分方案dfdx = (f(x+eps) - f(x-eps)) / (2.0*eps)eps 是一个小数字,比如说eps=1e-10)。
  • 我对优化算法感到困惑。另外,你为什么不指定什么 fc 和什么 fd ?他们似乎从未被宣布。
  • 这里的max函数是一种优化算法。它试图在给定的间隔[a,b] 中找到函数f 的最大值。这只是一种这样的算法,还有很多。有些使用函数的导数,有些则不使用。我列出的不需要知道衍生物。
  • fcfd 是函数fcd 的值,它们是在while 语句之后定义的。我从维基百科伪代码中复制了代码,所以其中有一些错误,我将编辑我的答案以修复这些:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 2013-09-04
  • 1970-01-01
相关资源
最近更新 更多