概率分布函数的Java实现

概率分布函数的Java实现,java,math,probability,discrete-mathematics,Java,Math,Probability,Discrete Mathematics,我试图在java中实现一个概率分布函数,它以概率返回数组中的ith项: Fi=6i(n-i)/(n3-n) 其中n是数组长度,即对于数组长度4: P1=3/10,P2=4/10,P3=3/10,P4=0 请注意,此函数假定编号从1到n而不是从0到n-1,与Java中一样 目前我只是使用均匀分布,即 int i = (int)(Math.random()*((arraySize)-1)); 使用-1,这样它就不会选择最后一个元素(如上面公式中的Pn=0) 任何人对实现这一点有任何想法或建议吗?

我试图在java中实现一个概率分布函数,它以概率返回数组中的
ith
项:

Fi=6i(n-i)/(n3-n)

其中
n
是数组长度,即对于数组长度4:

P1=3/10,P2=4/10,P3=3/10,P4=0

请注意,此函数假定编号从1到
n
而不是从0到
n-1
,与Java中一样

目前我只是使用均匀分布,即

 int i = (int)(Math.random()*((arraySize)-1));
使用-1,这样它就不会选择最后一个元素(如上面公式中的Pn=0)


任何人对实现这一点有任何想法或建议吗?

要做到这一点,您需要将范围[0,1]划分为具有所需大小的区域。因此,在这种情况下:

0 -> 0.0 - 0.3
1 -> 0.3 - 0.7
2 -> 0.7 - 1.0
3 -> 1.0 - 1.0
然后使用
Math.random()
生成一个随机数,并查看它属于哪个区间

通常,您希望执行类似以下伪代码的操作:

double r = Math.random();
int i = -1;

while (r >= 0)
{
  i++;
  r -= F(i);
}

// i is now the value you want.

你在[0,1]上生成一个值,然后减去每个区间的大小,直到小于0,这时你就找到了随机值。

这基本上是汤姆森·马特所说的,但更正式一点:你应该执行。您的示例的伪代码:

p = [0.3, 0.4, 0.3. 0.0]
c = [0.3, 0.7, 1.0, 1.0] // cumulative sum

generate x uniformly in continuous range [0,1]
find max i such that c[i] < x.
p=[0.3,0.4,0.3.0.0]
c=[0.3,0.7,1.0,1.0]//累积和
在连续范围[0,1]内均匀生成x
求max i,使c[i]
double rand=Math.random();//在[0,1]中生成一个随机数
F=0;
//你测试rand是否在[F(1)+..+F(i):F(1)+..+F(i)+F(i+1)]中,它在这个带有概率P(i)的rnge中,因此如果它在这个范围内,你返回i

对于(int i=1,i您可以尝试使用具有概率分布的可导航映射。与普通映射不同,可导航映射定义了其键的绝对顺序。如果键不在映射中,它可以告诉您哪个键是最接近的键,或者哪个键是比参数大的最小键。我使用了
ceilingtry
which返回具有大于或等于给定键的最小键的映射项

如果使用树映射作为NavigableMap的实现,那么查找具有多个类的发行版会更快,因为它执行二进制搜索,而不是从第一个键开始,然后依次测试每个键

NaviableMap的另一个优点是,您可以获得您直接感兴趣的数据类,而不是另一个数组或列表的索引,这可以使代码更干净

在我的例子中,我使用了大小数,因为我不太喜欢使用浮点数,因为你不能指定你所需要的精度。但是你可以使用浮点数、双精度或者其他什么

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.NavigableMap;
import java.util.TreeMap;


public class Main {

    public static void main(String[] args) {

        String[] classes = {"A", "B", "C", "D"};
        BigDecimal[] probabilities = createProbabilities(classes.length);
        BigDecimal[] distribution = createDistribution(probabilities);

        System.out.println("probabilities: "+Arrays.toString(probabilities));
        System.out.println("distribution: "+Arrays.toString(distribution)+"\n");

        NavigableMap<BigDecimal, String> map = new TreeMap<BigDecimal, String>();

        for (int i = 0; i < distribution.length; i++) {
            map.put(distribution[i], classes[i]);
        }

        BigDecimal d = new BigDecimal(Math.random());

        System.out.println("probability: "+d);

        System.out.println("result: "+map.ceilingEntry(d).getValue());

    }

    private static BigDecimal[] createDistribution(BigDecimal[] probabilities) {
        BigDecimal[] distribution = new BigDecimal[probabilities.length];

        distribution[0] = probabilities[0];
        for (int i = 1; i < distribution.length; i++) {
            distribution[i] = distribution[i-1].add(probabilities[i]); 
        }
        return distribution;
    }

    private static BigDecimal[] createProbabilities(int n) {
        BigDecimal[] probabilities = new BigDecimal[n];

        for (int i = 0; i < probabilities.length; i++) {
            probabilities[i] = F(i+1, n);
        }
        return probabilities;
    }

    private static BigDecimal F(int i, int n) {
//      6i(n-i) / (n3 - n)
        BigDecimal j = new BigDecimal(i);
        BigDecimal m = new BigDecimal(n);
        BigDecimal six = new BigDecimal(6);

        BigDecimal dividend = m.subtract(j).multiply(j).multiply(six);
        BigDecimal divisor = m.pow(3).subtract(m);

        return dividend.divide(divisor, 64, RoundingMode.HALF_UP);
    }
}
import java.math.BigDecimal;
导入java.math.RoundingMode;
导入java.util.array;
导入java.util.NavigableMap;
导入java.util.TreeMap;
公共班机{
公共静态void main(字符串[]args){
字符串[]类={“A”、“B”、“C”、“D”};
BigDecimal[]概率=createProbabilities(classes.length);
BigDecimal[]分布=createDistribution(概率);
System.out.println(“概率:”+Arrays.toString(概率));
System.out.println(“分发:“+Arrays.toString(分发)+”\n”);
NavigableMap=newtreemap();
对于(int i=0;i
pdf
与此有什么关系?@Eng.Fouad:大概它也意味着“概率分布函数”。F(i)这是一个概率分布function@user528676:很高兴你编辑了这篇文章,请用首字母缩略词思考一下,在一个节目网站上,观众最有可能得到的解释是什么。可能重复的是,对于一般的n,你会怎么做,而不是将n=4作为固定值?谢谢,这些都是非常有用的答案什么是F(I)或者更具体地说是F()?问题中的PDF-在本例中,F(i)=6*i*(n-i)/(n^3-n)我本想早点发布,但我的internet连接中断了:/
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.NavigableMap;
import java.util.TreeMap;


public class Main {

    public static void main(String[] args) {

        String[] classes = {"A", "B", "C", "D"};
        BigDecimal[] probabilities = createProbabilities(classes.length);
        BigDecimal[] distribution = createDistribution(probabilities);

        System.out.println("probabilities: "+Arrays.toString(probabilities));
        System.out.println("distribution: "+Arrays.toString(distribution)+"\n");

        NavigableMap<BigDecimal, String> map = new TreeMap<BigDecimal, String>();

        for (int i = 0; i < distribution.length; i++) {
            map.put(distribution[i], classes[i]);
        }

        BigDecimal d = new BigDecimal(Math.random());

        System.out.println("probability: "+d);

        System.out.println("result: "+map.ceilingEntry(d).getValue());

    }

    private static BigDecimal[] createDistribution(BigDecimal[] probabilities) {
        BigDecimal[] distribution = new BigDecimal[probabilities.length];

        distribution[0] = probabilities[0];
        for (int i = 1; i < distribution.length; i++) {
            distribution[i] = distribution[i-1].add(probabilities[i]); 
        }
        return distribution;
    }

    private static BigDecimal[] createProbabilities(int n) {
        BigDecimal[] probabilities = new BigDecimal[n];

        for (int i = 0; i < probabilities.length; i++) {
            probabilities[i] = F(i+1, n);
        }
        return probabilities;
    }

    private static BigDecimal F(int i, int n) {
//      6i(n-i) / (n3 - n)
        BigDecimal j = new BigDecimal(i);
        BigDecimal m = new BigDecimal(n);
        BigDecimal six = new BigDecimal(6);

        BigDecimal dividend = m.subtract(j).multiply(j).multiply(six);
        BigDecimal divisor = m.pow(3).subtract(m);

        return dividend.divide(divisor, 64, RoundingMode.HALF_UP);
    }
}