C# 在C语言中植入伪随机数生成器
我需要C的Random类的一个实例的种子,我了解到大多数人使用当前时间的滴答数计数器来实现这一点。但这是一个64位的值,种子需要是一个32位的值。现在我认为返回int的GetHashCode方法应该为其对象提供一个合理分布的值,这可以用来避免只使用tick count中较低的32位。但是,我找不到关于Int64数据类型的GetHashCode的任何信息 所以,我知道这不会有多大关系,但是下面的工作是否会像我认为的那样好,因为我不能尝试和错误随机性,或者它的工作原理可能与使用intDateTime.Now.Ticks作为种子一样?或者可能效果更糟?谁能解释一下呢C# 在C语言中植入伪随机数生成器,c#,random,gethashcode,C#,Random,Gethashcode,我需要C的Random类的一个实例的种子,我了解到大多数人使用当前时间的滴答数计数器来实现这一点。但这是一个64位的值,种子需要是一个32位的值。现在我认为返回int的GetHashCode方法应该为其对象提供一个合理分布的值,这可以用来避免只使用tick count中较低的32位。但是,我找不到关于Int64数据类型的GetHashCode的任何信息 所以,我知道这不会有多大关系,但是下面的工作是否会像我认为的那样好,因为我不能尝试和错误随机性,或者它的工作原理可能与使用intDateTime
int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
Random r = new Random(seed);
编辑:为什么我需要一个种子,而不是让随机构造函数来完成工作?我需要将种子发送给对相同随机序列使用相同种子的其他客户端。new random已使用当前时间。它相当于新的RandomEnvironment.TickCount
但这是一个实现细节,在未来的.net版本中可能会发生变化
我建议使用新的随机数,如果你想得到一个可复制的伪随机值序列,只提供一个固定的种子
因为您需要一个已知的种子,所以只需像MS一样使用Environment.TickCount。然后将其作为种子传输到其他程序实例
如果在短时间间隔内创建多个随机实例(可能是16ms),则可以将它们播种到相同的值,从而创建相同的伪随机序列。但这很可能不是问题。这种常见的陷阱是由windows仅每隔几毫秒更新一次当前的timeDateTime.Now/.UtcNow和TickCountEnvironment.TickCount造成的。确切的间隔时间取决于windows版本和正在运行的其他程序。它们不会改变的典型间隔为16毫秒或1毫秒。如果需要使用当前时间以外的时间来进行种子设定,在这种情况下,可以使用默认构造函数,可以使用以下方法:
Random random = new Random(Guid.NewGuid().GetHashCode());
我有一个类似的问题,从一个更大的问题列表中随机选择一组问题。但当我用时间作为种子时,它给出了相同的随机数 这就是我的解决方案
int TOTALQ = 7;
int NOOFQ = 5;
int[] selectedQuestion = new int[TOTALQ];
int[] askQuestion = new int[NOOFQ];
/* Genarae a random number 1 to TOTALQ
* - if that number in selectedQuestion array is not o
* - Fill askQuestion array with that number
* - remove that number from selectedQuestion
* - if not re-do that - - while - array is not full.
*/
for (int i = 0; i < TOTALQ; i++) // fill the array
selectedQuestion[i] = 1;
int question = 0;
int seed = 1;
while (question < NOOFQ)
{
DateTime now1 = new DateTime();
now1 = DateTime.Now;
Random rand = new Random(seed+now1.Millisecond);
int RandomQuestion = rand.Next(1, TOTALQ);
Response.Write("<br/> seed " + seed + " Random number " + RandomQuestion );
if (selectedQuestion[RandomQuestion] != 0)
{
selectedQuestion[RandomQuestion] = 0; // set that q =0 so not to select
askQuestion[question] = selectedQuestion[RandomQuestion];
Response.Write(". Question no " + question + " will be question " + RandomQuestion + " from list " );
question++;
}
seed++;
}
你忘了写关于需要种子的非常好的论点。好吧,我现在加上了这个非常好的论点+请注意,真正提供您自己的种子值的唯一时间是当您想要复制特定的值序列时。按照Windows纸牌游戏号码选项思考。我编辑了我的问题。我知道新的随机构造函数,但我需要种子。@AndrewBarber或者如果你在随机构造函数的生成之外迭代方法/块,则需要唯一的种子,并希望避免由于时间分辨率不足而导致冲突的风险,正如CodesInChaos所写的那样。@Alex我相当确定CodeInChaos实际上不是这么说的。我引用,如果你想得到一个可复制的…值序列,只提供一个固定的种子。你不应该创建这么多随机实例。@Alex我也这么想;我确实认为你已经掌握了这一点,但我只是认为我们之间有一些细微的技术问题或是一些闪烁其词的东西!可怜的CodeInChaos会想为什么他的答案会被炸掉;为什么这个值比DateTime.Now.Ticks.GetHashCode更好呢?因为它没有DateTime.Now每几毫秒更改一次的问题。使用这种方法,即使在快速连续初始化时,随机的两个实例也不太可能获得相同的种子。而且您确定没有哈希冲突吗?@CodesInChaos正是oɔɯǝɹ所说的-如果您只使用GUI,可能会更少。该方法将在gethashcode由于在种子上随机执行abs而返回int.minvalue,并且abs在int.minvalue上爆炸的任何时候随机爆炸。你需要这样做,而不是。。。Random Random=new RandomGuid.NewGuid.GetHashCode&int.MaxValue;以确保只发送正整数。