潘志宝
2024-09-05 054fb90cd08c6e2fcc0df9a95f7247ee5870ca6d
执行调度模型
已修改4个文件
已添加5个文件
347 ■■■■■ 文件已修改
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleRespDTO.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleFactory.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleSampleData.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/dto/ScheduleUserMat.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/ScheduleModelHandler.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/ScheduleResultVO.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
}
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;
}
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);
    }
}
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;
    }
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;
}
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;
}
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;
}
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;
    }
}
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;
}