海南初始版本提交

This commit is contained in:
hzj
2024-03-06 17:04:08 +08:00
parent 34b76fe7ff
commit 4ed75512fb
66 changed files with 7663 additions and 33 deletions

View File

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

View File

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

File diff suppressed because it is too large Load Diff