public void generateRangeWater() throws IOException { // 从4.2 - 3.8 - 2.0 雨量范围可以推测历史数据 File file = new File("E:\\2025 水务局\\20250614\\" + System.currentTimeMillis() / 1000 + ".csv"); if (!file.exists()) { file.createNewFile(); } double[] waterHeight = new double[]{4.2, 3.8, 3.4, 3.0, 2.6, 2.2}; DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String[] header = {"code", "source", "target", "rangeStart", "rangeEnd", "time"}; // 数据组 List<Double[]> trainingData = new ArrayList<>(); try (FileWriter writer = new FileWriter(file)) { // 写入文件头 writer.write(String.join(",", header) + "\n"); for (int i = 1; i < waterHeight.length; i++) { String where = " Z >= " + waterHeight[i] + " and Z <=" + waterHeight[i - 1]; log.info("{}", where); List<Map<String, Object>> maps = remoteService.queryRangeData("hdz", "81212478", where); for (Map<String, Object> map : maps) { log.error("输出结束start......"); // 每个去找他历史得消息 PredictionDeviceDataVo objData = PredictionDeviceDataVo.createFromMap(map); if (null != objData) { if (objData.getUpdateTime() != null) { Date startDate = DateUtils.addHours(objData.getUpdateTime(), -1); Date endDate = DateUtils.addHours(objData.getUpdateTime(), 0); log.info("河道站 峡口 输出情况:{}", objData); // 大圳埔排站(外) List<Map<String, Object>> keyPointOne = remoteService.queryData(df.format(startDate), df.format(endDate), "hdz", "81212375"); String oneRecord = this.outCsv("81212375", keyPointOne, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(oneRecord); PredictionDeviceDataVo avgOne = this.avg(keyPointOne); String oneRecordAvg = this.outCsv("--81212375--", avgOne, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(oneRecordAvg); // 同沙村 List<Map<String, Object>> keyPointTwo = remoteService.queryData(df.format(startDate), df.format(endDate), "hdz", "81212448"); String twoRecord = this.outCsv("81212448", keyPointTwo, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(twoRecord); PredictionDeviceDataVo avgTwo = this.avg(keyPointTwo); String twoRecordAvg = this.outCsv("--81212448--", avgTwo, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(twoRecordAvg); // 横沥 Date startDate2 = DateUtils.addHours(objData.getUpdateTime(), -2); Date endDate2 = DateUtils.addHours(objData.getUpdateTime(), -1); List<Map<String, Object>> keyPointThree = remoteService.queryData(df.format(startDate2), df.format(endDate2), "hdz", "81212356"); String threeRecord = this.outCsv("81212356", keyPointThree, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(threeRecord); PredictionDeviceDataVo avgThree = this.avg(keyPointTwo); String threeRecordAvg = this.outCsv("--81212356--", avgThree, objData.getData(), waterHeight[i], waterHeight[i - 1]); writer.write(threeRecordAvg); // 数据处理 if (CollectionUtil.isNotEmpty(keyPointOne) && CollectionUtil.isNotEmpty(keyPointTwo) && CollectionUtil.isNotEmpty(keyPointThree)) { int minIndex = Math.min(Math.min(keyPointOne.size(), keyPointTwo.size()), keyPointThree.size()); for (int j = 0; j < minIndex; j++) { PredictionDeviceDataVo one = PredictionDeviceDataVo.createFromMap(keyPointOne.get(j)); PredictionDeviceDataVo two = PredictionDeviceDataVo.createFromMap(keyPointTwo.get(j)); PredictionDeviceDataVo three = PredictionDeviceDataVo.createFromMap(keyPointThree.get(j)); trainingData.add(new Double[]{one.getData(), two.getData(), three.getData(), objData.getData()}); } } } } log.error("输出结束over......"); } } this.generate(trainingData); } catch (IOException e) { System.err.println("生成CSV文件时出错: " + e.getMessage()); } } // 4参数 private void generate(List<Double[]> trainingData) { int n = trainingData.size(); // 对于 4 个自变量 (a,b,c,d),采用二次多项式展开后共有 15 列特征 double[][] X = new double[n][15]; double[] Y = new double[n]; for (int j = 0; j < n; j++) { Double[] data = trainingData.get(j); double a = data[0], b = data[1], c = data[2], d = data[3]; // 填充二次项和交叉项 X[j][0] = a * a; X[j][1] = b * b; X[j][2] = c * c; X[j][3] = d * d; X[j][4] = a * b; X[j][5] = a * c; X[j][6] = a * d; X[j][7] = b * c; X[j][8] = b * d; X[j][9] = c * d; // 填充一次项 X[j][10] = a; X[j][11] = b; X[j][12] = c; X[j][13] = d; // 常数项(截距) X[j][14] = 1; // 目标值 e Y[j] = data[4]; } this.minMartix(X, Y); } private void generate(List<Double[]> trainingData) { double[][] X = new double[trainingData.size()][10]; double[] Y = new double[trainingData.size()]; for (int j = 0; j < trainingData.size(); j++) { Double[] data = trainingData.get(j); for (int i = 0; i < data.length; i++) { double a = data[i], b = data[i], c = data[i]; double d = data[i]; X[j][0] = a * a; X[j][1] = b * b; X[j][2] = c * c; X[j][3] = a * b; X[j][4] = a * c; X[j][5] = b * c; X[j][6] = a; X[j][7] = b; X[j][8] = c; X[j][9] = 1; Y[j] = d; } } this.minMartix(X, Y); } private void minMartix(double[][] features, double[] targets) { RealMatrix X = MatrixUtils.createRealMatrix(features); RealVector Y = new ArrayRealVector(targets); // 正则化项 λ * I,避免 X^T * X 奇异 RealMatrix XT = X.transpose(); RealMatrix XT_X = XT.multiply(X); // 添加正则项 λ * I double lambda = 1e-6; RealMatrix identity = MatrixUtils.createRealIdentityMatrix(XT_X.getRowDimension()); RealMatrix XT_X_reg = XT_X.add(identity.scalarMultiply(lambda)); RealVector XT_Y = XT.operate(Y); DecompositionSolver solver = new LUDecomposition(XT_X_reg).getSolver(); RealVector solution = solver.solve(XT_Y); log.info("系统矩阵参数结果:{}", solution.toArray()); List<Double> args = Arrays.stream(solution.toArray()) .boxed() .collect(Collectors.toList()); BaseParamsArgs vo = new BaseParamsArgs(); vo.setArgId(IdGeneratorHelper.next()); vo.setArgJson(JsonUtils.toJsonString(args)); baseParamsArgsMapper.insert(vo); } private double predict(double a, double b, double c, Double[] coefficients) { return coefficients[0] * a * a + coefficients[1] * b * b + coefficients[2] * c * c + coefficients[3] * a * b + coefficients[4] * a * c + coefficients[5] * b * c + coefficients[6] * a + coefficients[7] * b + coefficients[8] * c + coefficients[9] // migic number - 0.5d ; } private String outCsv(String code, List<Map<String, Object>> keyPointOne, double data, double start, double end) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); StringBuilder sb = new StringBuilder(); for (Map<String, Object> keyTwo : keyPointOne) { PredictionDeviceDataVo two = PredictionDeviceDataVo.createFromMap(keyTwo); if (null != two) { sb.append(code); sb.append(","); sb.append(two.getData()); sb.append(","); sb.append(data); sb.append(","); sb.append(start); sb.append(","); sb.append(end); sb.append(","); sb.append(df.format(two.getUpdateTime())); sb.append("\n"); } } return sb.toString(); } private String outCsv(String code, PredictionDeviceDataVo two, double data, double start, double end) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); StringBuilder sb = new StringBuilder(); if (null != two) { sb.append(code); sb.append(","); sb.append(two.getData()); sb.append(","); sb.append(data); sb.append(","); sb.append(start); sb.append(","); sb.append(end); sb.append(","); sb.append(df.format(two.getUpdateTime())); sb.append("\n"); } return sb.toString(); }
helochen - Overview