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<List<Dictionary<int, BlockItem>>> _dictCalcCache;
|
|
/// <summary>
|
///
|
/// </summary>
|
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;
|
//}
|
}
|
/// <summary>
|
/// 递归
|
/// </summary>
|
/// <param name="dd_minute"></param>
|
/// <returns></returns>
|
protected override List<AnaPrj> CalcOptPrjsCore()
|
{
|
_minTimeCountOpenPump = this.MinOpenPumpMinute / this.CalcSpaceMinute;
|
_minTimeCountSwitch = this.MinSwitchPumpMinute / this.CalcSpaceMinute;
|
this._maxPumpSwitchCount = 3;
|
|
_dictCalcCache = new List<List<Dictionary<int , BlockItem>>>(timeDataListCount + 1);
|
for (int i = 0; i < timeDataListCount + 1; i++)
|
{
|
var ak = new List<Dictionary<int, BlockItem>>(timeDataListCount + 1);
|
for (int j = 0; j < timeDataListCount + 1; j++)
|
{
|
ak.Add(new Dictionary<int, BlockItem>());
|
}
|
_dictCalcCache.Add(ak);
|
}
|
|
|
var result = RecursionFind(this._targetFlowTotal, this._maxPumpSwitchCount, 0, timeDataListCount - 1);
|
|
|
//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.PumpCount == 0)
|
// {
|
// continue;
|
// }
|
// var itemSumDatas = new List<AnaPrjItemSumData>();
|
// 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<AnaPrj>();
|
//opt_prjs.Add(opt_prj);
|
return opt_prjs;
|
}
|
|
|
|
|
|
/// <summary>
|
/// 递归
|
/// </summary>
|
/// <param name="currentTargetTotalFlow"></param>
|
/// <param name="startTimeIndx"></param>
|
/// <param name="endTimeIndx"></param>
|
/// <param name="maxPumpSwitchSize"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|