From 1c5fa983ae3506c2edaa88c51a959d46685c1ba1 Mon Sep 17 00:00:00 2001 From: tangxu <tangxu76880903> Date: 星期三, 24 四月 2024 14:25:34 +0800 Subject: [PATCH] 分离成3个分析 --- /dev/null | 18 Calc/IStation.Calc.Core/IStation.Calc.Core.csproj | 3 Calc/IStation.Calc.Core/递归计算2/ErQuCalcHelper_2_递归_定水位 - 副本.cs | 655 +++++++++++++++++ Calc/IStation.Calc.Core/计算基类/ErQuCalcBaseHelper.cs | 85 + Calc/IStation.Calc.Core/递归计算2/ErQuCalcHelper_2_递归_定水位_任意时间.cs | 678 +++++++++++++++++ WinFrmUI/IStation.WinFrmUI.CalcErQu/Wizard/pageCalcParas.cs | 10 WinFrmUI/IStation.WinFrmUI.Monitor/IStation.WinFrmUI.Monitor.csproj | 1 Calc/IStation.Calc.Core/计算基类/ErQuCalcBaseHelper_水库.cs | 45 Calc/IStation.Calc.Core/递归计算2/ErQuCalcHelper_2_递归.cs | 4 Calc/IStation.Calc.Core/递归计算2/ErQuCalcHelper_2_递归_定水位_指定时间.cs | 697 ++++++++++++++++++ Calc/IStation.Calc.Core/递归计算2/ErQuCalcHelper_2_递归_定水量.cs | 42 11 files changed, 2,149 insertions(+), 89 deletions(-) diff --git a/Calc/IStation.Calc.Core/IStation.Calc.Core.csproj b/Calc/IStation.Calc.Core/IStation.Calc.Core.csproj index 83ced8f..d66b1d5 100644 --- a/Calc/IStation.Calc.Core/IStation.Calc.Core.csproj +++ b/Calc/IStation.Calc.Core/IStation.Calc.Core.csproj @@ -78,7 +78,8 @@ <Compile Include="璁$畻鍩虹被\ErQuCalcBaseHelper_TimeList.cs" /> <Compile Include="璁$畻鍩虹被\ErQuCalcBaseHelper_鎵嬪姩娣诲姞椤圭洰.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="閫掑綊璁$畻2\ErQuCalcHelper_2_閫掑綊_瀹氭按浣�.cs" /> + <Compile Include="閫掑綊璁$畻2\ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗鎸囧畾鏃堕棿.cs" /> + <Compile Include="閫掑綊璁$畻2\ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗浠绘剰鏃堕棿.cs" /> <Compile Include="閫掑綊璁$畻2\ErQuCalcHelper_2_閫掑綊.cs" /> <Compile Include="閫掑綊璁$畻2\ErQuCalcHelper_2_閫掑綊_瀹氭按閲�.cs" /> <EmbeddedResource Include="Properties\Resources.resx"> diff --git "a/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper.cs" "b/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper.cs" index c832821..9e6592c 100644 --- "a/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper.cs" +++ "b/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper.cs" @@ -15,15 +15,74 @@ /// <returns></returns> public static IStation.Calc.ErQuCalcBaseHelper Build(IStation.CalcModel.AnaRequest anaRequest) { - //if(anaRequest.MaxLimitWaterBoxLevel != null) - //{ + if (anaRequest.MaxLimitWaterBoxLevel != null) + { + DateTime? limit_time = GetMaxLimitWaterBoxTime(anaRequest); - //} - //else - //{ + if(limit_time == null) + { + var calc = new IStation.Calc.ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗浠绘剰鏃堕棿(); + calc.SetMaxReservoirHeight(anaRequest.MaxLimitWaterBoxLevel.Value); + + return calc; + } + else + { + var calc = new IStation.Calc.ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗鎸囧畾鏃堕棿(); + calc.SetMaxReservoirHeight(anaRequest.MaxLimitWaterBoxLevel.Value, limit_time.Value); + return calc; + } + } + else + { + return new IStation.Calc.ErQuCalcHelper_2_閫掑綊_瀹氭按閲�(); + } + + } - //} - return new IStation.Calc.ErQuCalcHelper_2_閫掑綊_瀹氭按閲�(); + private static DateTime? GetMaxLimitWaterBoxTime(IStation.CalcModel.AnaRequest anaRequest) + { + + if (string.IsNullOrEmpty(anaRequest.MaxLimitWaterBoxTime)) + { + return null; + } + + + DateTime time; + if (DateTime.TryParse(anaRequest.MaxLimitWaterBoxTime, out time)) + { + return time; + } + + if (anaRequest.MaxLimitWaterBoxTime.Contains(":")) + { + var sss = anaRequest.MaxLimitWaterBoxTime.Split(':'); + 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.MaxLimitWaterBoxTime, 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> @@ -74,19 +133,7 @@ this._startOpenCount = anaRequest.StartOpenCount; this._clacOptType = anaRequest.CalcOptType; - if (anaRequest.MaxLimitWaterBoxLevel != null) - { - // this._max_level鏃堕棿 = anaRequest.MinLimitWaterBoxLevel.Value; - this._max_level姘村簱姘翠綅 = anaRequest.MaxLimitWaterBoxLevel.Value; - - if (!string.IsNullOrEmpty(anaRequest.MaxLimitWaterBoxTime)) - { - //DateTime time; - // if(!string.IsNullOrEmpty()) - // anaRequest. - } - } if (anaRequest.TotalFlow鍙栨按鎬婚噺 != null) diff --git "a/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper_\346\260\264\345\272\223.cs" "b/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper_\346\260\264\345\272\223.cs" index 627b18e..d3b3c07 100644 --- "a/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper_\346\260\264\345\272\223.cs" +++ "b/Calc/IStation.Calc.Core/\350\256\241\347\256\227\345\237\272\347\261\273/ErQuCalcBaseHelper_\346\260\264\345\272\223.cs" @@ -11,9 +11,8 @@ protected double _start_level姘村簱姘翠綅; - protected double _max_level姘村簱姘翠綅 = 10000; - protected DateTime _max_level鏃堕棿; + protected List<double> _reservoirDropFlowList = null;//鎺掓按娴侀噺鏃堕棿鍒嗛厤(涓囨柟) //protected List<double?> _reservoirMinLimitHours = null; @@ -142,22 +141,22 @@ /// </summary> /// <param name="first_block"></param> /// <returns></returns> - protected bool CheckReservoirHeightOnlyOne(RunBlock first_block) - { - double min_height = _start_level姘村簱姘翠綅; - min_height = Math.Min(min_height, first_block.ReservoirStartHeight); - min_height = Math.Min(min_height, first_block.ReservoirEndHeight); + // protected bool CheckReservoirHeightOnlyOne(RunBlock first_block) + // { + // double min_height = _start_level姘村簱姘翠綅; + // min_height = Math.Min(min_height, first_block.ReservoirStartHeight); + // min_height = Math.Min(min_height, first_block.ReservoirEndHeight); - double max_height = _start_level姘村簱姘翠綅; - max_height = Math.Max(max_height, first_block.ReservoirEndHeight); - max_height = Math.Max(max_height, first_block.ReservoirEndHeight); + // double max_height = _start_level姘村簱姘翠綅; + // max_height = Math.Max(max_height, first_block.ReservoirEndHeight); + // max_height = Math.Max(max_height, first_block.ReservoirEndHeight); - var total_drop_flow = this._timeList.Last().ReservoirDropFlowTotal - - this._timeList[first_block.EndIndx].ReservoirDropFlowTotal; - var last_heigt = CalcReservoirHeight(total_drop_flow, 0, - first_block.ReservoirEndHeight); - min_height = Math.Min(min_height, last_heigt); + // var total_drop_flow = this._timeList.Last().ReservoirDropFlowTotal - + //this._timeList[first_block.EndIndx].ReservoirDropFlowTotal; + // var last_heigt = CalcReservoirHeight(total_drop_flow, 0, + // first_block.ReservoirEndHeight); + // min_height = Math.Min(min_height, last_heigt); @@ -165,18 +164,18 @@ - bool isOk_max = false; - if (max_height >= this._max_level姘村簱姘翠綅) - isOk_max = true; + // bool isOk_max = false; + // if (max_height >= this._max_level姘村簱姘翠綅) + // isOk_max = true; - if (isOk_max ) - return true; - else - return false; - } + // if (isOk_max ) + // return true; + // else + // return false; + // } diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222.cs" index 786f0db..f0738d3 100644 --- "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222.cs" +++ "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222.cs" @@ -12,7 +12,7 @@ { public List<RunBlock> Items { get; set; } public double TotalCompare;//鍔熺巼鎴栬�呯數璐�(鍚堣) - public double TotalFlow; + public double TotalFlow; } @@ -107,7 +107,7 @@ opt_prj.SumPower = sumPower; - OnShowDebugInfo.Invoke(string.Format("璁$畻娆℃暟:{0:N0}, 缂撳瓨浣跨敤娆℃暟:{1:N0}", this._totalCalcCount, this._totalCacheCount)); + var opt_prjs = new List<AnaPrj>(); diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215 - \345\211\257\346\234\254.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215 - \345\211\257\346\234\254.cs" new file mode 100644 index 0000000..078b8c4 --- /dev/null +++ "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215 - \345\211\257\346\234\254.cs" @@ -0,0 +1,655 @@ +锘縰sing IStation.CalcModel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace IStation.Calc +{ + internal partial class ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗浠绘剰鏃堕棿 : ErQuCalcHelper_2_閫掑綊 + { + List<List<Dictionary<int, BlockItemList>>> _dictCalcCache; + + /// <summary> + /// + /// </summary> + /// <returns></returns> + protected override List<AnaPrj> CalcOptPrjsCore() + { + _minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute; + _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; + //this._maxPumpSwitchCount = 5; + + var result = CalcOptPrjsBlockItems(); + if (result == null) + return null; + return ToAnaPrj(result); + } + + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList CalcOptPrjsBlockItems() + { + _dictCalcCache = new List<List<Dictionary<int, BlockItemList>>>(_timeDataListCount + 1); + for (int i = 0; i < _timeDataListCount + 1; i++) + { + var ak = new List<Dictionary<int, BlockItemList>>(_timeDataListCount + 1); + for (int j = 0; j < this.MaxPumpSwitchCount + 2; j++) + { + ak.Add(new Dictionary<int, BlockItemList>()); + } + _dictCalcCache.Add(ak); + } + + + var result = RecursionFind鍒濆(); + if (result == null || result.Items == null) + return null; + if (result.Items.First().StartIndx > 0) + { + var empty_0 = new RunBlock(); + empty_0.PumpCount = 0; + empty_0.StartIndx = 0; + empty_0.EndIndx = result.Items.First().StartIndx; + empty_0.ReservoirStartHeight = this._start_level姘村簱姘翠綅; + empty_0.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_0.StartIndx, + empty_0.EndIndx, + 0, this._start_level姘村簱姘翠綅); + result.Items.Insert(0, empty_0); + } + + double lastLevelHeight = this._start_level姘村簱姘翠綅; + foreach (var s in from x in result.Items orderby x.StartIndx select x) + { + if (s.PumpCount == 0) + { + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + 0, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + else + { + var td = GetTimeDataBundle(s.PumpCount); + double sumFlow = 0; + for (int i = s.StartIndx; i < s.EndIndx; i++) + { + sumFlow += td.TimeDatas[i].SumFlow; + } + + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + sumFlow, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + } + + if (result.Items.Last().EndIndx < this._timeDataListCount - 3) + { + var empty_l = new RunBlock(); + empty_l.PumpCount = 0; + empty_l.StartIndx = result.Items.Last().EndIndx; + empty_l.EndIndx = this._timeDataListCount - 1; + empty_l.ReservoirStartHeight = result.Items.Last().ReservoirEndHeight; + empty_l.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_l.StartIndx, + empty_l.EndIndx, + 0, result.Items.Last().ReservoirEndHeight); + result.Items.Add(empty_l); + } + + return result; + } + public void SetMaxReservoirHeight(double level姘村簱姘翠綅) + { + _maxReservoirHeight = level姘村簱姘翠綅; + + } + protected double _maxReservoirHeight = 10000; + private bool CheckMaxLevel(double start_level,double end_level) + { + if (start_level >= this._maxReservoirHeight || end_level >= this._maxReservoirHeight) + return true; + else + return false; + } + private bool CheckMaxLevel(double start_level, List<RunBlock> Items) + { + if (start_level >= this._maxReservoirHeight ) + return true; + if(Items != null) + { + foreach(var item in Items) + { + if (item.ReservoirStartHeight >= this._maxReservoirHeight || item.ReservoirEndHeight >= this._maxReservoirHeight) + return true; + } + } + + + return false; + } + + private bool CheckMaxLevel(double start_level, double middle_level, double end_level) + { + if (start_level >= this._maxReservoirHeight || middle_level >= this._maxReservoirHeight || end_level >= this._maxReservoirHeight) + return true; + else + return false; + } + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList RecursionFind鍒濆() + { + int startSwitchTimeIndx = _minTimeCountSwitch;//淇濊瘉涓嶆槸涓�寮�濮嬪氨杩涜娉靛垏鎹� + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + _totalCalcCount++; + + // + double sumCompareWhole = 0; + double sumFlowWhole = 0; + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(0, out sumFlowWhole, out sumCompareWhole); + + if (sumFlowWhole >= this._stationTotalFlow) + { + if (sumCompareWhole < current_best_solution.TotalCompare) + { + // 缁撴潫鏃剁殑姘翠綅 + var end_level = CalcReservoirHeight( + 0, + _timeDataListCount - 1, + sumFlowWhole, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, end_level)) + {//妫�鏌ユ按浣� + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = _timeDataListCount-1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = end_level + } + }; + } + } + } + + #endregion + + + #region 寮�濮� 涓嶅紑鏈� 鎯呭喌 + if (this._startOpenCount == 0 || this._startOpenCount == -1) + { + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + {//_timeList[i].IsLimitSwitch + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + //鍙充晶缁х画杩唬 + var end_level = CalcReservoirHeight(// 缁撴潫鏃剁殑姘翠綅 + 0, + splitIndx, + 0, this._start_level姘村簱姘翠綅); + + BlockItemList right_solutions = RecursionFindRight( + 0, end_level, this._start_level姘村簱姘翠綅, 1, 0, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + } + } + } + #endregion + + + #region 寮�鏈� + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + double sumCompareLeft = 0; + double sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(0, splitIndx, out sumFlowLeft, out sumCompareLeft); + + + if (sumFlowLeft >= this._stationTotalFlow) + { + #region 宸︿晶宸茬粡鑳借揪鍒拌姹備簡,鍙宠竟鐨勫叏鍏虫満 + if (current_best_solution.TotalCompare > sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, left_end_level)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = sumCompareLeft; + current_best_solution.TotalFlow = sumFlowLeft; + + current_best_solution.Items = new List<RunBlock>() {//鍙湁涓�涓椂闂村潡 + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + } }; + } + #endregion + break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + + + //鍙充晶缁х画杩唬 + var left_max_level = Math.Max(_start_level姘村簱姘翠綅, left_end_level); + BlockItemList right_solutions = RecursionFindRight( + sumFlowLeft, left_end_level, left_max_level, 1, pumpNum_left, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!CheckMaxLevel(left_max_level, right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + + + #endregion + + + if (current_best_solution.TotalCompare == double.MaxValue) + return null; + + return current_best_solution; + } + + + /// <summary> + /// 閫掑綊 + /// </summary> + /// <param name="lastTotalFlow">褰撳墠鐨勬祦閲�(宸︿晶鏃堕棿鍧楁祦閲�)</param> + /// <param name="lastReservoirHeight">褰撳墠鐨勬按搴撴按浣�(宸︿晶鏃堕棿鍧�)</param> + /// <param name="lastSwitchCount">褰撳墠鍒囨崲娆℃暟</param> + /// <param name="startTimeIndx">寮�濮嬫椂闂存瑙掓爣</param> + /// <returns></returns> + BlockItemList RecursionFindRight( + double lastTotalFlow, + double lastReservoirHeight,//缁撴潫鏃剁殑姘翠綅,鏈杩唬寮�濮嬫椂姘翠綅 + double lastMaxReservoirHeight,//浠ュ墠鐨勬渶楂樻按浣� + int lastSwitchCount, + int lastOpenPumpCount, + int startTimeIndx) + { + if (lastSwitchCount > this.MaxPumpSwitchCount) + {//涓嶈兘鍐嶅垏鎹㈡车浜�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (lastTotalFlow > this._stationTotalFlow) + {//宸茶揪鍒版祦閲�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (!_timeList[startTimeIndx].IsSwitchPumpAble) return null; + + + // + int flowKey = 0; + if (lastTotalFlow > 0) + { + flowKey = (int)(lastTotalFlow / 2000); + } + + //bool isNeedInsertCache = true; + + //if (_dictCalcCache[startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) + //{ + // _totalCacheCount++; + // var cache_model = _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey]; + // if (cache_model == null) + // return null; + // if (cache_model.Items.First().PumpCount == lastOpenPumpCount) + // return null; + + // isNeedInsertCache = false; + + // if (cache_model.TotalFlow + lastTotalFlow >= this._stationTotalFlow) + // { + // if (this.CheckMaxLevel(lastMaxReservoirHeight, cache_model.MaxReservoirHeight)) + // { + // BlockItemList cache_model_copy = new BlockItemList(); + // cache_model_copy.TotalCompare = cache_model.TotalCompare; + // cache_model_copy.TotalFlow = cache_model.TotalFlow; + // cache_model_copy.MaxReservoirHeight = cache_model.MaxReservoirHeight; + // cache_model_copy.Items = new List<RunBlock>(cache_model.Items); + // return cache_model_copy; + // } + // } + //} + + + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.TotalFlow = 0; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + _totalCalcCount++; + + + double sumCompareWhole = 0; + double sumFlowWhole = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(startTimeIndx, out sumFlowWhole, out sumCompareWhole); + if (sumCompareWhole == double.MaxValue) + continue; + + if (sumFlowWhole + lastTotalFlow >= this._stationTotalFlow && + sumCompareWhole < current_best_solution.TotalCompare) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + _timeDataListCount - 1, + sumFlowWhole, lastReservoirHeight); + if (!this.CheckMaxLevel(lastMaxReservoirHeight, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = _timeDataListCount - 1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } + }; + } + } + + #endregion + + if (startTimeIndx < this._timeDataListCount - _minTimeCountSwitch) + { + #region 宸︿晶 涓嶅紑鏈� + if (0 != lastOpenPumpCount) + { + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + 0, lastReservoirHeight); + + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight( + lastTotalFlow, left_end_level, lastMaxReservoirHeight, lastSwitchCount + 1, 0, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!this.CheckMaxLevel(lastMaxReservoirHeight, right_solutions.Items)) + { + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items.Count + 1); + current_best_solution.Items.Add(new RunBlock() + { + PumpCount = 0, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + current_best_solution.Items.AddRange(right_solutions.Items); + } + } + } + #endregion + + #region 宸︿晶 寮�鏈� + { + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + double left_sumCompareLeft = 0; + double left_sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(startTimeIndx, splitIndx, + out left_sumFlowLeft, out left_sumCompareLeft); + if (left_sumCompareLeft == double.MaxValue) + continue; + + var total_current_flow = left_sumFlowLeft + lastTotalFlow; + if (total_current_flow >= this._stationTotalFlow) + {//宸︿晶宸茬粡鑳借揪鍒拌姹備簡 + if (current_best_solution.TotalCompare > left_sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + if (!this.CheckMaxLevel(lastMaxReservoirHeight, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = left_sumCompareLeft; + current_best_solution.TotalFlow = left_sumFlowLeft; + current_best_solution.Items = new List<RunBlock>() { + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = startTimeIndx, + EndIndx = splitIndx , + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } }; + } + //break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + var mmm = Math.Max(left_end_level, lastMaxReservoirHeight); + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight( + total_current_flow, left_end_level, mmm, lastSwitchCount + 1, pumpNum_left, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = left_sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!this.CheckMaxLevel(mmm, current_best_solution.Items)) + { + continue; + } + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = left_sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + } + + #endregion + } + else + { + + } + + if (current_best_solution.TotalCompare == double.MaxValue) + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = null; + //} + + return null; + } + else + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = current_best_solution; + //} + return current_best_solution; + } + } + + + + + + + } +} \ No newline at end of file diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215.cs" deleted file mode 100644 index e753fe2..0000000 --- "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215.cs" +++ /dev/null @@ -1,18 +0,0 @@ -锘縰sing IStation.CalcModel; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace IStation.Calc -{ - internal partial class ErQuCalcHelper_2_閫掑綊 : ErQuCalcBaseHelper - { - - - - - - - } -} \ No newline at end of file diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\344\273\273\346\204\217\346\227\266\351\227\264.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\344\273\273\346\204\217\346\227\266\351\227\264.cs" new file mode 100644 index 0000000..776c67e --- /dev/null +++ "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\344\273\273\346\204\217\346\227\266\351\227\264.cs" @@ -0,0 +1,678 @@ +锘縰sing IStation.CalcModel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace IStation.Calc +{ + internal partial class ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗浠绘剰鏃堕棿 : ErQuCalcHelper_2_閫掑綊_瀹氭按閲� + { + + /// <summary> + /// + /// </summary> + /// <returns></returns> + protected override List<AnaPrj> CalcOptPrjsCore() + { + _minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute; + _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; + //this._maxPumpSwitchCount = 5; + + var result瀹氭按閲� = CalcOptPrjsBlockItems瀹氭按閲�(); + if (result瀹氭按閲� == null) + return null; + + foreach(var item in result瀹氭按閲�.Items) + { + if(item.ReservoirStartHeight>= _maxReservoirHeight || item.ReservoirEndHeight>= _maxReservoirHeight) + { + return ToAnaPrj(result瀹氭按閲�); + } + } + + + var result = CalcOptPrjsBlockItems_瀹氭按浣峗浠绘剰鏃堕棿(); + if (result == null) + return null; + return ToAnaPrj(result); + } + + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList CalcOptPrjsBlockItems_瀹氭按浣峗浠绘剰鏃堕棿() + { + var result = RecursionFind鍒濆_瀹氭按浣峗浠绘剰鏃堕棿(); + if (result == null || result.Items == null) + return null; + if (result.Items.First().StartIndx > 0) + { + var empty_0 = new RunBlock(); + empty_0.PumpCount = 0; + empty_0.StartIndx = 0; + empty_0.EndIndx = result.Items.First().StartIndx; + empty_0.ReservoirStartHeight = this._start_level姘村簱姘翠綅; + empty_0.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_0.StartIndx, + empty_0.EndIndx, + 0, this._start_level姘村簱姘翠綅); + result.Items.Insert(0, empty_0); + } + + double lastLevelHeight = this._start_level姘村簱姘翠綅; + foreach (var s in from x in result.Items orderby x.StartIndx select x) + { + if (s.PumpCount == 0) + { + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + 0, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + else + { + var td = GetTimeDataBundle(s.PumpCount); + double sumFlow = 0; + for (int i = s.StartIndx; i < s.EndIndx; i++) + { + sumFlow += td.TimeDatas[i].SumFlow; + } + + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + sumFlow, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + } + + if (result.Items.Last().EndIndx < this._timeDataListCount - 3) + { + var empty_l = new RunBlock(); + empty_l.PumpCount = 0; + empty_l.StartIndx = result.Items.Last().EndIndx; + empty_l.EndIndx = this._timeDataListCount - 1; + empty_l.ReservoirStartHeight = result.Items.Last().ReservoirEndHeight; + empty_l.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_l.StartIndx, + empty_l.EndIndx, + 0, result.Items.Last().ReservoirEndHeight); + result.Items.Add(empty_l); + } + + return result; + } + + /// <summary> + /// + /// </summary> + /// <param name="level姘村簱姘翠綅"></param> + public void SetMaxReservoirHeight(double level姘村簱姘翠綅) + { + _maxReservoirHeight = level姘村簱姘翠綅; + } + protected double _maxReservoirHeight = 0; + private bool CheckMaxLevel(double start_level,double end_level) + { + if (start_level >= this._maxReservoirHeight || end_level >= this._maxReservoirHeight) + return true; + else + return false; + } + private bool CheckMaxLevel(double start_level, List<RunBlock> Items) + { + if (start_level >= this._maxReservoirHeight ) + return true; + if(Items != null) + { + foreach(var item in Items) + { + if (item.ReservoirStartHeight >= this._maxReservoirHeight || item.ReservoirEndHeight >= this._maxReservoirHeight) + return true; + } + } + + + return false; + } + + private bool CheckMaxLevel(double start_level, double middle_level, double end_level) + { + if (start_level >= this._maxReservoirHeight || middle_level >= this._maxReservoirHeight || end_level >= this._maxReservoirHeight) + return true; + else + return false; + } + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList RecursionFind鍒濆_瀹氭按浣峗浠绘剰鏃堕棿() + { + int startSwitchTimeIndx = _minTimeCountSwitch;//淇濊瘉涓嶆槸涓�寮�濮嬪氨杩涜娉靛垏鎹� + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + _totalCalcCount++; + + // + double sumCompareWhole = 0; + double sumFlowWhole = 0; + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(0, out sumFlowWhole, out sumCompareWhole); + + if (sumFlowWhole >= this._stationTotalFlow) + { + if (sumCompareWhole < current_best_solution.TotalCompare) + { + // 缁撴潫鏃剁殑姘翠綅 + var end_level = CalcReservoirHeight( + 0, + _timeDataListCount - 1, + sumFlowWhole, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, end_level)) + {//妫�鏌ユ按浣� + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = _timeDataListCount-1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = end_level + } + }; + } + } + } + + #endregion + + + #region 寮�濮� 涓嶅紑鏈� 鎯呭喌 + if (this._startOpenCount == 0 || this._startOpenCount == -1) + { + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + {//_timeList[i].IsLimitSwitch + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + //鍙充晶缁х画杩唬 + var end_level = CalcReservoirHeight(// 缁撴潫鏃剁殑姘翠綅 + 0, + splitIndx, + 0, this._start_level姘村簱姘翠綅); + + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗浠绘剰鏃堕棿( + 0, end_level, this._start_level姘村簱姘翠綅, 1, 0, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + } + } + } + #endregion + + + #region 寮�鏈� + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + double sumCompareLeft = 0; + double sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(0, splitIndx, out sumFlowLeft, out sumCompareLeft); + + + if (sumFlowLeft >= this._stationTotalFlow) + { + #region 宸︿晶宸茬粡鑳借揪鍒拌姹備簡,鍙宠竟鐨勫叏鍏虫満 + if (current_best_solution.TotalCompare > sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(_start_level姘村簱姘翠綅, left_end_level)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = sumCompareLeft; + current_best_solution.TotalFlow = sumFlowLeft; + + current_best_solution.Items = new List<RunBlock>() {//鍙湁涓�涓椂闂村潡 + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + } }; + } + #endregion + break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + + + //鍙充晶缁х画杩唬 + var left_max_level = Math.Max(_start_level姘村簱姘翠綅, left_end_level); + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗浠绘剰鏃堕棿( + sumFlowLeft, left_end_level, left_max_level, 1, pumpNum_left, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!CheckMaxLevel(left_max_level, right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + + + #endregion + + + if (current_best_solution.TotalCompare == double.MaxValue) + return null; + + return current_best_solution; + } + + + /// <summary> + /// 閫掑綊 + /// </summary> + /// <param name="lastTotalFlow">褰撳墠鐨勬祦閲�(宸︿晶鏃堕棿鍧楁祦閲�)</param> + /// <param name="lastReservoirHeight">褰撳墠鐨勬按搴撴按浣�(宸︿晶鏃堕棿鍧�)</param> + /// <param name="lastSwitchCount">褰撳墠鍒囨崲娆℃暟</param> + /// <param name="startTimeIndx">寮�濮嬫椂闂存瑙掓爣</param> + /// <returns></returns> + BlockItemList RecursionFindRight_瀹氭按浣峗浠绘剰鏃堕棿( + double lastTotalFlow, + double lastReservoirHeight,//缁撴潫鏃剁殑姘翠綅,鏈杩唬寮�濮嬫椂姘翠綅 + double lastMaxReservoirHeight,//浠ュ墠鐨勬渶楂樻按浣� + int lastSwitchCount, + int lastOpenPumpCount, + int startTimeIndx) + { + if (lastSwitchCount > this.MaxPumpSwitchCount) + {//涓嶈兘鍐嶅垏鎹㈡车浜�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (lastTotalFlow > this._stationTotalFlow) + {//宸茶揪鍒版祦閲�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (!_timeList[startTimeIndx].IsSwitchPumpAble) return null; + + + // + int flowKey = 0; + if (lastTotalFlow > 0) + { + flowKey = (int)(lastTotalFlow / 2000); + } + + + if (lastMaxReservoirHeight > this._maxReservoirHeight) + { + if (_dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) + { + _totalCacheCount++; + var cache_model = _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey]; + if (cache_model == null) + return null; + if (cache_model.Items.First().PumpCount == lastOpenPumpCount) + return null; + + if (cache_model.TotalFlow + lastTotalFlow >= this._stationTotalFlow) + { + BlockItemList cache_model_copy = new BlockItemList(); + cache_model_copy.TotalCompare = cache_model.TotalCompare; + cache_model_copy.TotalFlow = cache_model.TotalFlow; + cache_model_copy.Items = new List<RunBlock>(cache_model.Items); + return cache_model_copy; + } + } + } + //else + //{ + // if (_dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) + // { + // _totalCacheCount++; + // var cache_model = _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey]; + // if (cache_model == null) + // return null; + // if (cache_model.Items.First().PumpCount == lastOpenPumpCount) + // return null; + + // if (cache_model.TotalFlow + lastTotalFlow >= this._stationTotalFlow && cache_model.Items) + // { + // BlockItemList cache_model_copy = new BlockItemList(); + // cache_model_copy.TotalCompare = cache_model.TotalCompare; + // cache_model_copy.TotalFlow = cache_model.TotalFlow; + // cache_model_copy.Items = new List<RunBlock>(cache_model.Items); + // return cache_model_copy; + + // } + // } + //} + + + + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.TotalFlow = 0; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + _totalCalcCount++; + + + double sumCompareWhole = 0; + double sumFlowWhole = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(startTimeIndx, out sumFlowWhole, out sumCompareWhole); + if (sumCompareWhole == double.MaxValue) + continue; + + if (sumFlowWhole + lastTotalFlow >= this._stationTotalFlow && + sumCompareWhole < current_best_solution.TotalCompare) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + _timeDataListCount - 1, + sumFlowWhole, lastReservoirHeight); + if (!this.CheckMaxLevel(lastMaxReservoirHeight, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = _timeDataListCount - 1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } + }; + } + } + + #endregion + + if (startTimeIndx < this._timeDataListCount - _minTimeCountSwitch) + { + #region 宸︿晶 涓嶅紑鏈� + if (0 != lastOpenPumpCount) + { + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + 0, lastReservoirHeight); + + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗浠绘剰鏃堕棿( + lastTotalFlow, left_end_level, lastMaxReservoirHeight, lastSwitchCount + 1, 0, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!this.CheckMaxLevel(lastMaxReservoirHeight, right_solutions.Items)) + { + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items.Count + 1); + current_best_solution.Items.Add(new RunBlock() + { + PumpCount = 0, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + current_best_solution.Items.AddRange(right_solutions.Items); + } + } + } + #endregion + + #region 宸︿晶 寮�鏈� + { + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + double left_sumCompareLeft = 0; + double left_sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(startTimeIndx, splitIndx, + out left_sumFlowLeft, out left_sumCompareLeft); + if (left_sumCompareLeft == double.MaxValue) + continue; + + var total_current_flow = left_sumFlowLeft + lastTotalFlow; + if (total_current_flow >= this._stationTotalFlow) + {//宸︿晶宸茬粡鑳借揪鍒拌姹備簡 + if (current_best_solution.TotalCompare > left_sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + if (!this.CheckMaxLevel(lastMaxReservoirHeight, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = left_sumCompareLeft; + current_best_solution.TotalFlow = left_sumFlowLeft; + current_best_solution.Items = new List<RunBlock>() { + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = startTimeIndx, + EndIndx = splitIndx , + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } }; + } + //break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + var mmm = Math.Max(left_end_level, lastMaxReservoirHeight); + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗浠绘剰鏃堕棿( + total_current_flow, left_end_level, mmm, lastSwitchCount + 1, pumpNum_left, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = left_sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!this.CheckMaxLevel(mmm, current_best_solution.Items)) + { + continue; + } + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = left_sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + } + + #endregion + } + else + { + + } + + if (current_best_solution.TotalCompare == double.MaxValue) + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = null; + //} + + return null; + } + else + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = current_best_solution; + //} + return current_best_solution; + } + } + + + + + + + } +} \ No newline at end of file diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\346\214\207\345\256\232\346\227\266\351\227\264.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\346\214\207\345\256\232\346\227\266\351\227\264.cs" new file mode 100644 index 0000000..b2800a4 --- /dev/null +++ "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\344\275\215_\346\214\207\345\256\232\346\227\266\351\227\264.cs" @@ -0,0 +1,697 @@ +锘縰sing IStation.CalcModel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace IStation.Calc +{ + internal partial class ErQuCalcHelper_2_閫掑綊_瀹氭按浣峗鎸囧畾鏃堕棿 : ErQuCalcHelper_2_閫掑綊_瀹氭按閲� + { + + /// <summary> + /// + /// </summary> + /// <returns></returns> + protected override List<AnaPrj> CalcOptPrjsCore() + { + _minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute; + _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; + //this._maxPumpSwitchCount = 5; + + for (int i = 0; i < _timeList.Count; i++) + { + if (_timeList[i].Time >= _maxReservoirTime) + { + _maxReservoirTimeIndex = i; + break; + } + } + + + + + var result瀹氭按閲� = CalcOptPrjsBlockItems瀹氭按閲�(); + if (result瀹氭按閲� == null) + return null; + + if (CheckMaxLevel(result瀹氭按閲�.Items)) + { + return ToAnaPrj(result瀹氭按閲�); + } + + + // + var result = CalcOptPrjsBlockItems_瀹氭按浣峗鎸囧畾鏃堕棿(); + if (result == null) + return null; + return ToAnaPrj(result); + } + + + + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList CalcOptPrjsBlockItems_瀹氭按浣峗鎸囧畾鏃堕棿() + { + var result = RecursionFind鍒濆_瀹氭按浣峗鎸囧畾鏃堕棿(); + if (result == null || result.Items == null) + return null; + if (result.Items.First().StartIndx > 0) + { + var empty_0 = new RunBlock(); + empty_0.PumpCount = 0; + empty_0.StartIndx = 0; + empty_0.EndIndx = result.Items.First().StartIndx; + empty_0.ReservoirStartHeight = this._start_level姘村簱姘翠綅; + empty_0.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_0.StartIndx, + empty_0.EndIndx, + 0, this._start_level姘村簱姘翠綅); + result.Items.Insert(0, empty_0); + } + + double lastLevelHeight = this._start_level姘村簱姘翠綅; + foreach (var s in from x in result.Items orderby x.StartIndx select x) + { + if (s.PumpCount == 0) + { + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + 0, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + else + { + var td = GetTimeDataBundle(s.PumpCount); + double sumFlow = 0; + for (int i = s.StartIndx; i < s.EndIndx; i++) + { + sumFlow += td.TimeDatas[i].SumFlow; + } + + var end = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + s.StartIndx, + s.EndIndx, + sumFlow, lastLevelHeight); + s.ReservoirStartHeight = lastLevelHeight; + s.ReservoirEndHeight = end; + lastLevelHeight = end; + } + } + + if (result.Items.Last().EndIndx < this._timeDataListCount - 3) + { + var empty_l = new RunBlock(); + empty_l.PumpCount = 0; + empty_l.StartIndx = result.Items.Last().EndIndx; + empty_l.EndIndx = this._timeDataListCount - 1; + empty_l.ReservoirStartHeight = result.Items.Last().ReservoirEndHeight; + empty_l.ReservoirEndHeight = CalcReservoirHeight(//涓嬫寮�濮嬫椂鐨勬按浣� + empty_l.StartIndx, + empty_l.EndIndx, + 0, result.Items.Last().ReservoirEndHeight); + result.Items.Add(empty_l); + } + + return result; + } + + /// <summary> + /// + /// </summary> + /// <param name="level姘村簱姘翠綅"></param> + public void SetMaxReservoirHeight(double level姘村簱姘翠綅, DateTime time) + { + _maxReservoirHeight = level姘村簱姘翠綅; + _maxReservoirHeightMin = level姘村簱姘翠綅 - 0.2; + _maxReservoirHeightMax = level姘村簱姘翠綅 + 0.2; + _maxReservoirTime = time; + } + protected double _maxReservoirHeight = 0; + protected DateTime _maxReservoirTime; + protected int _maxReservoirTimeIndex = -1; + protected double _maxReservoirHeightMin = 0; + protected double _maxReservoirHeightMax = 0; + + private bool CheckMaxLevel(int start_time_index, double start_level, int end_time_index, double end_level) + { + if (_maxReservoirTimeIndex < start_level || _maxReservoirTimeIndex > end_time_index) + return true; + + var WaterLevelH = start_level + (start_time_index - _maxReservoirTimeIndex) * (-start_level + end_level) / (start_time_index - end_time_index); + + if (WaterLevelH > _maxReservoirHeightMin && WaterLevelH < _maxReservoirHeightMax) + return true; + else + return false; + } + private bool CheckMaxLevel(List<RunBlock> Items) + { + + if (Items == null) + return true; + + + foreach (var item in Items) + { + if (_maxReservoirTimeIndex < item.StartIndx || _maxReservoirTimeIndex > item.EndIndx) + continue; + + var WaterLevelH = Math.Round( + item.ReservoirStartHeight + + (item.StartIndx - _maxReservoirTimeIndex) * (-item.ReservoirStartHeight + item.ReservoirEndHeight) / (item.StartIndx - item.EndIndx), 4); + + if (WaterLevelH > _maxReservoirHeightMin && WaterLevelH < _maxReservoirHeightMax) + return true; + else + return false; + } + + + + return true; + } + + + /// <summary> + /// + /// </summary> + /// <returns></returns> + private BlockItemList RecursionFind鍒濆_瀹氭按浣峗鎸囧畾鏃堕棿() + { + int startSwitchTimeIndx = _minTimeCountSwitch;//淇濊瘉涓嶆槸涓�寮�濮嬪氨杩涜娉靛垏鎹� + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + _totalCalcCount++; + + // + double sumCompareWhole = 0; + double sumFlowWhole = 0; + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(0, out sumFlowWhole, out sumCompareWhole); + + if (sumFlowWhole >= this._stationTotalFlow) + { + if (sumCompareWhole < current_best_solution.TotalCompare) + { + // 缁撴潫鏃剁殑姘翠綅 + var end_level = CalcReservoirHeight( + 0, + _timeDataListCount - 1, + sumFlowWhole, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(0, _start_level姘村簱姘翠綅, _timeDataListCount - 1, end_level)) + {//妫�鏌ユ按浣� + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = _timeDataListCount-1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = end_level + } + }; + } + } + } + + #endregion + + + #region 寮�濮� 涓嶅紑鏈� 鎯呭喌 + if (this._startOpenCount == 0 || this._startOpenCount == -1) + { + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + {//_timeList[i].IsLimitSwitch + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + //鍙充晶缁х画杩唬 + var end_level = CalcReservoirHeight(// 缁撴潫鏃剁殑姘翠綅 + 0, + splitIndx, + 0, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(0, _start_level姘村簱姘翠綅, splitIndx, end_level)) + {//妫�鏌ユ按浣� + continue; + } + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗鎸囧畾鏃堕棿( + 0, end_level, 1, 0, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!CheckMaxLevel(right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + } + } + } + #endregion + + + #region 寮�鏈� + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (this._startOpenCount >= 0) + { + if (this._startOpenCount != pumpNum_left) + continue; + } + + for (int splitIndx = startSwitchTimeIndx; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + double sumCompareLeft = 0; + double sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(0, splitIndx, out sumFlowLeft, out sumCompareLeft); + + + if (sumFlowLeft >= this._stationTotalFlow) + { + #region 宸︿晶宸茬粡鑳借揪鍒拌姹備簡,鍙宠竟鐨勫叏鍏虫満 + if (current_best_solution.TotalCompare > sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(0, _start_level姘村簱姘翠綅, splitIndx, left_end_level)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = sumCompareLeft; + current_best_solution.TotalFlow = sumFlowLeft; + + current_best_solution.Items = new List<RunBlock>() {//鍙湁涓�涓椂闂村潡 + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + } }; + } + #endregion + break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + 0, + splitIndx, + sumFlowLeft, this._start_level姘村簱姘翠綅); + if (!CheckMaxLevel(0, _start_level姘村簱姘翠綅, splitIndx, left_end_level)) + {//妫�鏌ユ按浣� + continue; + } + + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗鎸囧畾鏃堕棿( + sumFlowLeft, left_end_level, 1, pumpNum_left, splitIndx); + if (right_solutions == null) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!CheckMaxLevel(right_solutions.Items)) + {//妫�鏌ユ按浣� + continue; + } + + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = 0, + EndIndx = splitIndx, + TotalCompare = sumCompareLeft, + TotalFlow = sumFlowLeft, + ReservoirStartHeight = _start_level姘村簱姘翠綅, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + + + #endregion + + + if (current_best_solution.TotalCompare == double.MaxValue) + return null; + + return current_best_solution; + } + + + /// <summary> + /// 閫掑綊 + /// </summary> + /// <param name="lastTotalFlow">褰撳墠鐨勬祦閲�(宸︿晶鏃堕棿鍧楁祦閲�)</param> + /// <param name="lastReservoirHeight">褰撳墠鐨勬按搴撴按浣�(宸︿晶鏃堕棿鍧�)</param> + /// <param name="lastSwitchCount">褰撳墠鍒囨崲娆℃暟</param> + /// <param name="startTimeIndx">寮�濮嬫椂闂存瑙掓爣</param> + /// <returns></returns> + BlockItemList RecursionFindRight_瀹氭按浣峗鎸囧畾鏃堕棿( + double lastTotalFlow, + double lastReservoirHeight,//缁撴潫鏃剁殑姘翠綅,鏈杩唬寮�濮嬫椂姘翠綅 + int lastSwitchCount, + int lastOpenPumpCount, + int startTimeIndx) + { + if (lastSwitchCount > this.MaxPumpSwitchCount) + {//涓嶈兘鍐嶅垏鎹㈡车浜�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (lastTotalFlow > this._stationTotalFlow) + {//宸茶揪鍒版祦閲�:鍩烘湰涓婁笉浼氬嚭鐜�,杩涘叆鍓嶅凡鍒ゆ柇 + return null; + } + + if (!_timeList[startTimeIndx].IsSwitchPumpAble) return null; + + + // + int flowKey = 0; + if (lastTotalFlow > 0) + { + flowKey = (int)(lastTotalFlow / 2000); + } + + + //if (lastMaxReservoirHeight > this._maxReservoirHeight) + //{ + // if (_dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) + // { + // _totalCacheCount++; + // var cache_model = _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey]; + // if (cache_model == null) + // return null; + // if (cache_model.Items.First().PumpCount == lastOpenPumpCount) + // return null; + + // if (cache_model.TotalFlow + lastTotalFlow >= this._stationTotalFlow) + // { + // BlockItemList cache_model_copy = new BlockItemList(); + // cache_model_copy.TotalCompare = cache_model.TotalCompare; + // cache_model_copy.TotalFlow = cache_model.TotalFlow; + // cache_model_copy.Items = new List<RunBlock>(cache_model.Items); + // return cache_model_copy; + // } + // } + //} + + + + + + BlockItemList current_best_solution = new BlockItemList(); + current_best_solution.TotalCompare = double.MaxValue; + current_best_solution.TotalFlow = 0; + current_best_solution.Items = null; + + #region 鍒ゆ柇: 鍏ㄩ儴閮戒竴鏍�(涓嶅垏鎹㈡车), 鏄惁鍙互 + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + _totalCalcCount++; + + + double sumCompareWhole = 0; + double sumFlowWhole = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeDataStart1(startTimeIndx, out sumFlowWhole, out sumCompareWhole); + if (sumCompareWhole == double.MaxValue) + continue; + + if (sumFlowWhole + lastTotalFlow >= this._stationTotalFlow && + sumCompareWhole < current_best_solution.TotalCompare) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + _timeDataListCount - 1, + sumFlowWhole, lastReservoirHeight); + if (!this.CheckMaxLevel(startTimeIndx, lastReservoirHeight, _timeDataListCount - 1, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = sumCompareWhole; + current_best_solution.TotalFlow = sumFlowWhole; + + current_best_solution.Items = new List<RunBlock>() + { + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = _timeDataListCount - 1, + TotalCompare = sumCompareWhole, + TotalFlow = sumFlowWhole, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } + }; + } + } + + #endregion + + if (startTimeIndx < this._timeDataListCount - _minTimeCountSwitch) + { + #region 宸︿晶 涓嶅紑鏈� + if (0 != lastOpenPumpCount) + { + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + 0, lastReservoirHeight); + if (!CheckMaxLevel(startTimeIndx, lastReservoirHeight, splitIndx, left_end_level)) + {//妫�鏌ユ按浣� + continue; + } + + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗鎸囧畾鏃堕棿( + lastTotalFlow, left_end_level, lastSwitchCount + 1, 0, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + if (current_best_solution.TotalCompare > right_solutions.TotalCompare) + { + if (!this.CheckMaxLevel(right_solutions.Items)) + { + continue; + } + + current_best_solution.TotalCompare = right_solutions.TotalCompare; + current_best_solution.TotalFlow = right_solutions.TotalFlow; + current_best_solution.Items = new List<RunBlock>(right_solutions.Items.Count + 1); + current_best_solution.Items.Add(new RunBlock() + { + PumpCount = 0, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + current_best_solution.Items.AddRange(right_solutions.Items); + } + } + } + #endregion + + #region 宸︿晶 寮�鏈� + { + for (int pumpNum_left = 1; pumpNum_left <= 4; pumpNum_left++) + { + if (pumpNum_left == lastOpenPumpCount) + continue; + for (int splitIndx = startTimeIndx + _minTimeCountSwitch; + splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) + { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 + + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; + + _totalCalcCount++; + + double left_sumCompareLeft = 0; + double left_sumFlowLeft = 0; // 鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勬祦閲� + + //鑾峰彇浠庡紑濮嬫椂闂达紝鍒扮粨鏉熸椂闂达紝寮�pumpNum鍙版车鐨勮垂鐢� + var td = GetTimeDataBundle(pumpNum_left); + td.GetRangeData1(startTimeIndx, splitIndx, + out left_sumFlowLeft, out left_sumCompareLeft); + if (left_sumCompareLeft == double.MaxValue) + continue; + + var total_current_flow = left_sumFlowLeft + lastTotalFlow; + if (total_current_flow >= this._stationTotalFlow) + {//宸︿晶宸茬粡鑳借揪鍒拌姹備簡 + if (current_best_solution.TotalCompare > left_sumCompareLeft) + { + //宸︿晶缁撴潫鏃剁殑姘翠綅(鍙充晶寮�濮嬫椂) + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + if (!this.CheckMaxLevel(startTimeIndx, lastReservoirHeight, splitIndx, left_end_level)) + { + continue; + } + current_best_solution.TotalCompare = left_sumCompareLeft; + current_best_solution.TotalFlow = left_sumFlowLeft; + current_best_solution.Items = new List<RunBlock>() { + new RunBlock(){ + PumpCount = pumpNum_left , + StartIndx = startTimeIndx, + EndIndx = splitIndx , + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + } }; + } + //break;//涓嶇敤鍐嶇户缁簡,鍐嶇户缁� 鍔熺巼鍙細瓒婃潵瓒婂ぇ + } + else + { + //宸︿晶缁撴潫鏃剁殑姘翠綅 + var left_end_level = CalcReservoirHeight( + startTimeIndx, + splitIndx, + left_sumFlowLeft, lastReservoirHeight); + if (!this.CheckMaxLevel(startTimeIndx, lastReservoirHeight, splitIndx, left_end_level)) + { + continue; + } + //鍙充晶缁х画杩唬 + BlockItemList right_solutions = RecursionFindRight_瀹氭按浣峗鎸囧畾鏃堕棿( + total_current_flow, left_end_level, lastSwitchCount + 1, pumpNum_left, splitIndx); + if (right_solutions == null || right_solutions.TotalCompare == double.MaxValue) + {//娌℃湁鎵惧埌鍚堥�傜殑 + continue; + } + double cur_sumPower = left_sumCompareLeft + right_solutions.TotalCompare; + if (current_best_solution.TotalCompare > cur_sumPower) + { + if (!this.CheckMaxLevel(current_best_solution.Items)) + { + continue; + } + current_best_solution.TotalCompare = cur_sumPower; + current_best_solution.TotalFlow = left_sumFlowLeft + right_solutions.TotalFlow; + + current_best_solution.Items = new List<RunBlock>(right_solutions.Items); + current_best_solution.Items.Insert(0,//鍦ㄥ墠闈㈡彃鍏ュ乏渚ф椂闂村潡 + new RunBlock() + { + PumpCount = pumpNum_left, + StartIndx = startTimeIndx, + EndIndx = splitIndx, + TotalCompare = left_sumCompareLeft, + TotalFlow = left_sumFlowLeft, + ReservoirStartHeight = lastReservoirHeight, + ReservoirEndHeight = left_end_level + }); + } + } + } + } + } + + #endregion + } + else + { + + } + + if (current_best_solution.TotalCompare == double.MaxValue) + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = null; + //} + + return null; + } + else + { + //if (isNeedInsertCache) + //{ + // _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = current_best_solution; + //} + return current_best_solution; + } + } + + + + + + + } +} \ No newline at end of file diff --git "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\351\207\217.cs" "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\351\207\217.cs" index ec7176a..cc06db6 100644 --- "a/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\351\207\217.cs" +++ "b/Calc/IStation.Calc.Core/\351\200\222\345\275\222\350\256\241\347\256\2272/ErQuCalcHelper_2_\351\200\222\345\275\222_\345\256\232\346\260\264\351\207\217.cs" @@ -8,7 +8,7 @@ { internal partial class ErQuCalcHelper_2_閫掑綊_瀹氭按閲� : ErQuCalcHelper_2_閫掑綊 { - List<List<Dictionary<int, BlockItemList>>> _dictCalcCache; + protected List<List<Dictionary<int, BlockItemList>>> _dictCalcCache瀹氭按閲�; /// <summary> /// @@ -20,9 +20,12 @@ _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; //this._maxPumpSwitchCount = 5; - var result = CalcOptPrjsCore_瀹氭祦閲�(); + var result = CalcOptPrjsBlockItems瀹氭按閲�(); if (result == null) return null; + + OnShowDebugInfo.Invoke(string.Format("璁$畻娆℃暟:{0:N0}, 缂撳瓨浣跨敤娆℃暟:{1:N0}", this._totalCalcCount, this._totalCacheCount)); + return ToAnaPrj(result); } @@ -30,9 +33,9 @@ /// /// </summary> /// <returns></returns> - private BlockItemList CalcOptPrjsCore_瀹氭祦閲�() + protected BlockItemList CalcOptPrjsBlockItems瀹氭按閲�() { - _dictCalcCache = new List<List<Dictionary<int, BlockItemList>>>(_timeDataListCount + 1); + _dictCalcCache瀹氭按閲� = new List<List<Dictionary<int, BlockItemList>>>(_timeDataListCount + 1); for (int i = 0; i < _timeDataListCount + 1; i++) { var ak = new List<Dictionary<int, BlockItemList>>(_timeDataListCount + 1); @@ -40,11 +43,11 @@ { ak.Add(new Dictionary<int, BlockItemList>()); } - _dictCalcCache.Add(ak); + _dictCalcCache瀹氭按閲�.Add(ak); } - var result = RecursionFind鍒濆_瀹氭祦閲�(); + var result = RecursionFind鍒濆_瀹氭按閲�(); if (result == null || result.Items == null) return null; if (result.Items.First().StartIndx > 0) @@ -114,7 +117,7 @@ /// /// </summary> /// <returns></returns> - private BlockItemList RecursionFind鍒濆_瀹氭祦閲�() + private BlockItemList RecursionFind鍒濆_瀹氭按閲�() { int startSwitchTimeIndx = _minTimeCountSwitch;//淇濊瘉涓嶆槸涓�寮�濮嬪氨杩涜娉靛垏鎹� @@ -249,8 +252,8 @@ StartIndx = 0, EndIndx = splitIndx, TotalCompare = sumCompareLeft, - TotalFlow = sumFlowLeft - }); + TotalFlow = sumFlowLeft + }); //if (opt_num == 3)//涓存椂 // return current_best_solution; } @@ -276,7 +279,7 @@ /// <param name="lastSwitchCount">褰撳墠鍒囨崲娆℃暟</param> /// <param name="startTimeIndx">寮�濮嬫椂闂存瑙掓爣</param> /// <returns></returns> - BlockItemList RecursionFindRight_瀹氭按閲�( + private BlockItemList RecursionFindRight_瀹氭按閲�( double lastTotalFlow, int lastSwitchCount, int lastOpenPumpCount, @@ -304,17 +307,17 @@ bool isNeedInsertCache = true; - if (_dictCalcCache[startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) + if (_dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount].ContainsKey(flowKey)) { _totalCacheCount++; - var cache_model = _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey]; + var cache_model = _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey]; if (cache_model == null) return null; if (cache_model.Items.First().PumpCount == lastOpenPumpCount) return null; isNeedInsertCache = false; - + if (cache_model.TotalFlow + lastTotalFlow >= this._stationTotalFlow) { BlockItemList cache_model_copy = new BlockItemList(); @@ -323,7 +326,6 @@ cache_model_copy.Items = new List<RunBlock>(cache_model.Items); return cache_model_copy; } - } @@ -359,7 +361,7 @@ { new RunBlock() { - PumpCount = pumpNum_left , + PumpCount = pumpNum_left, StartIndx = startTimeIndx, EndIndx = _timeDataListCount - 1, TotalCompare = sumCompareWhole, @@ -416,7 +418,7 @@ for (int splitIndx = startTimeIndx + _minTimeCountSwitch; splitIndx < _timeDataListCount - _minTimeCountSwitch; splitIndx++) { //娌℃湁 splitIndx = endTimeIndx鐨勬儏鍐�,鍓嶉潰宸茶�冭檻 - + if (!_timeList[splitIndx].IsSwitchPumpAble) continue; _totalCalcCount++; @@ -488,18 +490,18 @@ if (current_best_solution.TotalCompare == double.MaxValue) { - if(isNeedInsertCache) + if (isNeedInsertCache) { - _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = null; + _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey] = null; } - + return null; } else { if (isNeedInsertCache) { - _dictCalcCache[startTimeIndx][lastSwitchCount][flowKey] = current_best_solution; + _dictCalcCache瀹氭按閲廩startTimeIndx][lastSwitchCount][flowKey] = current_best_solution; } return current_best_solution; } diff --git a/WinFrmUI/IStation.WinFrmUI.CalcErQu/Wizard/pageCalcParas.cs b/WinFrmUI/IStation.WinFrmUI.CalcErQu/Wizard/pageCalcParas.cs index ff5404f..7ee8542 100644 --- a/WinFrmUI/IStation.WinFrmUI.CalcErQu/Wizard/pageCalcParas.cs +++ b/WinFrmUI/IStation.WinFrmUI.CalcErQu/Wizard/pageCalcParas.cs @@ -309,11 +309,11 @@ //IStation.SettingsHelper.Save(); - PredictWater predictWater = new PredictWater(); - //绠楁硶 - var Predict= predictWater.GetPredictWaterOneDay(new DateTime(2023, 3, 1, 0, 0, 0), new DateTime(2023, 3, 1, 23, 0, 0), 30,out string error); - //骞冲潎鏁� - var Ana = predictWater.GetAnaWaterOneDay(new DateTime(2023, 3, 1, 0, 0, 0), new DateTime(2023, 3, 1, 23, 0, 0), 30,out string error1); + //PredictWater predictWater = new PredictWater(); + // //绠楁硶 + //var Predict= predictWater.GetPredictWaterOneDay(new DateTime(2023, 3, 1, 0, 0, 0), new DateTime(2023, 3, 1, 23, 0, 0), 30,out string error); + // //骞冲潎鏁� + // var Ana = predictWater.GetAnaWaterOneDay(new DateTime(2023, 3, 1, 0, 0, 0), new DateTime(2023, 3, 1, 23, 0, 0), 30,out string error1); diff --git a/WinFrmUI/IStation.WinFrmUI.Monitor/IStation.WinFrmUI.Monitor.csproj b/WinFrmUI/IStation.WinFrmUI.Monitor/IStation.WinFrmUI.Monitor.csproj index 64973d6..148d166 100644 --- a/WinFrmUI/IStation.WinFrmUI.Monitor/IStation.WinFrmUI.Monitor.csproj +++ b/WinFrmUI/IStation.WinFrmUI.Monitor/IStation.WinFrmUI.Monitor.csproj @@ -398,7 +398,6 @@ <EmbeddedResource Include="monitor\chart\TimeValueEasyChartView.resx"> <DependentUpon>TimeValueEasyChartView.cs</DependentUpon> </EmbeddedResource> - <EmbeddedResource Include="Properties\licenses.licx" /> <EmbeddedResource Include="Properties\Resources.resx"> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> -- Gitblit v1.9.3