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; using static IStation.InternalModel.TimeData; namespace IStation.Calc { public partial class ErQuCalcHelper { /// /// 递归 /// /// /// private List CalcOptPrjsCoreCCC( ) { _minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute; _minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute; //int rangeMinIndx = 0; //int rangeMaxIndx = TimeDataListCount - 1; //sum_Q = new double[5, TimeDataListCount, TimeDataListCount]; //sum_P = new double[5, TimeDataListCount, TimeDataListCount]; dictCalcCache = new Dictionary[MaxPumpSwitchCount + 1]; for (int i = 0; i < dictCalcCache.Length; i++) { dictCalcCache[i] = new Dictionary(); } //dict.Clear(); var result = RecursionFuncCCC(this._targetFlowTotal, 0, timeDataListCount-1, MaxPumpSwitchCount); 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.PumpNum == 0) { continue; } var itemSumDatas = new List(); var td = GetTimeDataBundle(s.PumpNum); 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; } int TotalCalcCount = 0; Dictionary[] dictCalcCache; //List> prices = new List>(); //List> qs = new List>(); //double[,,] sum_Q = null;// new double[5, 288, 288]; //double[,,] sum_P = null;//new double[5, 288, 288]; class RecSolutionBundle { public List Solutions = new List(); public double BestPara;//功率或者电费 public int PumpSwitchCount; } class RecSolution { public int PumpNum; public int EndIndx; public int StartIndx; public double SumFlow; public double SumPower; public double SumMoney; //public Solution(int pumpNum, int startIndx, int endIndx ) //{ // PumpNum = pumpNum; // StartTimeIndx = startIndx; // EndTimeIndx = endIndx; //} public RecSolution(int pumpNum, int startIndx, int endIndx, double sumFlow,double sumPower, double sumMoney) { PumpNum = pumpNum; StartIndx = startIndx; EndIndx = endIndx; SumFlow = sumFlow; SumPower = sumPower; SumMoney = sumMoney; } } /// /// 递归 /// /// /// /// /// /// RecSolutionBundle RecursionFuncCCC(double TotalFlow, int startTimeIndx, int endTimeIndx, int maxPumpSwitchSize) { RecSolutionBundle bestPumpStateSolution = new RecSolutionBundle(); if (maxPumpSwitchSize < 0) {//不能再切换泵了 TotalCalcCount++; bestPumpStateSolution.Solutions.Insert(0, new RecSolution(0, startTimeIndx, endTimeIndx, TotalFlow, double.MaxValue, double.MaxValue)); // 将当前泵和i的选择加入最优解 bestPumpStateSolution.BestPara = double.MaxValue; return bestPumpStateSolution; } if (TotalFlow <= 0) {//已达到流量 TotalCalcCount++; bestPumpStateSolution.Solutions.Insert(0, new RecSolution(0, startTimeIndx, endTimeIndx, TotalFlow, 0, 0)); // 将当前泵和i的选择加入最优解 bestPumpStateSolution.BestPara = 0; return bestPumpStateSolution; } // string key = string.Format("{0}.{1}.{2}",startTimeIndx , endTimeIndx, ((int)TotalFlow)/10000); if (dictCalcCache[maxPumpSwitchSize].ContainsKey(key)) { TotalCalcCount++; return dictCalcCache[maxPumpSwitchSize][key]; } //if (dict.ContainsKey(key) ) //{ // TotalCalcCount++; // return dict[key]; //} double bestParas = double.MaxValue; for (int iTime = startTimeIndx + 1; iTime <= endTimeIndx; iTime++) { for (int pumpNum = 0; pumpNum <= 4; pumpNum++) { double sumPower = 0; double sumMoney1 = 0; double sumFlow = 0;////获取从开始时间,到结束时间,开pumpNum台泵的流量 if(pumpNum > 0) {//获取从开始时间,到结束时间,开pumpNum台泵的费用 var td = GetTimeDataBundle(pumpNum); td.GetSpanData(startTimeIndx, iTime, out sumFlow, out sumPower, out sumMoney1); } double best0 = double.MaxValue; RecSolutionBundle solution = new RecSolutionBundle(); if (iTime < endTimeIndx) { solution = RecursionFuncCCC(TotalFlow - sumFlow, iTime, endTimeIndx, maxPumpSwitchSize - 1); best0 = sumPower + solution.BestPara; } else if (TotalFlow - sumFlow <= 0) { best0 = sumPower; solution.Solutions.Insert(0, new RecSolution(0, iTime, endTimeIndx, TotalFlow - sumFlow, 0, 0)); } if (bestParas > best0) { bestParas = best0; bestPumpStateSolution.Solutions = new List(solution.Solutions); // 更新最优解 bestPumpStateSolution.Solutions.Insert(0, new RecSolution(pumpNum, startTimeIndx, iTime, sumFlow, sumPower, sumMoney1)); // 将当前泵和i的选择加入最优解 } } } bestPumpStateSolution.BestPara = bestParas; bestPumpStateSolution.PumpSwitchCount = maxPumpSwitchSize; dictCalcCache[maxPumpSwitchSize][key] = bestPumpStateSolution; TotalCalcCount++; return bestPumpStateSolution; } } }