ningshuxia
2025-04-03 4917fb959e2befec07a693e72d7010c09494ec7c
01-api/_Expand/IStation.Win.Schedule/bjMain.cs
@@ -1,4 +1,9 @@
using System.Text;
using IStation.Curve;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using System.Formats.Asn1;
using System.IO;
using System.Text;
using Yw.Untity;
namespace IStation.Win.Schedule
@@ -44,8 +49,8 @@
        private List<PumpScheduleVm> _pump_schedule_vm_list1 = null;
        private List<PumpScheduleVm> _pump_schedule_vm_list2 = null;
        private List<Model.Pump> _pump_list1 = new List<Model.Pump>();
        private List<Model.Pump> _pump_list2 = new List<Model.Pump>();
        private List<Model.Pump> _pump_list1 = new();
        private List<Model.Pump> _pump_list2 = new();
        private List<Model.ScheduleRequest> _schedule_request_list = null;
        private Dictionary<DateTime, List<Model.MonitorRecord>> _monitor_record_dict = null;
@@ -119,9 +124,7 @@
            if (this.barCekSimSchedule.Checked)
            {
                var target_flow1 = request.TargetFlow1;
                var target_flow2 = request.TargetFlow2;
                //var target_pressure1 = DoubleHelper.Mpa2M(request.TargetPressure1);
                //var target_pressure2 = DoubleHelper.Mpa2M(request.TargetPressure2);
                var target_flow2 = request.TargetFlow2;
                var target_pressure1 = Curve.PumpCalculateHelper.Mpa2M(request.TargetPressure1);
                var target_pressure2 = Curve.PumpCalculateHelper.Mpa2M(request.TargetPressure2);
@@ -136,6 +139,59 @@
                {
                    analysis_deviation_list = null;
                }
                if (this.barCekCalcFlowDiff.Checked)
                {
                    var ptList = new List<CurvePoint>();
                    try
                    {
                        var filePath = @"D:\WorkCode\Project\ChDt1\Schedule.Ch.V1.0\02-desktop\Desktop\IStation.Test\bin\Debug\net6.0-windows\csv\alow.csv";
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            reader.ReadLine();
                            string line;
                            while ((line = reader.ReadLine()) != null)
                            {
                                // 按逗号分隔每一行
                                string[] values = line.Split(',');
                                var xStr = values[0];
                                var yStr = values[1];
                                var pX = double.Parse(xStr);
                                var pY = double.Parse(yStr);
                                ptList.Add(new CurvePoint(pX, pY));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("读取文件时出错: " + ex.Message);
                    }
                    var x = ptList.Select(x => x.X).ToArray();
                    var y = ptList.Select(x => x.Y).ToArray();
                    // 多项式回归的阶数(例如,二次多项式)
                    int degree = 8;
                    // 拟合多项式回归模型
                    double[] coefficients = NonlinearRegressionHelper.FitPolynomial(x, y, degree);
                    // 使用模型进行预测
                    double xNew = target_pressure2;
                    double yPredicted = NonlinearRegressionHelper.PredictPolynomial(xNew, coefficients);
                    target_flow2 -= yPredicted;
                    AlertTool.ShowInfo(this,"预测缺失",$"{yPredicted}");
                    // 计算 R² 和 MSE
                    double rSquared = NonlinearRegressionHelper.CalculateRSquared(x, y, coefficients);
                    double mse = NonlinearRegressionHelper.CalculateMSE(x, y, coefficients);
                }
                GlobalHelper.GetStationOpenFlagList(monitor_record_list, out List<int> station1_open_flag_list, out List<int> station2_open_flag_list);
@@ -483,7 +539,7 @@
                            if (hz_item == null)
                            {
                                AlertTool.ShowInfo(this, "提示", $"{flag} 无法获取压差:{pressure_diff}");
                                //AlertTool.ShowInfo(this, "提示", $"{flag} 无法获取压差:{pressure_diff}");
                            }
@@ -620,6 +676,14 @@
        }
        private void barCekUseCalcDev_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var time = Convert.ToDateTime(this.barEditImgRealTime.EditValue);
            Schedule(_schedule_request);
            Verify(time);
        }
        private void barCekCalcFlowDiff_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var time = Convert.ToDateTime(this.barEditImgRealTime.EditValue);
            Schedule(_schedule_request);
@@ -1026,6 +1090,80 @@
        #endregion
        public class NonlinearRegressionHelper
        {
            // 多项式回归拟合
            public static double[] FitPolynomial(double[] x, double[] y, int degree)
            {
                // 构建设计矩阵
                Matrix<double> X = DenseMatrix.OfArray(new double[x.Length, degree + 1]);
                for (int i = 0; i < x.Length; i++)
                {
                    for (int j = 0; j <= degree; j++)
                    {
                        X[i, j] = Math.Pow(x[i], j);
                    }
                }
                // 构建目标向量
                Vector<double> Y = DenseVector.OfArray(y);
                // 使用最小二乘法求解
                var qr = X.QR();
                Vector<double> coefficients = qr.Solve(Y);
                return coefficients.ToArray();
            }
            // 使用多项式模型进行预测
            public static double PredictPolynomial(double x, double[] coefficients)
            {
                double prediction = 0.0;
                for (int i = 0; i < coefficients.Length; i++)
                {
                    prediction += coefficients[i] * Math.Pow(x, i);
                }
                return prediction;
            }
            // 计算 R²(决定系数)
            public static double CalculateRSquared(double[] x, double[] y, double[] coefficients)
            {
                double yMean = 0.0;
                double ssTotal = 0.0;
                double ssResidual = 0.0;
                for (int i = 0; i < y.Length; i++)
                {
                    yMean += y[i];
                }
                yMean /= y.Length;
                for (int i = 0; i < y.Length; i++)
                {
                    double yPredicted = PredictPolynomial(x[i], coefficients);
                    ssTotal += Math.Pow(y[i] - yMean, 2);
                    ssResidual += Math.Pow(y[i] - yPredicted, 2);
                }
                return 1.0 - (ssResidual / ssTotal);
            }
            // 计算 MSE(均方误差)
            public static double CalculateMSE(double[] x, double[] y, double[] coefficients)
            {
                double mse = 0.0;
                for (int i = 0; i < y.Length; i++)
                {
                    double yPredicted = PredictPolynomial(x[i], coefficients);
                    mse += Math.Pow(y[i] - yPredicted, 2);
                }
                return mse / y.Length;
            }
        }
    }
}