Java 线性内推算法



内推法:指根据已知的系列数值推算出一个在已知数值之间的数值. 内推法假定数值之间存在某种明确的关系,不是一种精确的推算法,但可用于估算债券价格和收益率。内推法分三种类型:线性内推法、对数内推法和立方内推法


import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Random;






/**
 * 计算一定日期内缺失的日期
 * @author Administrator
 *
 */


public class Chazhi {


static List<Meter> aList = new ArrayList<Meter>();


static {
Random r = new Random();


int temp = 0, temp2;

List<Integer> idList = new ArrayList<Integer>();
idList.add(2);
idList.add(3);
idList.add(6);




for (int i = 1, j = i + 1; i < 10; j++, i++) {
Date dat = null;
Calendar cd = Calendar.getInstance();
cd.add(Calendar.DATE, i);
dat = cd.getTime();
if (idList.contains(i)) {
continue;
}


if (i == 1) {
temp = i + r.nextInt(10);
} else {
temp += i + r.nextInt(10);
}
aList.add(new Meter("meter0", dat, temp));


}


}


static SimpleDateFormat dformat = new SimpleDateFormat("yyyy-MM-dd");


public static void main(String[] args) {
//System.out.println(daysBetween("2017-05-22", "2017-05-23"));


List<Meter> bList = new ArrayList<Meter>();



//第一步补缺失的日期,把日期补全,并且默认值为0
System.out.println("原始值:");
for (int i = 0; i < aList.size(); i++) {


Meter m1 = aList.get(i);


bList.add(m1);

System.out.println(m1.getMeterNo() + "-" + dformat.format(m1.getDay()) + "-" + m1.getVal());


if (i < aList.size() - 1) {
Meter m2 = aList.get(i + 1);
// 日期是连续的,正确
if (daysBetween(dformat.format(m1.getDay()), dformat.format(m2.getDay())) == 1) {


} else {
//相差天数,相差几天就补几天
int d = daysBetween(dformat.format(m1.getDay()), dformat.format(m2.getDay()));
for(int a=1;a<d;a++){
// 说明有缺失日期,需要补值
Calendar calendar = new GregorianCalendar();
calendar.setTime(m1.getDay());
calendar.add(calendar.DATE, a);// 把日期往后增加一天.整数往后推,负数往前移动
// calendar.getTime(); //这个时间就是日期往后推一天的结果
Meter e = new Meter(m1.getMeterNo(), calendar.getTime(), 0);
bList.add(e);
}




}


//System.out.println(daysBetween(dformat.format(m1.getDay()), dformat.format(m2.getDay())));
}


}


// 补缺日期后的值
//第二步 计算缺失值上下的已知值间的斜率
System.out.println("日期补缺后的值========");
System.out.println("计算缺失值上下的已知值间的斜率");
for (int a = 0; a < bList.size(); a++) {

Meter m3 = bList.get(a);
System.out.println(m3.getMeterNo() + "-" + dformat.format(m3.getDay()) + "-" + m3.getVal());

//如果值为0表示缺失值
if(a!=0 && m3.getVal()==0){
//如果不是第一条或者最后一条为0,就查找相邻的两个有值的数据
Meter m3_1 = bList.get(a-1);
Meter m3_2 = bList.get(a+1);

//k = (b2 - b1)/(n + 1)   n 为缺失数据的个数
int k = (m3_2.getVal()-m3_1.getVal())/(1 + 1) ;
//步骤二:计算对应的缺失值
//a(i) = b1 + k * i
m3.setVal(m3_1.getVal()+k*a);

}


}

System.out.println("补缺日期和值后的最终结果");
//// 补缺日期和值后的最终结果
for (int a = 0; a < bList.size(); a++) {

Meter m4 = bList.get(a);
System.out.println(m4.getMeterNo() + "-" + dformat.format(m4.getDay()) + "-" + m4.getVal());

}







}


/**
* 返回两个string类型日期之间相差的天数

* @param smdate
* @param bdate
* @return
*/
public static int daysBetween(String smdate, String bdate) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
long time1 = 0;
long time2 = 0;


try {
cal.setTime(sdf.parse(smdate));
time1 = cal.getTimeInMillis();
cal.setTime(sdf.parse(bdate));
time2 = cal.getTimeInMillis();
} catch (Exception e) {
e.printStackTrace();
}
long between_days = (time2 - time1) / (1000 * 3600 * 24);


return Integer.parseInt(String.valueOf(between_days));
}


}

猜你喜欢

转载自blog.csdn.net/rdhj5566/article/details/72601670
今日推荐