Math.Random算法

时间:2013-03-21 15:30:30

标签: c# java c++ c algorithm

这是一位采访者提出的问题。我无法回答。

问题是,假设您要从给定数组中选择一个随机数。

  

条件是你不应该按顺序选择任何东西   不要使用内置随机函数。

我不知道。想知道这个Math.Random对我们有什么影响吗?

我用谷歌搜索并没有找到背后的实现/逻辑。

有人知道吗?

8 个答案:

答案 0 :(得分:22)

到目前为止,有三个人告诉过你使用Ticks的最后一位数字。 这不起作用。尝试在紧密循环中执行此操作,您很快就会明白为什么这是一个坏主意。

问题不是很好。我喜欢在面试中提出含糊不清的问题,因为你可以找出候选人如何处理一个模棱两可的情况。在这种情况下,我会立即回过头来,通过“随机”找出面试官的意思。伪随机性是否足够好?是否有高质量熵的来源?

一旦你有一个澄清的问题,它应该更容易回答。

问题归结为管理熵。如果你有一个非常弱的熵源 - 比如Ticks的值(不是最后一个数字,这是没有价值的,而是整个值)那么你可以使用它来为一个伪随机数生成器播种。如果您拥有高质量的熵源,那么您可以直接使用它来生成随机位。

答案 1 :(得分:7)

保证随机。 (舌头 FIRMLY 在脸颊上):

void Main()
{
    Enumerable.Range(0, 10).Select(x => ComeOnItsKindaRandom(0, 10)).Dump();
}

public int ComeOnItsKindaRandom(int minValue, int maxValue)
{
    var query = "http://www.random.org/integers/?num=1&min={0}&max={1}&col=1&base=10&format=plain&rnd=new";
    var request = WebRequest.Create(string.Format(query, minValue, maxValue));
    var response = request.GetResponse();
    using(var sr = new StreamReader(response.GetResponseStream()))
    {
        var body = sr.ReadToEnd().Trim();
        return int.Parse(body);
    }
}

答案 2 :(得分:5)

如果您只想从数组中获取一个项目而不使用Random类,则可以使用具有未知值的modulo函数,例如{ {1}}:

DateTime.Now.Ticks

答案 3 :(得分:4)

我会用

DateTime.Now.Tick 

然后为Math.Random(10)提供足够的数字,我将只采用最后两个数字。

或者你可以采用这个勾号的模数如下:

public static class MyMath
{
    private static int counter = 1;

    public static int Random(int max)
    {
        counter++;
        long ticks = DateTime.Now.Ticks;
        int result = Math.Abs((int) (ticks/counter)%max);
        return result;
    }
}

参见以下测试:

    [Test]
    public void test()
    {
        List<int> test = new List<int>();

        for (int i = 0; i < 10; i++)
        {
            test.Add(MyMath.Random(100));
        }

        Console.WriteLine("result:");
        foreach (int i in test)
        {
            Console.WriteLine();
        }
    }

答案 4 :(得分:1)

这是C中随机数的实现。您可以尝试用C#重写它。

C的随机数:结束,最后? http://www.cse.yorku.ca/~oz/marsaglia-rng.html

它看起来质量很高。

但是在面试中写下这段代码并不容易,但你绝对可以告诉他所使用的想法。

答案 5 :(得分:0)

只有一个想法,您可以使用DateTime.Now.Ticks中的最后一位数来获得选择索引的基础。或者也许是一些哈希函数同一件事。或者使用可以为您提供从辐射测量的随机数的网络服务。 Math.Random只是从预定义的表中选择(是的,它确实不是真正随机的)。

答案 6 :(得分:0)

我认为他们只是看到你是否了解LCG (Linear Congruential Generator)算法。

然而,他们背后的数学有点棘手,所以我怀疑他们能指望你能够写下一首头脑。

但如果不这样做,你不能像这样作弊产生一个随机索引吗?

int index = Guid.NewGuid().GetHashCode() % array.Length;

答案 7 :(得分:0)

首先,它被称为伪随机而不仅仅是随机,因为随机序列不可能以计算形式生成,

大多数伪随机数生成器PRNG都采用以下形式:

在时间0:R(0)=随机(种子)

在时间i:R(i)=随机(R(i-1));

其次,随机并不意味着你不知道第i个结果会是什么,但是这个系列是健壮的&amp;在结果链中猜测公式或种子是非常困难的

希望这有帮助