插值法计算库容相关信息,是常见的业务之一,用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列表中没有足够的数据点或存在重复数据,可能会出现插值异常。
到此,插值法计算库容量相关信息分享完毕,下期更加精彩,敬请期待!