随机,不是那么随机,在Windows Phone 7上随机上课

本文关键字:随机 Phone Windows | 更新日期: 2023-09-27 18:10:24

事情是这样的。

我已经为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];
        });
    }

随机,不是那么随机,在Windows Phone 7上随机上课

Random(100)创建Random的第一个实例,即一个常量种子。所以它总是返回相同的序列。这反过来意味着Random的第二个实例的种子也是恒定的,它返回的所有值也是恒定的。

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

警告:由于时间每隔几毫秒才改变一次(在典型的windows计算机上是1-16ms),如果您使用默认构造函数快速连续创建多个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];
    });
}

你在显式地声明种子:

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

r1将始终使用相同的种子(100),因此r1.Next(0, 50)将始终给出相同的种子,因此r2将始终使用相同的种子。你没有真正的随机性。

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

请参阅我关于。net中随机数生成的文章。

除非您想要可重复的序列,否则您不应该使用固定种子为随机生成器提供种子:

new Random(100);
应该

new Random();

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

随机数对于PC来说是不可能的,尽管这听起来很奇怪。所以你需要一个"随机"数来初始化你的随机生成器。

长话短说。删除第一个随机对象,并在第二个对象上使用空构造函数。

默认种子值来自系统时钟,并且具有有限的分辨率

每次都用相同的种子播种。只要使用new Random()。如果在WP7上不可用,则使用当前时间的导数作为种子。

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

尝试另一种方式播种:

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

你有相同的种子。使用从当前日期生成的数字之类的东西

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

只需使用以下代码;

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