【问题标题】:Create a identical "random" float based on multiple data基于多个数据创建相同的“随机”浮点数
【发布时间】:2018-06-10 02:02:31
【问题描述】:

我正在开发一款游戏 (Unity),我需要根据多个 int 和/或 float 创建一个随机浮点值(介于 0 和 1 之间)。

我认为手动为函数创建单个字符串会更容易,但也许它可以接受int 和/或float 的列表。

结果示例:

  • "[5-91]-52-1" > 0.158756..

要点:

  • 结果的分布(0 和 1 之间)必须相等(不希望 90% 的结果在 0.45 和 0.55 之间)
  • 询问 2 次相同的字符串必须返回完全相同的结果(即使我重新加载应用程序,或在不同的计算机上启动它,..)
  • 结果不必是唯一的。

奖励积分:

  • 有时我需要关闭类似的字符串返回关闭结果,但不是每次。 “随机生成”可以使用此功能处理布尔值吗?

【问题讨论】:

  • 使用字符串的哈希码作为Random 对象的种子可能吗?
  • 看起来不错的解决方案,谢谢。我正在检查那个。我只是关心创建一个新的Random 对象并为每个请求设置一个新种子,是不是太重了?而不是设置种子并在其上请求多个号码(normal 使用)
  • 创建多个实例并不繁重;它通常只会导致您实际瞄准的场景(复制序列);这通常是不受欢迎的
  • 好的,非常感谢。最后一个问题(接近奖励点),哈希码的分布以及它与种子设置的联系是什么?例如:如果我用[ 声明每个字符串,它会影响结果分布还是根本不影响? (您也可以创建一个回复以设置为答案)
  • 如果即使在程序重新启动后(或在程序的多个实例之间)您仍需要相同的结果,您应该知道Object.GetHashCode() 保证仅在原始应用程序内返回相同的值-域,否则您可能需要创建自己的哈希函数实现,即使在应用程序域之间也能返回稳定的结果。

标签: c# unity3d random hash


【解决方案1】:

您所描述的本质上是散列函数的定义。

所以只需使用一个并将结果标准化为您想要的范围。大多数基本情况都可以使用GetHashCode,但不保证在不同版本的框架中产生相同的结果。

保证跨机器提供完全相同结果的稳定版本将使用众所周知的良好哈希 - 像加密哈希 SHA256 并将结果的几个第一个字节作为整数并进行规范化。加密哈希函数还可以方便地以字节数组作为输入,因此您可以直接将多个值组合为字节并获得稳定的结果。

    var intValue = 42;

    var bytesToHash = BitConverter.GetBytes(intValue);
    var hash = System.Security.Cryptography.SHA256Managed.Create()
             .ComputeHash(bytesToHash);
    var toNormalize = BitConverter.ToUInt32(hash,0);
    var fancyRandom = (double)toNormalize/UInt32.MaxValue;

要将多个值组合到字节数组中,您可以手动组合BitConverter.GetBytes 的结果或在MemoryStream 上使用BinaryWriter

或者,您可以使用生成的整数作为伪随机生成器的某些自定义实现的种子(因为 .Net 中的一个不保证在 .Net 的机器/版本中提供相同的结果),如 cmets 中所建议的那样,但我不这样做不认为它会显着更好地分配。

注意:确保根据您的情况“随机地”分配结果数字。加密哈希函数可能会给出你想要的结果,但我不知道如何证明这一点。

对于“奖励”部分:如果您能找到伪随机生成器,它会始终为“相似”种子产生接近的结果,我会感到非常惊讶。相反,您可以对单独的部分使用与上述相同的方法 - 一个“相同”,另一个处理变化(即 intValue & 0xFFFFFF00 用于稳定部分,intValue & 0xFF 用于“小差异”),而不是将产生的“随机”数字与一些重量:randomFromStable + 0.05 * randomFromDifference.

【讨论】:

  • 太棒了,我正在寻找所有这些。
【解决方案2】:

我建议使用哈希码(或类似的东西)作为Random 对象的种子。相同字符串的哈希码必须相同,因此您将始终得到相同的序列。

正如 Nuf 所说,哈希码只保证在同一个应用程序域中是相同的;所以它可能无法在重新启动后工作。

至于你的奖励点,不编写自己的 RNG 就很难到达那里。种子中的任何变化都可能而且应该导致结果序列出现很多变化。

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 1970-01-01
    • 2010-12-14
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多