【发布时间】:2015-04-19 02:28:44
【问题描述】:
这个问题非常具体。我找到了几十个地方告诉你如何在 Java 中生成随机排列,但它从来没有达到计算卡方分布的概率。让我告诉你,设置它似乎很公平,网上有很多教程,但是关于这段代码的一件事确实让我烦恼的是,在作业的第二部分,我应该生成一个随机排列来自索引 j 的字符串,其中 j 在 0 和 i 的范围内随机选择。一种方法应该一直输出 1.0 的概率,这是有偏见的和不公平的,而第二种方法生成的概率是 0 到 1.0 之间的任意数字。我在第 1 部分中有第一部分,但第二部分我无法让它一直显示 1.0。作业说我只是简单地遍历数组。在这种情况下,尝试了两种排列生成方式:
方法一:
public static String generatePermutation(String prefix, String t){
int n = 6;
String s = "";
StringBuilder test = new StringBuilder(t);
if (n == 0){
System.out.println(prefix);
}
else {
for(int i = 0; i < n; i++){
int j = randInt(0, i);
char temp = test.charAt(j);
test.setCharAt(j, test.charAt(i));
test.setCharAt(i, temp);
}
s = test.toString();
return s;
}
return s;
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
方法二:
public static String generatePermutation(String prefix, String t){
char[] letters = t.toCharArray();
shuffle(letters);
String s = new String(letters);
return s;
}
public static void shuffle(char[] array){
int n = array.length;
Random rand = new Random();
while(n > 1){
int k = rand.nextInt(n--);
char temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
这两种方法似乎都没有给我一个介于 0 和 1.0 之间的随机数概率。作业第 2 部分的当前代码结构如下:
package math3323assignment7;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Collections;
import org.apache.commons.math3.distribution.ChiSquaredDistribution;
import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultiset;
public class assignment7part2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "ABCDEF";
Map<String, Integer> counts = new HashMap<>();
Integer count;
int expected = (int)factorial(s.length());
for(int i = 0; i < 720000; i++){
String t = generatePermutation("",s);
count = counts.get(t);
if(count == null){
count = 1;
}
else {
count = count + 1;
}
counts.put(t, count);
System.out.println(t);
}
for(Entry<String, Integer> entry : counts.entrySet()){
System.out.println(entry.getValue() + " times: " + entry.getKey());
}
double chistat = 0.0;
for(Entry<String, Integer> entry: counts.entrySet()){
double di = entry.getValue() - expected;
chistat += di*di/expected;
}
ChiSquaredDistribution chisq = new ChiSquaredDistribution(719.0);
double prob = chisq.cumulativeProbability(chistat);
System.out.printf("ChiSquare statistic = " + chistat + " the probability is " + prob);
}
public static String generatePermutation(String prefix, String t){
char[] letters = t.toCharArray();
shuffle(letters);
String s = new String(letters);
return s;
}
public static long factorial(int n){
if (n <= 1){
return 1;
}
else {
return n * factorial(n-1);
}
}
public static void shuffle(char[] array){
int n = array.length;
Random rand = new Random();
while(n > 1){
int k = rand.nextInt(n--);
char temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
如您所见,Apache API 中的 Apache Math Distribution 类被用于创建 Chi Square Distribution。正在使用单独的 for 循环来计算卡方统计量。不幸的是,当我运行程序时,输出的最后总是与此类似:
Prints all random permutations 720,000 times
Counts all the times each permutation occurs, and print out the numbers
ChiSquare statistic = 79360.74444444438 the probability is 1.0
我希望最后的部分像这样打印出来:
ChiSquare statistic = 79360.74444444438 the probability is 0.64
能否请您帮我解决这个问题,使程序第二部分的最终结果看起来像上面那行?
【问题讨论】:
标签: java apache count permutation chi-squared