java语言实现插值法计算库容量相关信息
插值法计算库容相关信息,是常见的业务之一,用Float数组数据的形式分别输入原始数据的X值和Y值,随后输入需要预测数值的数据,随即以数组的形式输出数据,今天我们分析测试一下:
1、业务逻辑概述
寻找最接近的两个点:遍历xianYouShuJuYi列表,找到与输入值inputValue最接近的两个x值及其索引位置。
2、插值计算
使用线性插值公式:
如果两个索引值相同,直接返回第一个y值。
3、更新数据
如果输入值不在已有数据中,则将inputValue和计算出的结果添加到数据列表中。
4、结果校验
如果计算结果为NaN(非数字),则返回0.00f;否则返回计算出的结果。
5、核心测试代码
public static float ydChaZhi(float inputValue, List<Float> liShiShuJuRz, List<Float> liShiShuJuW) {
// 定义用于存储插值计算所需的临时变量
float firstxValue; // 第一个x值
float secondxValue; // 第二个x值
float firstyValue; // 第一个y值
float secondyValue; // 第二个y值
float outputValue; // 输出的插值结果
// 初始化差值变量,存储输入值与已有数据之间的差值
Float chaZhiYi = null; // 用于保存距离最接近的x值之间的差值
Float chaZhiEr = null; // 用于保存第二接近的x值之间的差值
// 用于存储找到的两个最接近输入值的索引位置
int chaZhiWeiZhiYi = 0;
int chaZhiWeiZhiEr = 0;
// 遍历现有的x数据,找到与输入值最接近的x值及其索引位置
for (int i = 0; i < liShiShuJuRz.size(); i++) {
firstxValue = liShiShuJuRz.get(i); // 获取当前的x值
if (chaZhiYi == null) {
// 初始化chaZhiYi,保存第一个差值及其索引位置
chaZhiYi = Math.abs(inputValue - firstxValue);
chaZhiWeiZhiYi = i;
} else if (Math.abs(inputValue - firstxValue) <= chaZhiYi) {
// 更新最接近的差值和索引位置
chaZhiYi = Math.abs(inputValue - firstxValue);
chaZhiWeiZhiYi = i;
}
}
// 遍历现有的x数据,找到与输入值第二接近的x值及其索引位置
for (int j = 0; j < liShiShuJuRz.size(); j++) {
secondxValue = liShiShuJuRz.get(j); // 获取当前的x值
if (chaZhiEr == null) {
chaZhiEr = chaZhiYi; // 初始化chaZhiEr为第一个最小差值
}
// 如果找到的x值与第一个最接近的x值不同,并且差值更小,则更新
if (Math.abs(inputValue - secondxValue) < chaZhiEr &&
secondxValue != liShiShuJuRz.get(chaZhiWeiZhiYi)) {
chaZhiEr = Math.abs(inputValue - secondxValue);
chaZhiWeiZhiEr = j;
}
}
// 获取最接近的两个x值和对应的y值
firstyValue = liShiShuJuW.get(chaZhiWeiZhiYi);
secondyValue = liShiShuJuW.get(chaZhiWeiZhiEr);
firstxValue = liShiShuJuRz.get(chaZhiWeiZhiYi);
secondxValue = liShiShuJuRz.get(chaZhiWeiZhiEr);
// 插值计算:使用线性插值公式计算输出值
outputValue = (chaZhiWeiZhiYi == chaZhiWeiZhiEr)
? firstyValue // 如果两个索引相同,则直接返回对应的y值
: firstyValue + (secondyValue - firstyValue) *
(inputValue - firstxValue) / (secondxValue - firstxValue);
// 如果输入值不在已有数据中,将输入值和计算出的结果加入列表
if (inputValue != firstxValue) {
liShiShuJuRz.add(inputValue);
liShiShuJuW.add(outputValue);
}
// 检查计算结果是否为NaN(非法数值),如果是,则返回0.00f,否则返回结果
if (Float.isNaN(outputValue)) {
return 0.00f;
} else {
return outputValue;
}
}
6、main方法测试
public static void main(String[] args) {
//库水位
List<Float> x = new ArrayList<>(Arrays.asList(
114.0f,
115.0f,
116.0f,
117.0f,
118.0f,
119.0f,
120.0f,
121.0f,
122.0f,
123.0f,
124.0f,
135.0f
));
//水量
List<Float> y = new ArrayList<>(Arrays.asList(
0.18f,
1.39f,
4.67f,
8.88f,
13.53f,
19.88f,
26.22f,
34.78f,
45.28f,
57.04f,
70.55f,
85.87f
));
System.out.println(ydChaZhi(122.9f,x,y));//测试数据
}
注意事项:
该代码默认输入值是浮点数,如果数据类型不一致可能导致错误。
若xianYouShuJuYi列表中没有足够的数据点或存在重复数据,可能会出现插值异常。
到此,插值法计算库容量相关信息分享完毕,下期更加精彩,敬请期待!