Browse Source

Merge branch 'master' of http://124.70.43.205:3000/xieshengjie/sis-background

chenminghua 2 years ago
parent
commit
fa6c366cf2

+ 30 - 3
power-fitting/pom.xml

@@ -29,9 +29,30 @@
         </dependency>
 
         <dependency>
-            <groupId>com.oracle</groupId>
-            <artifactId>ojdbc6</artifactId>
-            <version>11.2.0.3</version>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.1.1</version>
+        </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>com.oracle</groupId>-->
+<!--            <artifactId>ojdbc6</artifactId>-->
+<!--            <version>11.2.0.3</version>-->
+<!--        </dependency>-->
+
+        <!--oracle驱动-->
+        <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
+        <dependency>
+            <groupId>com.oracle.database.jdbc</groupId>
+            <artifactId>ojdbc8</artifactId>
+            <version>19.7.0.0</version>
+        </dependency>
+
+        <!-- oracle字符集  https://mvnrepository.com/artifact/cn.easyproject/orai18n -->
+        <dependency>
+            <groupId>cn.easyproject</groupId>
+            <artifactId>orai18n</artifactId>
+            <version>12.1.0.2.0</version>
         </dependency>
 
         <dependency>
@@ -64,6 +85,12 @@
             <optional>true</optional>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-math3</artifactId>
+            <version>3.6.1</version>
+        </dependency>
+
 
         <!--http请求-->
         <dependency>

+ 465 - 0
power-fitting/src/main/java/com/gyee/power/fitting/common/alg/MpptFittingAlg.java

@@ -0,0 +1,465 @@
+package com.gyee.power.fitting.common.alg;
+
+//package easyexcel;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+//绘制曲线需要
+import  java.awt.*;
+import  javax.swing.*;
+import  java.awt.geom.GeneralPath;
+
+
+import com.gyee.power.fitting.model.custom.LineCurveFitting;
+import com.gyee.power.fitting.model.custom.PointVo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import java.math.BigDecimal;
+
+import org.apache.commons.math3.fitting.PolynomialCurveFitter;
+import org.apache.commons.math3.fitting.WeightedObservedPoints;
+
+
+/**
+ * I-V曲线拟合算法
+ * 最小二乘法
+ */
+public class MpptFittingAlg {
+
+
+    public static List<PointVo> BuildLine_IV_LSC(double[] arrX, double[] arrY, int length, int dimension, double scale){
+
+        List<PointVo> points = new ArrayList<>();
+
+        if(arrX.length != arrY.length || arrX.length < 3){
+            return points;
+        }
+
+        double minValue = arrY[arrY.length - 1];
+        double maxValue = arrY[0];
+
+        double min = 0;
+        double max = 0;
+
+        double[] coefficient = MultiLine(arrX, arrY, length, dimension);
+
+        for (double i = arrX[arrX.length - 1]; i > arrX[0]; i -= scale) {
+            PointVo point = new PointVo();
+            point.setX(i);
+
+            for (int j = 0; j < coefficient.length; j++) {
+                if (j == 0) {
+                    point.setY(coefficient[j] * Math.pow(point.getX(), j));
+                } else {
+                    double temp = coefficient[j] *Math.pow(point.getX(), j);
+                    point.setY(point.getY() + temp);
+                }
+            }
+
+            if (point.getY() < minValue) {
+                point.setY(minValue);
+
+
+            }
+            if (point.getY() > maxValue) {
+                point.setY(maxValue);
+
+            }
+
+            if (point.getY() < min) {
+                min = point.getY();
+            }
+            if (point.getY() > max) {
+                max = point.getY();
+            }
+
+            points.add(point);
+        }
+        Builder(points, min, max);
+        System.out.print("X轴数据\n");
+        int len = points.size();
+        double[] aX = new double[len];
+        for (int i = len-1; i >0; i --){
+            aX[i] = points.get(i).getX();
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("\n");
+        System.out.print("Y轴数据\n");
+
+        double[] aY = new double[len];
+        for(int i = len-1;i >0; i--){
+            aY[i] = points.get(i).getY();
+            System.out.print(aY[i]+",");
+            System.out.print("\n");
+        }
+
+        return points;
+    }
+    /**
+     * P-V曲线拟合算法
+     * 最小二乘法
+     */
+    public static List<PointVo> BuildLine_PV_LSC(double[] arrX, double[] arrY, int length, int dimension, double scale){
+
+        List<PointVo> points = new ArrayList<>();
+
+        if(arrX.length != arrY.length || arrX.length < 3){
+            return points;
+        }
+
+        double minValue = arrY[0];
+        double maxValue = 0;
+        for(int i = 0 ;i < arrY.length; i++){
+            double val = arrY[i];
+            if(val > maxValue){
+                maxValue = val;
+            }
+        }
+
+        double min = 0;
+        double max = 0;
+
+        double[] coefficient = MultiLine(arrX, arrY, length, dimension);
+
+        for (double i = arrX[arrX.length - 1]; i > arrX[0]; i -= scale) {
+            PointVo point = new PointVo();
+            point.setX(i);
+
+            for (int j = 0; j < coefficient.length; j++) {
+                if (j == 0) {
+                    point.setY(coefficient[j] * Math.pow(point.getX(), j));
+                } else {
+                    double temp = coefficient[j] *Math.pow(point.getX(), j);
+                    point.setY(point.getY() + temp);
+                }
+            }
+
+            if (point.getY() < minValue) {
+                point.setY(minValue);
+
+
+            }
+            if (point.getY() > maxValue) {
+                point.setY(maxValue);
+
+            }
+
+            if (point.getY() < min) {
+                min = point.getY();
+            }
+            if (point.getY() > max) {
+                max = point.getY();
+            }
+
+            points.add(point);
+        }
+        Builder(points, min, max);
+        System.out.print("X轴数据\n");
+        int len = points.size();
+        double[] aX = new double[len];
+        for (int i = len-1; i >0; i --){
+            aX[i] = points.get(i).getX();
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("\n");
+        System.out.print("Y轴数据\n");
+
+        double[] aY = new double[len];
+        for (int i = len-1;i >0; i--){
+            aY[i] = points.get(i).getY();
+            System.out.print(aY[i]+",");
+            System.out.print("\n");
+        }
+
+        return points;
+    }
+
+    private static void Builder(List<PointVo> points, double min, double max) {
+        boolean b = false;
+        for (int i = 0; i < points.size(); i++) {
+            if (b) {
+                points.get(i).setY(max);
+            } else {
+                if (max == points.get(i).getY()) {
+                    b = true;
+                }
+            }
+
+        }
+        for (int i = points.size() - 1; i > -1; i--) {
+            if (!b) {
+                points.get(i).setY(min);
+            } else {
+                if (min == points.get(i).getY()) {
+                    b = false;
+                }
+            }
+        }
+    }
+
+    private static double[] MultiLine(double[] arrX, double[] arrY, int length,int dimension)
+    {
+        int n = dimension + 1;                  //dimension次方程需要求 dimension+1个 系数
+        double[][] Guass = new double[n][n + 1];      //高斯矩阵 例如:y=a0+a1*x+a2*x*x
+        for (int i = 0; i < n; i++) {
+            int j;
+            for (j = 0; j < n; j++) {
+                Guass[i][j] = SumArr(arrX, j + i, length);
+            }
+            Guass[i][j] = SumArr(arrX, i, arrY, 1, length);
+        }
+        return ComputGauss(Guass, n);
+    }
+
+    private static double SumArr(double[] arr, int n, int length) //求数组的元素的n次方的和
+    {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if (arr[i] != 0 || n != 0)
+                s = s + Math.pow(arr[i], n);
+            else
+                s = s + 1;
+        }
+        return s;
+    }
+
+    private static double SumArr(double[] arr1, int n1, double[] arr2, int n2, int length) {
+        double s = 0;
+        for (int i = 0; i < length; i++) {
+            if ((arr1[i] != 0 || n1 != 0) && (arr2[i] != 0 || n2 != 0))
+                s = s + Math.pow(arr1[i], n1) * Math.pow(arr2[i], n2);
+            else
+                s = s + 1;
+        }
+        return s;
+
+    }
+
+    private static double[] ComputGauss(double[][] Guass, int n) {
+        int i, j;
+        int k, m;
+        double temp;
+        double max;
+        double s;
+        double[] x = new double[n];
+        for (i = 0; i < n; i++) x[i] = 0.0;//初始化
+
+        for (j = 0; j < n; j++) {
+            max = 0;
+            k = j;
+            for (i = j; i < n; i++) {
+                if (Math.abs(Guass[i][j]) > max) {
+                    max = Guass[i][j];
+                    k = i;
+                }
+            }
+
+
+            if (k != j) {
+                for (m = j; m < n + 1; m++) {
+                    temp = Guass[j][m];
+                    Guass[j][m] = Guass[k][m];
+                    Guass[k][m] = temp;
+                }
+            }
+            if (0 == max) {
+                // "此线性方程为奇异线性方程"
+                return x;
+            }
+
+            for (i = j + 1; i < n; i++) {
+                s = Guass[i][j];
+                for (m = j; m < n + 1; m++) {
+                    Guass[i][m] = Guass[i][m] - Guass[j][m] * s / (Guass[j][j]);
+                }
+            }
+
+        }//结束for (j=0;j<n;j++)
+
+        for (i = n - 1; i >= 0; i--) {
+            s = 0;
+            for (j = i + 1; j < n; j++) {
+                s = s + Guass[i][j] * x[j];
+            }
+            x[i] = (Guass[i][n] - s) / Guass[i][i];
+        }
+        return x;
+    }//返回值是函数的系数
+
+
+
+    /**
+     * P-V曲线拟合算法
+     * 多项式曲线拟合
+     * @param arrX --功率(P)值
+     * @param arrY  --电流(I)值
+     * @param order 进行拟合的阶数
+     */
+
+    public static List<PointVo> BuildLine_PV_Poly(double[] arrX, double[] arrY, int order) {
+
+        double[] aX = new double[10];
+
+        double maxValue = 0;
+        for(int i = 0 ;i < arrX.length; i++){
+            double val = arrX[i];
+            if(val > maxValue){
+                maxValue = val;
+            }
+        }
+        double scale = 0.1;
+        int ylen = (int)(maxValue/scale);
+
+        double[] aY = new double[ylen];
+        for(int i = 0; i< arrX.length; i++){
+            aX[i] = arrX[i];
+        }
+        PointVo point = new PointVo();
+        List<PointVo> points = new ArrayList<>();
+
+        // N阶多项式会有N+1个系数,其中之一为常数项
+        double[] factor = new double[order + 1];
+        for(int index = 0; index < factor.length; index++) {
+            factor[index] = index + 1;
+        }
+        for(int index = 0; index < arrY.length; index++) {
+            arrX[index] = index * 0.00001;
+            arrY[index] = calcPoly(arrX[index], factor); // y = sum(x[n) * fact[n])
+
+        }
+
+        //调用将arrX和arrY序列中的数据逐个添加到观察点序列对象中
+        WeightedObservedPoints point1 = new WeightedObservedPoints();
+        for(int index = 0; index < arrX.length; index++) {
+            point1.add(arrX[index], arrY[index]);
+        }
+       // 创建PolynomialCurveFitter对象,需指定拟合多项式的阶数
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order);
+
+        List<Object> params = new ArrayList<Object>();
+        params.add(point1);
+       // 调用PolynomialCurveFitter的fit方法进行多项式曲线拟合
+        WeightedObservedPoints point2 = (WeightedObservedPoints)params.get(0);
+     //   拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。
+        double[] result = fitter.fit(point2.toList());//例如 3,4,2,6 y=3*x^3+4*x^2+2*x+6
+
+       // String y = printPoly(result);
+        int k = result.length - 1;
+        System.out.print("X轴数据\n");
+        for(int i = 0;i < aX.length; i++){
+            System.out.print(aX[i]+",");
+            System.out.print("\n");
+        }
+        System.out.print("Y轴数据\n");
+
+        int q = 0;
+
+        for (double i = aX[aX.length - 1]; i > aX[0]; i -= scale) {
+
+            for (int j = 0; j < result.length; j++) {
+                if (j == 0) {
+                    aY[q] = result[k];
+                } else {
+                    aY[q] += Math.pow(arrX[q], j) * result[k - j];
+                }
+            }
+            System.out.print(aY[q]+",");
+            System.out.print("\n");
+            q++;
+        }
+        return points;
+    }
+
+    /**
+     * P-V曲线拟合算法
+     * 多项式曲线拟合
+     *
+     * @param arrX --电压(V)值
+     * @param arrY  --电流(I)值
+     * @param order 进行拟合的阶数
+     */
+
+    public static List<PointVo> BuildLine_IV_Poly(double[] arrX, double[] arrY, int order) {
+
+        PointVo point = new PointVo();
+        List<PointVo> points = new ArrayList<>();
+
+        // N阶多项式会有N+1个系数,其中之一为常数项
+        double[] factor = new double[order + 1];
+        for(int index = 0; index < factor.length; index++)
+        {
+            factor[index] = index + 1;
+        }
+        for(int index = 0; index < arrY.length; index++)
+        {
+            arrX[index] = index * 0.00001;
+            arrY[index] = calcPoly(arrX[index], factor); // y = sum(x[n) * fact[n])
+        }
+        //调用将arrX和arrY序列中的数据逐个添加到观察点序列对象中
+        WeightedObservedPoints point1 = new WeightedObservedPoints();
+        for(int index = 0; index < arrX.length; index++)
+        {
+            point1.add(arrX[index], arrY[index]);
+        }
+        // 创建PolynomialCurveFitter对象,需指定拟合多项式的阶数
+        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(order);
+
+        List<Object> params = new ArrayList<Object>();
+        params.add(point1);
+        // 调用PolynomialCurveFitter的fit方法进行多项式曲线拟合
+        WeightedObservedPoints point2 = (WeightedObservedPoints)params.get(0);
+        //   拟合结果通过一个double数组返回,按元素顺序依次是常数项、一次项、二次项、……。
+        double[] result = fitter.fit(point2.toList());//例如 3,4,2,6 y=3*x^3+4*x^2+2*x+6
+
+        int k = result.length - 1;
+        for (int i = 0 ; i <= arrX[arrX.length - 1]; i++) {
+            for (int j = 0; j < result.length; j++) {
+                if (j == 0) {
+                    arrY[i] = result[k];
+                    break;
+                }
+                arrY[i] += Math.pow(arrX[i], j) * result[k - j];
+            }
+            point.setX(arrX[i]);
+            point.setX(arrY[i]);
+            points.add(point);
+        }
+
+        return points;
+    }
+
+    public static double calcPoly(double x, double[] factor)
+    {
+        double y = 0;
+        for(int deg = 0; deg < factor.length; deg++)
+        {
+            y += Math.pow(x, deg) * factor[deg];
+        }
+        return y;
+    }
+    public static String printPoly(double[] result) {
+
+        String polynomialString = "";
+        for (int i = 0; i < result.length; i++) {
+            if (i == 0) {
+                polynomialString += result[i];
+                break;
+            }
+            polynomialString += result[i] + "x^" + i + " ";
+        }
+        return polynomialString;
+    }
+}
+
+

+ 66 - 0
power-fitting/src/test/java/AlgTest.java

@@ -0,0 +1,66 @@
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.gyee.power.fitting.common.alg.MpptFittingAlg;
+
+import java.util.*;
+
+public class AlgTest {
+
+    public static void main(String[] args){
+        double[] arrX = new double[10];
+        double[] arrY = new double[10];
+        importdata_1("data1", arrX);
+        importdata_1("data2", arrY);
+
+        int order = 2;
+        double[] result = new double[3];
+    //   MpptFittingAlg.BuildLine_PV_Poly(arrX,arrY,order);
+       MpptFittingAlg.BuildLine_PV_LSC(arrX,arrY,10,10,0.1);
+      //  MpptFittingAlg.BuildLine_IV_LSC(arrX,arrY,10,10,0.1);
+    }
+
+    /**
+     * 从execl中导入数据
+     */
+    public static void importdata_1(String sheet, final double[] data)
+    {
+        int i=0;
+        List<Map<Integer,String>> list = new LinkedList<>(); //初始化列表
+
+        EasyExcel.read("D:/JavaCode/WTest.xlsx") //文件路径
+                .sheet(sheet) //表单名
+                .registerReadListener(new AnalysisEventListener<Map<Integer,String>>() { //监听器,以行的形式读取Excel
+
+                    //一行一行读取Excel,在这里处理读取到的数据
+                    @Override
+                    public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
+                        // TODO Auto-generated method stub
+                        list.add(integerStringMap); //将读取到的每一行为一组存入列表中
+                    }
+
+                    //数据读取完毕后运行下面
+                    @Override
+                    public void doAfterAllAnalysed(AnalysisContext context) {
+                        System.out.println("数据读取完毕");
+                    }
+                }).headRowNumber(1).doRead(); //headRowNumber(num)为指定前num行为表头,从num+1开始读,默认为1
+
+        //遍历列表存储数据
+        for (Map<Integer, String> integerStringMap : list)
+        {
+            Set<Integer> keySet =integerStringMap.keySet();
+            Iterator<Integer> iterator = keySet.iterator();
+            while (iterator.hasNext())
+            {
+                Integer key = iterator.next();
+                Double val = Double.valueOf(integerStringMap.get(key));
+                System.out.print(val+",");
+                data[i++] = val;
+            }
+        }
+        System.out.println();
+        System.out.println(i+"条数据已导入");
+    }
+
+}