数学算法.随机

Algorithm for Math.Random

本文关键字:随机 算法      更新时间:2023-10-16

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

问题是,假设你想从给定的数组中随机选择一个数字。

条件是你不应该在顺序和中选择任何东西不要使用内置的Random函数。

我不知道。想知道这是怎么回事数学。兰登能为我们做什么?

我搜索了一下,没有找到它背后的实现/逻辑。

有人知道吗?

到目前为止已经有三个人告诉你使用Ticks的最后一个数字。这不起作用。试着在一个紧密的循环中这样做,你很快就会明白为什么这是一个坏主意。

这个问题提得不太好。我喜欢在面试中提出模棱两可的问题,因为这样你就能知道应聘者是如何处理模棱两可的情况的。在这种情况下,我会立即反驳并找出面试官所说的"随机"是什么意思。伪随机性足够好吗?是否有高质量熵的可用来源?

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

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

保证随机。(舌头坚定地在脸颊上):

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);
    }
}

如果您只想从数组中获得一个项,而不使用Random类,则可以使用具有未知值的modulo函数,例如DateTime.Now.Ticks:

string[] items = new[] { "1", "2", "3", "4", "5" };
// Modulo items.Lenth returns a value from 0 to Length - 1
int index = (int)(DateTime.Now.Ticks % items.Length);
Console.WriteLine(items[index]);

我会使用

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();
        }
    }

这是C语言中随机数的实现,你可以尝试用c#重写它。

C的随机数:End, at last?http://www.cse.yorku.ca/oz/marsaglia-rng.html

看起来质量很好。

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

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

我想他们只是想知道你是否了解LCG(线性同余生成器)算法。

它们背后的数学有点棘手,所以我怀疑他们能指望你能在你的头脑中写出一个。

但是如果失败了,你就不能像这样作弊来生成一个随机索引吗?

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

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

大多数伪随机数生成器PRNG都是这种形式:

时刻0:R(0) = Random(Seed)

at Time i: R(i) = Random(R(i-1));

第二,随机并不意味着你不知道第i个结果是什么,而是意味着这个序列是鲁棒的& &;很难猜测公式或种子给定的结果链

希望能有所帮助