【问题标题】:random number with an expected average without loops具有预期平均值的随机数,没有循环
【发布时间】:2017-06-22 14:55:31
【问题描述】:

给定一个在 O(1) 中工作的统一随机数生成器,在区间 [0..1) 上生成一个随机浮点数,我如何在 [a..b] 范围内生成一个随机整数,其中a 和 b 是整数,我希望大量迭代生成的平均值为 c,其中 c 是区间 (a..b) 上的浮点数?

我已经在 StackOverflow 上查看过类似的问题,例如 thisthisthis,但它们似乎都与我所追求的不同。

编辑:我很抱歉说出显然是一个不清楚的问题。我想要一个函数,它接受三个参数 a、b 和 c 并生成一个介于 和 n 之间的随机数,如果它被重复调用相同的值,则它们的预期平均值将是 c。例如,如果 a 和 b 分别为 0 和 10,而 c 的值为 2.5,则该函数往往会产生较小的数字(即,在大量调用中平均为 2.5 的偏态但其他正态分布),而如果 c 为 5,则它产生的值的分布将更加均匀。该解决方案还必须是自包含的,并且不依赖于除统一随机数生成器之外的任何其他功能的可用性。编程语言的选择在很大程度上无关紧要,任何命令式的类似 c 的伪代码都可以。进一步注意,不应该有循环,并且应该在 O(1) 时间内完成

【问题讨论】:

  • 对于任何参数a < c < b 的选择,{a, a+1, a+2, ..., b} 上的概率分布有无限多个,其中c 作为期望值。因此,您的问题根本未确定。另外——为什么你认为O(1) 解决方案是可能的?
  • 理想的分布应该是最接近正常分布的分布,但它向左或向右倾斜(定义适用于统计数据),因此平均值与中心。有什么理由让我认为它不一定是可能的?
  • 我找到了一个便宜的O(1) 解决方案,但它与您的理想分布相去甚远。设p 为选择小于c 的数字的概率,以均匀概率(如果你选择这样的点)选择小于c 的点,以均匀概率选择大于或等于c 的点(如果你选择这样一个点)。 By appropriate choice of p you can get the expected value of c exactly.这是从中间值定理得出的。此外,您可以代数求解p
  • 顺便说一句,O(1) 在离散的、不均匀的情况下很难。 O(log(n)) 其中n = b-a+1 相当容易实现(尽管以O(n) 内存和预处理时间为代价)。
  • "如果您希望 中位数 为 @987654340,则选择小于 c 的数字的概率应该等于选择数字 >c 的概率@,不是预期值。对于某些离散分布,没有任何已知的O(1) 模拟它们的方法。我认为情况就是这样。二项分布。从根本上说,离散的比连续的更难模拟,它通常像反转 CDF 一样简单。 Gentle 的《随机数生成和蒙特卡洛方法》一书讨论了许多相关问题。

标签: random


【解决方案1】:

在没有提供代码的情况下,我假设它是一种基于 C 的语言。

总结你的问题,你想从你的随机整数的平均值中得到一个十进制数吗?我不明白你在问题的第一部分的意思。

我会做这样的事情(c#):

    static float getDecimalAverageFromInts(int a, int b)
    {
        if (a > b)
        {
            throw new System.ArgumentException("Right opperand cannot be greater than left opperand", "a");
        };
        float running_total = 0;
        float total = 0;
        float average = 0;
        for (int i = a; i < b; i++)
        {
            total += a;
            running_total++;
        }
        return average = (total / running_total);
    }

.................................................. .....

我在控制台中对其进行了测试。以下是完整代码:

using System;

namespace average
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello. Please give minimum value");            
            int l_opperand;
            int r_opperand;
            if(int.TryParse(Console.ReadLine(), out l_opperand))
            {
                Console.WriteLine("Thank you for {0}, please provide a max value.", l_opperand);
                if (int.TryParse(Console.ReadLine(), out r_opperand))
                {
                    Console.WriteLine("Thank you for min value: {0} and max value: {1}", l_opperand, r_opperand);
                    Console.WriteLine("Calculating Average....");
                    float average = getDecimalAverageFromInts(l_opperand, r_opperand);
                    Console.WriteLine("Average is {0}", average);
                    Console.ReadLine();
                }
                else
                {
                    Console.WriteLine("Incorrect response");
                    Console.ReadLine();
                }
            }
            else
            {
                Console.WriteLine("Incorrect response");
                Console.ReadLine();
            }
        }
        public static float getDecimalAverageFromInts(int a, int b)
        {
            if (a > b)
            {
                throw new System.ArgumentException("Right opperand cannot be greater than left opperand", "a");
            };
            float running_total = 0;
            float total = 0;
            float average = 0;
            for (int i = a; i < b; i++)
            {
                total += a;
                running_total++;
            }
            return average = (total / running_total);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    相关资源
    最近更新 更多