随机数的问题
asp.net一个类文件里有如下静态函数
public static int getRandom(int s)
{
Thread.Sleep(1);
Random autoRand = new Random(DateTime.Now.Millisecond);
return autoRand.Next(s)+1;
}
public static int bonus(){
string[] apositionstr = "a,b".Split(',');
string positionStr = apositionstr[getRandom(apositionstr.Length) - 1];
HttpContext.Current.Response.Write(getRandom(apositionstr.Length).ToString() + "\t");
return positionStr;
}
我以为getRandom(apositionstr.Length) - 1表达式的值应该是在 0 和 1 之间随机出现的 。可是。
输出结果是这样的
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
只有一个是2 这是为什么呢 。如果我在.aspx里直接输入getRandom得到的返回值是比较平均的。
--------------------编程问答-------------------- getRandom(2)
在.aspx文件中的输出结果
1 2 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2 1 --------------------编程问答-------------------- 我在想lz这句没错?
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答--------------------
public static int bonus(){
string[] apositionstr = "a,b".Split(',');
string positionStr = apositionstr[getRandom(apositionstr.Length) - 1];
HttpContext.Current.Response.Write(getRandom(apositionstr.Length).ToString() + "\t");
return positionStr;
}
public static int bonus()--------------------编程问答-------------------- 用同一个Random ,才能产生随机数,每次都新实例化,因为种子一样会产生同样的数出来。 --------------------编程问答-------------------- up lz 调用两次产生随机数方法 所以。。。 --------------------编程问答-------------------- HttpContext.Current.Response.Write(getRandom(apositionstr.Length).ToString() + "\t"); --------------------编程问答-------------------- Random autoRand = new Random(DateTime.Now.Millisecond);
{
Random autoRand = new Random();
string[] apositionstr = "a,b".Split(',');
string positionStr = apositionstr[autoRand.Next(apositionstr.Length)];
HttpContext.Current.Response.Write((autoRand.Next(apositionstr.Length) + 1).ToString() + "\t");
return positionStr;
}
你用系统时钟做初始化种子,但不幸地是系统时钟精度不够...现在的Windows系统时钟精度是大概15毫秒,所以在15毫秒内产生的伪随机数是相同的序列,你执行的太快了... --------------------编程问答-------------------- 这样修改就可以了:
public static int bonus()
{
Random autoRand = new Random();
string[] apositionstr = "a,b".Split(',');
string positionStr = apositionstr[autoRand.Next(apositionstr.Length)];
HttpContext.Current.Response.Write((autoRand.Next(apositionstr.Length) + 1).ToString() + "\t");
return positionStr;
}
--------------------编程问答-------------------- 你们的意思是
Random autoRand = new Random(); 代替
Random autoRand = new Random(DateTime.Now.Millisecond); ?
我把生成随机数放到函数就不行了吗?为什么。不是都重新初始化了了吗 --------------------编程问答--------------------
up --------------------编程问答-------------------- andom autoRand = new Random(DateTime.Now.Millisecond);
你用系统时钟做初始化种子,但不幸地是系统时钟精度不够...现在的Windows系统时钟精度是大概15毫秒,所以在15毫秒内产生的伪随机数是相同的序列,你执行的太快了.
我是用手动测试过的。在页面上点击然后执行一次。也是这个样子 范围大一些的时候出的比较 平均。加入范围小的时候比如 1-2就总是出1 --------------------编程问答-------------------- 额干才贴的代码。是我摘出来的。这个是实际的代码
类文件
int ibouns = getRandom(10000);
int iLevelSum = 0;
for (int i = 0; i < dtBonus.Rows.Count; i++)
{
if (Convert.ToInt32(dtBonus.Rows[i]["leftCount"].ToString()) > 0)
{
iLevelSum+=Convert.ToInt32(dtBonus.Rows[i]["BonusLevel"].ToString());
if (iLevelSum >= ibouns)
{
string[] apositionstr = dtBonus.Rows[i]["BonusPositionStr"].ToString().Split(',');
if (apositionstr.Length == 2)
{
positionStr = apositionstr[getRandom(apositionstr.Length) - 1];
HttpContext.Current.Response.Write(positionStr+"\t");
}
else
positionStr = apositionstr[0];
bonusid = dtBonus.Rows[i]["id"].ToString();
//中奖记录
addBonusLog(memberid, bonusid, memberip);
break;
}
}
}
public static int getRandom(int s)
{
Thread.Sleep(1);
Random autoRand = new Random(DateTime.Now.Millisecond);
return autoRand.Next(s)+1;
}
.aspx文件
private void doDebug()
{
for (int i = 0; i < 1000; i++)
{
//SqlHelper.ExecuteNonQuery("insert into test ([value]) values (" + yc.bonus() + ")");
//string[] apositionstr = "a,b".Split(',');
//string positionStr = apositionstr[yc.getRandom(apositionstr.Length) - 1];
//Response.Write(positionStr + "\t");
yc.bonus();
}
}
--------------------编程问答-------------------- public static string bonus()
{
string memberid = "";
string memberip = HttpContext.Current.Request.UserHostAddress;
string bonusid = "";
string positionStr = "";
DataTable dtMember = getLoginUser();
if (dtMember != null)
if (dtMember.Rows.Count != 0)
memberid = dtMember.Rows[0]["id"].ToString();
dtMember = null;
if (memberid == "") return "";
DataTable dtBonus = getBonus();
if (dtBonus == null) ;
else if (dtBonus.Rows.Count == 0) ;
else
{
int ibouns = getRandom(10000);
int iLevelSum = 0;
for (int i = 0; i < dtBonus.Rows.Count; i++)
{
if (Convert.ToInt32(dtBonus.Rows[i]["leftCount"].ToString()) > 0)
{
iLevelSum+=Convert.ToInt32(dtBonus.Rows[i]["BonusLevel"].ToString());
if (iLevelSum >= ibouns)
{
string[] apositionstr = dtBonus.Rows[i]["BonusPositionStr"].ToString().Split(',');
if (apositionstr.Length == 2)
{
positionStr = apositionstr[getRandom(apositionstr.Length) - 1];
HttpContext.Current.Response.Write(positionStr+"\t");
}
else
positionStr = apositionstr[0];
bonusid = dtBonus.Rows[i]["id"].ToString();
//中奖记录
addBonusLog(memberid, bonusid, memberip);
break;
}
}
}
}
dtBonus = null;
//减少积分
SqlHelper.ExecuteNonQuery("update ycMember set points=points-1 where id=" + memberid);
if (positionStr == "")
{
//随机没中奖的位置
string[] noBonusPosition = { "2", "6", "10" };
positionStr = noBonusPosition[getRandom(3) - 1];
}
//中奖和未中奖的记录
log("NOBONUS", positionStr + "," + memberid + "," + memberip);
return positionStr;
} --------------------编程问答-------------------- 首先随机的意思不是平均,其次所谓概率是大量样本的统计结果...比如一个硬币猜正反面50%概率,不代表你丢20次一定是10次正面10次反面,甚至接近0.5都没保证,RP好连出多次20次同一面也有可能...
正因为取值范围小而你的样本量还不够大,你测个成千上万次可能就比较接近了... --------------------编程问答-------------------- Thread.Sleep(1);
我没看程序啊
试试让线程多睡一会怎么样
我单线程的模拟发数据就是睡的时间太短了
数据变化基本没有 --------------------编程问答--------------------
推荐 --------------------编程问答-------------------- 不是时间的问题,否则应该是11111111222222222这样的情况。
也不可能是随机不平均问题,计算机随机数是绝对平均的,这些样本数已经足够概率显现了,绝对不可能只有一个2的情况出现。
现在的情况不是“为什么有一个2”而是这个2到底是怎么出现又突然消失的。LZ可以将每次执行时的毫秒数记录下来,看看是怎么回事? --------------------编程问答-------------------- 参考:
http://school.itzcn.com/special-spid-12.html
补充:.NET技术 , C#