diff --git a/pqs-advance/advance-api/pom.xml b/pqs-advance/advance-api/pom.xml index dcc9f55f9..b1e0f522e 100644 --- a/pqs-advance/advance-api/pom.xml +++ b/pqs-advance/advance-api/pom.xml @@ -70,5 +70,16 @@ cglib 3.3.0 + + + org.ejml + ejml-simple + 0.41 + + + org.apache.commons + commons-math3 + 3.6.1 + diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java index dd1363d24..6e34eed28 100644 --- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java +++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java @@ -65,6 +65,12 @@ public enum AdvanceResponseEnum { EVENT_DATA_MISS("A0102","没有可供参考的暂降数据"), + WIN_DATA_ERROR("A0102","算法校验窗宽超限"), + + DATA_ERROR("A0102","算法校验数据长度超限"), + + INIT_DATA_ERROR("A0102","算法初始化数据失败"), + USER_HAS_PRODUCT("A0102","当前用户存在生产线"), PRODUCT_HAS_MACHINE("A0102","当前生产线存在设备"), diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/CacheQvvrData.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/CacheQvvrData.java index 4958089da..5d90ea4ad 100644 --- a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/CacheQvvrData.java +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/CacheQvvrData.java @@ -26,9 +26,9 @@ public class CacheQvvrData implements Serializable { private float[] harmData; - private PDataStruct[] FKdata; + private float[][] fKData; - private HKDataStruct[] HKdata; + private float[][] hKData; private List names; diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrDataEntity.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrDataEntity.java new file mode 100644 index 000000000..7fdf73884 --- /dev/null +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrDataEntity.java @@ -0,0 +1,54 @@ +package com.njcn.advance.model.responsibility; + + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class QvvrDataEntity implements Serializable { + + public static final int MAX_P_NODE= 200; //功率节点个数限制,按200个限制 + public static final int MAX_P_NUM= 96 * 100; //功率数据按15分钟间隔,100天处理 + public static final int MAX_HARM_NUM= 1440 * 100; //谐波数据按一分钟间隔,100天处理 + public static final int MAX_WIN_LEN=96 * 10; //按15分钟算10天 + public static final int MIN_WIN_LEN = 4; //按15分钟算1小时 + + + //输入参数 + public int calFlag; //计算标志,0默认用电压和功率数据计算相关系数和责任,1用代入的动态相关系数计算责任 + public int harmNum; //谐波数据个数 + public int pNum; //功率数据个数 + public int pNode; //功率负荷节点数 + public int win; //数据窗大小 + public int resNum; //代入的责任数据个数 + public float harmMk; //谐波电压门槛 + public float harmData[]; //谐波数据序列 + public float [][] pData; //功率数据序列 + public float [][] simData; //动态相关系数数据序列,可作为输入或者输出 + public float [][] fKData; //不包含背景动态谐波责任数据序列,可作为输入或者输出 + public float [][] hKData; //包含背景动态谐波责任数据序列,可作为输入或者输出 + public float [] core; //典则相关系数 + public float [] bjCore; //包含背景典则相关系数 + + //输出结果 + public int calOk; //是否计算正确标志,置位0表示未计算,置位1表示计算完成 + public float [] sumFKdata;//不包含背景谐波责任 + public float [] sumHKdata;//包含背景谐波责任 + + public QvvrDataEntity() { + calFlag = 0; + harmData = new float[MAX_HARM_NUM]; + pData = new float[MAX_P_NUM][MAX_P_NODE]; + simData = new float[MAX_P_NUM][MAX_P_NODE]; + fKData = new float[MAX_P_NUM][MAX_P_NODE]; + hKData = new float[MAX_P_NUM][MAX_P_NODE+1]; + core = new float[MAX_P_NUM]; + bjCore = new float[MAX_P_NUM]; + sumFKdata = new float[MAX_P_NODE]; + sumHKdata = new float[MAX_P_NODE + 1]; + } + + + +} diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrStruct.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrStruct.java index 0225caa1b..bd8a3459d 100644 --- a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrStruct.java +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/model/responsibility/QvvrStruct.java @@ -7,10 +7,10 @@ import java.util.Arrays; import java.util.List; public class QvvrStruct extends HIKSDKStructure implements Serializable { - public static final int MAX_P_NODE= 200; //功率节点个数限制,按200个限制 - public static final int MAX_P_NUM= 96 * 100; //功率数据按15分钟间隔,100天处理 - public static final int MAX_HARM_NUM= 1440 * 100; //谐波数据按一分钟间隔,100天处理 - public static final int MAX_WIN_LEN=96 * 10; //按15分钟算10天 + public static final int MAX_P_NODE = 200; //功率节点个数限制,按200个限制 + public static final int MAX_P_NUM = 96 * 100; //功率数据按15分钟间隔,100天处理 + public static final int MAX_HARM_NUM = 1440 * 100; //谐波数据按一分钟间隔,100天处理 + public static final int MAX_WIN_LEN = 96 * 10; //按15分钟算10天 public static final int MIN_WIN_LEN = 4; //按15分钟算1小时 @@ -193,8 +193,13 @@ public class QvvrStruct extends HIKSDKStructure implements Serializable { this.sim_data = sim_data; } -// @Override -// protected List getFieldOrder() { -// return Arrays.asList(new String[]{"sumFKdata", "sumHKdata"}); -// } + @Override + protected List getFieldOrder() { + return Arrays.asList( + "cal_flag", "harm_num", "p_num", "p_node", "win", + "res_num", "harm_mk", "harm_data", "p_data", "sim_data", + "FKdata", "HKdata", "Core", "BjCore", "cal_ok", + "sumFKdata", + "sumHKdata"); + } } diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/responsibility/impl/RespDataServiceImpl.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/responsibility/impl/RespDataServiceImpl.java index 86d843b3a..b3290f472 100644 --- a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/responsibility/impl/RespDataServiceImpl.java +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/service/responsibility/impl/RespDataServiceImpl.java @@ -18,10 +18,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.njcn.advance.enums.AdvanceResponseEnum; import com.njcn.advance.mapper.responsibility.RespDataMapper; -import com.njcn.advance.model.responsibility.CacheQvvrData; -import com.njcn.advance.model.responsibility.HKDataStruct; -import com.njcn.advance.model.responsibility.PDataStruct; -import com.njcn.advance.model.responsibility.QvvrStruct; +import com.njcn.advance.model.responsibility.*; import com.njcn.advance.pojo.bo.responsibility.*; import com.njcn.advance.pojo.dto.responsibility.CustomerData; import com.njcn.advance.pojo.dto.responsibility.CustomerResponsibility; @@ -31,10 +28,10 @@ import com.njcn.advance.pojo.param.ResponsibilityCalculateParam; import com.njcn.advance.pojo.param.ResponsibilitySecondCalParam; import com.njcn.advance.pojo.po.responsibility.RespData; import com.njcn.advance.pojo.po.responsibility.RespDataResult; -import com.njcn.advance.pojo.po.responsibility.RespUserData; import com.njcn.advance.service.responsibility.IRespDataResultService; import com.njcn.advance.service.responsibility.IRespDataService; import com.njcn.advance.service.responsibility.IRespUserDataService; +import com.njcn.advance.utils.ResponsibilityAlgorithm; import com.njcn.advance.utils.ResponsibilityCallDllOrSo; import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.exception.BusinessException; @@ -104,7 +101,7 @@ public class RespDataServiceImpl extends ServiceImpl i //没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序 queryWrapper.orderBy(true, false, "pqs_resp_data.create_time"); } - queryWrapper.between("pqs_resp_data.create_time", queryParam.getSearchBeginTime(), queryParam.getSearchEndTime()); + queryWrapper.between("pqs_resp_data.create_time",DateUtil.beginOfDay(DateUtil.parse(queryParam.getSearchBeginTime())), DateUtil.endOfDay(DateUtil.parse(queryParam.getSearchEndTime()))); } queryWrapper.eq("pqs_resp_data.state", DataStateEnum.ENABLE.getCode()); Page page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper); @@ -185,69 +182,67 @@ public class RespDataServiceImpl extends ServiceImpl i names.add(userName); } //然后开始组装数据 - PDataStruct[] pData = new PDataStruct[QvvrStruct.MAX_P_NUM]; + float[][] pData = new float[QvvrDataEntity.MAX_P_NUM][QvvrDataEntity.MAX_P_NODE]; for (int i = 0; i < names.size(); i++) { //当前某用户测量节点的所有数据 List userDataExcelBodies1 = originalPData.get(names.get(i)); for (int k = 0; k < userDataExcelBodies1.size(); k++) { - PDataStruct pDataStruct = pData[k]; + float[] pDataStruct = pData[k]; if (pDataStruct == null) { - pDataStruct = new PDataStruct(); + pDataStruct = new float[QvvrDataEntity.MAX_P_NODE]; } - float[] p = pDataStruct.getP(); + float[] p = pDataStruct; p[i] = userDataExcelBodies1.get(k).getWork().floatValue(); pData[k] = pDataStruct; } } //至此功率数据也组装完毕,调用友谊提供的接口 - QvvrStruct qvvrStruct = null; - try { - qvvrStruct = new QvvrStruct(); - } catch (Exception exception) { - exception.printStackTrace(); - } - qvvrStruct.cal_flag = 0; - qvvrStruct.p_node = pNode; - qvvrStruct.p_num = pNum; - qvvrStruct.win = win; - qvvrStruct.harm_num = harmNum; - qvvrStruct.harm_mk = harmMk; - qvvrStruct.p_data = pData; - qvvrStruct.harm_data = respHarmData.getHarmData(); - ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); - responsibilityCallDllOrSo.setPath(); - ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; - try { - responsibilityLibrary.harm_response(qvvrStruct); - } catch (Exception exception) { - exception.printStackTrace(); - } + QvvrDataEntity qvvrDataEntity = new QvvrDataEntity(); + qvvrDataEntity.calFlag = 0; + qvvrDataEntity.pNode = pNode; + qvvrDataEntity.pNum = pNum; + qvvrDataEntity.win = win; + qvvrDataEntity.harmNum = harmNum; + qvvrDataEntity.harmMk = harmMk; + qvvrDataEntity.pData = pData; + qvvrDataEntity.harmData = respHarmData.getHarmData(); +// ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); +// responsibilityCallDllOrSo.setPath(); +// ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; +// try { +// responsibilityLibrary.harm_response(qvvrStruct); +// } catch (Exception exception) { +// exception.printStackTrace(); +// } + + ResponsibilityAlgorithm responsibilityAlgorithm = new ResponsibilityAlgorithm(); + qvvrDataEntity = responsibilityAlgorithm.getResponsibilityResult(qvvrDataEntity); //至此接口调用结束,开始组装动态责任数据和用户责任量化结果 //首先判断cal_ok的标识位是否为1,为0表示程序没有计算出结果 - if (qvvrStruct.cal_ok == 0) { + if (qvvrDataEntity.calOk == 0) { throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR); } //没问题后,先玩动态责任数据 - CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node]; - PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata(); + CustomerData[] customerDatas = new CustomerData[qvvrDataEntity.pNode]; + float[][] fKdata/*无背景的动态责任数据*/ = qvvrDataEntity.getFKData(); //第一个时间节点是起始时间+win窗口得到的时间 Date sTime = DateUtil.parse(dateStr.get(0).concat(" 00:00:00"), DatePattern.NORM_DATETIME_PATTERN); Calendar calendar = Calendar.getInstance(); calendar.setTime(sTime); calendar.add(Calendar.MINUTE, (win - 1) * userIntervalTime); List timeDatas = new ArrayList<>(); - for (int i = 0; i < qvvrStruct.p_num - qvvrStruct.win; i++) { + for (int i = 0; i < qvvrDataEntity.pNum - qvvrDataEntity.win; i++) { calendar.add(Calendar.MINUTE, userIntervalTime); //一个时间点所有的用户数据 - PDataStruct fKdatum = fKdata[i]; - for (int k = 0; k < qvvrStruct.p_node; k++) { + float[] fKdatum = fKdata[i]; + for (int k = 0; k < qvvrDataEntity.pNode; k++) { CustomerData customerData = customerDatas[k]; if (null == customerData) { customerData = new CustomerData(); customerData.setCustomerName(names.get(k)); } List valueDatas = customerData.getValueDatas(); - Float valueTemp = fKdatum.getP()[k]; + Float valueTemp = fKdatum[k]; if (valueTemp.isNaN()) { valueTemp = 0.0f; } @@ -273,7 +268,7 @@ public class RespDataServiceImpl extends ServiceImpl i customerDataTemp.put(name, customerData); } //动态数据组装完成后,开始组装责任数据 - List customerResponsibilities = getCustomerResponsibilityData(names, qvvrStruct.sumFKdata, qvvrStruct.p_node); + List customerResponsibilities = getCustomerResponsibilityData(names, qvvrDataEntity.sumFKdata, qvvrDataEntity.pNode); //根据前十的用户数据,获取这些用户的动态责任数据 List customerData = new ArrayList<>(); for (CustomerResponsibility customerResponsibility : customerResponsibilities) { @@ -378,9 +373,10 @@ public class RespDataServiceImpl extends ServiceImpl i String customerPath = fileStorageUtil.uploadStream(customerStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json")); respDataResult.setUserDetailData(customerPath); //调用qvvr生成的中间数据 - CacheQvvrData cacheQvvrData = new CacheQvvrData(qvvrStruct.getP_node(), qvvrStruct.getHarm_num(), qvvrStruct.getHarm_data(), qvvrStruct.FKdata, qvvrStruct.HKdata, names, userIntervalTime, qvvrStruct.win, userIntervalTime, respHarmData.getHarmTime()); - JSONObject cacheQvvrDataDataJson = (JSONObject) JSONObject.toJSON(cacheQvvrData); - InputStream cacheQvvrDataStream = IoUtil.toStream(cacheQvvrDataDataJson.toString(), CharsetUtil.UTF_8); + CacheQvvrData cacheQvvrData = new CacheQvvrData(qvvrDataEntity.getPNode(), qvvrDataEntity.getHarmNum(), qvvrDataEntity.getHarmData(), qvvrDataEntity.fKData, qvvrDataEntity.hKData, names, userIntervalTime, qvvrDataEntity.win, userIntervalTime, respHarmData.getHarmTime()); +// JSONObject cacheQvvrDataDataJson = (JSONObject) JSONObject.toJSON(cacheQvvrData); + String cacheJson = PubUtils.obj2json(cacheQvvrData); + InputStream cacheQvvrDataStream = IoUtil.toStream(cacheJson, CharsetUtil.UTF_8); String cacheQvvrDataPath = fileStorageUtil.uploadStream(cacheQvvrDataStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json")); respDataResult.setQvvrData(cacheQvvrDataPath); //用户前10数据存储 @@ -422,7 +418,9 @@ public class RespDataServiceImpl extends ServiceImpl i try { InputStream fileStream = fileStorageUtil.getFileStream(respDataResultTemp.getQvvrData()); String qvvrDataStr = IoUtil.read(fileStream, CharsetUtil.UTF_8); - cacheQvvrData = JSONObject.parseObject(qvvrDataStr, CacheQvvrData.class); +// cacheQvvrData = JSONObject.parseObject(qvvrDataStr, CacheQvvrData.class); + cacheQvvrData = PubUtils.json2obj(qvvrDataStr,CacheQvvrData.class); + } catch (Exception exception) { throw new BusinessException(AdvanceResponseEnum.RESP_RESULT_DATA_NOT_FOUND); } @@ -443,25 +441,25 @@ public class RespDataServiceImpl extends ServiceImpl i //间隔中的时间长度 int minus = timeEndIndex - timeStartIndex + 1; //组装参数 - QvvrStruct qvvrStruct = new QvvrStruct(); - qvvrStruct.cal_flag = 1; - qvvrStruct.p_node = cacheQvvrData.getPNode(); - qvvrStruct.harm_mk = responsibilitySecondCalParam.getLimitValue(); - qvvrStruct.win = win; + QvvrDataEntity qvvrDataEntity = new QvvrDataEntity(); + qvvrDataEntity.calFlag = 1; + qvvrDataEntity.pNode = cacheQvvrData.getPNode(); + qvvrDataEntity.harmMk = responsibilitySecondCalParam.getLimitValue(); + qvvrDataEntity.win = win; int resNum; - PDataStruct[] FKdata = new PDataStruct[9600]; - HKDataStruct[] HKdata = new HKDataStruct[9600]; + float[][] FKdata = new float[9600][QvvrDataEntity.MAX_P_NODE]; + float[][] HKdata = new float[9600][QvvrDataEntity.MAX_P_NODE + 1]; float[] harmData = new float[1440 * 100]; - PDataStruct[] fKdataOriginal = cacheQvvrData.getFKdata(); - HKDataStruct[] hKdataOriginal = cacheQvvrData.getHKdata(); + float[][] fKdataOriginal = cacheQvvrData.getFKData(); + float[][] hKdataOriginal = cacheQvvrData.getHKData(); float[] harmDataOriginal = cacheQvvrData.getHarmData(); //如果起始索引与截止索引的差值等于时间轴的长度,则说明用户没有选择限值时间,直接带入全部的原始数据,参与计算即可 if (minus == times.size()) { - qvvrStruct.harm_num = cacheQvvrData.getHarmNum(); - qvvrStruct.res_num = cacheQvvrData.getHarmNum() - cacheQvvrData.getWin(); - qvvrStruct.setFKdata(cacheQvvrData.getFKdata()); - qvvrStruct.setHKdata(cacheQvvrData.getHKdata()); - qvvrStruct.harm_data = cacheQvvrData.getHarmData(); + qvvrDataEntity.harmNum = cacheQvvrData.getHarmNum(); + qvvrDataEntity.resNum = cacheQvvrData.getHarmNum() - cacheQvvrData.getWin(); + qvvrDataEntity.setFKData(cacheQvvrData.getFKData()); + qvvrDataEntity.setHKData(cacheQvvrData.getHKData()); + qvvrDataEntity.harmData = cacheQvvrData.getHarmData(); } else { if (win == 4) { //当窗口为4时,两个时间限制范围在最小公倍数为15时,最起码有5个有效时间点,在最小公倍数为30时,最起码有3个有效时间点 @@ -497,33 +495,39 @@ public class RespDataServiceImpl extends ServiceImpl i } else { throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR); } - qvvrStruct.res_num = resNum; - qvvrStruct.harm_num = minus; + qvvrDataEntity.resNum = resNum; + qvvrDataEntity.harmNum = minus; //因为限值时间实际是含头含尾的,所以harmNum需要索引差值+1 for (int i = timeStartIndex; i <= timeEndIndex; i++) { harmData[i - timeStartIndex] = harmDataOriginal[i]; } - qvvrStruct.harm_data = harmData; + qvvrDataEntity.harmData = harmData; //FKData与HKData的值则等于resNum for (int i = timeStartIndex; i < timeStartIndex + resNum; i++) { FKdata[i - timeStartIndex] = fKdataOriginal[i]; HKdata[i - timeStartIndex] = hKdataOriginal[i]; } - qvvrStruct.setFKdata(FKdata); - qvvrStruct.setHKdata(HKdata); + qvvrDataEntity.setFKData(FKdata); + qvvrDataEntity.setHKData(HKdata); } - ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); - responsibilityCallDllOrSo.setPath(); - ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; - responsibilityLibrary.harm_response(qvvrStruct); - if (qvvrStruct.cal_ok == 0) { +// ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); +// responsibilityCallDllOrSo.setPath(); +// ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; +// responsibilityLibrary.harm_response(qvvrStruct); +// if (qvvrStruct.cal_ok == 0) { +// throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR); +// } + ResponsibilityAlgorithm responsibilityAlgorithm = new ResponsibilityAlgorithm(); + qvvrDataEntity = responsibilityAlgorithm.getResponsibilityResult(qvvrDataEntity); + if (qvvrDataEntity.calOk == 0) { throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR); } + //没问题后,先玩动态责任数据 List names = cacheQvvrData.getNames(); - CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node]; - PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata(); + CustomerData[] customerDatas = new CustomerData[qvvrDataEntity.pNode]; + float[][] fKdata/*无背景的动态责任数据*/ = qvvrDataEntity.getFKData(); //第一个时间节点是起始时间+win窗口得到的时间 Date sTime = new Date(); sTime.setTime(times.get(timeStartIndex)); @@ -531,18 +535,18 @@ public class RespDataServiceImpl extends ServiceImpl i calendar.setTime(sTime); calendar.add(Calendar.MINUTE, (win - 1) * minMultiple); List timeDatas = new ArrayList<>(); - for (int i = 0; i < qvvrStruct.harm_num - qvvrStruct.win; i++) { + for (int i = 0; i < qvvrDataEntity.harmNum - qvvrDataEntity.win; i++) { calendar.add(Calendar.MINUTE, minMultiple); //一个时间点所有的用户数据 - PDataStruct fKdatum = fKdata[i]; - for (int k = 0; k < qvvrStruct.p_node; k++) { + float[] fKdatum = fKdata[i]; + for (int k = 0; k < qvvrDataEntity.pNode; k++) { CustomerData customerData = customerDatas[k]; if (null == customerData) { customerData = new CustomerData(); customerData.setCustomerName(names.get(k)); } List valueDatas = customerData.getValueDatas(); - Float valueTemp = fKdatum.getP()[k]; + Float valueTemp = fKdatum[k]; if (valueTemp.isNaN()) { valueTemp = 0.0f; } @@ -568,8 +572,8 @@ public class RespDataServiceImpl extends ServiceImpl i customerDataTemp.put(name, customerData); } //调用程序接口后,首先组装责任量化结果 - float[] sumFKdata = qvvrStruct.sumFKdata; - List customerResponsibilities = getCustomerResponsibilityData(names, sumFKdata, qvvrStruct.p_node); + float[] sumFKdata = qvvrDataEntity.sumFKdata; + List customerResponsibilities = getCustomerResponsibilityData(names, sumFKdata, qvvrDataEntity.pNode); //根据前十的用户数据,获取这些用户的动态责任数据 List customerData = new ArrayList<>(); diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/utils/ResponsibilityAlgorithm.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/utils/ResponsibilityAlgorithm.java new file mode 100644 index 000000000..9f7d0d05a --- /dev/null +++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/utils/ResponsibilityAlgorithm.java @@ -0,0 +1,765 @@ +package com.njcn.advance.utils; + +import cn.hutool.core.bean.BeanUtil; +import com.njcn.advance.enums.AdvanceResponseEnum; +import com.njcn.advance.model.responsibility.QvvrDataEntity; +import com.njcn.common.pojo.exception.BusinessException; +import org.apache.commons.math3.linear.*; +import org.ejml.data.DMatrixRMaj; +import org.ejml.dense.row.CommonOps_DDRM; +import org.ejml.dense.row.factory.DecompositionFactory_DDRM; +import org.ejml.interfaces.decomposition.EigenDecomposition_F64; +import org.ejml.simple.SimpleMatrix; + +import java.util.Arrays; + +/** + * 责任量化的算法细节: + * 此代码用以计算刻度不等两序列之间的动态相关系数与动态谐波责任指标; + * 随机数生成器生成原始谐波U数据,一维数组长度为LL;生成原始负荷PE数据,二维数组,(行)长度为TL,(列)宽度为P(表示P个负荷公司); + * 只能识别 U数据长度 为PE数据长度的 JIANGE倍,也即无法自动判别时间间隔,需人为定义; + * Width用以控制动态相关系数的计算窗宽; + * 使用库中函数进行矩阵构造与计算; + * 最终的到结果为:向量Core为动态典则相关系数 + * 矩阵simCor为剥离背景后的动态相关系数,其中每列为每一用户负荷 + * 矩阵HKdata为使用simCor计算的动态谐波责任指标,其中每列为每一用户负荷 + * 向量sumHKdata为超限额的谐波时,不同用户的长时谐波责任指标; + * 函数说明:cov(a,b)计算协方差; + * SXX(a,width)计算(行)长度为width序列的方差矩阵; + * SXY(a,b,width)计算长度为width两序列的协方差矩阵; + * TransCancor(Ma,Vb,width)计算长度为width的矩阵a与向量b的典则相关系数; + * SlideCanCor(a,b,width)计算a与b的在 窗宽 width下 的动态典则相关系数; + * SlideCor(a,b,slidecancor,width)计算a,b,在窗宽 width 下 典则相关剥离背景后的动态相关系数。 + * + * 算法很多代码没有注释,这些代码翻译的友谊的C代码,不清楚实际逻辑 + */ +public class ResponsibilityAlgorithm { + + static int P = 21; + static int TL = 671; + static int LL = 3355; + static int JIANGE = 5; + static int wdith = 96; + static float XIANE = 0; + static int RES_NUM = 0; + + static QvvrDataEntity qvvrResult; + + + public QvvrDataEntity getResponsibilityResult(QvvrDataEntity qvvrParam) { + int i, j; + if (qvvrParam != null) { + // 计算责任 + harm_res(qvvrParam.calFlag, qvvrParam); + // 输出结果 + qvvrParam.calOk = qvvrResult.calOk; + if (qvvrParam.calOk == 1) { + // 长时越限谐波责任 + for (i = 0; i < qvvrParam.pNode; i++) + qvvrParam.sumFKdata[i] = qvvrResult.sumFKdata[i]; + for (i = 0; i < (qvvrParam.pNode + 1); i++) + qvvrParam.sumHKdata[i] = qvvrResult.sumHKdata[i]; + // 如果是原始功率数据和谐波数据代入计算,将动态相关系数和动态谐波责任输出 + if (qvvrParam.calFlag == 0) { + qvvrParam.resNum = qvvrResult.resNum; + for (i = 0; i < qvvrResult.resNum; i++) { + qvvrParam.core[i] = qvvrResult.core[i]; + qvvrParam.bjCore[i] = qvvrResult.bjCore[i]; + for (j = 0; j < qvvrParam.pNode; j++) { + qvvrParam.fKData[i][j] = qvvrResult.fKData[i][j]; + qvvrParam.simData[i][j] = qvvrResult.simData[i][j]; + } + for (j = 0; j < (qvvrParam.pNode + 1); j++) + qvvrParam.hKData[i][j] = qvvrResult.hKData[i][j]; + } + } + } + } + return qvvrParam; + } + + + public static int harm_res(int calFlag, QvvrDataEntity qvvrParam) { + if (calFlag == 0) { + harm_res_all(qvvrParam); + } else if (calFlag == 1) { + harm_res_part(qvvrParam); + } + return 0; + } + + static int harm_res_part(QvvrDataEntity qvvrParam) { + int ret = 0; + //缓冲大小初始化 + ret = data_init_part(qvvrParam); + if (ret != 0) { + qvvrResult.calOk = 0; +// System.out.printf("data init err,exit\r\n"); + throw new BusinessException(AdvanceResponseEnum.DATA_ERROR); + } + int colK = P + 1; + RealMatrix HKdata = MatrixUtils.createRealMatrix(RES_NUM, colK); + for (int i = 0; i < P + 1; i++) { + for (int j = 0; j < RES_NUM; j++) { + HKdata.setEntry(j, i, qvvrResult.hKData[j][i]); + } + } + + RealVector Udata = new ArrayRealVector(TL); + for (int j = 0; j < TL; j++) { + Udata.setEntry(j, qvvrResult.harmData[j]); + } + + float[] arrHKsum = SumHK(HKdata, Udata, wdith, colK, TL); + RealVector sumHKdata = new ArrayRealVector(colK); + for (int i = 0; i < colK; i++) { + sumHKdata.setEntry(i, 0); + } + + float sum_hk = 0; + for (int i = 0; i < colK; i++) { + sumHKdata.setEntry(i, arrHKsum[i]); + sum_hk += sumHKdata.getEntry(i); + qvvrResult.sumHKdata[i] = (float) sumHKdata.getEntry(i); + } + + RealMatrix FKdata = MatrixUtils.createRealMatrix(RES_NUM, P); + for (int i = 0; i < P; i++) { + for (int j = 0; j < RES_NUM; j++) { + FKdata.setEntry(j, i, qvvrResult.fKData[j][i]); + } + } + + colK = P; + arrHKsum = SumHK(FKdata, Udata, wdith, colK, TL); + RealVector sumFKdata = new ArrayRealVector(colK); + for (int i = 0; i < colK; i++) { + sumFKdata.setEntry(i, 0); + } + + float sum_fk = 0; + for (int i = 0; i < colK; i++) { + sumFKdata.setEntry(i, arrHKsum[i]); + sum_fk += sumFKdata.getEntry(i); + qvvrResult.sumFKdata[i] = (float) sumFKdata.getEntry(i); + } + + qvvrResult.calOk = 1; + return 0; + } + + static int data_init_part(QvvrDataEntity qvvrParam) { + qvvrResult = new QvvrDataEntity(); + //输入数据处理 + BeanUtil.copyProperties(qvvrParam, qvvrResult); +// if ((qvvrResult.resNum + qvvrResult.win) != qvvrResult.harmNum) { +// System.out.printf("数据未对齐...\r\n"); +// return -1; +// } + RES_NUM = qvvrResult.resNum; + P = qvvrResult.pNode; + TL = qvvrResult.win + qvvrResult.resNum; + wdith = qvvrResult.win; + XIANE = qvvrResult.harmMk; + + if ((wdith < QvvrDataEntity.MIN_WIN_LEN) || (wdith > QvvrDataEntity.MAX_WIN_LEN)) { + System.out.printf("窗宽超限...\r\n"); + throw new BusinessException(AdvanceResponseEnum.WIN_DATA_ERROR); + } + + if ((P > QvvrDataEntity.MAX_P_NODE) || (TL > QvvrDataEntity.MAX_P_NUM)) { + System.out.printf("数据长度超限...\r\n"); + throw new BusinessException(AdvanceResponseEnum.DATA_ERROR); + } + for (int i = 0; i < RES_NUM; i++) { + for (int j = 0; j < P; j++) { + qvvrResult.fKData[i][j] = qvvrParam.fKData[i][j]; + } + for (int j = 0; j < P + 1; j++) { + qvvrResult.hKData[i][j] = qvvrParam.hKData[i][j]; + } + } + + // 复制 qvvrParam + for (int i = 0; i < TL; i++) { + qvvrResult.harmData[i] = qvvrParam.harmData[i]; + } + return 0; + } + + static int harm_res_all(QvvrDataEntity qvvrParam) { + int ret = 0; + //缓冲大小初始化 + ret = data_init_all(qvvrParam); + if (ret != 0) { + qvvrResult.calOk = 0; + System.out.printf("data init err,exit\r\n"); + throw new BusinessException(AdvanceResponseEnum.INIT_DATA_ERROR); + } + //测试数据申请空间 + float[][] a = new float[TL][]; + for (int i = 0; i < TL; i++) { + a[i] = new float[P]; + } + + float[] b = new float[LL]; + float[] u = new float[TL]; + + for (int i = 0; i < TL; i++) { + for (int j = 0; j < P; j++) { + a[i][j] = qvvrResult.pData[i][j]; + } + } + for (int i = 0; i < LL; i++) { + b[i] = qvvrResult.harmData[i]; + } + + for (int i = 0; i < LL; i += JIANGE) { + float tempt = 0.0f; + for (int j = 0; j < JIANGE; j++) { + tempt += b[i + j]; + } + b[i] = tempt / JIANGE; + } + int width = wdith; + int slcorlength = TL - width; + + //剥离背景谐波后的动态相关系数计算 + //数据格式转换 + // 创建矩阵Pdata并复制数据 + double[][] PdataArray = new double[TL][P]; + for (int i = 0; i < TL; i++) { + for (int j = 0; j < P; j++) { + PdataArray[i][j] = a[i][j]; + } + } + RealMatrix Pdata = new Array2DRowRealMatrix(PdataArray); + // 创建向量Udata并复制数据 + double[] UdataArray = new double[TL]; + for (int i = 0; i < TL; i++) { + UdataArray[i] = b[i * JIANGE]; + } + RealVector Udata = new ArrayRealVector(UdataArray); + for (int i = 0; i < TL; i++) { + u[i] = (float) UdataArray[i]; + } + + //动态典则相关系数数组获得 并转化为向量 + + float[] cancorrelation = SlideCanCor(a, u, width, P, TL); + + RealVector Core = new ArrayRealVector(slcorlength); + RealVector bjCore = new ArrayRealVector(slcorlength); + for (int i = 0; i < slcorlength; i++) { + Core.setEntry(i, cancorrelation[i]); + qvvrResult.core[i] = (float) Core.getEntry(i); + } + for (int i = 0; i < slcorlength; i++) { + bjCore.setEntry(i, 1 - cancorrelation[i]); + qvvrResult.bjCore[i] = (float) bjCore.getEntry(i); + } + + float[] y = new float[TL]; + float[] xe = new float[TL]; + float[] slidecor; + RealVector temptPe = new ArrayRealVector(TL); + RealVector temptU = new ArrayRealVector(TL); + RealMatrix simCor = new Array2DRowRealMatrix(slcorlength, P); + + // 格式转换 + temptU = Udata.getSubVector(0, TL); + for (int m = 0; m < TL; m++) { + y[m] = (float) temptU.getEntry(m); + } + // 格式转换、计算系数、格式转换 + for (int i = 0; i < P; i++) { + temptPe = Pdata.getColumnVector(i); + for (int m = 0; m < TL; m++) { + xe[m] = (float) temptPe.getEntry(m); + } + slidecor = slideCor(xe, y, cancorrelation, width, TL); // 计算每个用户负荷与用户谐波的动态相关系数 + + for (int j = 0; j < slcorlength; j++) { + simCor.setEntry(j, i, slidecor[j]); + qvvrResult.simData[j][i] = (float) simCor.getEntry(j, i); + } + } + + //动态谐波责任指标计算 + //EK计算,用于后续计算FK(不含背景的用户责任指标)、HK(包含背景的用户责任指标) + //float **EKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间 + //for (int i = 0; i < TL; i++) + //EKarr[i] = (float *)malloc(TL * sizeof(float)); + + float[][] EKarr; + EKarr = dyEKCom(simCor, Pdata, width, P, TL); + RealMatrix EKdata = MatrixUtils.createRealMatrix(slcorlength, P); + for (int i = 0; i < slcorlength; i++) { + for (int j = 0; j < P; j++) { + EKdata.setEntry(i, j, EKarr[i][j]); + } + } + + //不含背景的用户谐波责任指标 + //float **FKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间 + //for (int i = 0; i < TL; i++) + //FKarr[i] = (float *)malloc(TL * sizeof(float)); + float[][] FKarr; + FKarr = DyFKCom(EKdata, width, P, TL); + RealMatrix FKdata = MatrixUtils.createRealMatrix(slcorlength, P); + for (int i = 0; i < slcorlength; i++) { + for (int j = 0; j < P; j++) { + FKdata.setEntry(i, j, FKarr[i][j]); + } + } + qvvrResult.fKData=FKarr; + //包含背景的谐波责任指标 + //float **HKarr = (float **)malloc(TL * sizeof(float *));//先申请P个指针型字节的空间 + //for (int i = 0; i < TL; i++) + //HKarr[i] = (float *)malloc(TL * sizeof(float)); + float[][] HKarr; + HKarr = DyHKCom(bjCore, EKdata, width, P, TL); + RealMatrix HKdata = MatrixUtils.createRealMatrix(slcorlength, (P + 1)); + for (int i = 0; i < slcorlength; i++) { + for (int j = 0; j < (P + 1); j++) { + HKdata.setEntry(i, j, HKarr[i][j]); + qvvrResult.hKData[i][j] = (float) HKdata.getEntry(i, j); + } + } + qvvrResult.resNum = slcorlength; + + + //超限额长时谐波责任指标计算 + float[] arrHKsum = new float[TL]; + int colK = P + 1;//FKdata时为P + arrHKsum = SumHK(HKdata, Udata, width, colK, TL);//可更改FKdata,表示为不包含背景时的长时责任划分 + RealVector sumHKdata = new ArrayRealVector(colK); + for (int i = 0; i < colK; i++) { + sumHKdata.setEntry(i, 0); + } + + float sum_hk = 0; + for (int i = 0; i < colK; i++) { + sumHKdata.setEntry(i, arrHKsum[i]); + sum_hk += sumHKdata.getEntry(i); + qvvrResult.sumHKdata[i] = (float) sumHKdata.getEntry(i); + } + + colK = P;//FKdata时为P + arrHKsum = SumHK(FKdata, Udata, width, colK, TL);//可更改FKdata,表示为不包含背景时的长时责任划分 + RealVector sumFKdata = new ArrayRealVector(colK); + + for (int i = 0; i < colK; i++) { + sumFKdata.setEntry(i, 0); + } + float sum_fk = 0; + for (int i = 0; i < colK; i++) { + sumFKdata.setEntry(i, arrHKsum[i]); + sum_fk += sumFKdata.getEntry(i); + qvvrResult.sumFKdata[i] = (float) sumHKdata.getEntry(i); + } + //结果输出 + qvvrResult.calOk = 1; + return 0; + } + + + + static int data_init_all(QvvrDataEntity qvvrParam) { + qvvrResult = new QvvrDataEntity(); + //输入数据处理 + BeanUtil.copyProperties(qvvrParam, qvvrResult); + P = qvvrResult.pNode; + TL = qvvrResult.pNum; + LL = qvvrResult.harmNum; + JIANGE = qvvrResult.harmNum / qvvrResult.pNum; + wdith = qvvrResult.win; + XIANE = qvvrResult.harmMk; + + if ((JIANGE * TL != LL) || (JIANGE < 1)) { + return -1; + } + if ((wdith < QvvrDataEntity.MIN_WIN_LEN) || (wdith > QvvrDataEntity.MAX_WIN_LEN)) { +// System.out.printf("窗宽超限...\r\n"); + throw new BusinessException(AdvanceResponseEnum.EVENT_DATA_MISS); + } +// if (TL < (2 * wdith)) { +// System.out.printf("窗宽和数据长度不匹配...\r\n"); +// return -1; +// } + + if ((P > QvvrDataEntity.MAX_P_NODE) || (TL > QvvrDataEntity.MAX_P_NUM) || (LL > QvvrDataEntity.MAX_HARM_NUM)) { + System.out.printf("数据长度超限...\r\n"); + throw new BusinessException(AdvanceResponseEnum.EVENT_DATA_MISS); + } + + + float[][] clone = new float[qvvrParam.getPData().length][]; + for (int i = 0; i < qvvrParam.getPData().length; i++) { + clone[i] = Arrays.copyOf(qvvrParam.getPData()[i], qvvrParam.getPData()[i].length); + } + qvvrResult.setPData(clone); + + + for (int i = 0; i < LL; i++) { + qvvrResult.getHarmData()[i] = qvvrParam.getHarmData()[i]; + } + //System.out.printf("win = %d\r\n",wdith); + return 0; + } + + + public static float[] SlideCanCor(float[][] x, float[] y, int width, int p_num, int tl_num) { + int slcorlength = tl_num - width; + float[][] a = new float[width][p_num]; + for (int i = 0; i < width; i++) { + a[i] = new float[p_num]; + } + float[] b = new float[width]; + + float[][] sxxmatrix = new float[p_num][p_num]; + for (int i = 0; i < p_num; i++) { + sxxmatrix[i] = new float[p_num]; + } + float[] sxymatrix = new float[tl_num]; + float[] x1 = new float[tl_num]; + float[] x2 = new float[tl_num]; + float[] x3 = new float[tl_num]; + float[][] xx = new float[width][p_num]; + for (int i = 0; i < width; i++) { + xx[i] = new float[p_num]; + } + float[] yy = new float[width]; + + RealMatrix Pdata = new Array2DRowRealMatrix(tl_num, p_num); + RealVector Udata = new ArrayRealVector(tl_num); + for (int i = 0; i < tl_num; i++) { + for (int j = 0; j < p_num; j++) { + Pdata.setEntry(i, j, x[i][j]); + } + Udata.setEntry(i, y[i]); + } + + RealMatrix temptP = new Array2DRowRealMatrix(width, p_num); + RealVector temptU = new ArrayRealVector(width); + float[] slideCancor = new float[tl_num]; + for (int i = 0; i < slcorlength; i++) { + temptU = Udata.getSubVector(i, width); + temptP = Pdata.getSubMatrix(i, i + width - 1, 0, p_num - 1); + slideCancor[i] = TransCancor(temptP, temptU, width, p_num, tl_num, sxxmatrix, sxymatrix, x1, x2, x3, xx, yy); + } + + return slideCancor; + } + + + public static float TransCancor(RealMatrix a, RealVector b, int width, int p_num, int tl_num, + float[][] sxxMatrix, float[] sxyMatrix, float[] x1, float[] x2, + float[] x3, float[][] x, float[] y) { + float syymatrix; + for (int i = 0; i < width; i++) { + for (int j = 0; j < p_num; j++) { + x[i][j] = (float) a.getEntry(i, j); + } + y[i] = (float) b.getEntry(i); + } + // 假设的SXX函数,需要根据实际实现来调整 + sxxMatrix = SXX(x, width, p_num, tl_num, sxxMatrix, x1, x2); + syymatrix = cov(y, y, width); // 假设的COV函数,需要根据实际实现来调整 + if (syymatrix == 0) { + syymatrix = 0.00001F; + } + // 假设的SXY函数,需要根据实际实现来调整 + sxyMatrix = SXY(x, y, width, p_num, tl_num, sxyMatrix, x3); + +// +// RealMatrix A = MatrixUtils.createRealMatrix(p_num, p_num); +// RealMatrix invSXX = MatrixUtils.createRealMatrix(p_num, p_num); +// RealMatrix I = MatrixUtils.createRealIdentityMatrix(p_num); // I is an identity matrix +// +// // 二维数组转为矩阵 +// for (int i = 0; i < p_num; i++) { +// for (int j = 0; j < p_num; j++) { +// A.setEntry(i, j, sxxMatrix[i][j]); +// } +// } +// +// // 使用 LU 分解方法计算矩阵 invSXX +// invSXX = new LUDecomposition(A).getSolver().solve(I); + + // 创建 p_num × p_num 的矩阵 A + SimpleMatrix A = new SimpleMatrix(p_num, p_num); + + // 创建 p_num × p_num 的逆矩阵 invSXX + SimpleMatrix invSXX = new SimpleMatrix(p_num, p_num); + + // 创建 p_num × p_num 的单位矩阵 I + SimpleMatrix I = SimpleMatrix.identity(p_num); + + // 二维数组转为矩阵 A + for (int i = 0; i < p_num; i++) { + for (int j = 0; j < p_num; j++) { + A.set(i, j, sxxMatrix[i][j]); + } + } + + // 使用 LU 分解方法计算矩阵 invSXX + invSXX = A.invert().mult(I); + + // 创建长度为 p_num 的向量 sXYMa_Eigen + DMatrixRMaj sXYMa_Eigen = new DMatrixRMaj(p_num, 1); + for (int i = 0; i < p_num; i++) { + sXYMa_Eigen.set(i, 0, sxyMatrix[i]); + } + + // 计算 Umatrix + DMatrixRMaj Umatrix = new DMatrixRMaj(p_num, p_num); + CommonOps_DDRM.multOuter(sXYMa_Eigen, Umatrix); // 外积 + CommonOps_DDRM.divide(Umatrix, syymatrix); // 矩阵按标量除法 + CommonOps_DDRM.divide(Umatrix, syymatrix); // 再次按标量除法 + + // 计算特征值 + EigenDecomposition_F64 eigenDecomposition = DecompositionFactory_DDRM.eig(p_num, false); + eigenDecomposition.decompose(Umatrix); + + float corrMax = 0; + for (int i = 0; i < p_num; i++) { + float absCorr = (float) Math.abs(eigenDecomposition.getEigenvalue(i).getReal()); + if (absCorr > corrMax) { + corrMax = absCorr; + } + } + + float cancor = (float) Math.sqrt(corrMax); + if (cancor >= 1) { + cancor = 1; + } + + return cancor; + } + + + public static float[][] SXX(float[][] x, int width, int p_num, int tl_num, float[][] sxxmatrix, float[] x1, float[] x2) { + int i, j, m; + for (i = 0; i < p_num; i++) { + for (j = 0; j < p_num; j++) { + for (m = 0; m < width; m++) { + x1[m] = x[m][i]; + x2[m] = x[m][j]; + } + sxxmatrix[i][j] = cov(x1, x2, width); + } + } + return sxxmatrix; + } + + public static float[] SXY(float[][] x, float[] y, int width, int p_num, int tl_num, float[] sxymatrix, float[] x1) { + int i, m; + for (i = 0; i < p_num; i++) { + for (m = 0; m < width; m++) { + x1[m] = x[m][i]; + } + sxymatrix[i] = cov(x1, y, width); + } + return sxymatrix; + } + + public static float cov(float[] x, float[] y, int width) { + float d1, d2, d3, d4; + float mx, my; + float cov; + int i; + int xlength = width; + int ylength = width; + d1 = d2 = d3 = d4 = mx = my = 0.0f; + for (i = 0; i < xlength; i++) { + mx += x[i]; + my += y[i]; + } + mx = mx / xlength; + my = my / ylength; + for (i = 0; i < xlength; i++) { + d1 += (x[i] - mx) * (y[i] - my); + } + cov = d1 / (xlength - 1); + return cov; + } + + public static float[] slideCor(float[] x, float[] y, float[] slidecor, int width, int tlNum) { + int slcorLength = tlNum - width; + float[] slcor = new float[tlNum]; // 注意调整数组大小根据实际需要 + + // 动态相关系数 + for (int i = 0; i < slcorLength; i++) { + float[] temptp = new float[width]; + float[] temptq = new float[width]; + for (int j = 0; j < width; j++) { + temptp[j] = x[i + j]; + temptq[j] = y[i + j] * slidecor[i]; + } + slcor[i] = pearCor(temptq, temptp, width); + } + + return slcor; + } + + public static float pearCor(float[] x, float[] y, int count) { + float d1 = 0, d2 = 0, d3 = 0, d4 = 0; + float mx = 0, my = 0; + float result = 0; + + // 计算x和y的平均值 + for (int i = 0; i < count; i++) { + mx += x[i]; + my += y[i]; + } + mx /= count; + my /= count; + + // 计算相关系数的数据组成部分 + for (int i = 0; i < count; i++) { + d1 += (x[i] - mx) * (y[i] - my); + d2 += (x[i] - mx) * (x[i] - mx); + d3 += (y[i] - my) * (y[i] - my); + } + d4 = (float) Math.sqrt(d2 * d3); + + if (d4 == 0) { + // 除数为0时,相关系数为0 + result = 0; + } else { + result = d1 / d4; + } + + return result; + } + + private static float[][] dyEKCom(RealMatrix Dydata, RealMatrix Pdata, int width, int p_num, int tl_num) { + int slg = tl_num - width; + RealMatrix AKdata = MatrixUtils.createRealMatrix(slg, p_num); + RealMatrix SumP = MatrixUtils.createRealMatrix(slg, 1); + RealMatrix EKdata = MatrixUtils.createRealMatrix(slg, p_num); + + for (int i = 0; i < slg; i++) { + SumP.setEntry(i, 0, 0); + for (int j = 0; j < p_num; j++) { + float sumPValue = (float) (SumP.getEntry(i, 0) + Pdata.getEntry(i, j)); + SumP.setEntry(i, 0, sumPValue); + } + for (int j = 0; j < p_num; j++) { + float AKdataValue = (float) (Dydata.getEntry(i, j) * (Pdata.getEntry(i, j) / SumP.getEntry(i, 0))); + AKdata.setEntry(i, j, AKdataValue); + } + } + for (int i = 0; i < slg; i++) { + float maxdata = Float.MIN_VALUE; + float mindata = Float.MAX_VALUE; + for (int j = 0; j < p_num; j++) { + maxdata = Math.max(maxdata, (float) AKdata.getEntry(i, j)); + mindata = Math.min(mindata, (float) AKdata.getEntry(i, j)); + } + for (int j = 0; j < p_num; j++) { + EKdata.setEntry(i, j, (AKdata.getEntry(i, j) - mindata) / (maxdata - mindata)); + } + } + + float[][] arrEK = new float[slg][p_num]; + for (int i = 0; i < slg; i++) { + for (int j = 0; j < p_num; j++) { + arrEK[i][j] = (float) EKdata.getEntry(i, j); + } + } + return arrEK; + } + + private static float[][] DyFKCom(RealMatrix EKdata, int width, int p_num, int tl_num) { + int slg = tl_num - width; + RealMatrix FKdata = MatrixUtils.createRealMatrix(slg, p_num); + ArrayRealVector SumEK = new ArrayRealVector(slg); + + for (int i = 0; i < slg; i++) { + SumEK.setEntry(i, 0); + for (int j = 0; j < p_num; j++) { + float sumEKValue = (float) (SumEK.getEntry(i) + EKdata.getEntry(i, j)); + SumEK.setEntry(i, sumEKValue); + } + for (int j = 0; j < p_num; j++) { + float FKdataValue = (float) (EKdata.getEntry(i, j) / SumEK.getEntry(i)); + FKdata.setEntry(i, j, FKdataValue); + } + } + + float[][] arrFK = new float[tl_num][p_num]; + for (int i = 0; i < slg; i++) { + for (int j = 0; j < p_num; j++) { + arrFK[i][j] = (float) FKdata.getEntry(i, j); + } + } + return arrFK; + } + + private static float[][] DyHKCom(RealVector cancordata, RealMatrix EKdata, int width, int p_num, int tl_num) { + int slg = tl_num - width; + RealMatrix HKdata = MatrixUtils.createRealMatrix(slg, p_num + 1); + RealMatrix newEK = MatrixUtils.createRealMatrix(slg, p_num + 1); + ArrayRealVector SumEK = new ArrayRealVector(slg); + + for (int i = 0; i < slg; i++) { + for (int j = 0; j < p_num; j++) { + newEK.setEntry(i, j, EKdata.getEntry(i, j)); + } + newEK.setEntry(i, p_num, cancordata.getEntry(i)); + } + + for (int i = 0; i < slg; i++) { + SumEK.setEntry(i, 0); + for (int j = 0; j < p_num + 1; j++) { + float sumEKValue = (float) (SumEK.getEntry(i) + newEK.getEntry(i, j)); + SumEK.setEntry(i, sumEKValue); + } + for (int j = 0; j < p_num + 1; j++) { + float HKdataValue = (float) (newEK.getEntry(i, j) / SumEK.getEntry(i)); + HKdata.setEntry(i, j, HKdataValue); + } + } + + float[][] arrHK = new float[tl_num][p_num + 1]; + for (int i = 0; i < slg; i++) { + for (int j = 0; j < p_num + 1; j++) { + arrHK[i][j] = (float) HKdata.getEntry(i, j); + } + } + return arrHK; + } + + private static float[] SumHK(RealMatrix HKdata, RealVector Udata, int width, int colK, int tl_num) { + int P1 = colK; + RealVector HKSum = new ArrayRealVector(P1); + int slg = tl_num - width; + int coutt = 0; + + for (int j = 0; j < P1; j++) { + HKSum.setEntry(j, 0); + coutt = 0; + for (int i = 0; i < slg; i++) { + if (Udata.getEntry(i) > XIANE) { + float HKdataEntry = (float) HKdata.getEntry(i, j); + HKSum.setEntry(j, HKSum.getEntry(j) + HKdataEntry); + coutt++; + } + } + } + + float[] arrHKsum = new float[P1]; + for (int i = 0; i < P1; i++) { + arrHKsum[i] = 0; + } + for (int i = 0; i < P1; i++) { + if (coutt > 0) { + arrHKsum[i] = (float) (100 * (HKSum.getEntry(i) / coutt)); + } + } + return arrHKsum; + } + +} diff --git a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java index b0baabae5..743c69672 100644 --- a/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java +++ b/pqs-harmonic/harmonic-boot/src/main/java/com/njcn/harmonic/service/impl/HistoryResultServiceImpl.java @@ -91,7 +91,6 @@ public class HistoryResultServiceImpl implements HistoryResultService { private final DicDataFeignClient dicDataFeignClient; - @Override public List getHistoryResult(HistoryParam historyParam) { List historyDataResultVOList = new ArrayList<>(); @@ -195,16 +194,16 @@ public class HistoryResultServiceImpl implements HistoryResultService { historyDataResultVO.setValue(objectListData); } else { //按时间分组 - Map> map = harmonicHistoryDataList.stream().collect(Collectors.groupingBy(HarmonicHistoryData::getTime,TreeMap::new, Collectors.toList())); + Map> map = harmonicHistoryDataList.stream().collect(Collectors.groupingBy(HarmonicHistoryData::getTime, TreeMap::new, Collectors.toList())); - Float maxI = null; - Float minI = null; + Float maxI = null; + Float minI = null; for (Map.Entry> entry : map.entrySet()) { List val = entry.getValue(); - Object[] objects = {PubUtils.instantToDate(entry.getKey()),0,0,0}; + Object[] objects = {PubUtils.instantToDate(entry.getKey()), 0, 0, 0}; //需要保证val的长度为3 - if(val.size()!=3){ - for(int i =0;i<3-val.size();i++){ + if (val.size() != 3) { + for (int i = 0; i < 3 - val.size(); i++) { HarmonicHistoryData tem = new HarmonicHistoryData(); tem.setAValue(0f); val.add(tem); @@ -215,7 +214,7 @@ public class HistoryResultServiceImpl implements HistoryResultService { if (InfluxDBTableConstant.PHASE_TYPE_A.equalsIgnoreCase(harmonicHistoryData.getPhasicType())) { BigDecimal a = BigDecimal.valueOf(harmonicHistoryData.getAValue()).setScale(4, RoundingMode.HALF_UP); - objects[1] =a; + objects[1] = a; maxI = max(maxI, a.floatValue()); minI = min(minI, a.floatValue()); @@ -237,7 +236,8 @@ public class HistoryResultServiceImpl implements HistoryResultService { objectListData.add(list); - }; + } + ; //下面代码稳定后可删除 /* List aList = harmonicHistoryDataList.stream() @@ -336,24 +336,24 @@ public class HistoryResultServiceImpl implements HistoryResultService { } - private Float max(Float ding,Float a){ - if(Objects.isNull(ding)){ + private Float max(Float ding, Float a) { + if (Objects.isNull(ding)) { ding = a; } - if(a>ding){ + if (a > ding) { ding = a; } - return ding; + return ding; } - private Float min(Float ding,Float a){ - if(Objects.isNull(ding)){ + private Float min(Float ding, Float a) { + if (Objects.isNull(ding)) { ding = a; } - if(a