From 054fb90cd08c6e2fcc0df9a95f7247ee5870ca6d Mon Sep 17 00:00:00 2001
From: 潘志宝 <979469083@qq.com>
Date: 星期四, 05 九月 2024 17:59:45 +0800
Subject: [PATCH] 执行调度模型

---
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java                   |    4 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleUserMat.java             |   21 +++
 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java             |    9 +
 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java              |    5 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/ScheduleResultVO.java                    |   51 ++++++++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java |  197 ++++++++++++++++++++++++++++++++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleSampleData.java          |   27 ++++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java                             |   17 ++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/ScheduleModelHandler.java          |   16 ++
 9 files changed, 346 insertions(+), 1 deletions(-)

diff --git a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
index f4bb80e..f0a18cc 100644
--- a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
+++ b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 
 import java.util.Date;
+import java.util.Map;
 
 /**
  * @author PanZhibao
@@ -14,7 +15,11 @@
 @Data
 public class MdkScheduleReqDTO {
 
+    private String scheduleCode;
+
     private Date scheduleTime;
 
     private String modelCode;
+
+    private Map<String, Object> params;
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java
index 40e1861..1b88f23 100644
--- a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java
+++ b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java
@@ -3,6 +3,9 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import java.util.Date;
+import java.util.Map;
+
 /**
  * @author PanZhibao
  * @Description
@@ -11,4 +14,10 @@
 @Schema(description = "RPC 模型 - 调度 DTO")
 @Data
 public class MdkScheduleRespDTO {
+
+    private String scheduleCode;
+
+    private Date scheduleTime;
+
+    private Map<String, Object> result;
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
index 8f73d14..40a2600 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
@@ -13,9 +13,11 @@
 import com.iailab.module.model.mdk.predict.PredictItemHandler;
 import com.iailab.module.model.mdk.predict.PredictModuleHandler;
 import com.iailab.module.model.mdk.predict.PredictResultHandler;
+import com.iailab.module.model.mdk.schedule.ScheduleModelHandler;
 import com.iailab.module.model.mdk.vo.DataValueVO;
 import com.iailab.module.model.mdk.vo.ItemVO;
 import com.iailab.module.model.mdk.vo.PredictResultVO;
+import com.iailab.module.model.mdk.vo.ScheduleResultVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
@@ -61,6 +63,9 @@
 
     @Autowired
     private PredictResultHandler predictResultHandler;
+
+    @Autowired
+    private ScheduleModelHandler scheduleModelHandler;
 
     /**
      * 按模块预测
@@ -169,7 +174,17 @@
     @Override
     public CommonResult<MdkScheduleRespDTO> doSchedule(@Valid @RequestBody MdkScheduleReqDTO reqDTO) {
         MdkScheduleRespDTO resp = new MdkScheduleRespDTO();
-
+        resp.setScheduleCode(reqDTO.getScheduleCode());
+        resp.setScheduleTime(reqDTO.getScheduleTime());
+        try {
+            log.info("调度计算开始: " + System.currentTimeMillis());
+            ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getModelCode(), reqDTO.getScheduleTime());
+            resp.setResult(scheduleResult.getResult());
+            log.info("预测计算结束: " + System.currentTimeMillis());
+        } catch (Exception ex) {
+            log.info("调度计算异常: " + System.currentTimeMillis());
+            ex.printStackTrace();
+        }
         return success(resp);
     }
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java
index 587c0ca..55ad888 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java
@@ -27,6 +27,8 @@
         PredictSampleInfoConstructor sampleInfoConstructor = null;
         if (typeA.compareTo(TypeA.Predict.name()) == 0) {
             sampleInfoConstructor = predictSampleInfoConstructor;
+        } else if (typeA.compareTo(TypeA.Schedule.name()) == 0) {
+            sampleInfoConstructor = predictSampleInfoConstructor;
         }
         return sampleInfoConstructor;
     }
@@ -35,6 +37,8 @@
         SampleDataConstructor sampleDataConstructor = null;
         if (typeA.compareTo(TypeA.Predict.name()) == 0) {
             sampleDataConstructor = predictSampleDataConstructor;
+        } else if (typeA.compareTo(TypeA.Schedule.name()) == 0) {
+            sampleDataConstructor = predictSampleDataConstructor;
         }
         return sampleDataConstructor;
     }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleSampleData.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleSampleData.java
new file mode 100644
index 0000000..218adda
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleSampleData.java
@@ -0,0 +1,27 @@
+package com.iailab.module.model.mdk.sample.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * ScheduleSampleData
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ScheduleSampleData {
+    /**
+     * 包括1.输入的预测项矩阵;2.输入的受调度用户的历史数据
+     */
+    private List<SampleData> preItemMatList;
+
+    /**
+     * 受调度用户的瞬时量矩阵
+     */
+    private ScheduleUserMat schUserMat;
+}
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleUserMat.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleUserMat.java
new file mode 100644
index 0000000..4995814
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleUserMat.java
@@ -0,0 +1,21 @@
+package com.iailab.module.model.mdk.sample.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * ScheduleUserMat
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class ScheduleUserMat {
+
+    /**
+     * 用户瞬时值暂时为空
+     */
+    private String nullForNow;
+}
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/ScheduleModelHandler.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/ScheduleModelHandler.java
new file mode 100644
index 0000000..2674a05
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/ScheduleModelHandler.java
@@ -0,0 +1,16 @@
+package com.iailab.module.model.mdk.schedule;
+
+import com.iailab.module.model.mdk.common.exceptions.ModelInvokeException;
+import com.iailab.module.model.mdk.vo.ScheduleResultVO;
+
+import java.util.Date;
+
+/**
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年09月05日
+ */
+public interface ScheduleModelHandler {
+
+    ScheduleResultVO doSchedule(String scheduleCode, Date scheduleTime) throws ModelInvokeException;
+}
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java
new file mode 100644
index 0000000..f5aeede
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java
@@ -0,0 +1,197 @@
+package com.iailab.module.model.mdk.schedule.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.iail.IAILMDK;
+import com.iail.model.IAILModel;
+import com.iailab.module.model.mcs.sche.entity.StScheduleModelEntity;
+import com.iailab.module.model.mcs.sche.entity.StScheduleParamSettingEntity;
+import com.iailab.module.model.mcs.sche.service.StScheduleModelService;
+import com.iailab.module.model.mcs.sche.service.StScheduleParamSettingService;
+import com.iailab.module.model.mcs.sche.service.StScheduleService;
+import com.iailab.module.model.mdk.common.enums.TypeA;
+import com.iailab.module.model.mdk.common.exceptions.ModelInvokeException;
+import com.iailab.module.model.mdk.sample.SampleConstructor;
+import com.iailab.module.model.mdk.sample.dto.SampleData;
+import com.iailab.module.model.mdk.schedule.ScheduleModelHandler;
+import com.iailab.module.model.mdk.vo.ScheduleResultVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年09月05日
+ */
+@Slf4j
+@Component
+public class ScheduleModelHandlerImpl implements ScheduleModelHandler {
+
+    @Autowired
+    private StScheduleModelService stScheduleModelService;
+
+    @Autowired
+    private StScheduleService stScheduleService;
+
+    @Autowired
+    private SampleConstructor sampleConstructor;
+
+    @Autowired
+    private StScheduleParamSettingService stScheduleParamSettingService;
+
+    @Override
+    public ScheduleResultVO doSchedule(String scheduleCode, Date scheduleTime) throws ModelInvokeException {
+        ScheduleResultVO scheduleResult = new ScheduleResultVO();
+
+        // todo
+        StScheduleModelEntity schModelEntity = stScheduleModelService.selectById(scheduleCode);
+        if (schModelEntity == null) {
+            throw new ModelInvokeException(MessageFormat.format("{0},modelId={1}",
+                    ModelInvokeException.errorGetModelEntity, schModelEntity.getId()));
+        }
+        String modelId = schModelEntity.getId();
+        try {
+            IAILModel newModelBean = new IAILModel();
+            //1.根据模型id构造模型输入样本
+            List<SampleData> sampleDataList = sampleConstructor.constructSample(TypeA.Schedule.name(), modelId, scheduleTime);
+            if (CollectionUtils.isEmpty(sampleDataList)) {
+                log.info("调度模型构造样本失败,scheduleCode=" + scheduleCode);
+                return null;
+            }
+
+            //2.拼接newModelBean的参数结构:a.类名、方法名 b.参数类型
+            String className = schModelEntity.getClassname().trim();
+            String methodName = schModelEntity.getMethodname().trim();
+            newModelBean.setClassName(className);
+            newModelBean.setMethodName(methodName);
+
+            Class<?>[] paramsArray = new Class[3];
+            paramsArray[0] = double[][].class;
+            paramsArray[1] = double[][].class;
+            paramsArray[2] = HashMap.class;
+            newModelBean.setParamsArray(paramsArray);
+
+            //3.拼接settings参数
+            HashMap<String, Object> settings_predict = getPredictSettingsByModelId(modelId);
+
+            //4.构造param2Values参数结构
+            int count = sampleDataList.size();
+            Object[] param2Values = new Object[count + 1];
+            for (int i = 0; i < count; i++) {
+                param2Values[i] = sampleDataList.get(i).getMatrix();
+            }
+            param2Values[count] = settings_predict;
+
+            //打印参数
+            log.info("##############调度模型:modelId=" + modelId + " ##########################");
+            JSONObject jsonObjNewModelBean = new JSONObject();
+            jsonObjNewModelBean.put("newModelBean", newModelBean);
+            log.info(String.valueOf(jsonObjNewModelBean));
+            JSONObject jsonObjParam2Values = new JSONObject();
+            jsonObjParam2Values.put("param2Values", param2Values);
+            log.info(String.valueOf(jsonObjParam2Values));
+
+            //IAILMDK.run
+            HashMap<String, Object> result = IAILMDK.run(newModelBean, param2Values);
+
+            //打印结果
+            JSONObject jsonObjResult = new JSONObject();
+            jsonObjResult.put("result", result);
+            log.info(String.valueOf(jsonObjResult));
+            log.info("调度模型计算完成:modelId=" + modelId + result);
+
+            //5.返回调度结果
+            scheduleResult.setResult(result);
+            scheduleResult.setModelId(modelId);
+            scheduleResult.setScheduleId(schModelEntity.getId());
+            scheduleResult.setScheduleTime(scheduleTime);
+        } catch (Exception ex) {
+            log.error("IAILMDK.run()执行失败");
+            log.error(ex.getMessage());
+            log.error("调用发生异常,异常信息为:{}", ex);
+            ex.printStackTrace();
+        }
+        return scheduleResult;
+    }
+
+    /**
+     * 根据模型id获取参数map
+     *
+     * @param modelId
+     * @return
+     */
+    private HashMap<String, Object> getPredictSettingsByModelId(String modelId) {
+        List<StScheduleParamSettingEntity> list = stScheduleParamSettingService.getByModelid(modelId);
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        HashMap<String, Object> result = new HashMap<>();
+        for (StScheduleParamSettingEntity entry : list) {
+            String valueType = entry.getValuetype().trim();
+            String valueStr = entry.getValue().trim();
+            if ("int".equals(valueType)) {
+                int value = Integer.parseInt(valueStr);
+                result.put(entry.getKey(), value);
+            } else if ("double".equals(valueType)) {
+                double value = Double.parseDouble(valueStr);
+                result.put(entry.getKey(), value);
+            } else if ("string".equals(valueType)) {
+                String value = valueStr;
+                result.put(entry.getKey(), value);
+            } else if ("float".equals(valueType)) {
+                float value = Float.parseFloat(valueStr);
+                result.put(entry.getKey(), value);
+            } else if ("[[D".equals(valueType)) {
+                String valueStrTemp = entry.getValue();
+                try {
+                    //1.二位数组的行按照"/"来分割
+                    String[] rowList = valueStrTemp.split("/");
+                    int row = rowList.length;
+                    int col = rowList[0].split(",").length;
+                    double[][] value1 = new double[row][col];
+                    for (int i = 0; i < rowList.length; i++) {
+                        //2.二位数组的列按照","来分割
+                        String[] colList = rowList[i].split(",");
+                        for (int j = 0; j < colList.length; j++) {
+                            value1[i][j] = Double.parseDouble(colList[j]);
+                        }
+                    }
+                    //把从数据库的得到的参数的二维数组降为一维数组
+                    //int len =0;
+                    double[] value = new double[row * col];
+                    /*for (int j = 0; j <value1.length ; j++) {
+                        len+= value1.length;
+                    }*/
+                    //value = new double[len];
+                    int index = 0;
+                    for (int i = 0; i < value1.length; i++) {
+                        for (int j = 0; j < value1[i].length; j++) {
+                            value[index++] = value1[i][j];
+                        }
+                    }
+                    result.put(entry.getKey(), value);
+                } catch (Exception ex) {
+                    System.out.println("二维数组类型的setting格式不正确");
+                    ex.printStackTrace();
+                }
+            } else if ("decimalArray".equals(valueType)) {
+                JSONArray valueArray = JSONArray.parseArray(entry.getValue());
+                double[] value = new double[valueArray.size()];
+                for (int i = 0; i < valueArray.size(); i++) {
+                    value[i] = Double.parseDouble(valueArray.get(i).toString());
+                }
+                result.put(entry.getKey(), value);
+            } else if ("decimal".equals(valueType)) {
+                double value = Double.parseDouble(entry.getValue());
+                //BigDecimal value = new BigDecimal(entry.getValue());
+                result.put(entry.getKey(), value);
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/ScheduleResultVO.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/ScheduleResultVO.java
new file mode 100644
index 0000000..82451f1
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/ScheduleResultVO.java
@@ -0,0 +1,51 @@
+package com.iailab.module.model.mdk.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * add by zfc 2020.12.09 调度结果实体类
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ScheduleResultVO {
+    /**
+     * 调度方案ID
+     */
+    private String scheduleId;
+
+    /**
+     * 调度方案CODE
+     */
+    private String scheduleCode;
+
+    /**
+     * 模型ID
+     */
+    private String modelId;
+
+    /**
+     * 模型Code
+     */
+    private String modelCode;
+
+    /**
+     * 调度时间
+     */
+    private Date scheduleTime;
+
+    /**
+     * 模型结果
+     */
+    private Map<String, Object> result;
+
+}

--
Gitblit v1.9.3