2011-10-05 119 views
2

所以,这是交易。随机不是随机的,在Windows Phone 7上随机班级

我已经为wp7设置了一个应用程序,其中有50个引号的数组。当用户单击按钮时,会显示阵列中的随机引号。问题是,报价总是以相同的顺序出现。例如,引号是1-50。订单总是2,4,20,31,10,... 有没有办法解决这个问题?我希望每次使用应用程序时都会出现随机和不同的引用。

下面的代码:

string[] listaCantadas; 
    Random r1, r2; 

    public MainPage() 
    { 
     InitializeComponent(); 

     listaCantadas = new string[] 
     {"//set of quotes 
     }; 

     r1 = new Random(100); 
     r2 = new Random(r1.Next(0, 50)); 
    } 

    //click event for display a random quote 

      int Cantada = r2.Next(0, listaCantadas.Length - 1); 
      txtBlockCantada.Text = listaCantadas[Cantada]; 

     }); 
    } 

回答

14

你创建你的第一个实例RandomRandom(100)即恒定种子。所以它会一直返回相同的序列。这又意味着你的第二个实例Random的种子也将保持不变,并且它返回的所有值也是如此。

只需使用默认构造函数创建一个Random的单个实例,即new Random()。这是随着时间的推移,因此在程序的不同运行之间可能会有所不同。

警告:由于时间只会每隔几毫秒(在典型的Windows计算机上为1-16毫秒)改变,如果您使用默认构造函数快速连续创建Random的几个实例,它们很可能都会返回相同的序列。

另一个常见的缺陷是Random不是线程安全的。但看起来你不会遇到这个问题。

string[] listaCantadas; 
Random r;//No need for more than one instance 

public MainPage() 
{ 
    InitializeComponent(); 

    listaCantadas = new string[] 
    {"//set of quotes 
    }; 

    r = new Random(); 
} 

//click event for display a random quote 

     int Cantada = r.Next(0, listaCantadas.Length - 1); 
     txtBlockCantada.Text = listaCantadas[Cantada]; 

    }); 
} 
+0

非常感谢,现在它就像一个魅力! – Boga

+0

而** do **使其成为一个静态实例。 –

+3

@ClausJørgensen:好的,只有当你打算*确保你不会从多个线程调用它时。通常静态成员预计是线程安全的。 'Random' *不是*线程安全的。 –

1

你每一次相同的种子播种了。只需使用new Random()即可。如果WP7上没有此功能,请使用当前时间的派生作为种子。

0

你有相同的种子。使用类似从当前日期

r1 = new Random(DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Second); // etc 
+3

或者只是调用'new Random()'它为你做... –

1

种子生成的数字总是相同的,甚至从另一个随机初始化!

播种尝试另一种方式:

new Random(unchecked((int) (DateTime.Now.Ticks))); 
+0

这比使用'Random'的默认构造函数更糟糕。它受到与默认构造函数相同的问题,以及使用'Ticks'限制种子空间的额外问题。 – CodesInChaos

2

你不应该有种子的固定种子随机发生器,除非你想重复序列:

new Random(100); 

应该

new Random(); 
4

您正在明确说明种子:

r1 = new Random(100); 
r2 = new Random(r1.Next(0, 50)); 

r1将始终使用相同的种子(100),所以r1.Next(0, 50)将总是得到相同的种子,所以r2将始终使用相同的种子。你没有真正的随机性。

您应该创建一个Random的实例并重用它 - 同时注意Random不是线程安全的。 (如果你只打算从UI线程使用你的实例,那很好。)

有关更多信息,请参阅我的article on random number generation in .NET

2

那么你初始化的种子总是在你的r1随机数上是100。这当然意味着根据种子你总会得到相同的数字。这意味着你的r2总是用相同的种子初始化的,所以r1和r2总是相同的。

随机数对于个人电脑来说是不可能的,这听起来很奇怪。所以你需要一个“随机”数字来初始化你的随机生成器。

长话短说。第二个删除第一个随机对象并使用空的constructor

默认种子值被从系统时钟导出,并且具有有限的分辨率

0

只需使用下面的代码;

Random r = new Random(); 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      string[] listaCantadas = 
      { 
       "q1", 
       "q2", 
       "q3", 
       "q4", 
       "q5" 
      }; 

      //click event for display a random quote 
      txtBlockCantada.Text = listaCantadas[r.Next(0, listaCantadas.Length)]; 
     }