我在一个类中有一个Random,它旨在在不同的上下文中生成随机序列:这是从Java代码移植的结果。 在Java版本中,一切正常,因为java.lang.Random类具有方法setSeed,它允许动态更改种子值。
Random rnd = new Random();
...
rnd.nextInt();
...
rnd.setSeed(seedValue);
这会生成一致的结果,因为每次设置种子值时,结果都是随机的。
不幸的是,在C#中,行为有很大不同,因为Random类需要在构造时设置种子:
Random rnd = new Random(seedValue);
...
rnd.Next();
...
因此,我每次都必须使用给定的种子构建一个新的Random实例,在某些备用情况下,它会生成与之前调用相同的值。
是否可以动态地在C#中设置Random实例的种子,而不会丢失全局实例的一致性?
非常感谢!
答案 0 :(得分:1)
通常我为我的应用程序创建一个Random实例,在实例化后设置种子可以依赖于每次调用Next给我一个新的随机数。诀窍是确保种子尽可能随机。在C#应用程序中使用Random是一个很好的例子,说明Singleton非常适合。
有多种方法可以在种子中获得不同的随机性优势,并且有一些很好的SO问题可以解决这个问题。
以下示例是我使用的方法。
m_randomURL = "https://www.random.org/cgi-bin/randnum?num=1&min=1&max=1000000000";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_randomURL);
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
Random rand = new Random(Convert.ToInt32(stIn.ReadToEnd()));
random.org使用大气噪声产生随机性,显然用于彩票等。
答案 1 :(得分:0)
尝试将Random实例包装为伪代码:
class MyRandom {
private Random random;
public void setSeed(long seed) {
random = new Random(seed);
...
public long next() {
return random.next();
答案 2 :(得分:0)
首先,我不希望setSeed
在运行时期间在Random
上多次调用Random
。 FreeCell 这样做是为了让你可以通过写下使用的种子来“加载”游戏实例。
如果您更改种子,它应该像重置 Random实例,因此如果您重新注册它应该没有冲突。 class MyRandom {
private Random random = new Random(DateTime.Now.Ticks);
public void setSeed(long seed) {
random = new Random(seed * this.random.next());
...
public long next() {
return random.next();
}
class MyClass {
private MyRandom random = new MyRandom();
public void Test() {
random.setSeed(seedValue);
int x = random.next();
random.setSeed(seedValue);
int y = random.next();
// x,y will be different in most of the cases now
}
}
只是基础算法的包装器。
如果你想每次都收到不同的结果(即使你使用setSeed),你可以试试这个:
{{1}}
这将改变随机生成器的种子应该如何工作的前/后条件,但可能适合你。