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;
}
}
}