使用两个种子获取静态随机值

时间:2017-09-26 22:38:10

标签: c# random

  

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

     
      
  1. 我想要一个类似随机的函数,如果我输入两组种子/键,它将返回一个静态值集,转换为ranged   使用伪随机数发生器(PNRG)算法的数字(例如1-99)   (由用户boriaz50回答。见他的线性同余生成器   代码为他的例子或以下为它的修改)。
  2.   
  3. 我不使用System.Random的原因是因为我无法设置该函数的第二个种子/密钥。 System.Random似乎使用“0”作为   第二个种子/密钥,每次我使用Next()那个密钥增加了   一。这意味着如果我改变使用的线的位置或数量   Next()函数然后整个结果将改变(使得没有   记住下一个程序构建中的种子)。编辑3:每次在boriaz50第一次代码调用“新随机”中实现,其种子/密钥不断重置,使其成为一种解决方案。
  4.         
    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
}

3 个答案:

答案 0 :(得分:4)

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

Random r = new Random(gameSeed ^ popSeed);

Next对于给定的种子是确定性的,因此只需调用r.Next(1, 99)即可。

答案 1 :(得分:1)

您似乎希望将您的方法用作静态数字集合。您可以通过更改游戏种子来生成新的集合。

实现目标的最简单方法:

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

答案 2 :(得分:0)

System.Randoma constructor that takes a seed

如果你有两颗种子,只需按照你想要的方式组合它们:

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