【问题标题】:Get Static Random Value with two seed使用两个种子获取静态随机值
【发布时间】:2017-09-26 22:38:10
【问题描述】:

编辑 2:新的解释,因为我的问题看起来很模糊。我的问题是 用户boriaz50已经回答了:

  1. 我想要一个类似随机的函数,如果我输入两组种子/密钥,它将返回一组静态值,这些值将转换为范围 使用伪随机数生成器 (PNRG) 算法的数字(例如 1-99) (由用户boriaz50回答。见他的线性同余生成器 他的示例代码或下面的代码进行修改)。
  2. 我不使用 System.Random 的原因是我无法设置该函数的第二个种子/密钥。 System.Random 似乎使用“0”作为 第二个种子/密钥,每次我使用 Next() 时,该密钥都会增加 一。这意味着如果我更改使用的线的位置或数量 Next() 函数然后整个结果将改变(使没有 点记住下一个程序构建的种子)。编辑 3:只需在 boriaz50 中实现第一个代码调用“new Random”,它的种子/密钥会不断重置,使其成为一种可行的解决方案。

public int RandomGenerator(int seed1, int seed2, int minRange, int maxRange)
{
    long temp = seed1;
    for(int i = 0; i < seed2; i++)
    {
        temp = (48271 * temp) % int.MaxValue;
    }
    int result = (int)(minRange + temp % maxRange);
    return result;
}

假设我有两个种子并且我想获得一个介于 1-99 之间的随机值,如何每次都获得相同的数字。

在 c# 中有一个 System.Random 函数,但它使用 next() 这意味着假设我知道两个种子,我无法猜测出来的数字。 c# 中是否还有另一个函数可以实现我的目标?

int gameSeed = 123;

public void GenerateAgeList(){
    GenerateAge(1); //Always return for example 23
    GenerateAge(2); //Always return for example 34
    GenerateAge(1); //Since the popSeed is also one also return 23
    for(int i = 1; i<5 ; i++){
        GenerateAge(i);
    } // Always return for example 23,34,10,...
}

public int GenerateAge(int popSeed){
    return unknownFunction(gameSeed,popSeed,1,99));
}

编辑 1:我不使用 System.Random Next() 的原因是因为如果我添加和/或删除使用 Next() 的变量,那么结果会改变。

void GenerateHuman(int seed){
    Random rnd = new Random(seed); //Say the seed are 1
    Human i = new Human();
    i.age = rnd.Next(1,99); //randomly return 36
    i.strength = rnd.Next(1,20); //randomly return 4
}
//Say in few month i added new level var to the code
void GenerateHuman(int seed){
    Random rnd = new Random(seed);
    Human i = new Human();
    i.age = rnd.Next(1,99); //still 36
    i.level = rnd.Next(1,5); //randomly return 1
    i.strength = rnd.Next(1,20); //not 4 but 19
}
//Then say i find the age not necresarry and delete it
void GenerateHuman(int seed){
    Random rnd = new Random(seed);
    Human i = new Human();
    i.level = rnd.Next(1,5); //not 1 but 2
    i.strength = rnd.Next(1,20); //not 19 but 4
}

【问题讨论】:

  • “我猜不出是什么数字”——你能猜到的随机数有什么意义?你为什么要使用种子值?您的问题非常不清楚您在这里实际要完成的工作
  • @PeterDuniho 生成一组统计上随机但确定性的数字是完全合理的。考虑生成一个我的世界的例子。您希望世界本身在统计上是随机的和无限的,并且能够生成“新的”变化,但也能够重新生成同一个世界,而无需存储“无限”的信息量。
  • 问题和意图也很清楚IMO,如果有点复杂的话。
  • @glennsl:“生成一组统计上随机但确定性的数字是完全合理的” -- 是的,我已经明白了。我一直使用种子进行 PRNG。这个问题是针对 OP 的,目的是了解为什么他们想要这个功能,为什么两个种子比一个更好,以及他们期望如何使用它们。
  • 我不使用 Random Next(),因为如果我添加或删除另一个也使用 Next() 的代码,它会返回不同的结果(查看我的编辑)。因为我希望我的程序总是返回相同的结果,只要我输入相同的种子,我需要两组种子。一个可以是随机生成的,也可以是手动输入的,第二个可以作为某种键,这样第一个 + 第二个种子的结果总是相同的。例如,如果第一个种子是 7,第二个种子是 1,并且范围是 1-5,它将始终返回 3。无法使用 System.Random 存档,因为每次我使用 Next() 时,密钥都会更改跨度>

标签: c# random


【解决方案1】:

如果您有两颗种子,您可以通过多种方式将它们组合在一起以创建一颗种子。例如,您可以像这样使用Random

Random r = new Random(gameSeed ^ popSeed);

Next 对于给定的种子是确定性的,所以只需调用 r.Next(1, 99) 就可以了。

【讨论】:

    【解决方案2】:

    您似乎想像使用静态数字集合一样使用您的方法。您可以通过更改游戏种子来生成新的收藏。

    实现目标的最简单方法:

    public int GenerateAge(int popSeed)
    {
        return new Random(gameSeed ^ popSeed).Next(1, 99);
    }
    

    由于 Random 类没有重置其状态的方法,因此每次需要值时都需要创建新对象。这种情况可能是不受欢迎的。

    解决办法可能是linear congruential generator:

    public int GenerateAge(int popSeed)
    {
        long age = gameSeed;
        for (int i = 0; i < popSeed; ++i)
        {
            age = (48271 * age) % int.MaxValue;
        }
        return (int)(1 + age % 99);
    }
    

    【讨论】:

    • 第二个代码是我的目标。是否有 c# 库,或者我必须自己制作?
    • 这样的算法被称为随机数生成器。请注意,不仅有线性同余生成器。例如,查看en.wikipedia.org/wiki/Mersenne_Twister。您可以找到用 C# 编写的实现。但是 System.Random 这样的系统生成器使用类似的算法。
    • 准确地说,此类算法会生成伪随机数。
    【解决方案3】:

    System.Randoma constructor that takes a seed

    如果您有两个种子,只需按照您想要的方式组合它们即可:

    var random = new Random(gameSeed ^ popSeed);
    var n = random.Next(1, 99); // Will give a deterministic answer
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-11
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 2018-07-05
      • 2011-09-26
      • 1970-01-01
      相关资源
      最近更新 更多