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
|
{
|
|
|
|
|
/// <summary>
|
/// 递归
|
/// </summary>
|
/// <param name="dd_minute"></param>
|
/// <returns></returns>
|
private List<AnaPrj> 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<string , RecSolutionBundle>[MaxPumpSwitchCount + 1];
|
for (int i = 0; i < dictCalcCache.Length; i++)
|
{
|
dictCalcCache[i] = new Dictionary<string, RecSolutionBundle>();
|
}
|
//dict.Clear();
|
|
var result = RecursionFuncCCC(this._targetFlowTotal, 0, timeDataListCount-1, MaxPumpSwitchCount);
|
|
|
AnaPrj opt_prj = new AnaPrj();
|
opt_prj.Items = new List<AnaPrjItem>();
|
|
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<AnaPrjItemSumData>();
|
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<AnaPrj>();
|
opt_prjs.Add(opt_prj);
|
return opt_prjs;
|
}
|
|
int TotalCalcCount = 0;
|
Dictionary<string , RecSolutionBundle>[] dictCalcCache;
|
|
//List<List<double>> prices = new List<List<double>>();
|
//List<List<double>> qs = new List<List<double>>();
|
//double[,,] sum_Q = null;// new double[5, 288, 288];
|
//double[,,] sum_P = null;//new double[5, 288, 288];
|
class RecSolutionBundle
|
{
|
public List<RecSolution> Solutions = new List<RecSolution>();
|
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;
|
|
}
|
}
|
/// <summary>
|
/// 递归
|
/// </summary>
|
/// <param name="TotalFlow"></param>
|
/// <param name="startTimeIndx"></param>
|
/// <param name="endTimeIndx"></param>
|
/// <param name="maxPumpSwitchSize"></param>
|
/// <returns></returns>
|
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<RecSolution>(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;
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|