C# 按rand(5)生成1-7之间的随机数
我想写一个算法来生成1-7之间的随机数,给定一个生成1-5之间随机数的方法 我想到的一个解决方案是rand(5)/5*7 我认为这应该行得通 有人能告诉我一个最佳的解决方案吗 我在某个地方读过这个解决方案,但我不知道他们是如何考虑保留“int num=5*(rand5()-1)+(rand5()-1);”的。我知道它会产生一个介于1-7之间的随机数,但他们是如何思考这个逻辑的,或者他们试图传达什么,并没有进入我的脑海。谁能帮我解释一下吗C# 按rand(5)生成1-7之间的随机数,c#,java,C#,Java,我想写一个算法来生成1-7之间的随机数,给定一个生成1-5之间随机数的方法 我想到的一个解决方案是rand(5)/5*7 我认为这应该行得通 有人能告诉我一个最佳的解决方案吗 我在某个地方读过这个解决方案,但我不知道他们是如何考虑保留“int num=5*(rand5()-1)+(rand5()-1);”的。我知道它会产生一个介于1-7之间的随机数,但他们是如何思考这个逻辑的,或者他们试图传达什么,并没有进入我的脑海。谁能帮我解释一下吗 public static int rand7() { w
public static int rand7() {
while (true) {
int num = 5 * (rand5() - 1) + (rand5() - 1);
if (num < 21)
return (num % 7 + 1);
}
}
public static int rand7(){
while(true){
int num=5*(rand5()-1)+(rand5()-1);
if(num<21)
返回(数值%7+1);
}
}
将5更改为所需的数字。您必须导入import java.util.Random代码>
int range = 7; // Now you can change your limit here.
Random r = new Random();
int number = r.nextInt(range);
它是另一个不使用rand5()
的解决方案。您发布的代码就是一个示例。表情
5 * (rand5() - 1) + (rand5() - 1);
生成均匀分布在0和24之间的随机数。第一项是0到4之间的随机数的5倍,产生一个概率相等的集合{0,5,10,15,20}。第二个是介于0和4之间的随机数。由于这两个随机数可能是相互独立的,因此将它们相加会得到一个均匀分布在0和24之间的随机数。第二个数字“填补”了第一个术语生成的数字之间的空白
然后,测试拒绝21或以上的任何数字,并重复该过程。当一个数字通过测试时,它将是一个均匀分布在0和20(含)之间的随机数。然后使用%7
将该范围划分为7个数字(0到6之间),并在返回之前添加一个数字。由于区间[0,20]中有21个数字,且21可被7整除,因此0和6之间的数字出现的概率相等
在表格中:
A B num
rand5()-1 rand5()-1 5 * A + B num % 7 + 1
--------- --------- --------- -----------
0 0 0 1
1 0 5 6
2 0 10 4
3 0 15 2
4 0 20 7
0 1 1 2
1 1 6 7
2 1 11 5
3 1 16 3
4 1 21 reject
0 2 2 3
1 2 7 1
2 2 12 6
3 2 17 4
4 2 22 reject
0 3 3 4
1 3 8 2
2 3 13 7
3 3 18 5
4 3 23 reject
0 4 4 5
1 4 9 3
2 4 14 1
3 4 19 6
4 4 24 reject
请注意,最后一列正好有[1,6]范围内每个数字中的三个
理解逻辑的另一种方式是根据5进制算术进行思考。由于rand5()
生成一个介于1和5(含)之间的随机整数,因此我们可以使用rand5()-1
为基数为5的数字生成随机数字。我们试图生成数字1到7(或者,等价地,0到6),所以我们至少需要两个5进制数字才能有七个数字。让我们一位一位地生成一个随机的,两位数,以5为基数的数字。这就是5*(rand5()-1)+(rand5()-1)
所做的。然后我们可以一遍又一遍地这样做,直到得到一个介于0和6(0和115)之间的数字。然而,拒绝我们生成的两位数中较少的一个会更有效。我们可以通过使用最大的两位数(以5为基数,是7的倍数)来实现这一点。正好是415,也就是2110。(我们排除415本身,因为我们从0开始,而不是1。)因为我们想要一个介于0和6之间的数字,所以我们使用%7
缩小范围。(我们也可以除以3,因为[0405]中正好有三个7-整数范围。但是,使用余数运算符可以清楚地表明我们的目标是范围[0,6]。)
另外,你提出的解决方案行不通。虽然表达式似乎具有正确的范围,但它只能生成五个不同的数字,因此不可能是正确的。它还可以生成0(当rand5()
返回1时)。如果您正在处理浮点随机数生成,那么像这样简单的缩放将是一个很好的方法。(但是,在缩放之前,您需要先移到0,然后再移回1,以获得正确的范围下限。我认为表达式应该是1+7*(rand5()-1)/5
。但是rand5()
返回一个整数,而不是浮点。)寻找解决方案@VighaneshGursale not duplicate bro。。甚至不到1%,,如果我能得到解决方案,我就不会只发布第二行了。请解释一下第二行?它的内置java类。OP试图解决的问题是:给定一个“黑盒”生成器,生成一个均匀分布在0和5之间的随机整数,编写一个生成一个均匀分布在0和7之间的随机整数的生成器。我想,使用Random
类违反了赋值规则。我试过用c#,但它有nextDouble,并且不包含任何参数。这里按范围如果我写nextInt(50),那么它会从0-50生成一个随机数?C#random。接下来谢谢。但是为什么需要生成两个单独的随机数,然后相加,然后再次检查一个条件呢?我不明白,为什么生成两个随机数,然后再加上it@user2387900-其思想是生成一个均匀分布的范围,其中拒绝区域较小。对于大多数接受-拒绝方法,在您为获得一个不太浪费的范围所做的工作与您因拒绝太频繁而必须做的工作之间存在权衡。您需要多次调用rand5()
以获得五个以上的不同值(至少需要7个)。通过添加第二项,您可以确保表达式能够以相同的概率生成1到24之间的每个数字。@user2387900-我重新编写了我的答案,以解决我上一条评论中的一些问题。rand(5)/5*7??这个..@user2387900会有什么问题?记住这都是整数运算。使用该表达式只能生成五个值。请看我答案中的P.S。