海南初始版本提交
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
package com.njcn.advance.utils;
|
||||
|
||||
import org.apache.commons.math3.linear.DecompositionSolver;
|
||||
import org.apache.commons.math3.linear.LUDecomposition;
|
||||
import org.apache.commons.math3.linear.MatrixUtils;
|
||||
import org.apache.commons.math3.linear.RealMatrix;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CZNLPG {
|
||||
|
||||
private static final String DATA_CSV = "C:\\njcn\\pqs\\pqs-advance\\advance-boot\\src\\main\\resources\\test.csv";
|
||||
private static final int MAX_PRO_DATA_NUM = 5000;
|
||||
private static final int MAX_DATA_COL_NUM = 9;
|
||||
private static double[][] arr = new double[MAX_PRO_DATA_NUM][MAX_DATA_COL_NUM];
|
||||
|
||||
public static void main(String[] args) {
|
||||
double[] data_u = new double[MAX_PRO_DATA_NUM];
|
||||
double[] data_p = new double[MAX_PRO_DATA_NUM];
|
||||
double[] data_q = new double[MAX_PRO_DATA_NUM];
|
||||
|
||||
int data_num = parseCSV(DATA_CSV, data_u, data_p, data_q);
|
||||
System.out.println("data_num: " + data_num);
|
||||
|
||||
double[] res = new double[3];
|
||||
// cznlpgDataTrain(data_u, data_p, data_q, data_num, res);
|
||||
System.out.println("C = " + res[0] + " a = " + res[1] + " b = " + res[2]);
|
||||
}
|
||||
|
||||
private static int parseCSV(String path, double[] data_u, double[] data_p, double[] data_q) {
|
||||
int line = 0;
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
|
||||
String lines;
|
||||
while ((lines = br.readLine()) != null) {
|
||||
String[] tokens = lines.split(",");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
arr[line][i] = Double.parseDouble(tokens[i]);
|
||||
}
|
||||
|
||||
System.out.println("line " + line + ": ");
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
System.out.println("arr[" + line + "][" + i + "]=" + arr[line][i]);
|
||||
}
|
||||
|
||||
data_u[line] = arr[line][0];
|
||||
data_p[line] = arr[line][1];
|
||||
data_q[line] = arr[line][2];
|
||||
|
||||
line++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return line;
|
||||
}
|
||||
/*
|
||||
* 模型训练
|
||||
* */
|
||||
public static void cznlpgDataTrain(List<Double> u, List<Double> p, List<Double> q, int num, Double[] outRes) {
|
||||
if (num > MAX_PRO_DATA_NUM) {
|
||||
return;
|
||||
}
|
||||
|
||||
RealMatrix matPQ = MatrixUtils.createRealMatrix(num, 3);
|
||||
RealMatrix matU = MatrixUtils.createRealMatrix(num, 1);
|
||||
RealMatrix matW = MatrixUtils.createRealMatrix(3, 1);
|
||||
|
||||
// Matrix assignment
|
||||
for (int i = 0; i < num; i++) {
|
||||
matPQ.setEntry(i, 0, 1);
|
||||
matPQ.setEntry(i, 1, p.get(i));
|
||||
matPQ.setEntry(i, 2, q.get(i));
|
||||
|
||||
matU.setEntry(i, 0, u.get(i));
|
||||
}
|
||||
|
||||
System.out.println("matPQ=");
|
||||
printMatrix(matPQ);
|
||||
System.out.println("matPQ transpose=");
|
||||
printMatrix(matPQ.transpose());
|
||||
|
||||
// w = inv(PQ1'*PQ1)*PQ1'*U
|
||||
// U = 224.5133 - 2.3041e-5 * P - 1.1900e-4 * Q
|
||||
RealMatrix matPQT = matPQ.transpose();
|
||||
RealMatrix matInverse = inverseMatrix(matPQT.multiply(matPQ));
|
||||
matW = matInverse.multiply(matPQT).multiply(matU);
|
||||
|
||||
outRes[0] = matW.getEntry(0, 0);
|
||||
outRes[1] = matW.getEntry(1, 0);
|
||||
outRes[2] = matW.getEntry(2, 0);
|
||||
}
|
||||
|
||||
private static void printMatrix(RealMatrix matrix) {
|
||||
System.out.println(matrix);
|
||||
}
|
||||
|
||||
|
||||
//矩阵求逆
|
||||
|
||||
public static RealMatrix inverseMatrix(RealMatrix matrix) {
|
||||
LUDecomposition LUDe = new LUDecomposition(matrix);
|
||||
DecompositionSolver solver = LUDe.getSolver();
|
||||
RealMatrix result = solver.getInverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 负载率约束指标计算P_βmin和Q_βmin分别为近一周的配变每日9时~15时段的负载率数据中概率95%小值所对应时刻的有功功率和无功功率值;
|
||||
* S_T为配变额定容量;S_pv为拟接入光伏容量;k为修正系数 ,取值可参照如下。
|
||||
* 台区日照条件 k
|
||||
* 光照强度大于1250kWh/m^2 0.8~0.9
|
||||
* 光照强度小于1250kWh/m^2 0.75~0.8
|
||||
* 海南 0.8
|
||||
* @Param:
|
||||
* @return: double Loadrate
|
||||
* @Author: clam
|
||||
* @Date: 2024/1/26
|
||||
*/
|
||||
public static double calculateB(double P_βmin, double Q_βmin, double k, double S_T, double S_pv, double P_pv) {
|
||||
double term1 = Math.pow(P_βmin - k * S_T, 2);
|
||||
double term2 = Math.pow(Q_βmin, 2);
|
||||
double numerator = Math.sqrt(term1 + term2);
|
||||
if (P_βmin > P_pv) {
|
||||
return numerator / S_pv;
|
||||
} else {
|
||||
return -numerator / S_pv;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @Description: calculatePF_T 功率因数指标计算
|
||||
* @Param:
|
||||
* @return: double
|
||||
* @Author: clam
|
||||
* @Date: 2024/2/20
|
||||
*/
|
||||
public static double calculatePF_T(double P_βmin, double Q_βmin, double k, double S_pv) {
|
||||
double term1 = Math.pow(P_βmin - k * S_pv, 2);
|
||||
double term2 = Math.pow(Q_βmin, 2);
|
||||
double v = P_βmin - k * S_pv;
|
||||
double numerator = Math.sqrt(term1 + term2);
|
||||
|
||||
return v/numerator;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 总结:
|
||||
* p_min和 q_min能够根据测点数据获取得到;
|
||||
* S_pv为拟接入光伏容量,此部分需要现场选取好台区后获取。
|
||||
* k为修正系数,徐工提供海南k系数,是否需要考虑不同季节台区日照系数。
|
||||
* C、a、b需要用模型计算,是此算法中难点。
|
||||
* 结论:【拟接入光伏容量】为入参;【A/B/C相有功功率】和【A/B/C相无功功率值】95%小值从A/B/C相历史数据中计算得出; 为枚举参数;能够计算三相配变首端电压 、 、 ,从而得出U 。
|
||||
* 380v -U=C-a(p_min -k*S_pv/3)-b*q_min
|
||||
* 220v -U=C-a(p_min -k*S_pv)-b*q_min
|
||||
*
|
||||
* @Param:
|
||||
* @return: double
|
||||
* @Author: clam
|
||||
* @Date: 2024/2/2
|
||||
*/
|
||||
public static double calculateU(double C, double a, double b, double p_min, double K, double q_min,double S_pv, double voltage) {
|
||||
|
||||
if (voltage == 220) {
|
||||
return C-a*(p_min-K*S_pv)-b*q_min;
|
||||
} else if (voltage == 380) {
|
||||
return C-a*(p_min-K*S_pv/3)-b*q_min;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* I_(stock,h)为台区一周内的h次谐波电流95%概率大值,I_"inv" ^h%为光伏逆变器第h次的典型谐波电流含有率;
|
||||
* S_pv为拟接入光伏容量,此部分需要现场选取好台区后获取。
|
||||
* k为修正系数,徐工提供海南k系数,是否需要考虑不同季节台区日照系数。
|
||||
* 结论:【电压等级】为入参;I_(stock,h)为台区一周内的h次谐波电流95%概率大值,I_"inv" ^h%为光伏逆变器第h次的典型谐波电流含有率,
|
||||
* 为枚举参数;k为枚举参数;能够计算各次的谐波电流幅值 、 、 ,从而得出 。
|
||||
*/
|
||||
public static double calculateITm(double I_cp95, double k, double voltage, double S_pv, double K, double I_inv) {
|
||||
double term1 = Math.pow(I_cp95, 2);
|
||||
double term2 = 0, term3 = 0;
|
||||
if (voltage == 220) {
|
||||
term2 = Math.pow(k * S_pv * I_inv / 220, 2);
|
||||
term3 = K * I_cp95 * (k * S_pv * I_inv / 220);
|
||||
} else if (voltage == 380) {
|
||||
term2 = Math.pow(k * S_pv * I_inv / 3 * 220, 2);
|
||||
term3 = K * I_cp95 * (k * S_pv * I_inv / 3 * 220);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double sumOfTerms = term1 + term2 + term3;
|
||||
|
||||
return Math.sqrt(sumOfTerms);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: evaluateVoltageLevel 根据规则评估配变首端电压等级
|
||||
* @Param:
|
||||
* @return: int
|
||||
* @Author: clam
|
||||
* @Date: 2024/1/30
|
||||
*/
|
||||
public static int evaluateVoltageLevel(double voltage) {
|
||||
if (voltage <= 235.4) {
|
||||
return 1; // 安全
|
||||
} else if (voltage > 235.4 && voltage <= 253.0) {
|
||||
return 2; // Ⅲ级预警
|
||||
} else if (voltage > 253.0 && voltage < 260.0) {
|
||||
return 3; // Ⅱ级预警
|
||||
} else {
|
||||
return 4; // Ⅰ级预警
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: evaluatePowerFactorLevel // 根据规则评估功率因数等级
|
||||
* @Param:
|
||||
* @return: int
|
||||
* @Author: clam
|
||||
* @Date: 2024/1/30
|
||||
*/
|
||||
public static int evaluatePowerFactorLevel(double powerFactor) {
|
||||
if (powerFactor >= 0.9) {
|
||||
return 1; // 安全
|
||||
} else if (powerFactor >= 0.85 && powerFactor < 0.9) {
|
||||
return 2; // Ⅲ级预警
|
||||
} else if (powerFactor >= 0.8 && powerFactor < 0.85) {
|
||||
return 3; // Ⅱ级预警
|
||||
} else {
|
||||
return 4; // Ⅰ级预警
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: / 根据规则评估等效负载率等级
|
||||
* @Param:
|
||||
* @return: int
|
||||
* @Author: clam
|
||||
* @Date: 2024/1/30
|
||||
*/
|
||||
public static int evaluateEquivalentLoadRateLevel(double equivalentLoadRate) {
|
||||
if (equivalentLoadRate >= 0.0) {
|
||||
return 1; // 安全
|
||||
} else if (equivalentLoadRate >= -40.0 && equivalentLoadRate < 0.0) {
|
||||
return 2; // Ⅲ级预警
|
||||
} else if (equivalentLoadRate >= -80.0 && equivalentLoadRate < -40.0) {
|
||||
return 3; // Ⅱ级预警
|
||||
} else {
|
||||
return 4; // Ⅰ级预警
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Description: 判断O:各项指标是否均为“安全” 安全接入
|
||||
* 判断2: 至多2项指标达到“III级预警”,其余指标均为“安全” 3接入预警
|
||||
* @: 超过2项指标达到“III级预警”且无“II级预警”及以上的指标:或至多1项指标达到“I 级预警且其余指标均为“安全” 2接入预警
|
||||
* 判断@: 至多2项指标达到“II 级预警”且其余指标均为“安全”: 或至多1项指标达到“II级预警”且其余指标存在“III级预警” 1级接入预警
|
||||
* 否则 限制接入
|
||||
* @Param:
|
||||
* @return:
|
||||
* @Author: clam
|
||||
* @Date: 2024/1/30
|
||||
*/
|
||||
public static int evaluateG(List<Integer> indicators) {
|
||||
long count1 = indicators.stream().filter(i -> i == 1).count();
|
||||
long count2 = indicators.stream().filter(i -> i == 2).count();
|
||||
long count3 = indicators.stream().filter(i -> i == 3).count();
|
||||
if (count1 == 4) {
|
||||
return 1;
|
||||
} else if (count2 <= 2 && count2 + count1 == 4) {
|
||||
return 2;
|
||||
} else if ((count2 >= 2 && count2 + count1 == 4) || (count3 == 1 && count1 == 3)) {
|
||||
return 3;
|
||||
} else if ((count3 <= 2 && count1 + count3 == 4) || (count3 == 1 && count2 >= 1 && count1 + count2 == 3)) {
|
||||
return 4;
|
||||
} else {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算一组数据的最大95概率值,最小95概率值 入参一组double集合,一个flag表示计算类型 返回double
|
||||
*
|
||||
* @param data
|
||||
* @param type 0 最大95概率值 1 最小95概率值
|
||||
* @return
|
||||
*/
|
||||
public static double calculatePercentile(List<Double> data, Integer type) {
|
||||
// 对数组进行排序
|
||||
// 正序排序
|
||||
Collections.sort(data);
|
||||
int index =0;
|
||||
if (type == 0) {
|
||||
// 计算最大95%概率值的索引
|
||||
index =(int) Math.ceil(0.95 * data.size()) ;
|
||||
} else if (type == 1) {
|
||||
// 计算最小95%概率值的索引
|
||||
index = (int) Math.ceil(0.05 * data.size()) - 1;
|
||||
}
|
||||
|
||||
// 根据计算类型返回相应的值
|
||||
return data.get(index);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ package com.njcn.advance.utils;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -99,4 +102,34 @@ public class Utils {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// 辅助方法:检查时间是否在指定范围内
|
||||
public static boolean isTimeInRange(Instant instant, LocalTime startTime, LocalTime endTime) {
|
||||
LocalTime localTime = instant.atZone(Instant.now().atZone(java.time.ZoneId.systemDefault()).getZone()).toLocalTime();
|
||||
return !localTime.isBefore(startTime) && !localTime.isAfter(endTime);
|
||||
}
|
||||
|
||||
public static <T> List<Double> getAttributeValueByPropertyName(List<T> list, String propertyName) {
|
||||
List<Double> resultList = new ArrayList<>();
|
||||
for (T item : list) {
|
||||
try {
|
||||
Field field = item.getClass().getDeclaredField(propertyName);
|
||||
field.setAccessible(true);
|
||||
resultList.add((Double) field.get(item));
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
public static <T> Double getAttributeValueByPropertyName(T item, String propertyName) {
|
||||
Double result = null;
|
||||
try {
|
||||
Field field = item.getClass().getDeclaredField(propertyName);
|
||||
field.setAccessible(true);
|
||||
result=(Double) field.get(item);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
2524
pqs-advance/advance-boot/src/main/java/com/njcn/advance/utils/sql
Normal file
2524
pqs-advance/advance-boot/src/main/java/com/njcn/advance/utils/sql
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user