C# 产生随机数
private void Form1_Load(object sender, EventArgs e)
{
double u1, u2, v1 = 0, v2 = 0, s = 0, z1 = 0, z2 = 0;
for (int i = 0; i < 50; i++)
{
Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));
while (s > 1 || s == 0)
{
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + " ";
}
}
winform窗体,textbox显示计算出的正态分布随机数。
现在问题是,运行之后产生的数据都是一样的。但是调试单步执行,数据又不同,大家有没有什么解决的办法吗? C# random --------------------编程问答-------------------- new Random要放在循环外面 --------------------编程问答-------------------- 把 Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));
放到循环外边 --------------------编程问答-------------------- 放在循环外面,数据也是重复的 --------------------编程问答-------------------- 我刚才在VS上把你的代码运行了一下.
问题就是 那个while 循环 只能进去2次 所以 只有2个数字 剩下的都是循环他们的.
不知道你那么多数字是干啥的,反正你解决这个问题貌似就行了... --------------------编程问答--------------------
static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
Random rand1 = new Random(GetRandomSeed());
private void Form1_Load(object sender, EventArgs e)
{
// Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));
double u1, u2, v1 = 0, v2 = 0, s = 0, z1 = 0, z2 = 0;
for (int i = 0; i < 50; i++)
{
while (s > 1 || s == 0)
{
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + " ";
}
}
上面的方法试了,数据还是重复的 --------------------编程问答-------------------- 如果new Random()时没传递不一样的种子的话,生成的随机数,在顺序上是一样的,建议,可以生成一个静态的Random这样的 --------------------编程问答-------------------- 贡献下我自己的高斯分布的类吧..
--------------------编程问答-------------------- O(∩_∩)O~ 下班了,回去再试试大家提供的方法,先谢谢你们啦 --------------------编程问答-------------------- private void Form1_Load(object sender, EventArgs e)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
///正态分布帮助
/// </summary>
public class NormalDistribution
{
public NormalDistribution()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 正态分布随机数
/// </summary>
const int N = 100;
const int MAX = 50;
const double MIN = 0.1;
const int MIU = 40;
const int SIGMA = 1;
static Random aa = new Random((int)(DateTime.Now.Ticks / 10000));
/// <summary>
/// 产生(min,max)之间均匀分布的随机数
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public double AverageRandom(double min, double max)
{
int MINnteger = (int)(min * 10000);
int MAXnteger = (int)(max * 10000);
int resultInteger = aa.Next(MINnteger, MAXnteger);
return resultInteger / 10000.0;
}
/// <summary>
/// 正态分布概率密度函数
/// </summary>
/// <param name="x"></param>
/// <param name="miu"></param>
/// <param name="sigma"></param>
/// <returns></returns>
public double Normal(double x, double miu, double sigma)
{
return 1.0 / (x * Math.Sqrt(2 * Math.PI) * sigma) * Math.Exp(-1 * (Math.Log(x) - miu) * (Math.Log(x) - miu) / (2 * sigma * sigma));
}
/// <summary>
/// 产生正态分布随机数
/// </summary>
/// <param name="miu"></param>
/// <param name="sigma"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public double Random_Normal(double miu, double sigma, double min, double max)
{
double x;
double dScope;
double y;
do
{
x = AverageRandom(min, max);
y = Normal(x, miu, sigma);
dScope = AverageRandom(0, Normal(miu, miu, sigma));
} while (dScope > y);
return x;
}
/// <summary>
/// 指数分布随机数
/// </summary>
/// <param name="const_a">const_a是指数分布的参数λ</param>
/// <returns></returns>
public double RandExp(double const_a)
{
Random rand = new Random(Guid.NewGuid().GetHashCode());
double p;
double temp;
if (const_a != 0)
temp = 1 / const_a;
else
throw new System.InvalidOperationException("除数不能为零!不能产生参数为零的指数分布!");
double randres;
while (true) //用于产生随机的密度,保证比参数λ小
{
p = rand.NextDouble();
if (p < const_a)
break;
}
randres = -temp * Math.Log(temp * p, Math.E);
return randres;
}
/// <summary>
/// 求出数据平均值,并保留三位小数
/// </summary>
/// <param name="Valist">数据集合</param>
/// <returns></returns>
public double average(List<double> Valist)
{
double sum = 0;
foreach (double d in Valist)
{
sum = sum + d;
}
double revl = System.Math.Round(sum / Valist.Count, 2);
return revl;
}
/// <summary>
/// 求数据集合标准差
/// </summary>
/// <param name="ValList"></param>
/// <returns></returns>
public double stdev(List<double> ValList)
{
double avg = average(ValList);
double sumstdev = 0;
foreach (double d in ValList)
{
sumstdev = sumstdev + (d - avg) * (d - avg);
}
double stdeval = System.Math.Sqrt(sumstdev);
return System.Math.Round(stdeval, 2);
}
}
{
double u1, u2, v1 = 0, v2 = 0, z1 = 0, z2 = 0;
for (int i = 0; i < 3; i++)
{
double s = 0;
while (s > 1 || s == 0)
{
Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + " ";
}
}
其实这只是小小的改动,电脑没你想象的那么快的可以那么快就可以产生那么多的随机数,它也需要时间的,估计是反应不过来就把上次的内容输出了,你可以加个timer控件看看,一次次它有时间产生随机数当然是可以成功的! --------------------编程问答-------------------- 上面很多是误人子弟呀
static int GetRandomSeed()C#的Random类默认是用当前的时间做为Seed的,所以如果时间一样的话,你怎么调用都是一样的,所以要保证真正的随机,必须保证获取随机数的时候,随机种子是不一样的。 --------------------编程问答-------------------- Random rd = new Random();
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
private void Form1_Load(object sender, EventArgs e)
{
// Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));
double u1, u2, v1 = 0, v2 = 0, s = 0, z1 = 0, z2 = 0;
for (int i = 0; i < 50; i++)
{
Random rand1 = new Random(GetRandomSeed());
Random rand2 = new Random(GetRandomSeed());
while (s > 1 || s == 0)
{
u1 = rand1.NextDouble();
u2 = rand2.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + " ";
}
}
rd.Next(0, str.Length);
你给next一下 试试。 --------------------编程问答--------------------
http://blog.csdn.net/conmajia/article/details/7596149 --------------------编程问答-------------------- 上面的方法都试过了,不管怎么改,数据都还是重复的,除非调试单步执行会生成不一样的数据。
#7的代码可以用 --------------------编程问答-------------------- 有什么办法可以延缓代码执行吗 --------------------编程问答-------------------- thread。sleep(100); --------------------编程问答-------------------- 楼主,你自己先写一简单的测试随机函数三,并且我估计是你的逻辑有问题,写程序一定要学会调试 --------------------编程问答-------------------- 问题解决了,用Thread.Sleep()延长时间,这样每次获取的种子数据就不一样了,谢谢大家的解答。 --------------------编程问答-------------------- 代码贴出来大家看下
static int GetRandomSeed()--------------------编程问答-------------------- 这个实验证明了.net的Random是将当前时间带入运算的。当种子正好是当前时间时,会产生相同结果。 --------------------编程问答-------------------- 因为程序计算比较快,50次循环下来,DateTime.Now.Ticks值根本变
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
private void Form1_Load(object sender, EventArgs e)
{
double u1, u2, v1 = 0, v2 = 0, z1 = 0, z2 = 0;
for (int i = 0; i < 50; i++)
{
double s = 0;
//为了保证lns<0,要求s<1且s !=0,若不满足条件,则重新产生u和v
Thread.Sleep(100);
Random rand1 = new Random(GetRandomSeed());
while (s > 1 || s == 0)
{
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + "\r\n";
}
}
}
for (int i = 0; i < 50; i++)
{
this.txtContent.Text += DateTime.Now.Ticks.ToString()+"<br/>";
}
得到的结果全部是:635085529614859793
Random rand1 = new Random(unchecked((int)DateTime.Now.Ticks));并不是随机的 而是根据种子数值通过算法计算出来的 --------------------编程问答-------------------- LZ
这个是别人给的资源 里面有用到随机数 LZ可以看看
http://pan.baidu.com/share/link?shareid=1455601487&uk=1677815159 --------------------编程问答--------------------
用timer也可以延长! --------------------编程问答-------------------- 其实不需要延时,把random放到外面,再把while改成dowhile就行了。 --------------------编程问答--------------------
--------------------编程问答-------------------- 怎么不想下 , 当 s 在(0,1]之间的时候是不会进while循环的 所以 你能不能保证s一定不在那个区间里面? --------------------编程问答--------------------
private void Form1_Load(object sender, EventArgs e)
{
double u1, u2, v1 = 0, v2 = 0, s = 0, z1 = 0, z2 = 0;
Random rand1 = new Random();
for (int i = 0; i < 50; i++)
{
do
{
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
}
while (s > 1 || s == 0);
z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
textBox1.Text += z1.ToString() + " " + z2.ToString() + " ";
}
}
试了下,确实可以,为什么把while改成do-while结果会不一样呢? --------------------编程问答-------------------- 因为使用while (s > 1 || s == 0),判断的变量是s。
但是在for (int i = 0; i < 50; i++)循环里面你没有对s重新赋值,这样i=1-49使用的都是i=0时的s,换句话说你的while (s > 1 || s == 0)循环只能i=0的时候才会进入。 --------------------编程问答-------------------- while是先判断,后执行。do-while是先执行,后判断。
--------------------编程问答-------------------- 这么简单的问题回答的人好多阿 --------------------编程问答--------------------
和随机数一毛钱关系都没有 while语句只执行了一次
--------------------编程问答-------------------- 我表示难的问题找谁呢 --------------------编程问答--------------------
string ss="";
double u1, u2, v1 = 0, v2 = 0, s = 0, z1 = 0, z2 = 0;
Random rand1;
for (int i = 0; i < 50; i++)
{
rand1 = new Random(unchecked((int)DateTime.Now.Ticks)+i);
//while (s > 1 || s == 0)
//{
u1 = rand1.NextDouble();
u2 = rand1.NextDouble();
v1 = 2 * u1 - 1;
v2 = 2 * u2 - 1;
s = v1 * v1 + v2 * v2;
//}
//z1 = Math.Sqrt(-2 * Math.Log(s) / s) * v1;
//z2 = Math.Sqrt(-2 * Math.Log(s) / s) * v2;
ss += u1.ToString() + " " + u2.ToString() + "<br />";
}
Response.Write(ss);
只有靠 本拉登了 --------------------编程问答-------------------- public string returnStr()
{
Random rd = new Random();
string str = "";
string[] s = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
for (int i = 0; i < 20; i++)
{
str += s[rd.Next(26)].ToString()+".";
}
return str.ToString();
}
--------------------编程问答-------------------- --------------------编程问答-------------------- 学习了,这个很有用!
补充:.NET技术 , C#