tangxu
2024-12-19 9acdf3c826311bd67180821ce19c625d0e384ca8
Calc/IStation.Calc.Core/¼ÆËã»ùÀà/ErQuCalcBaseHelper.cs
@@ -1,23 +1,90 @@
using IStation.CalcModel;
using IStation.CalcModel;
using IStation.Model;
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
namespace IStation.Calc
{
    internal partial class ErQuCalcBaseHelper
    {
        protected int _maxOpenPumpCount = 4;//最大开泵数量
        /// <summary>
        ///
        ///
        /// </summary>
        /// <returns></returns>
        public static IStation.Calc.ErQuCalcBaseHelper Build()
        public static IStation.Calc.ErQuCalcBaseHelper Build(IStation.CalcModel.AnaRequest anaRequest)
        {
            return new IStation.Calc.ErQuCalcHelper_2_递归();
            if (anaRequest.MaxReservoirLevel != null)
            {
                DateTime? limit_time = GetMaxReservoirLevelTime(anaRequest);
                if (limit_time == null)
                {
                    var calc = new IStation.Calc.ErQuCalcHelper_2_递归_定水位_任意时间();
                    calc.SetMaxReservoirHeight(anaRequest.MaxReservoirLevel.Value);
                    return calc;
                }
                else
                {
                    var calc = new IStation.Calc.ErQuCalcHelper_2_递归_定水位_指定时间();
                    calc.SetMaxReservoirHeight(anaRequest.MaxReservoirLevel.Value, limit_time.Value);
                    return calc;
                }
            }
            else
            {
                return new IStation.Calc.ErQuCalcHelper_2_递归_定水量();
            }
        }
        private static DateTime? GetMaxReservoirLevelTime(IStation.CalcModel.AnaRequest anaRequest)
        {
            if (string.IsNullOrEmpty(anaRequest.MaxReservoirLevelTime))
            {
                return null;
            }
            DateTime time;
            if (DateTime.TryParse(anaRequest.MaxReservoirLevelTime, out time))
            {
                return time;
            }
            if (anaRequest.MaxReservoirLevelTime.Contains(":"))
            {
                var sss = anaRequest.MaxReservoirLevelTime.Split(':');
                if (sss.Count() == 2)
                {
                    int hour = 0;
                    int miut = 0;
                    if (int.TryParse(sss[0], out hour) && int.TryParse(sss[1], out miut))
                    {
                        if (hour < anaRequest.StartTime.Hour)
                            return new DateTime(anaRequest.EndTime.Year, anaRequest.EndTime.Month, anaRequest.EndTime.Day, hour, miut, 0);
                        else
                            return new DateTime(anaRequest.StartTime.Year, anaRequest.StartTime.Month, anaRequest.StartTime.Day, hour, miut, 0);
                    }
                }
            }
            else
            {
                int hour = 0;
                if (int.TryParse(anaRequest.MaxReservoirLevelTime, out hour))
                {
                    if (hour < anaRequest.StartTime.Hour)
                        return new DateTime(anaRequest.EndTime.Year, anaRequest.EndTime.Month, anaRequest.EndTime.Day, hour, 0, 0);
                    else
                        return new DateTime(anaRequest.StartTime.Year, anaRequest.StartTime.Month, anaRequest.StartTime.Day, hour, 0, 0);
                }
            }
            return null;
        }
        /// <summary>
        ///
        ///
        /// </summary>
        public class RunBlock
        {
@@ -31,18 +98,26 @@
        }
        /// <summary>
        ///
        ///
        /// </summary>
        protected ErQuCalcBaseHelper()
        {
            _calStartTime = DateTime.Now;
            _calEndTime = DateTime.Now.AddDays(1);
            var calStartTime = DateTime.Now;
            _calStartTime =  new DateTime(calStartTime.Year, calStartTime.Month, calStartTime.Day, calStartTime.Hour, 0, 0);
            _calEndTime = _calStartTime.AddDays(1);
        }
        public void SetCalcTimeRange(DateTime calStartTime, DateTime calEndTime)
        public void SetCalcTimeRange(DateTime calStartTime, DateTime calEndTime,int calcSpaceMinute)
        {
            this._calStartTime = calStartTime;
            this._calEndTime = calEndTime;
            if (calcSpaceMinute <= 1)
            {
                calcSpaceMinute = 10;
            }
            this._calcSpaceMinute = calcSpaceMinute;
            this._calStartTime = new DateTime(calStartTime.Year, calStartTime.Month, calStartTime.Day, calStartTime.Hour, ((int)(calStartTime.Minute/ calcSpaceMinute)) * calcSpaceMinute, 0);
            this._calEndTime = new DateTime(calEndTime.Year, calEndTime.Month, calEndTime.Day, calEndTime.Hour, ((int)(calEndTime.Minute / calcSpaceMinute)) * calcSpaceMinute, 0);
        }
        //
        public Action<string> OnShowDebugInfo = null;
@@ -50,52 +125,64 @@
        protected IStation.CalcModel.eCalcOptType _clacOptType = CalcModel.eCalcOptType.功率;
        /// <summary>
        ///
        ///
        /// </summary>
        protected double _stationTotalFlow=0;//供水总量(不一定有值 å•位: å¨)
        protected double _flowInTotalFlow = 0;//取水总量(不一定有值 å•位: å¨)
        /// <summary>
        ///
        ///
        /// </summary>
        /// <param name="anaRequest"></param>
        public void SetAnaRequest(IStation.CalcModel.AnaRequest anaRequest)
        {
            this._start_level水库水位 = anaRequest.CurrentWaterBoxLevel;
            this._startOpenCount = anaRequest.StartOpenCount;
            this._start_level水库水位 = anaRequest.StartReservoirLevel;
            this._clacOptType = anaRequest.CalcOptType;
            if (anaRequest.MinLimitWaterBoxLevel != null &&
               anaRequest.MaxLimitWaterBoxLevel != null)
            if (anaRequest.IsKnownStartOpenPump)
            {
                this._isHaveLevelLimit = true;
                this._min_level水库水位 = anaRequest.MinLimitWaterBoxLevel.Value;
                this._max_level水库水位 = anaRequest.MaxLimitWaterBoxLevel.Value;
                if (anaRequest.StartOpenPumpIndexArray == null)
                {//没有赋值就是表示不知道, å¦‚果都不开机, èµ‹å€¼[]
                    this._startOpenPumpCount = -1;
                }
                else
                {
                    this._startOpenPumpArray = anaRequest.StartOpenPumpIndexArray;
                    this._startOpenPumpCount = anaRequest.StartOpenPumpIndexArray.Count;
                }
            }
            else
            {
                this._startOpenPumpCount = -1;
            }
            if (anaRequest.TotalFlowIn != null)
                this._flowInTotalFlow = anaRequest.TotalFlowIn.Value;
            if (anaRequest.TotalFlow取水总量 != null)
                this._stationTotalFlow = anaRequest.TotalFlow取水总量.Value;
            this.Initial水库参数(anaRequest);
            this.Initial水库参数(anaRequest);
            this.SetRiverWaterLevels(anaRequest.WaterLevels长江);
        }
        /// <summary>
        /// è®¡ç®—最优
        /// </summary>
        /// <param name="TargetFlowTotal"></param>
        /// <param name="error_info"></param>
        /// <returns></returns>
        public virtual List<AnaPrj> CalcOptPrjs(out string error_info)
        public virtual AnaPrj CalcOptPrj(out string error_info)
        {
            error_info = null;
            #region æ£€æŸ¥æ•°æ®
            if (this._calStartTime >= this._calEndTime)
            {
                error_info = "时间范围不对";
                return null;
            }
            if (this._allPumpInfo == null || this._allPumpInfo.Count() != 5)
            {
                error_info = "泵台数不正确";
@@ -116,30 +203,23 @@
                    return null;
                }
            }
            #endregion
            #endregion æ£€æŸ¥æ•°æ®
            List<AnaPrj> listPrj;
            System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
            sw2.Start();
            // List<AnaPrj> listPrj;
            //System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch();
            //sw2.Start();
            //迭代浮动, ä¸è¦æ¯æ¬¡éƒ½ä»Ž0开始, å¯èƒ½å·®å‡ åˆ†é’Ÿæ›´ä¼˜, åŽé¢æ­¤å˜é‡ä¹Ÿè¦è¿­ä»£
            int dd_minute = 0;
            //
            CalcTimeData(dd_minute);
            // çœŸæ­£å¼€å§‹åˆ†æž
            listPrj = CalcOptPrjsCore();
            sw2.Stop();
            // çœŸæ­£å¼€å§‹åˆ†æž
            var optPrj = CalcOptPrjsCore();
            //sw2.Stop();
            var seconds = (int)(sw2.ElapsedMilliseconds / 1000);
            //var seconds = (int)(sw2.ElapsedMilliseconds / 1000);
            //故意加1分钟
            //if (this._calcSpaceMinute >= 5)
            //{
@@ -152,54 +232,51 @@
            //    Thread.Sleep(20 * 1000);
            //}
            if (listPrj == null || listPrj.Count == 0)
            if (optPrj == null)
            {
                error_info = "未找到合适的调度方案";
                return null;
            }
            foreach(var prj in listPrj)
            {
                prj.StartTime = this._calStartTime;
                prj.EndTime = this._calEndTime;
            }
            optPrj.StartTime = this._calStartTime;
            optPrj.EndTime = this._calEndTime;
            OnShowDebugInfo.Invoke(string.Format("计算用时: {0} ç§’", seconds));
            // OnShowDebugInfo.Invoke(string.Format("计算用时: {0} ç§’", seconds));
            return listPrj;
            return optPrj;
        }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <returns></returns>
        protected virtual List<AnaPrj> CalcOptPrjsCore()
        protected virtual AnaPrj CalcOptPrjsCore()
        {
            return null;
        }
        /// <summary>
        ///
        ///
        /// </summary>
        protected ulong _totalCalcCount = 0;//计算次数
        protected ulong _totalCacheCount = 0;//缓存使用次数
        //时间范围
        protected DateTime _calStartTime;
        protected DateTime _calEndTime;
        protected DateTime _calEndTime;
        //泵信息
        internal List<IStation.CalcModel.PumpCurveInfo> _allPumpInfo = null;
        public void SetPumpInfo(List<IStation.CalcModel.PumpInfo> allPumpInfo)
        {
            if (allPumpInfo == null)
                return;
            this._allPumpInfo = new List<CalcModel.PumpCurveInfo>();
            for(int k=0;k<allPumpInfo.Count;k++)
            for (int k = 0; k < allPumpInfo.Count; k++)
            {
                var pump = allPumpInfo[k];
@@ -222,37 +299,53 @@
                    groupPoints.Add(new GroupPoint() { Q = q, H = h, E = eta, P = p });
                }
                pumpCurveInfo.GroupPoints  = groupPoints;
                pumpCurveInfo.GroupPoints = groupPoints;
                _allPumpInfo.Add(pumpCurveInfo);
            }
        }
        //计算时间跨度
        protected int _calcSpaceMinute = 5;
        public int CalcSpaceMinute { get { return _calcSpaceMinute; } set { _calcSpaceMinute = value; } }
        public int CalcSpaceMinute
        { get { return _calcSpaceMinute; } set { _calcSpaceMinute = value; } }
        /// <summary>
        /// ä¸­é—´æœ€å¤šåˆ‡æ¢æ¬¡æ•°
        /// </summary>
        protected int _maxPumpSwitchCount = 3;
        public int MaxPumpSwitchCount { get { return _maxPumpSwitchCount; } set { _maxPumpSwitchCount = value; } }
        public int MaxPumpSwitchCount
        { get { return _maxPumpSwitchCount; } set { _maxPumpSwitchCount = value; } }
        /// <summary>
        /// ä¸è®¸åˆ‡æ³µæ—¶é—´
        /// </summary>
        protected List<IStation.CalcModel.TimeRange> _limitSwitchPumpTimes = null;
        public List<IStation.CalcModel.TimeRange> LimitSwitchPumpTimes { get { return _limitSwitchPumpTimes; } set { _limitSwitchPumpTimes = value; } }
        public List<IStation.CalcModel.TimeRange> LimitSwitchPumpTimes
        {
            get { return _limitSwitchPumpTimes; }
            set
            {
                _limitSwitchPumpTimes = value;
            }
        }
        /// <summary>
        /// ä¸è®¸å¼€æ³µæ—¶é—´
        /// </summary>
        protected List<IStation.CalcModel.TimeRange> _limitOpenPumpTimes = null;
        public List<IStation.CalcModel.TimeRange> LimitOpenPumpTimes { get { return _limitOpenPumpTimes; } set { _limitOpenPumpTimes = value; } }
        public List<IStation.CalcModel.TimeRange> LimitOpenPumpTimes
        {
            get { return _limitOpenPumpTimes; }
            set
            {
                _limitOpenPumpTimes = value;
            }
        }
        #region æ³µå‡ºå£åŽ‹åŠ›
@@ -273,8 +366,8 @@
            return 0.068 * 100;
            //return _outBoxLevels.First().Level;
        }
        #endregion
        #endregion æ³µå‡ºå£åŽ‹åŠ›
        /// <summary>
        /// èŽ·å–æ‰¬ç¨‹(暂时简单处理)
@@ -316,18 +409,18 @@
            //    }
            //}
            m1 = m1 - dropHeight;
            return (m2 - m1);
        }
        //电费
        protected List<ElecPriceMonthSetting> _elecPrice  = null;
        public List<ElecPriceMonthSetting> ElecPrice  { get => _elecPrice; set => _elecPrice = value; }
        public double CalcMoney(DateTime time,double power)
        {
        protected List<ElecPriceMonthSetting> _elecPrice = null;
        public List<ElecPriceMonthSetting> ElecPrice { get => _elecPrice; set => _elecPrice = value; }
        public double CalcMoney(DateTime time, double power)
        {
            var month = time.Month;
            var hour = time.Hour;
            var monthSettings = _elecPrice.Find(x => month >= x.StartMonth && month <= x.EndMonth);
@@ -344,11 +437,11 @@
            }
        }
        /// <summary>
        /// æœ€å°‘开泵时间
        /// </summary>
        public int MinOpenPumpMinute = 30;
        protected int _minTimeCountOpenPump = 0;
        public int MinSwitchPumpMinute = 30;
        protected int _minTimeCountSwitch = 0;
@@ -356,17 +449,19 @@
        /// <summary>
        /// åˆå§‹åŒ–开机台数
        /// </summary>
        protected int _startOpenCount = -1;
        public int StartOpenCount { get => _startOpenCount; set => _startOpenCount = value; }
        protected int _startOpenPumpCount = -1;
        protected List<int> _startOpenPumpArray = null;
        /// <summary>
        ///
        ///
        /// </summary>
        protected bool isDispDebug = false;
        public bool IsDispDebug { get => isDispDebug; set => isDispDebug = value; }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <param name="prj"></param>
        /// <returns></returns>
@@ -411,4 +506,4 @@
            return true;
        }
    }
}
}