我正在寻找一种从 0-x 生成随机整数的方法,其中 x 由人类用户在运行时定义。但是,这些数字中的一半必须大于零且小于或等于 5 (0,5],而另一半必须在 [6,x] 的集合中。
我知道下面的代码会从 0-x 生成一个数字。主要问题是确保其中一半在 (0,5] 的集合中
Math.random() * x;
我不是在找人为我做这件事,只是在寻找一些提示。谢谢!
您可以先掷硬币,然后根据该硬币生成上限或下限:
final Random rnd = new Random();
while (true)
System.out.println(rnd.nextBoolean()? rnd.nextInt(6) : 6 + rnd.nextInt(x-5));
或者,使用笨重的Math.random()
(在范围的边缘肯定会遇到麻烦):
while (true)
System.out.println(Math.floor(
math.random() < 0.5 ? (Math.random() * 6) : (6 + (x-5) * Math.random())
));
仅将其视为提示:)
我会这样做:
double halfX= x / 2.0;
double random = Math.random() * x;
if( random< halfX ) {
random = random*5.0/(halfX);
} else {
random = (random/halfX - 1) * (x-5.0) + 5.0 ;
}
我觉得现在很好。这不太容易理解和可读,但每次调用只有一次随机调用。除了 MarkoTopolnic 指出的事实之外:用户需要一个整数......我必须计算四舍五入对分布的影响。
这绝对不容易......我的头疼,所以我能想出最好的:
double halfX= x / 2.0 + 1.0;
double random = Math.random() * (x+2.0);
int randomInt;
if( random< halfX ) {
randomInt = (int) (random*6.0/(halfX)); //truncating, means equal distribution from 0-5
} else {
randomInt = (int) ((random/halfX - 1.0) * (x-5.0) + 6.0) ; //notice x-5.0, this range before truncation is actually from 6.0 to x+1.0, after truncating it gets to [6;x], as this is integer
}
第二部分我不确定...睡几个小时就可以了...我希望意图和逻辑很清楚...
如果有人好奇,这是我根据 Marko 的解决方案提出的解决方案。
我为该程序的另一部分定义了以下类。
public class BooleanSource
{
private double probability;
BooleanSource(double p) throws IllegalArgumentException
{
if(p < 0.0)
throw new IllegalArgumentException("Probability too small");
if(p > 1.0)
throw new IllegalArgumentException("Probability too large");
probability = p;
}
public boolean occurs()
{
return (Math.random() < probability);
}
}
With that, I did the following
private static void setNumItems(Customer c, int maxItems)
{
BooleanSource numProb = new BooleanSource(0.5);
int numItems;
if(numProb.occurs())
{
double num = (Math.random()*4)+1;
numItems = (int) Math.round(num);
}
else
{
double num = 5 + (maxItems-5)*Math.random();
numItems = (int) Math.round(num);
}
c.setNumItems(numItems);
}