using IStation.CalcModel; using IStation.InternalModel; using IStation.Model; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlTypes; using System.Drawing; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace IStation.Calc { public partial class ErQuCalcHelper_Core秦白云飞版_优化2 : ErQuCalcBaseHelper { public ErQuCalcHelper_Core秦白云飞版_优化2() { this._calcSpaceMinute = 5; } List>> _dictCalcCache; /// /// /// class BlockItem { public BlockItem Next; public int PumpCount; public int EndIndx; public int StartIndx; //public double SumFlow; //public double SumCompare;//区间 public double BestTotalCompare;//功率或者电费(合计) //public BlockItem() { } //public BlockItem(int pumpNum, int startIndx, int endIndx, double sumFlow, double sumCompare) //{ // PumpCount = pumpNum; // StartIndx = startIndx; // EndIndx = endIndx; // SumFlow = sumFlow; // SumCompare = sumCompare; //} } /// /// 递归 /// /// /// protected override List CalcOptPrjsCore() { _minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute; _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; this._maxPumpSwitchCount = 3; _dictCalcCache = new List>>(timeDataListCount + 1); for (int i = 0; i < timeDataListCount + 1; i++) { var ak = new List>(timeDataListCount + 1); for (int j = 0; j < timeDataListCount + 1; j++) { ak.Add(new Dictionary()); } _dictCalcCache.Add(ak); } var result = RecursionFind(this._targetFlowTotal, this._maxPumpSwitchCount, 0, timeDataListCount - 1); //AnaPrj opt_prj = new AnaPrj(); //opt_prj.Items = new List(); //double sumPower = 0, sumFlow = 0, sumMoney = 0; //foreach (var s in from x in result.Solutions orderby x.StartIndx select x) //{ // if (s.PumpCount == 0) // { // continue; // } // var itemSumDatas = new List(); // var td = GetTimeDataBundle(s.PumpCount); // for (int i = s.StartIndx; i < s.EndIndx; i++) // { // itemSumDatas.Add(new AnaPrjItemSumData(_timeList[i], // td.TimeDatas[i])); // sumPower += td.TimeDatas[i].SumPower; // sumFlow += td.TimeDatas[i].SumFlow; // sumMoney += td.TimeDatas[i].SumMoney; // } // opt_prj.Items.Add(new AnaPrjItem() // { // StartTime = _timeList[s.StartIndx], // EndTime = _timeList[s.EndIndx], // OpenPumpIndexs = (from x in td.OpenPumpInfos select x.PumpIndex).ToList(), // SumData = itemSumDatas // }); //} //opt_prj.SumMoney = sumMoney; //opt_prj.SumFlow = sumFlow; //opt_prj.SumPower = sumPower; //string txt = $"计算耗时{(DateTime.Now - dt).TotalSeconds}秒\r\n最少的电费为{result.BestPrice}\r\n计算次数为{TotalCalcCount}\r\n"; //DateTime lastTime = default(DateTime); //foreach (var solution in solutions) //{ // // txt += $"{getTimebyInt(solution.IS):HH:mm}-{getTimebyInt(solution.I):HH:mm}\t开{solution.PumpNum}台\t流量{solution.Q}\t电费{solution.Price}\r\n"; // // lastTime = getTimebyInt(solution.I); //} var opt_prjs = new List(); //opt_prjs.Add(opt_prj); return opt_prjs; } /// /// 递归 /// /// /// /// /// /// BlockItem RecursionFind( double spanTargetTotalFlow, int maxSwitchCount, int startTimeIndx, int endTimeIndx) { if (maxSwitchCount < 0) {//不能再切换泵了 //_totalCalcCount++; return null; //current_best_solution.Solutions.Add( new RecSolution(0, startTimeIndx, endTimeIndx, currentTargetTotalFlow, double.MaxValue)); // 将当前泵和i的选择加入最优解 //current_best_solution.BestPara = double.MaxValue; //return current_best_solution; } if (spanTargetTotalFlow < 0) {//已达到流量 //_totalCalcCount++; return null; //current_best_solution.Solutions.Add( // new RecSolution(0, startTimeIndx, endTimeIndx, currentTargetTotalFlow, 0)); // 将当前泵和i的选择加入最优解 //current_best_solution.BestPara = 0; //return current_best_solution; } // int flowKey = (int)(spanTargetTotalFlow / 10); int key = maxSwitchCount * 1000000 + flowKey; if (_dictCalcCache[startTimeIndx][endTimeIndx].ContainsKey(key)) { _totalCalcCount++; return _dictCalcCache[startTimeIndx][endTimeIndx][key]; } BlockItem current_best_solution = new BlockItem(); current_best_solution.BestTotalCompare = double.MaxValue; #region 判断: 全部都一样(不切换泵), 是否可以 for (int pumpNum = 1; pumpNum <= 4; pumpNum++) { //_totalCalcCount++; double sumCompareWhole = 0; double sumFlowWhole = 0; // 获取从开始时间,到结束时间,开pumpNum台泵的流量 //获取从开始时间,到结束时间,开pumpNum台泵的费用 var td = GetTimeDataBundle(pumpNum); td.GetRangeData1(startTimeIndx, endTimeIndx, out sumFlowWhole, out sumCompareWhole ); if ( sumFlowWhole >= spanTargetTotalFlow && sumCompareWhole < current_best_solution.BestTotalCompare) {//完整 current_best_solution.BestTotalCompare = sumCompareWhole; current_best_solution.PumpCount = pumpNum; current_best_solution.StartIndx = startTimeIndx; current_best_solution.EndIndx = endTimeIndx; //current_best_solution.SumFlow = sumFlowWhole; //current_best_solution.SumCompare = sumPowerWhole; current_best_solution.Next = null; } } #endregion if (maxSwitchCount > 0) { for (int splitIndx = startTimeIndx + _minTimeCountSwitch; splitIndx < endTimeIndx; splitIndx++) {//没有 splitIndx = endTimeIndx的情况,前面已考虑 for (int pumpNum = 0; pumpNum <= 4; pumpNum++) { //_totalCalcCount++; double sumCompareLeft = 0; double sumFlowLeft = 0; // 获取从开始时间,到结束时间,开pumpNum台泵的流量 if (pumpNum > 0) {//获取从开始时间,到结束时间,开pumpNum台泵的费用 var td = GetTimeDataBundle(pumpNum); td.GetRangeData1(startTimeIndx, splitIndx, out sumFlowLeft, out sumCompareLeft); } double cur_sumPower = sumCompareLeft; BlockItem right_solution = null; if (sumFlowLeft < spanTargetTotalFlow) { //右侧继续迭代 right_solution = RecursionFind( spanTargetTotalFlow - sumFlowLeft, maxSwitchCount - 1, splitIndx, endTimeIndx); if (right_solution != null) { cur_sumPower = sumCompareLeft + right_solution.BestTotalCompare; } else {//没有找到合适的 continue; } } // if (lastTotalFlow + sumFlowWhole >= this._targetFlowTotal && sumPowerWhole < bestParas) if (current_best_solution.BestTotalCompare > cur_sumPower) { current_best_solution.BestTotalCompare = cur_sumPower; // 将当前泵和i的选择加入最优解 //if (right_solution != null) //{ current_best_solution.PumpCount = pumpNum; current_best_solution.StartIndx = startTimeIndx; current_best_solution.EndIndx = splitIndx; //current_best_solution.SumFlow = sumFlowLeft; //current_best_solution.SumCompare = sumPowerLeft; current_best_solution.Next = right_solution; //} //else //{ // current_best_solution.Solution.PumpCount = pumpNum; // current_best_solution.Solution.StartIndx = startTimeIndx; // current_best_solution.Solution.EndIndx = splitIndx; // current_best_solution.Solution.SumFlow = sumFlowLeft; // current_best_solution.Solution.SumCompare = sumPowerLeft; // current_best_solution.Solution.Next = null; //} } } } } if(current_best_solution.BestTotalCompare == double.MaxValue) { _dictCalcCache[startTimeIndx][endTimeIndx][key] = null; return null; } else { _dictCalcCache[startTimeIndx][endTimeIndx][key] = current_best_solution; return current_best_solution; } } } }