我正在尝试解决Java入门问题,似乎无法弄清楚该如何解决。目的如下:
编写一个程序DiscreteDistribution.java,该程序接受一个整数命令行参数m,然后是一系列正整数命令行参数a1,a2,…,an,并打印m个随机索引(用空格分隔),选择每个索引i的概率与ai成正比。
示例输入和输出如下:
> ~/Desktop/arrays> java DiscreteDistribution 25 1 1 1 1 1 1 5 2 4 4 5 5
> 4 3 4 3 1 5 2 4 2 6 1 3 6 2 3 2 4 1 4
到目前为止,我的实现如下:
public class DiscreteDistribution {
public static void main(String args[]) {
int n = args.length;
int[] freq = new int [n];
for(int i = 0; i < n; i++) {
freq[i] = Integer.parseInt(args[i]);
}
int total = 0;
for(int i = 1; i < freq.length;i++) {
total += freq[i];
}
int r = (int) (total * Math.random());
int sum = 0;
int event = -1;
for (int i = 0; i < n && sum <= r; i++) {
sum += freq[i];
event = i;
}
System.out.print(event);
}
}
问题的其他内容提出了以下建议:
定义累计和Si = a1 + a2 + ... + ai和S0 = 0。 统一选择一个介于0和Sn-1之间的随机整数r。 找到介于1和n之间的唯一索引i,以使Si-1≤r
我相信我已经在总变量中适当定义了累加总和,并且也选择了随机整数r。但是,我无法弄清楚如何找到唯一索引。
答案 0 :(得分:1)
一种无需重复即可获取 m 个索引的随机样本的简单方法是生成一个序列,对其进行洗牌,然后获取前一个 m 个项目。
// Produce a sequence.
List<Integer> allIndices = new ArrayList<>();
for (int i = 0; i < freq.length; i += 1) allIndices.add(i);
// Shuffle the sequence in place.
Collection.shuffle(allIndices);
// Take a sublist of m elements, and use it.
List<Integer> indices = allIndices.subList(0, m - 1);
for (Integer ix : indices) {
// Here ix will be a unique random index into freq, use it.
}