产生随机数,如果添加等于指定的数字
Producing random numbers, which if added equal to a specified number
我正在尝试生成 0 到 100 之间的四个随机数,它们等于 100。
我已经设法产生了结果,但效率不高。我的方法就是一直在0-100之间循环随机数,然后相加,如果不等于100就重复这个过程,直到等于100。有没有更有效的方法?
提前致谢
您可以生成第一个介于 1 和 (100-3) 之间的随机数。假设您的第一个随机数是 X。您生成的下一个随机数应该介于 X 和 (100-2) 之间。假设那个数字是 Y。下一个随机数应该在 (X+Y) 和 (100-1) 之间。假设那个数字是Z.
现在您有了第四个随机数,即 100-X-Y-Z。仔细检查其中的一些,以表明它与您当前的数字生成器具有相同的分布,以检查您的工作。
不重复地随机抽取 0 到 100 之间的 3 个数字。现在将它们按升序排序,并将后续数字之间的差距解释为您首先绘制的数字。使用 3 个分隔符,您要绘制的 4 个数字有 4 个间隔。
如果您不介意,使用此方法您可以多次使用相同的号码。
生成4个0到100之间的随机数
四个数求和(s)
将生成的四个数字中的每一个除以 s/100(四舍五入)
你的总和现在是 99, 100, 101
如果需要检查调整是否低于 0 或高于 100
,将其中一个随机数向上或向下调整 1
你可以这样做:
Random r = new Random();
int n1 = r.nextInt(100);
int n2 = r.nextInt(100 - n1);
int n3 = r.nextInt(100 - n1 - n2);
int n4 = 100 - n1 - n2 - n3;
这似乎工作得很好:
Random random = new Random();
public int[] fourRandoms(int limit) {
int[] randoms = new int[4];
int[] three = new int[3];
for (int i = 0; i < 3; i++) {
three[i] = random.nextInt(limit);
}
int min = Math.min(three[0], Math.min(three[1], three[2]));
int max = Math.max(three[0], Math.max(three[1], three[2]));
int mid = three[0] + three[1] + three[2] - max - min;
randoms[0] = min - 0;
randoms[1] = mid - min;
randoms[2] = max - mid;
randoms[3] = limit - max;
return randoms;
}
public void test() {
for (int i = 1; i < 10; i++) {
int[] randoms = fourRandoms(100);
int sum = Arrays.stream(randoms).sum();
System.out.println(Arrays.toString(randoms) + " = " + sum);
}
}
它是@SpaceTrucker 的实现。
或者 - 使用 Java 8 个流。
public int[] nRandomsThatSumToLimit(int n, int limit) {
return IntStream
.concat(
// Stream n-1 random ints and sort them.
random.ints(n - 1, 0, limit).sorted(),
// Plus the final limit value.
IntStream.of(limit))
// Convert into a stream of differences.
.map(new IntUnaryOperator() {
// Maintain the previous.
int p = 0;
@Override
public int applyAsInt(int n) {
// Difference.
int d = n - p;
// Persist.
p = n;
return d;
}
}).toArray();
}
我正在尝试生成 0 到 100 之间的四个随机数,它们等于 100。
我已经设法产生了结果,但效率不高。我的方法就是一直在0-100之间循环随机数,然后相加,如果不等于100就重复这个过程,直到等于100。有没有更有效的方法?
提前致谢
您可以生成第一个介于 1 和 (100-3) 之间的随机数。假设您的第一个随机数是 X。您生成的下一个随机数应该介于 X 和 (100-2) 之间。假设那个数字是 Y。下一个随机数应该在 (X+Y) 和 (100-1) 之间。假设那个数字是Z.
现在您有了第四个随机数,即 100-X-Y-Z。仔细检查其中的一些,以表明它与您当前的数字生成器具有相同的分布,以检查您的工作。
不重复地随机抽取 0 到 100 之间的 3 个数字。现在将它们按升序排序,并将后续数字之间的差距解释为您首先绘制的数字。使用 3 个分隔符,您要绘制的 4 个数字有 4 个间隔。
如果您不介意,使用此方法您可以多次使用相同的号码。
生成4个0到100之间的随机数
四个数求和(s)
将生成的四个数字中的每一个除以 s/100(四舍五入)
你的总和现在是 99, 100, 101
如果需要检查调整是否低于 0 或高于 100
你可以这样做:
Random r = new Random();
int n1 = r.nextInt(100);
int n2 = r.nextInt(100 - n1);
int n3 = r.nextInt(100 - n1 - n2);
int n4 = 100 - n1 - n2 - n3;
这似乎工作得很好:
Random random = new Random();
public int[] fourRandoms(int limit) {
int[] randoms = new int[4];
int[] three = new int[3];
for (int i = 0; i < 3; i++) {
three[i] = random.nextInt(limit);
}
int min = Math.min(three[0], Math.min(three[1], three[2]));
int max = Math.max(three[0], Math.max(three[1], three[2]));
int mid = three[0] + three[1] + three[2] - max - min;
randoms[0] = min - 0;
randoms[1] = mid - min;
randoms[2] = max - mid;
randoms[3] = limit - max;
return randoms;
}
public void test() {
for (int i = 1; i < 10; i++) {
int[] randoms = fourRandoms(100);
int sum = Arrays.stream(randoms).sum();
System.out.println(Arrays.toString(randoms) + " = " + sum);
}
}
它是@SpaceTrucker
或者 - 使用 Java 8 个流。
public int[] nRandomsThatSumToLimit(int n, int limit) {
return IntStream
.concat(
// Stream n-1 random ints and sort them.
random.ints(n - 1, 0, limit).sorted(),
// Plus the final limit value.
IntStream.of(limit))
// Convert into a stream of differences.
.map(new IntUnaryOperator() {
// Maintain the previous.
int p = 0;
@Override
public int applyAsInt(int n) {
// Difference.
int d = n - p;
// Persist.
p = n;
return d;
}
}).toArray();
}