需求:给定一串序列,统计这串序列的概率密度函数
步骤:1. 获取序列并从小到大排序,这里使用数组作为参数传入函数
2. 设定区间数量,序列总数/区间数量=区间宽度,每个区间的中点值作为横坐标
3. 求得: 概率= 每个区间内的序列数/序列总数;概率密度= 概率/区间宽度,概率密度作为当前区间的纵坐标
4. 将求得的横纵坐标写在二维数组里(写在map里无序,不方便存取)
5. 可以将二维数组中的横纵坐标读到两个list中
代码:
- /**
- * 统计序列的概率密度返回横纵坐标
- * @param frames 序列
- * @param framenum 序列长度,从外面计算一并传进来了
- * @param intervalCount 区间个数
- * @return
- */
- public static double[][] statisticPD(int[] frames, int framenum, int intervalCount) {
- // 概率密度
- double Pd;
- // 区间上下界和中间值
- int upInterval, downInterval, middleValue;
- // 每个区间内的帧数量
- int count = 0;
- // 横纵坐标保存数组
- double[][] frameArray = new double[intervalCount][2];
- Arrays.sort(frames);
- int minFrame = frames[0];
- int maxFrame = frames[framenum - 1];
- // 区间宽度
- int interval = (maxFrame - minFrame) / intervalCount;
- System.out.println("Min=" + minFrame + " " + "Max=" + maxFrame);
- for (int k = 0; k < intervalCount; k++) {
- upInterval = minFrame + (k + 1) * interval - 1;
- downInterval = minFrame + k * interval;
- middleValue = downInterval + interval / 2; // 中点值(每一个横坐标)
- for (int i = 0; i < framenum; i++) {
- if (frames[i] < upInterval && frames[i] >= downInterval) {
- count++;
- }
- }
- Pd = (double) count / framenum / interval; // 纵坐标
- frameArray[k][0] = middleValue;
- frameArray[k][1] = Pd;
- count = 0;
- }
- return frameArray;
- }
PS: 需要统计直方图就直接用count, 需要概率分布就 count/framenum
理论上是区间越多,区间宽度越小,图形越平滑。可以用平滑的曲线去拟合坐标值