代码改错:java实现马尔可夫的转移矩阵
我说打扰@ 2020-11-06 09:32:29 为了预测下一步的变化率,我需要获得建立马尔可夫链模型的转移矩阵,利用现有数据计算变化率,计算出相应的状态,然后求出每个状态的转移概率 。 通过转移概率,我们可以预测下一步的变化率,但是我得到的转移概率矩阵有问题。 几行概率的总和不等于1。我不知道如何修改它。 请帮忙!代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class TestA {
public static void main(String[] args) {
//12个测试的真实数据
double [] rainFall = new double[] {
1438.646484,1445.384766,1884.957031,1878.256836,1891.259766,
2364.574219,2773.780273,2865.074219,3365.361328,3390.108398,
4417.552734,5636.793945
};
double max = rainFall[0];
for(int e = 1;e<rainFall.length;e++){
if(rainFall[e]>max){
max = rainFall[e];
}}
double min = rainFall[0];
for(int k = 1;k<rainFall.length;k++){
if(rainFall[k]<min){
min = rainFall[k];
}}
double cha=0;
cha=max-min;
System.out.print("总变化量:"+cha+"\n");
double[] arr=new double[rainFall.length];
List<Integer> levelList = new ArrayList<Integer>();
//对应的状态值为0,1,2,3,4,5
int[] statusValue = new int[] {0,1,2,3,4,5};
// 此数组用于存储每种状态对应出现的次数及其状态值
int[] statusValueNum = new int[statusValue.length];
//计算改变率
for (int i =1; i < rainFall.length; i++) {
double h=rainFall[i]-rainFall[i-1];
arr[i]=new Double(Math.round(h*1000/cha)/1000.0);
System.out.print("变化率为:"+arr[i]+"\n");
}
//分为六个状态
// 改变率为-0.35--0.2为状态0,-0.2--0.1为状态1,-0.1-0为状态2,0-0.1为状态3,0.1-0.2为状态4,0.2-0.35为状态5
for(int j = 1; j < rainFall.length; j++){
if (arr[j] >= -0.35 && arr[j] < -0.2) {
statusValueNum[0]++;
levelList.add(0);
}
else if (arr[j]>=-0.2 &&arr[j]< -0.1) {
statusValueNum[1]++;
levelList.add(1);
}
else if (arr[j]>=-0.1 && arr[j]< 0) {
statusValueNum[2]++;
levelList.add(2);
}
else if (arr[j]>=0 && arr[j]< 0.1) {
statusValueNum[3]++;
levelList.add(3);
}
else if (arr[j]>=0.1 && arr[j]< 0.2) {
statusValueNum[4]++;
levelList.add(4);
}
else if(arr[j]>=0.2 && arr[j]< 0.35){
statusValueNum[5]++;
levelList.add(5);
}
//}
}
//对应的状态值
System.out.println("对应的状态值:\n" + levelList + "\n");
System.out.println("状态0,1,2,3,4,5分别出现的次数:\n" + Arrays.toString(statusValueNum) + "\n");
// 获取转移概率矩阵
Double[][] transProbablityMatrix = statusTransProbablity(statusValueNum, levelList);
System.out.println("一步转移概论矩阵结果:");
for (int i = 0; i < transProbablityMatrix.length; i++) {
for (int j = 0; j < transProbablityMatrix.length; j++) {
System.out.printf("%.4f\t", transProbablityMatrix[i][j]);// 输出格式化后的数据
}
System.out.println();
}
}
/* 一步转移概率矩阵 解释:状态有0 1 2 3 4 5 ,当 当前状态如0且下一状态为如1,称为一步状态转移 */
public static Double[][] statusTransProbablity(int[] statusValueNum, List<Integer> levelList) {
Double[][] transProbablityMatrix = new Double[6][6];
// 一步转移概率矩阵
// /**********************************遍历结果是一步状态转移概率矩阵*******************************/
for (int s = 0; s < statusValueNum.length; s++) {
// 控制数组的行数变化 s充当了状态值
int status = 0;
// 状态的类型取值为0 1 2 3 4 5当每一次遍历完之后,status要重新变化
for (int i = 0; i < statusValueNum.length; i++) {
int index = 0; // 记录一步转移状态的次数 每一次遍历完毕清0
for (int j = 0; j < levelList.size() - 1; j++) {
// levelList.size()-1 原因是k+1 已经可以达到链尾
int k = j;
// k值是为了在当前遍历中使用 如果当前状态值和下一次状态值相等遍历整个数据链 每次只查找一次状态的改变
// 例如先查找0转移到0,然后是0到1 依次类推
while (levelList.get(k).intValue() == s && levelList.get(k + 1).intValue() == status) {
index++;// 计数器加1
if (k < levelList.size() - 2) {// 减2解释 当k=28时 levelList.get(k+1) 此处会下标越界,已超出表述范围
k++;// 当前位置向后移动一位 即为了查询某个状态值连续出现的次数
} else {
break; // 当不满足当前条件,终止最近的循环体
}
}
}
// System.out.println("Trans[" + s + "][" + i + "] " + index);
// 计算概率值
transProbablityMatrix[s][i] = Double.valueOf(index) / Double.valueOf(statusValueNum[s]);
status++;
}
}
return transProbablityMatrix;
}
}