【问题标题】:How to select a random number in a range based on date?如何根据日期选择范围内的随机数?
【发布时间】:2011-07-01 23:40:31
【问题描述】:

我有数百种 ID 值范围为 1..999 的扇区类型的列表。用户希望每天在网站上看到不同的随机扇区。

解决此问题的一种方法是存储当天随机选择的扇区 ID,并使用它,然后在第二天使用新的扇区 ID 更新该字段。但这有点乱,因为这意味着我需要在数据库中的某处存储任意值......(或者应用程序状态或其他东西)

我也在想我可以拿 1..999 的列表并使用一些随机算法根据日期选择一个随机数,只要日期与上次随机数相同选中后,会出现相同的数字。

但我不知道如何实现,所以我正在寻找建议?

此外,考虑到范围的大小 (999) 和一年中的可用天数 (365),这是否意味着算法总是会错过某些扇区,因为它们的 ID 没有映射到随机number 选择过程选择Sector ID?有没有办法解决这个问题?

【问题讨论】:

    标签: c# algorithm random


    【解决方案1】:

    您可以将日期用作Random 类的种子:

    int day = (DateTime.Today - new DateTime(2000,1,1)).TotalDays;
    Random rnd = new Random(day);
    int id = rnd.Next(1, 1000);
    

    请注意,日期是从固定的开始日期而不是DateTime.DayOfYear 计算的,因此它不会每年重新开始,并且只使用其中的 365 个值。

    【讨论】:

    • 如果使用无参数构造函数,我认为Random 已经使用日期/时间作为默认种子。
    • 系统时钟是默认种子,而不是日期时间。无参数 ctor 将返回 0 到 2,147,483,647 之间的(一个 int)。
    • @Oded:没错,但在这种情况下,您只需要日期部分,因此结果一整天都保持不变。
    【解决方案2】:

    您真的想要一个随机值,还是只想每天显示一个不同的扇区?随机提供了相同部门信息将连续两天(或可能更多)显示的可能性。也很有可能在 365 天的时间里,您会得到多个副本。使用从 999 个项目的列表中随机选择,在 365 次尝试中获得 365 个非重复数字的可能性非常大。

    你有什么理由必须每年重新开始吗?为什么不设置某个日期(例如,2011 年 1 月 1 日)作为您的“纪元”日期。然后,要选择一个项目,只需从当前日期中减去该日期即可得到天数,除以 999 并取余数,即为您的索引。那就是:

    DateTime EpochDate = new DateTime(2011, 01, 01);
    TimeSpan Elapsed = DateTime.Now.Date - EpochDate;
    int index = Elapsed.Days % 999;
    

    此时,index 是 0..998 范围内的数字。然后,您可以使用该数字索引到您的扇区 ID。直接索引(因此 Jan 1 2011 将获得第一个扇区 ID,Jan 2 将获得第二个,等等),或者对索引进行某种计算以“随机化”它。

    【讨论】:

    • 不应该是TotalDays吗?
    • @XzaR 你从哪里得到 TotalDays?
    • Elapsed.Days 的最后一行应该是 Elapsed.TotalDays?如果我是正确的,天数只是该日期计数的当前年份,即 366 闰年。那么将不可能获得所有 999 个索引,而总天数是自纪元以来的计数天数。也许我想错了。
    【解决方案3】:

    回答你关于组合学的第二个问题:

    您有 999 个号码和 365 天。 您可以每天选择一个随机数字,这意味着您在任何情况下都不能显示超过 365 个(不同的)数字。当然,有些数字也可能会重复。你必须根据你想要表达的方式来设计逻辑。

    在这种情况下,您的随机对象必须持续 365 天确实是可取的。

    【讨论】:

      【解决方案4】:

      您可以使用Cache 类并在午夜使内容过期。当缓存条目不存在时,创建一个具有随机值的新条目,在午夜过期...

      对于随机值,使用System.Random - 这里不需要重新发明轮子。

      【讨论】:

      • 只要应用在此期间不回收!
      • @David - 非常正确,这就是为什么我建议在条目不存在时重新创建条目。同意,如果应用程序回收,它不会持续一整天,但这可能足以解决 OP 的问题。
      猜你喜欢
      • 2012-12-21
      • 2014-05-11
      • 2022-11-13
      • 2020-02-10
      • 2017-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多