谐波溯源翻译成java 第一版本,写完技术监督再回来优化

This commit is contained in:
2024-05-20 15:00:17 +08:00
parent 9a6c4e7244
commit f03fc1d1cf
8 changed files with 952 additions and 106 deletions

View File

@@ -70,5 +70,16 @@
<artifactId>cglib</artifactId> <artifactId>cglib</artifactId>
<version>3.3.0</version> <version>3.3.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-simple</artifactId>
<version>0.41</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -65,6 +65,12 @@ public enum AdvanceResponseEnum {
EVENT_DATA_MISS("A0102","没有可供参考的暂降数据"), EVENT_DATA_MISS("A0102","没有可供参考的暂降数据"),
WIN_DATA_ERROR("A0102","算法校验窗宽超限"),
DATA_ERROR("A0102","算法校验数据长度超限"),
INIT_DATA_ERROR("A0102","算法初始化数据失败"),
USER_HAS_PRODUCT("A0102","当前用户存在生产线"), USER_HAS_PRODUCT("A0102","当前用户存在生产线"),
PRODUCT_HAS_MACHINE("A0102","当前生产线存在设备"), PRODUCT_HAS_MACHINE("A0102","当前生产线存在设备"),

View File

@@ -26,9 +26,9 @@ public class CacheQvvrData implements Serializable {
private float[] harmData; private float[] harmData;
private PDataStruct[] FKdata; private float[][] fKData;
private HKDataStruct[] HKdata; private float[][] hKData;
private List<String> names; private List<String> names;

View File

@@ -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];
}
}

View File

@@ -7,10 +7,10 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
public class QvvrStruct extends HIKSDKStructure implements Serializable { public class QvvrStruct extends HIKSDKStructure implements Serializable {
public static final int MAX_P_NODE= 200; //功率节点个数限制按200个限制 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_P_NUM = 96 * 100; //功率数据按15分钟间隔100天处理
public static final int MAX_HARM_NUM= 1440 * 100; //谐波数据按一分钟间隔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_WIN_LEN = 96 * 10; //按15分钟算10天
public static final int MIN_WIN_LEN = 4; //按15分钟算1小时 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; this.sim_data = sim_data;
} }
// @Override @Override
// protected List getFieldOrder() { protected List getFieldOrder() {
// return Arrays.asList(new String[]{"sumFKdata", "sumHKdata"}); 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");
}
} }

View File

@@ -18,10 +18,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.advance.enums.AdvanceResponseEnum; import com.njcn.advance.enums.AdvanceResponseEnum;
import com.njcn.advance.mapper.responsibility.RespDataMapper; import com.njcn.advance.mapper.responsibility.RespDataMapper;
import com.njcn.advance.model.responsibility.CacheQvvrData; import com.njcn.advance.model.responsibility.*;
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.pojo.bo.responsibility.*; import com.njcn.advance.pojo.bo.responsibility.*;
import com.njcn.advance.pojo.dto.responsibility.CustomerData; import com.njcn.advance.pojo.dto.responsibility.CustomerData;
import com.njcn.advance.pojo.dto.responsibility.CustomerResponsibility; 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.param.ResponsibilitySecondCalParam;
import com.njcn.advance.pojo.po.responsibility.RespData; import com.njcn.advance.pojo.po.responsibility.RespData;
import com.njcn.advance.pojo.po.responsibility.RespDataResult; 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.IRespDataResultService;
import com.njcn.advance.service.responsibility.IRespDataService; import com.njcn.advance.service.responsibility.IRespDataService;
import com.njcn.advance.service.responsibility.IRespUserDataService; import com.njcn.advance.service.responsibility.IRespUserDataService;
import com.njcn.advance.utils.ResponsibilityAlgorithm;
import com.njcn.advance.utils.ResponsibilityCallDllOrSo; import com.njcn.advance.utils.ResponsibilityCallDllOrSo;
import com.njcn.common.pojo.enums.common.DataStateEnum; import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
@@ -104,7 +101,7 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
//没有排序参数默认根据sort字段排序没有排序字段的根据updateTime更新时间排序 //没有排序参数默认根据sort字段排序没有排序字段的根据updateTime更新时间排序
queryWrapper.orderBy(true, false, "pqs_resp_data.create_time"); 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()); queryWrapper.eq("pqs_resp_data.state", DataStateEnum.ENABLE.getCode());
Page<RespDataDTO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper); Page<RespDataDTO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
@@ -185,69 +182,67 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
names.add(userName); 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++) { for (int i = 0; i < names.size(); i++) {
//当前某用户测量节点的所有数据 //当前某用户测量节点的所有数据
List<UserDataExcel> userDataExcelBodies1 = originalPData.get(names.get(i)); List<UserDataExcel> userDataExcelBodies1 = originalPData.get(names.get(i));
for (int k = 0; k < userDataExcelBodies1.size(); k++) { for (int k = 0; k < userDataExcelBodies1.size(); k++) {
PDataStruct pDataStruct = pData[k]; float[] pDataStruct = pData[k];
if (pDataStruct == null) { 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(); p[i] = userDataExcelBodies1.get(k).getWork().floatValue();
pData[k] = pDataStruct; pData[k] = pDataStruct;
} }
} }
//至此功率数据也组装完毕,调用友谊提供的接口 //至此功率数据也组装完毕,调用友谊提供的接口
QvvrStruct qvvrStruct = null; QvvrDataEntity qvvrDataEntity = new QvvrDataEntity();
try { qvvrDataEntity.calFlag = 0;
qvvrStruct = new QvvrStruct(); qvvrDataEntity.pNode = pNode;
} catch (Exception exception) { qvvrDataEntity.pNum = pNum;
exception.printStackTrace(); qvvrDataEntity.win = win;
} qvvrDataEntity.harmNum = harmNum;
qvvrStruct.cal_flag = 0; qvvrDataEntity.harmMk = harmMk;
qvvrStruct.p_node = pNode; qvvrDataEntity.pData = pData;
qvvrStruct.p_num = pNum; qvvrDataEntity.harmData = respHarmData.getHarmData();
qvvrStruct.win = win; // ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response");
qvvrStruct.harm_num = harmNum; // responsibilityCallDllOrSo.setPath();
qvvrStruct.harm_mk = harmMk; // ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE;
qvvrStruct.p_data = pData; // try {
qvvrStruct.harm_data = respHarmData.getHarmData(); // responsibilityLibrary.harm_response(qvvrStruct);
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); // } catch (Exception exception) {
responsibilityCallDllOrSo.setPath(); // exception.printStackTrace();
ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; // }
try {
responsibilityLibrary.harm_response(qvvrStruct); ResponsibilityAlgorithm responsibilityAlgorithm = new ResponsibilityAlgorithm();
} catch (Exception exception) { qvvrDataEntity = responsibilityAlgorithm.getResponsibilityResult(qvvrDataEntity);
exception.printStackTrace();
}
//至此接口调用结束,开始组装动态责任数据和用户责任量化结果 //至此接口调用结束,开始组装动态责任数据和用户责任量化结果
//首先判断cal_ok的标识位是否为1为0表示程序没有计算出结果 //首先判断cal_ok的标识位是否为1为0表示程序没有计算出结果
if (qvvrStruct.cal_ok == 0) { if (qvvrDataEntity.calOk == 0) {
throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR); throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR);
} }
//没问题后,先玩动态责任数据 //没问题后,先玩动态责任数据
CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node]; CustomerData[] customerDatas = new CustomerData[qvvrDataEntity.pNode];
PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata(); float[][] fKdata/*无背景的动态责任数据*/ = qvvrDataEntity.getFKData();
//第一个时间节点是起始时间+win窗口得到的时间 //第一个时间节点是起始时间+win窗口得到的时间
Date sTime = DateUtil.parse(dateStr.get(0).concat(" 00:00:00"), DatePattern.NORM_DATETIME_PATTERN); Date sTime = DateUtil.parse(dateStr.get(0).concat(" 00:00:00"), DatePattern.NORM_DATETIME_PATTERN);
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(sTime); calendar.setTime(sTime);
calendar.add(Calendar.MINUTE, (win - 1) * userIntervalTime); calendar.add(Calendar.MINUTE, (win - 1) * userIntervalTime);
List<Long> timeDatas = new ArrayList<>(); List<Long> 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); calendar.add(Calendar.MINUTE, userIntervalTime);
//一个时间点所有的用户数据 //一个时间点所有的用户数据
PDataStruct fKdatum = fKdata[i]; float[] fKdatum = fKdata[i];
for (int k = 0; k < qvvrStruct.p_node; k++) { for (int k = 0; k < qvvrDataEntity.pNode; k++) {
CustomerData customerData = customerDatas[k]; CustomerData customerData = customerDatas[k];
if (null == customerData) { if (null == customerData) {
customerData = new CustomerData(); customerData = new CustomerData();
customerData.setCustomerName(names.get(k)); customerData.setCustomerName(names.get(k));
} }
List<Float> valueDatas = customerData.getValueDatas(); List<Float> valueDatas = customerData.getValueDatas();
Float valueTemp = fKdatum.getP()[k]; Float valueTemp = fKdatum[k];
if (valueTemp.isNaN()) { if (valueTemp.isNaN()) {
valueTemp = 0.0f; valueTemp = 0.0f;
} }
@@ -273,7 +268,7 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
customerDataTemp.put(name, customerData); customerDataTemp.put(name, customerData);
} }
//动态数据组装完成后,开始组装责任数据 //动态数据组装完成后,开始组装责任数据
List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, qvvrStruct.sumFKdata, qvvrStruct.p_node); List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, qvvrDataEntity.sumFKdata, qvvrDataEntity.pNode);
//根据前十的用户数据,获取这些用户的动态责任数据 //根据前十的用户数据,获取这些用户的动态责任数据
List<CustomerData> customerData = new ArrayList<>(); List<CustomerData> customerData = new ArrayList<>();
for (CustomerResponsibility customerResponsibility : customerResponsibilities) { for (CustomerResponsibility customerResponsibility : customerResponsibilities) {
@@ -378,9 +373,10 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
String customerPath = fileStorageUtil.uploadStream(customerStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json")); String customerPath = fileStorageUtil.uploadStream(customerStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
respDataResult.setUserDetailData(customerPath); respDataResult.setUserDetailData(customerPath);
//调用qvvr生成的中间数据 //调用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()); 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); // JSONObject cacheQvvrDataDataJson = (JSONObject) JSONObject.toJSON(cacheQvvrData);
InputStream cacheQvvrDataStream = IoUtil.toStream(cacheQvvrDataDataJson.toString(), CharsetUtil.UTF_8); 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")); String cacheQvvrDataPath = fileStorageUtil.uploadStream(cacheQvvrDataStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
respDataResult.setQvvrData(cacheQvvrDataPath); respDataResult.setQvvrData(cacheQvvrDataPath);
//用户前10数据存储 //用户前10数据存储
@@ -422,7 +418,9 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
try { try {
InputStream fileStream = fileStorageUtil.getFileStream(respDataResultTemp.getQvvrData()); InputStream fileStream = fileStorageUtil.getFileStream(respDataResultTemp.getQvvrData());
String qvvrDataStr = IoUtil.read(fileStream, CharsetUtil.UTF_8); 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) { } catch (Exception exception) {
throw new BusinessException(AdvanceResponseEnum.RESP_RESULT_DATA_NOT_FOUND); throw new BusinessException(AdvanceResponseEnum.RESP_RESULT_DATA_NOT_FOUND);
} }
@@ -443,25 +441,25 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
//间隔中的时间长度 //间隔中的时间长度
int minus = timeEndIndex - timeStartIndex + 1; int minus = timeEndIndex - timeStartIndex + 1;
//组装参数 //组装参数
QvvrStruct qvvrStruct = new QvvrStruct(); QvvrDataEntity qvvrDataEntity = new QvvrDataEntity();
qvvrStruct.cal_flag = 1; qvvrDataEntity.calFlag = 1;
qvvrStruct.p_node = cacheQvvrData.getPNode(); qvvrDataEntity.pNode = cacheQvvrData.getPNode();
qvvrStruct.harm_mk = responsibilitySecondCalParam.getLimitValue(); qvvrDataEntity.harmMk = responsibilitySecondCalParam.getLimitValue();
qvvrStruct.win = win; qvvrDataEntity.win = win;
int resNum; int resNum;
PDataStruct[] FKdata = new PDataStruct[9600]; float[][] FKdata = new float[9600][QvvrDataEntity.MAX_P_NODE];
HKDataStruct[] HKdata = new HKDataStruct[9600]; float[][] HKdata = new float[9600][QvvrDataEntity.MAX_P_NODE + 1];
float[] harmData = new float[1440 * 100]; float[] harmData = new float[1440 * 100];
PDataStruct[] fKdataOriginal = cacheQvvrData.getFKdata(); float[][] fKdataOriginal = cacheQvvrData.getFKData();
HKDataStruct[] hKdataOriginal = cacheQvvrData.getHKdata(); float[][] hKdataOriginal = cacheQvvrData.getHKData();
float[] harmDataOriginal = cacheQvvrData.getHarmData(); float[] harmDataOriginal = cacheQvvrData.getHarmData();
//如果起始索引与截止索引的差值等于时间轴的长度,则说明用户没有选择限值时间,直接带入全部的原始数据,参与计算即可 //如果起始索引与截止索引的差值等于时间轴的长度,则说明用户没有选择限值时间,直接带入全部的原始数据,参与计算即可
if (minus == times.size()) { if (minus == times.size()) {
qvvrStruct.harm_num = cacheQvvrData.getHarmNum(); qvvrDataEntity.harmNum = cacheQvvrData.getHarmNum();
qvvrStruct.res_num = cacheQvvrData.getHarmNum() - cacheQvvrData.getWin(); qvvrDataEntity.resNum = cacheQvvrData.getHarmNum() - cacheQvvrData.getWin();
qvvrStruct.setFKdata(cacheQvvrData.getFKdata()); qvvrDataEntity.setFKData(cacheQvvrData.getFKData());
qvvrStruct.setHKdata(cacheQvvrData.getHKdata()); qvvrDataEntity.setHKData(cacheQvvrData.getHKData());
qvvrStruct.harm_data = cacheQvvrData.getHarmData(); qvvrDataEntity.harmData = cacheQvvrData.getHarmData();
} else { } else {
if (win == 4) { if (win == 4) {
//当窗口为4时,两个时间限制范围在最小公倍数为15时最起码有5个有效时间点在最小公倍数为30时最起码有3个有效时间点 //当窗口为4时,两个时间限制范围在最小公倍数为15时最起码有5个有效时间点在最小公倍数为30时最起码有3个有效时间点
@@ -497,33 +495,39 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
} else { } else {
throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR); throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR);
} }
qvvrStruct.res_num = resNum; qvvrDataEntity.resNum = resNum;
qvvrStruct.harm_num = minus; qvvrDataEntity.harmNum = minus;
//因为限值时间实际是含头含尾的所以harmNum需要索引差值+1 //因为限值时间实际是含头含尾的所以harmNum需要索引差值+1
for (int i = timeStartIndex; i <= timeEndIndex; i++) { for (int i = timeStartIndex; i <= timeEndIndex; i++) {
harmData[i - timeStartIndex] = harmDataOriginal[i]; harmData[i - timeStartIndex] = harmDataOriginal[i];
} }
qvvrStruct.harm_data = harmData; qvvrDataEntity.harmData = harmData;
//FKData与HKData的值则等于resNum //FKData与HKData的值则等于resNum
for (int i = timeStartIndex; i < timeStartIndex + resNum; i++) { for (int i = timeStartIndex; i < timeStartIndex + resNum; i++) {
FKdata[i - timeStartIndex] = fKdataOriginal[i]; FKdata[i - timeStartIndex] = fKdataOriginal[i];
HKdata[i - timeStartIndex] = hKdataOriginal[i]; HKdata[i - timeStartIndex] = hKdataOriginal[i];
} }
qvvrStruct.setFKdata(FKdata); qvvrDataEntity.setFKData(FKdata);
qvvrStruct.setHKdata(HKdata); qvvrDataEntity.setHKData(HKdata);
} }
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response"); // ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response");
responsibilityCallDllOrSo.setPath(); // responsibilityCallDllOrSo.setPath();
ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE; // ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE;
responsibilityLibrary.harm_response(qvvrStruct); // responsibilityLibrary.harm_response(qvvrStruct);
if (qvvrStruct.cal_ok == 0) { // 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); throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR);
} }
//没问题后,先玩动态责任数据 //没问题后,先玩动态责任数据
List<String> names = cacheQvvrData.getNames(); List<String> names = cacheQvvrData.getNames();
CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node]; CustomerData[] customerDatas = new CustomerData[qvvrDataEntity.pNode];
PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata(); float[][] fKdata/*无背景的动态责任数据*/ = qvvrDataEntity.getFKData();
//第一个时间节点是起始时间+win窗口得到的时间 //第一个时间节点是起始时间+win窗口得到的时间
Date sTime = new Date(); Date sTime = new Date();
sTime.setTime(times.get(timeStartIndex)); sTime.setTime(times.get(timeStartIndex));
@@ -531,18 +535,18 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
calendar.setTime(sTime); calendar.setTime(sTime);
calendar.add(Calendar.MINUTE, (win - 1) * minMultiple); calendar.add(Calendar.MINUTE, (win - 1) * minMultiple);
List<Long> timeDatas = new ArrayList<>(); List<Long> 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); calendar.add(Calendar.MINUTE, minMultiple);
//一个时间点所有的用户数据 //一个时间点所有的用户数据
PDataStruct fKdatum = fKdata[i]; float[] fKdatum = fKdata[i];
for (int k = 0; k < qvvrStruct.p_node; k++) { for (int k = 0; k < qvvrDataEntity.pNode; k++) {
CustomerData customerData = customerDatas[k]; CustomerData customerData = customerDatas[k];
if (null == customerData) { if (null == customerData) {
customerData = new CustomerData(); customerData = new CustomerData();
customerData.setCustomerName(names.get(k)); customerData.setCustomerName(names.get(k));
} }
List<Float> valueDatas = customerData.getValueDatas(); List<Float> valueDatas = customerData.getValueDatas();
Float valueTemp = fKdatum.getP()[k]; Float valueTemp = fKdatum[k];
if (valueTemp.isNaN()) { if (valueTemp.isNaN()) {
valueTemp = 0.0f; valueTemp = 0.0f;
} }
@@ -568,8 +572,8 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
customerDataTemp.put(name, customerData); customerDataTemp.put(name, customerData);
} }
//调用程序接口后,首先组装责任量化结果 //调用程序接口后,首先组装责任量化结果
float[] sumFKdata = qvvrStruct.sumFKdata; float[] sumFKdata = qvvrDataEntity.sumFKdata;
List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, sumFKdata, qvvrStruct.p_node); List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, sumFKdata, qvvrDataEntity.pNode);
//根据前十的用户数据,获取这些用户的动态责任数据 //根据前十的用户数据,获取这些用户的动态责任数据
List<CustomerData> customerData = new ArrayList<>(); List<CustomerData> customerData = new ArrayList<>();

View File

@@ -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用以控制动态相关系数的计算窗宽
* 使用<Eigen>库中函数进行矩阵构造与计算;
* 最终的到结果为向量Core为动态典则相关系数
* 矩阵simCor为剥离背景后的动态相关系数其中每列为每一用户负荷
* 矩阵HKdata为使用simCor计算的动态谐波责任指标其中每列为每一用户负荷
* 向量sumHKdata为超限额的谐波时不同用户的长时谐波责任指标
* 函数说明cov(a,b)计算协方差;
* SXXa,width计算长度为width序列的方差矩阵
* SXYa,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<DMatrixRMaj> 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;
}
}

View File

@@ -91,7 +91,6 @@ public class HistoryResultServiceImpl implements HistoryResultService {
private final DicDataFeignClient dicDataFeignClient; private final DicDataFeignClient dicDataFeignClient;
@Override @Override
public List<HistoryDataResultVO> getHistoryResult(HistoryParam historyParam) { public List<HistoryDataResultVO> getHistoryResult(HistoryParam historyParam) {
List<HistoryDataResultVO> historyDataResultVOList = new ArrayList<>(); List<HistoryDataResultVO> historyDataResultVOList = new ArrayList<>();
@@ -195,16 +194,16 @@ public class HistoryResultServiceImpl implements HistoryResultService {
historyDataResultVO.setValue(objectListData); historyDataResultVO.setValue(objectListData);
} else { } else {
//按时间分组 //按时间分组
Map<Instant,List<HarmonicHistoryData>> map = harmonicHistoryDataList.stream().collect(Collectors.groupingBy(HarmonicHistoryData::getTime,TreeMap::new, Collectors.toList())); Map<Instant, List<HarmonicHistoryData>> map = harmonicHistoryDataList.stream().collect(Collectors.groupingBy(HarmonicHistoryData::getTime, TreeMap::new, Collectors.toList()));
Float maxI = null; Float maxI = null;
Float minI = null; Float minI = null;
for (Map.Entry<Instant, List<HarmonicHistoryData>> entry : map.entrySet()) { for (Map.Entry<Instant, List<HarmonicHistoryData>> entry : map.entrySet()) {
List<HarmonicHistoryData> val = entry.getValue(); List<HarmonicHistoryData> val = entry.getValue();
Object[] objects = {PubUtils.instantToDate(entry.getKey()),0,0,0}; Object[] objects = {PubUtils.instantToDate(entry.getKey()), 0, 0, 0};
//需要保证val的长度为3 //需要保证val的长度为3
if(val.size()!=3){ if (val.size() != 3) {
for(int i =0;i<3-val.size();i++){ for (int i = 0; i < 3 - val.size(); i++) {
HarmonicHistoryData tem = new HarmonicHistoryData(); HarmonicHistoryData tem = new HarmonicHistoryData();
tem.setAValue(0f); tem.setAValue(0f);
val.add(tem); val.add(tem);
@@ -215,7 +214,7 @@ public class HistoryResultServiceImpl implements HistoryResultService {
if (InfluxDBTableConstant.PHASE_TYPE_A.equalsIgnoreCase(harmonicHistoryData.getPhasicType())) { if (InfluxDBTableConstant.PHASE_TYPE_A.equalsIgnoreCase(harmonicHistoryData.getPhasicType())) {
BigDecimal a = BigDecimal.valueOf(harmonicHistoryData.getAValue()).setScale(4, RoundingMode.HALF_UP); BigDecimal a = BigDecimal.valueOf(harmonicHistoryData.getAValue()).setScale(4, RoundingMode.HALF_UP);
objects[1] =a; objects[1] = a;
maxI = max(maxI, a.floatValue()); maxI = max(maxI, a.floatValue());
minI = min(minI, a.floatValue()); minI = min(minI, a.floatValue());
@@ -237,7 +236,8 @@ public class HistoryResultServiceImpl implements HistoryResultService {
objectListData.add(list); objectListData.add(list);
}; }
;
//下面代码稳定后可删除 //下面代码稳定后可删除
/* List<HarmonicHistoryData> aList = harmonicHistoryDataList.stream() /* List<HarmonicHistoryData> aList = harmonicHistoryDataList.stream()
@@ -336,21 +336,21 @@ public class HistoryResultServiceImpl implements HistoryResultService {
} }
private Float max(Float ding,Float a){ private Float max(Float ding, Float a) {
if(Objects.isNull(ding)){ if (Objects.isNull(ding)) {
ding = a; ding = a;
} }
if(a>ding){ if (a > ding) {
ding = a; ding = a;
} }
return ding; return ding;
} }
private Float min(Float ding,Float a){ private Float min(Float ding, Float a) {
if(Objects.isNull(ding)){ if (Objects.isNull(ding)) {
ding = a; ding = a;
} }
if(a<ding){ if (a < ding) {
ding = a; ding = a;
} }
return ding; return ding;
@@ -369,12 +369,12 @@ public class HistoryResultServiceImpl implements HistoryResultService {
LineDevGetDTO lineDetailDataVO = commTerminalGeneralClient.getMonitorDetail(lineId).getData(); LineDevGetDTO lineDetailDataVO = commTerminalGeneralClient.getMonitorDetail(lineId).getData();
//获取限值 //获取限值
Overlimit overlimit = commTerminalGeneralClient.getOverLimitData(lineId).getData(); Overlimit overlimit = commTerminalGeneralClient.getOverLimitData(lineId).getData();
if(Objects.isNull(overlimit)){ if (Objects.isNull(overlimit)) {
//对配网没有限值的统一处理 //对配网没有限值的统一处理
DictData dictData = dicDataFeignClient.getDicDataById(lineDetailDataVO.getVoltageLevel()).getData(); DictData dictData = dicDataFeignClient.getDicDataById(lineDetailDataVO.getVoltageLevel()).getData();
float voltageLevel = Float.parseFloat(dictData.getValue()); float voltageLevel = Float.parseFloat(dictData.getValue());
float shortVal = COverlimitUtil.getDlCapByVoltageLevel(voltageLevel); float shortVal = COverlimitUtil.getDlCapByVoltageLevel(voltageLevel);
overlimit = COverlimitUtil.globalAssemble(voltageLevel,10f,10f,shortVal,1,1); overlimit = COverlimitUtil.globalAssemble(voltageLevel, 10f, 10f, shortVal, 1, 1);
} }
@@ -939,7 +939,7 @@ public class HistoryResultServiceImpl implements HistoryResultService {
if (Integer.parseInt(normHistoryParam.getTargetCode()) != 60 || Integer.parseInt(normHistoryParam.getTargetCode()) != 61 || Integer.parseInt(normHistoryParam.getTargetCode()) != 62) { if (Integer.parseInt(normHistoryParam.getTargetCode()) != 60 || Integer.parseInt(normHistoryParam.getTargetCode()) != 61 || Integer.parseInt(normHistoryParam.getTargetCode()) != 62) {
stringBuilder.append(" and ").append(InfluxDBTableConstant.VALUE_TYPE + "='").append(valueTypeName).append("'"); stringBuilder.append(" and ").append(InfluxDBTableConstant.VALUE_TYPE + "='").append(valueTypeName).append("'");
} }
if(StrUtil.isNotBlank(phasicType)){ if (StrUtil.isNotBlank(phasicType)) {
stringBuilder.append(" and ").append("phasic_type ='").append(phasicType).append("'"); stringBuilder.append(" and ").append("phasic_type ='").append(phasicType).append("'");
} }
@@ -1160,6 +1160,7 @@ public class HistoryResultServiceImpl implements HistoryResultService {
throw new BusinessException(HarmonicResponseEnum.NO_DATA); throw new BusinessException(HarmonicResponseEnum.NO_DATA);
} }
//最新两条数据的间隔与监测点查出的间隔做对比,返回一个合理的间隔 //最新两条数据的间隔与监测点查出的间隔做对比,返回一个合理的间隔
historyData = historyData.stream().filter(Objects::nonNull).collect(Collectors.toList());
int lineInterval = getInterval(lineDetailData.getInterval(), PubUtils.instantToDate(historyData.get(historyData.size() - 1).getTime()), PubUtils.instantToDate(historyData.get(historyData.size() - 2).getTime())); int lineInterval = getInterval(lineDetailData.getInterval(), PubUtils.instantToDate(historyData.get(historyData.size() - 1).getTime()), PubUtils.instantToDate(historyData.get(historyData.size() - 2).getTime()));
historyData = dealHistoryData(historyData, lineInterval); historyData = dealHistoryData(historyData, lineInterval);
if (CollectionUtils.isEmpty(historyData)) { if (CollectionUtils.isEmpty(historyData)) {