From d63b83c2c745c1f8a140221c28c0e6dbe61d6110 Mon Sep 17 00:00:00 2001 From: ningshuxia <ningshuxia0927@outlook.com> Date: 星期二, 30 四月 2024 17:47:17 +0800 Subject: [PATCH] 调度修改 --- Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs | 28 Schedule/IStation.Client/Form1.cs | 2 Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(4).cs | 291 +++++++++ Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(3).cs | 275 ++++++++ Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(5).cs | 290 +++++++++ Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs | 347 ++++++---- Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制.cs | 255 ++++++++ Schedule/IStation.Algorithm/IStation.Algorithm.csproj | 5 Schedule/IStation.Algorithm/Schedule/SchedulingHelper - 复制(2).cs | 288 +++++++++ Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs | 34 Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs | 25 Schedule/IStation.Algorithm/Entity/ScheduleConclusion.cs | 5 12 files changed, 1,695 insertions(+), 150 deletions(-) diff --git a/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs index fb0e762..f1c8372 100644 --- a/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs +++ b/Schedule/IStation.Algorithm/DAL/ScheduleConclusion.cs @@ -224,7 +224,29 @@ /// <summary> - /// 澶ф壒閲忔彃鍏� + /// 鏌ヨ + /// </summary> + public List<Entity.ScheduleConclusion> GetList(string runFlag, double targetHead) + { + var tableName = GetTableName(runFlag); + using (SqlSugarClient db = Connection) + { + var sql = $"select count(*) from sqlite_master where type = 'table' and name = '{tableName}';"; + if (db.Ado.GetInt(sql) < 1) + { + return default; + } + var list = db.Queryable<Entity.ScheduleConclusion>().AS(tableName) + .Where(x => x.Head == targetHead) + .OrderBy(x => x.Power) + .ToList(); + return list; + } + + } + + /// <summary> + /// 鏌ヨ /// </summary> public List<Entity.ScheduleConclusion> GetList(string runFlag, double targetFlow, double targetHead, int takeCount) { @@ -243,7 +265,6 @@ .ToList(); return list; } - } diff --git a/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs b/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs index 16b6bc6..798692e 100644 --- a/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs +++ b/Schedule/IStation.Algorithm/Entity/ScheduleCombine.cs @@ -19,6 +19,11 @@ this.Pump3 = rhs.Pump3; this.CurveQH = rhs.CurveQH; this.CurveQP = rhs.CurveQP; + + this.MinFlow = rhs.MinFlow; + this.MaxFlow = rhs.MaxFlow; + this.MaxHead = rhs.MaxHead; + this.MinHead = rhs.MinHead; this.AnaStatus = rhs.AnaStatus; } @@ -31,8 +36,7 @@ /// <summary> /// 杩愯鏍囧織 - /// </summary> - [SplitField] + /// </summary> public string RunFlag { get; set; } /// <summary> @@ -66,6 +70,26 @@ public string CurveQP { get; set; } /// <summary> + /// 鏈�澶ф祦閲� + /// </summary> + public double MaxFlow { get; set; } + + /// <summary> + /// 鏈�灏忔祦閲� + /// </summary> + public double MinFlow { get; set; } + + /// <summary> + /// 鏈�澶ф壃绋� + /// </summary> + public double MaxHead { get; set; } + + /// <summary> + /// 鏈�灏忔壃绋� + /// </summary> + public double MinHead { get; set; } + + /// <summary> /// 鍒嗘瀽鐘舵�� /// </summary> public bool AnaStatus { get; set; } diff --git a/Schedule/IStation.Algorithm/Entity/ScheduleConclusion.cs b/Schedule/IStation.Algorithm/Entity/ScheduleConclusion.cs index 13e5986..65a21ce 100644 --- a/Schedule/IStation.Algorithm/Entity/ScheduleConclusion.cs +++ b/Schedule/IStation.Algorithm/Entity/ScheduleConclusion.cs @@ -14,6 +14,7 @@ { this.ID = rhs.ID; this.ScheduleCombineID = rhs.ScheduleCombineID; + this.RunFlag = rhs.RunFlag; this.Pump1 = rhs.Pump1; this.Pump2 = rhs.Pump2; this.Pump3 = rhs.Pump3; @@ -50,10 +51,10 @@ /// <summary> /// 杩愯鏍囧織 - /// </summary> - // [SplitField] + /// </summary> public string RunFlag { get; set; } + /// <summary> /// 娉�1 /// </summary> diff --git a/Schedule/IStation.Algorithm/IStation.Algorithm.csproj b/Schedule/IStation.Algorithm/IStation.Algorithm.csproj index 36d7d7a..381f4a8 100644 --- a/Schedule/IStation.Algorithm/IStation.Algorithm.csproj +++ b/Schedule/IStation.Algorithm/IStation.Algorithm.csproj @@ -35,6 +35,11 @@ <Compile Remove="Schedule\SchedulingAnaHelper_v1.cs" /> <Compile Remove="Schedule\SchedulingAnaHelper_v3.cs" /> <Compile Remove="Schedule\SchedulingCombineAnaHelper - 澶嶅埗.cs" /> + <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%282%29.cs" /> + <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%283%29.cs" /> + <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%284%29.cs" /> + <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗%285%29.cs" /> + <Compile Remove="Schedule\SchedulingHelper - 澶嶅埗.cs" /> </ItemGroup> <ItemGroup> diff --git a/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs b/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs index 38a5f47..fa8d83e 100644 --- a/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs +++ b/Schedule/IStation.Algorithm/Schedule/SchedulingAnaHelper.cs @@ -195,6 +195,12 @@ scheduleCombine.Pump1 = freItem.Frequency; scheduleCombine.CurveQH = freItem.CurveQH.ToJson(); scheduleCombine.CurveQP = freItem.CurveQP.ToJson(); + + freItem.CurveQH.GetMinMaxPointY(out double maxHead, out double minHead); + scheduleCombine.MinFlow = freItem.CurveQH.Min; + scheduleCombine.MaxFlow = freItem.CurveQH.Max; + scheduleCombine.MaxHead = maxHead; + scheduleCombine.MinHead = minHead; scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } @@ -239,8 +245,18 @@ scheduleCombine.RunCount = pumpCount; scheduleCombine.Pump1 = freItem1.Frequency; scheduleCombine.Pump2 = freItem2.Frequency; - scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson(); - scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson(); + + var curveQH = FitHelper.BuildCurveExpress(pointQH); + var curveQP = FitHelper.BuildCurveExpress(pointQP); + + scheduleCombine.CurveQH = curveQH.ToJson(); + scheduleCombine.CurveQP = curveQP.ToJson(); + + curveQH.GetMinMaxPointY(out double maxHead, out double minHead); + scheduleCombine.MinFlow = curveQH.Min; + scheduleCombine.MaxFlow = curveQH.Max; + scheduleCombine.MaxHead = maxHead; + scheduleCombine.MinHead = minHead; scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } @@ -290,8 +306,18 @@ scheduleCombine.Pump1 = freItem1.Frequency; scheduleCombine.Pump2 = freItem2.Frequency; scheduleCombine.Pump3 = freItem3.Frequency; - scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson(); - scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson(); + + var curveQH = FitHelper.BuildCurveExpress(pointQH); + var curveQP = FitHelper.BuildCurveExpress(pointQP); + + scheduleCombine.CurveQH = curveQH.ToJson(); + scheduleCombine.CurveQP = curveQP.ToJson(); + + curveQH.GetMinMaxPointY(out double maxHead, out double minHead); + scheduleCombine.MinFlow = curveQH.Min; + scheduleCombine.MaxFlow = curveQH.Max; + scheduleCombine.MaxHead = maxHead; + scheduleCombine.MinHead = minHead; scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0502\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0502\051.cs" new file mode 100644 index 0000000..8f29a13 --- /dev/null +++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0502\051.cs" @@ -0,0 +1,288 @@ +锘縩amespace IStation.Algorithm +{ + + #region ViewModel + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class AnaItem + { + public AnaItem() { } + public string RunFlag { get; set; } + public int RunCount { get; set; } + public List<long> PumpIds { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + } + + #endregion + + /// <summary> + /// 璋冨害鍒嗘瀽杈呭姪绫� + /// </summary> + public class SchedulingHelper + { + double _frequency_def = 50; + double _frequency_min = 25; + double _frequency_max = 50; + double _frequency_space = 0.1;//棰戠巼闂撮殧 + + double _head_space = 0.1;//鎵▼闂撮殧 + + #region RunFlag + string _falgFrePumpTag = "B"; + string _falgFixPumpTag = "G"; + string _falgSpaceMark = "_"; + + string GetRunFlag(List<AnaPumpItem> pumpItems) + { + var tableName = string.Empty; + var count = pumpItems.Count; + pumpItems = pumpItems.OrderBy(p => p.ID).ToList(); + for (int i = 0; i < count; i++) + { + var pumpItem = pumpItems[i]; + tableName += GetRunFlag(pumpItem); + if ((i + 1) != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(AnaPumpItem pumpItem) + { + return (pumpItem.IsBp ? _falgFrePumpTag : _falgFixPumpTag) + pumpItem.ID; + } + + + string GetRunFlag(Dictionary<int, bool> dic) + { + var tableName = string.Empty; + var index = 0; + var count = dic.Count; + foreach (var item in dic) + { + tableName += GetRunFlag(item.Key, item.Value); + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(long id, bool isBp) + { + return (isBp ? _falgFrePumpTag : _falgFixPumpTag) + id; + } + + string GetRunFlag(List<string> flags) + { + var tableName = string.Empty; + var count = flags.Count; + var index = 0; + foreach (var flag in flags) + { + tableName += flag; + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(List<int> flags) + { + var tableName = string.Empty; + var count = flags.Count; + var index = 0; + foreach (var flag in flags) + { + tableName += flag; + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + + #endregion + + DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); + DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); + DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); + + + public class CurrentViewModel : Entity.ScheduleConclusion + { + public CurrentViewModel(Entity.ScheduleConclusion rhs) : base(rhs) + { + this.Flags = new List<int>(); + var flags = rhs.RunFlag.Split('_'); + foreach (var item in flags) + { + if (int.TryParse(item.Substring(1), out int flag)) + { + this.Flags.Add(flag); + } + + } + } + public List<int> Flags { get; set; } + } + + + public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead, List<int> openPumpCombine) + { + var pumpIds = pumps.Select(x => x.ID); + var dic_pump = pumps.ToDictionary(x => x.ID, x => x.IsBp); + + + if (openPumpCombine != null && openPumpCombine.Any()) + { + { + var optimalConclusionList = new List<CurrentViewModel>(); + foreach (var pump in openPumpCombine) + { + var runFalg = GetRunFlag(pump, dic_pump[pump]); + var list = _dalScheduleConclusion.GetList(runFalg, tagetHead, 1); + if (list != null && list.Any()) + { + var vmList = list.Select(x => new CurrentViewModel(x)).ToList(); + optimalConclusionList.AddRange(vmList); + } + } + if (optimalConclusionList == null || !optimalConclusionList.Any()) + { + return; + } + + var optimalConclusionCombineList = PermutationAndCombination<CurrentViewModel>.GetCombination(optimalConclusionList.ToArray(), 4); + var combines = new List<Combine>(); + foreach (var arr in optimalConclusionCombineList) + { + var falgs = arr.SelectMany(x => x.Flags).ToList(); + if (falgs.GroupBy(x => x).Where(x => x.Count() > 1).Count() > 0) + { + continue; + } + var combine = new Combine(); + combine.RunFlag = GetRunFlag(falgs); + combine.Power = arr.Sum(x => x.Power); + combine.Head = arr.Average(x => x.Head); + combine.Flow = arr.Sum(x => x.Flow); + combine.RunFlagList = falgs; + combines.Add(combine); + } + + var a = combines.OrderBy(x => x.Flow).ThenBy(x => x.Power).ToList(); + } + + + { + var allCombineList = PermutationAndCombination<int>.GetCombination(pumpIds.ToArray(), 2); + var combineList = new List<List<int>>(); + foreach (var combine in allCombineList) + { + var pump1 = combine[0]; + var pump2 = combine[1]; + if (!openPumpCombine.Contains(pump1)) + continue; + if (!openPumpCombine.Contains(pump2)) + continue; + combineList.Add(combine.ToList()); + } + if (combineList.Count < 1) + return; + + var avgFlow = tagetFlow / 2; + + var optimalConclusionList = new List<CurrentViewModel>(); + foreach (var combine in combineList) + { + var dic = new Dictionary<int, bool>(); + foreach (var pump in combine) + { + if (dic_pump.ContainsKey(pump)) + { + dic.Add(pump, dic_pump[pump]); + } + } + var runFalg = GetRunFlag(dic); + var list = _dalScheduleConclusion.GetList(runFalg, avgFlow, tagetHead, 5); + if (list != null && list.Any()) + { + var vmList = list.Select(x => new CurrentViewModel(x)).ToList(); + optimalConclusionList.AddRange(vmList); + } + } + if (optimalConclusionList == null || !optimalConclusionList.Any()) + { + return; + } + + var optimalConclusionCombineList = PermutationAndCombination<CurrentViewModel>.GetCombination(optimalConclusionList.ToArray(), 2); + var combines = new List<Combine>(); + foreach (var arr in optimalConclusionCombineList) + { + var falgs = arr.SelectMany(x => x.Flags).ToList(); + if (falgs.GroupBy(x => x).Where(x => x.Count() > 1).Count() > 0) + { + continue; + } + var combine = new Combine(); + combine.RunFlag = GetRunFlag(falgs); + combine.Power = arr.Sum(x => x.Power); + combine.Head = arr.Average(x => x.Head); + combine.Flow = arr.Sum(x => x.Flow); + combine.RunFlagList = falgs; + combines.Add(combine); + } + + var a = combines.OrderBy(x => x.Flow).ThenBy(x => x.Power).ToList(); + } + + + } + } + + private class Combine + { + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + public string RunFlag { get; set; } + public List<int> RunFlagList { get; set; } + } + + + + /// <summary> + /// 鎻掑叆鍒嗘瀽鏃ュ織 + /// </summary> + private void InsertAnaLog(string info) + { + var entity = new Entity.ScheduleAnaLog(info); + _dalAnaLog.Insert(entity); + } + + + /// <summary> + /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦� + /// </summary> + public bool ExistTable(string runFlag) + { + return _dal.ExistTable(runFlag); + } + + } +} diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0503\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0503\051.cs" new file mode 100644 index 0000000..83edfb0 --- /dev/null +++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0503\051.cs" @@ -0,0 +1,275 @@ +锘縰sing IStation.Model; + +namespace IStation.Algorithm +{ + + #region ViewModel + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class Combine + { + public Combine() { } + public List<int> PumpIds { get; set; } + public string RunFlag { get; set; } + public int RunCount { get; set; } + public double Frequency { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + } + + + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class OptimalCombine + { + public OptimalCombine() { } + public List<int> PumpIds { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + public List<Combine> Combines { get; set; } + } + + #endregion + + /// <summary> + /// 璋冨害鍒嗘瀽杈呭姪绫� + /// </summary> + public class SchedulingHelper + { + double _frequency_def = 50; + double _frequency_min = 25; + double _frequency_max = 50; + double _frequency_space = 0.1;//棰戠巼闂撮殧 + + double _head_space = 0.1;//鎵▼闂撮殧 + + #region RunFlag + string _falgFrePumpTag = "B"; + string _falgFixPumpTag = "G"; + string _falgSpaceMark = "_"; + + + string GetRunFlag(int[] flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Length; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetRunFlag(List<int> flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Count; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetGFlag(int flag) + { + return _falgFrePumpTag + flag; + } + + #endregion + + DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); + DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); + DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); + + + private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 }; + private List<int> _combineFlags2 = new List<int>() { 15 }; + + public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead, List<int> openPumpCombine) + { + List<int> open_combine_flags_1 = new List<int>(); + List<int> open_combine_flags_2 = new List<int>(); + + if (openPumpCombine != null && openPumpCombine.Any()) + { + foreach (var pump in openPumpCombine) + { + if (_combineFlags1.Contains(pump)) + { + open_combine_flags_1.Add(pump); + } + else + { + open_combine_flags_2.Add(pump); + } + } + } + else + { + open_combine_flags_1 = _combineFlags1.ToList(); + open_combine_flags_2 = _combineFlags2.ToList(); + } + + List<Combine> combineList1 = null; + List<Combine> combineList2 = null; + + var open_combine_flags_1_count = open_combine_flags_1.Count; + if (open_combine_flags_1_count > 0) + { + bool isSingular = false; + var combine_flags_combination_list = PermutationAndCombination<int>.GetCombination(open_combine_flags_1.ToArray(), 2); + if ((open_combine_flags_1_count % 2) > 0) + { + isSingular = true; + foreach (var flag in open_combine_flags_1) + { + combine_flags_combination_list.Add(new int[] { flag }); + } + } + + var combine_conclusion_dic = new Dictionary<string, List<Entity.ScheduleConclusion>>(); + foreach (var combine_flags in combine_flags_combination_list) + { + var runFlag = GetRunFlag(combine_flags); + if (combine_conclusion_dic.ContainsKey(runFlag)) + continue; + var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead); + combine_conclusion_dic[runFlag] = conclusionList; + } + + if (combine_conclusion_dic.Count < 1) + { + ////鏃犳硶璁$畻 + //return; + } + + var combine_flags_permutation_list = PermutationAndCombination<int>.GetPermutation(open_combine_flags_1.ToArray()); + foreach (var combine_flags_permutation in combine_flags_permutation_list) + { + var combine_part_flags_list = new List<int[]>(); + for (int i = 0; i < combine_flags_permutation.Length / 2; i++) + { + var flags = combine_flags_permutation.Skip(i * 2).Take(2).ToArray(); + combine_part_flags_list.Add(flags); + } + if (isSingular) + { + var last_flag = combine_flags_permutation[combine_flags_permutation.Length - 1]; + combine_part_flags_list.Add(new int[] { last_flag }); + } + if (combine_part_flags_list.Count < 1) + continue; + + + List<Combine> combines = new List<Combine>(); + foreach (var combine_part_flags in combine_part_flags_list) + { + var runFlag = GetRunFlag(combine_part_flags); + + } + + + } + + + } + + } + + + + + private OptimalCombine AnaOptimalCombine(List<Combine> combineList1, List<Combine> combineList2, double targetFlow, double targetHead) + { + double flowDeviation = targetFlow; + double totalPower = double.MaxValue; + double totalFlow = double.MaxValue; + + Combine optimalCombine1 = null; + Combine optimalCombine2 = null; + for (int combineIndex1 = 0; combineIndex1 < combineList1.Count; combineIndex1++) + { + for (int combineIndex2 = 0; combineIndex2 < combineList2.Count; combineIndex2++) + { + var combine1 = combineList1[combineIndex1]; + var combine2 = combineList2[combineIndex2]; + + var combineTotalFlow = combine1.Flow + combine2.Flow; + var combineTotalPower = combine1.Power + combine2.Power; + + var diffFlow = Math.Abs(combineTotalFlow - targetFlow); + if (diffFlow < flowDeviation) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + flowDeviation = diffFlow; + } + + if (diffFlow < targetFlow * 0.01 && combineTotalPower < totalPower) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + } + + } + } + if (optimalCombine1 == null && optimalCombine2 == null) + return default; + var optimalCombine = new OptimalCombine(); + optimalCombine.Combines = new List<Combine>(); + if (optimalCombine1 != null) + { + optimalCombine.Combines.Add(optimalCombine1); + } + if (optimalCombine2 != null) + { + optimalCombine.Combines.Add(optimalCombine2); + } + optimalCombine.Flow = totalFlow; + optimalCombine.Power = totalPower; + return optimalCombine; + } + + /// <summary> + /// 鎻掑叆鍒嗘瀽鏃ュ織 + /// </summary> + private void InsertAnaLog(string info) + { + var entity = new Entity.ScheduleAnaLog(info); + _dalAnaLog.Insert(entity); + } + + + /// <summary> + /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦� + /// </summary> + public bool ExistTable(string runFlag) + { + return _dal.ExistTable(runFlag); + } + + } +} diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0504\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0504\051.cs" new file mode 100644 index 0000000..f3d2535 --- /dev/null +++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0504\051.cs" @@ -0,0 +1,291 @@ +锘縰sing IStation.Model; + +namespace IStation.Algorithm +{ + + #region ViewModel + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class Combine + { + public Combine() { } + public List<int> PumpIds { get; set; } + public string RunFlag { get; set; } + public int RunCount { get; set; } + public double Frequency { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + } + + + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class OptimalCombine + { + public OptimalCombine() { } + public List<int> PumpIds { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + public List<Combine> Combines { get; set; } + } + + #endregion + + /// <summary> + /// 璋冨害鍒嗘瀽杈呭姪绫� + /// </summary> + public class SchedulingHelper + { + double _frequency_def = 50; + double _frequency_min = 25; + double _frequency_max = 50; + double _frequency_space = 0.1;//棰戠巼闂撮殧 + + double _head_space = 0.1;//鎵▼闂撮殧 + + #region RunFlag + string _falgFrePumpTag = "B"; + string _falgFixPumpTag = "G"; + string _falgSpaceMark = "_"; + + + string GetRunFlag(int[] flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Length; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetRunFlag(List<int> flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Count; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetGFlag(int flag) + { + return _falgFrePumpTag + flag; + } + + #endregion + + DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); + DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); + DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); + + + private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 }; + private List<int> _combineFlags2 = new List<int>() { 15 }; + + public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead, List<int> openPumpCombine) + { + List<int> open_combine_flags_1 = new List<int>(); + List<int> open_combine_flags_2 = new List<int>(); + + if (openPumpCombine != null && openPumpCombine.Any()) + { + foreach (var pump in openPumpCombine) + { + if (_combineFlags1.Contains(pump)) + { + open_combine_flags_1.Add(pump); + } + else + { + open_combine_flags_2.Add(pump); + } + } + } + else + { + open_combine_flags_1 = _combineFlags1.ToList(); + open_combine_flags_2 = _combineFlags2.ToList(); + } + + List<Combine> combineList1 = null; + List<Combine> combineList2 = null; + + var open_combine_flags_1_count = open_combine_flags_1.Count; + if (open_combine_flags_1_count > 0) + { + bool isSingular = false; + var combine_flags_combination_list = PermutationAndCombination<int>.GetCombination(open_combine_flags_1.ToArray(), 2); + if ((open_combine_flags_1_count % 2) > 0) + { + isSingular = true; + foreach (var flag in open_combine_flags_1) + { + combine_flags_combination_list.Add(new int[] { flag }); + } + } + + var combine_conclusion_dic = new Dictionary<string, List<Entity.ScheduleConclusion>>(); + foreach (var combine_flags in combine_flags_combination_list) + { + var runFlag = GetRunFlag(combine_flags); + if (combine_conclusion_dic.ContainsKey(runFlag)) + continue; + var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead); + combine_conclusion_dic[runFlag] = conclusionList; + } + + if (combine_conclusion_dic.Count < 1) + { + ////鏃犳硶璁$畻 + //return; + } + + var combine_flags_permutation_list = PermutationAndCombination<int>.GetPermutation(open_combine_flags_1.ToArray()); + for (int i = 0; i < length; i++) + { + + } + foreach (var combine_flags_permutation in combine_flags_permutation_list) + { + var combine_part_flags_list = new List<int[]>(); + for (int i = 0; i < combine_flags_permutation.Length / 2; i++) + { + var flags = combine_flags_permutation.Skip(i * 2).Take(2).ToArray(); + combine_part_flags_list.Add(flags); + } + if (isSingular) + { + var last_flag = combine_flags_permutation[combine_flags_permutation.Length - 1]; + combine_part_flags_list.Add(new int[] { last_flag }); + } + if (combine_part_flags_list.Count < 1) + continue; + + + List<Combine> combines = new List<Combine>(); + Dictionary<double, List<Combine>> combines_fre_list = new Dictionary<double, List<Combine>>(); + + for (double fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space) + { + var freItem = new AnaPumpFreItem(); + freItem.Frequency = Math.Round(fre, 1); + freItem.CurveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(this.CurveQH, freDef, fre); + freItem.CurveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(this.CurveQP, freDef, fre); + this.AnaFrequencyItems.Add(freItem); + } + + foreach (var combine_part_flags in combine_part_flags_list) + { + var runFlag = GetRunFlag(combine_part_flags); + + + } + + + } + + + } + + } + + + + + private OptimalCombine AnaOptimalCombine(List<Combine> combineList1, List<Combine> combineList2, double targetFlow, double targetHead) + { + double flowDeviation = targetFlow; + double totalPower = double.MaxValue; + double totalFlow = double.MaxValue; + + Combine optimalCombine1 = null; + Combine optimalCombine2 = null; + for (int combineIndex1 = 0; combineIndex1 < combineList1.Count; combineIndex1++) + { + for (int combineIndex2 = 0; combineIndex2 < combineList2.Count; combineIndex2++) + { + var combine1 = combineList1[combineIndex1]; + var combine2 = combineList2[combineIndex2]; + + var combineTotalFlow = combine1.Flow + combine2.Flow; + var combineTotalPower = combine1.Power + combine2.Power; + + var diffFlow = Math.Abs(combineTotalFlow - targetFlow); + if (diffFlow < flowDeviation) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + flowDeviation = diffFlow; + } + + if (diffFlow < targetFlow * 0.01 && combineTotalPower < totalPower) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + } + + } + } + if (optimalCombine1 == null && optimalCombine2 == null) + return default; + var optimalCombine = new OptimalCombine(); + optimalCombine.Combines = new List<Combine>(); + if (optimalCombine1 != null) + { + optimalCombine.Combines.Add(optimalCombine1); + } + if (optimalCombine2 != null) + { + optimalCombine.Combines.Add(optimalCombine2); + } + optimalCombine.Flow = totalFlow; + optimalCombine.Power = totalPower; + return optimalCombine; + } + + /// <summary> + /// 鎻掑叆鍒嗘瀽鏃ュ織 + /// </summary> + private void InsertAnaLog(string info) + { + var entity = new Entity.ScheduleAnaLog(info); + _dalAnaLog.Insert(entity); + } + + + /// <summary> + /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦� + /// </summary> + public bool ExistTable(string runFlag) + { + return _dal.ExistTable(runFlag); + } + + } +} diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0505\051.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0505\051.cs" new file mode 100644 index 0000000..258f7a3 --- /dev/null +++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266\0505\051.cs" @@ -0,0 +1,290 @@ +锘縩amespace IStation.Algorithm +{ + + #region ViewModel + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class Combine + { + public Combine() { } + public List<int> PumpIds { get; set; } + public string RunFlag { get; set; } + public int RunCount { get; set; } + public double Frequency { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + } + + + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class OptimalCombine + { + public OptimalCombine() { } + public List<int> PumpIds { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + public List<Combine> Combines { get; set; } + } + + #endregion + + /// <summary> + /// 璋冨害鍒嗘瀽杈呭姪绫� + /// </summary> + public class SchedulingHelper + { + double _frequency_def = 50; + double _frequency_min = 25; + double _frequency_max = 50; + double _frequency_space = 0.1;//棰戠巼闂撮殧 + + double _head_space = 0.1;//鎵▼闂撮殧 + + #region RunFlag + string _falgFrePumpTag = "B"; + string _falgFixPumpTag = "G"; + string _falgSpaceMark = "_"; + + + string GetRunFlag(int[] flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Length; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetRunFlag(List<int> flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Count; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + + string GetGFlag(int flag) + { + return _falgFrePumpTag + flag; + } + + #endregion + + DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); + DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); + DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); + + + private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 }; + private List<int> _combineFlags2 = new List<int>() { 15 }; + + public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead) + { + List<int> open_combine_flags_1 = new List<int>(); + List<int> open_combine_flags_2 = new List<int>(); + + + if (openPumpCombine != null && openPumpCombine.Any()) + { + foreach (var pump in openPumpCombine) + { + if (_combineFlags1.Contains(pump)) + { + open_combine_flags_1.Add(pump); + } + else + { + open_combine_flags_2.Add(pump); + } + } + } + else + { + open_combine_flags_1 = _combineFlags1.ToList(); + open_combine_flags_2 = _combineFlags2.ToList(); + } + + List<Combine> combineList1 = null; + List<Combine> combineList2 = null; + + var open_combine_flags_1_count = open_combine_flags_1.Count; + if (open_combine_flags_1_count > 0) + { + bool isSingular = false; + var combine_flags_combination_list = PermutationAndCombination<int>.GetCombination(open_combine_flags_1.ToArray(), 2); + if ((open_combine_flags_1_count % 2) > 0) + { + isSingular = true; + foreach (var flag in open_combine_flags_1) + { + combine_flags_combination_list.Add(new int[] { flag }); + } + } + + var combine_conclusion_dic = new Dictionary<string, List<Entity.ScheduleConclusion>>(); + foreach (var combine_flags in combine_flags_combination_list) + { + var runFlag = GetRunFlag(combine_flags); + if (combine_conclusion_dic.ContainsKey(runFlag)) + continue; + var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead); + combine_conclusion_dic[runFlag] = conclusionList; + } + + if (combine_conclusion_dic.Count < 1) + { + ////鏃犳硶璁$畻 + //return; + } + + var combine_flags_permutation_list = PermutationAndCombination<int>.GetPermutation(open_combine_flags_1.ToArray()); + for (int i = 0; i < length; i++) + { + + } + foreach (var combine_flags_permutation in combine_flags_permutation_list) + { + var combine_part_flags_list = new List<int[]>(); + for (int i = 0; i < combine_flags_permutation.Length / 2; i++) + { + var flags = combine_flags_permutation.Skip(i * 2).Take(2).ToArray(); + combine_part_flags_list.Add(flags); + } + if (isSingular) + { + var last_flag = combine_flags_permutation[combine_flags_permutation.Length - 1]; + combine_part_flags_list.Add(new int[] { last_flag }); + } + if (combine_part_flags_list.Count < 1) + continue; + + + List<Combine> combines = new List<Combine>(); + Dictionary<double, List<Combine>> combines_fre_list = new Dictionary<double, List<Combine>>(); + + for (double fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space) + { + var freItem = new AnaPumpFreItem(); + freItem.Frequency = Math.Round(fre, 1); + freItem.CurveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(this.CurveQH, freDef, fre); + freItem.CurveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(this.CurveQP, freDef, fre); + this.AnaFrequencyItems.Add(freItem); + } + + foreach (var combine_part_flags in combine_part_flags_list) + { + var runFlag = GetRunFlag(combine_part_flags); + + + } + + + } + + + } + + } + + + + + private OptimalCombine AnaOptimalCombine(List<Combine> combineList1, List<Combine> combineList2, double targetFlow, double targetHead) + { + double flowDeviation = targetFlow; + double totalPower = double.MaxValue; + double totalFlow = double.MaxValue; + + Combine optimalCombine1 = null; + Combine optimalCombine2 = null; + for (int combineIndex1 = 0; combineIndex1 < combineList1.Count; combineIndex1++) + { + for (int combineIndex2 = 0; combineIndex2 < combineList2.Count; combineIndex2++) + { + var combine1 = combineList1[combineIndex1]; + var combine2 = combineList2[combineIndex2]; + + var combineTotalFlow = combine1.Flow + combine2.Flow; + var combineTotalPower = combine1.Power + combine2.Power; + + var diffFlow = Math.Abs(combineTotalFlow - targetFlow); + if (diffFlow < flowDeviation) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + flowDeviation = diffFlow; + } + + if (diffFlow < targetFlow * 0.01 && combineTotalPower < totalPower) + { + optimalCombine1 = combine1; + optimalCombine2 = combine2; + totalPower = combine1.Power + combine2.Power; + totalFlow = combineTotalFlow; + } + + } + } + if (optimalCombine1 == null && optimalCombine2 == null) + return default; + var optimalCombine = new OptimalCombine(); + optimalCombine.Combines = new List<Combine>(); + if (optimalCombine1 != null) + { + optimalCombine.Combines.Add(optimalCombine1); + } + if (optimalCombine2 != null) + { + optimalCombine.Combines.Add(optimalCombine2); + } + optimalCombine.Flow = totalFlow; + optimalCombine.Power = totalPower; + return optimalCombine; + } + + /// <summary> + /// 鎻掑叆鍒嗘瀽鏃ュ織 + /// </summary> + private void InsertAnaLog(string info) + { + var entity = new Entity.ScheduleAnaLog(info); + _dalAnaLog.Insert(entity); + } + + + /// <summary> + /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦� + /// </summary> + public bool ExistTable(string runFlag) + { + return _dal.ExistTable(runFlag); + } + + } +} diff --git "a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266.cs" "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266.cs" new file mode 100644 index 0000000..99a5518 --- /dev/null +++ "b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper - \345\244\215\345\210\266.cs" @@ -0,0 +1,255 @@ +锘縰sing System; + +namespace IStation.Algorithm +{ + + #region ViewModel + + /// <summary> + /// 鍒嗘瀽娉甸」 + /// </summary> + public class AnaItem + { + public AnaItem() { } + public string RunFlag { get; set; } + public int RunCount { get; set; } + public List<long> PumpIds { get; set; } + public double Flow { get; set; } + public double Head { get; set; } + } + + #endregion + + /// <summary> + /// 璋冨害鍒嗘瀽杈呭姪绫� + /// </summary> + public class SchedulingHelper + { + double _frequency_def = 50; + double _frequency_min = 25; + double _frequency_max = 50; + double _frequency_space = 0.1;//棰戠巼闂撮殧 + + double _head_space = 0.1;//鎵▼闂撮殧 + + #region RunFlag + string _falgFrePumpTag = "B"; + string _falgFixPumpTag = "G"; + string _falgSpaceMark = "_"; + + string GetRunFlag(List<AnaPumpItem> pumpItems) + { + var tableName = string.Empty; + var count = pumpItems.Count; + pumpItems = pumpItems.OrderBy(p => p.ID).ToList(); + for (int i = 0; i < count; i++) + { + var pumpItem = pumpItems[i]; + tableName += GetRunFlag(pumpItem); + if ((i + 1) != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(AnaPumpItem pumpItem) + { + return (pumpItem.IsBp ? _falgFrePumpTag : _falgFixPumpTag) + pumpItem.ID; + } + + + string GetRunFlag(Dictionary<int, bool> dic) + { + var tableName = string.Empty; + var index = 0; + var count = dic.Count; + foreach (var item in dic) + { + tableName += GetRunFlag(item.Key, item.Value); + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(long id, bool isBp) + { + return (isBp ? _falgFrePumpTag : _falgFixPumpTag) + id; + } + + string GetRunFlag(List<string> flags) + { + var tableName = string.Empty; + var count = flags.Count; + var index = 0; + foreach (var flag in flags) + { + tableName += flag; + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + string GetRunFlag(List<int> flags) + { + var tableName = string.Empty; + var count = flags.Count; + var index = 0; + foreach (var flag in flags) + { + tableName += flag; + index++; + if (index != count) + { + tableName += _falgSpaceMark; + } + } + return tableName; + } + + + #endregion + + DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); + DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); + DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); + + + public class CurrentViewModel : Entity.ScheduleConclusion + { + public CurrentViewModel(Entity.ScheduleConclusion rhs) : base(rhs) + { + this.Flags = new List<int>(); + var flags = rhs.RunFlag.Split('_'); + foreach (var item in flags) + { + if (int.TryParse(item.Substring(1), out int flag)) + { + this.Flags.Add(flag); + } + + } + } + public List<int> Flags { get; set; } + } + + + public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead, List<int> openPumpCombine) + { + var pumpIds = pumps.Select(x => x.ID); + var dic_pump = pumps.ToDictionary(x => x.ID, x => x.IsBp); + + + + + if (openPumpCombine != null && openPumpCombine.Any()) + { + + var allCombineList = PermutationAndCombination<int>.GetCombination(pumpIds.ToArray(), 1); + + + + + allCombineList = PermutationAndCombination<int>.GetCombination(pumpIds.ToArray(), 2); + var combineList = new List<List<int>>(); + foreach (var combine in allCombineList) + { + var pump1 = combine[0]; + var pump2 = combine[1]; + if (!openPumpCombine.Contains(pump1)) + continue; + if (!openPumpCombine.Contains(pump2)) + continue; + combineList.Add(combine.ToList()); + } + if (combineList.Count < 1) + return; + + var avgFlow = tagetFlow / 2; + + var optimalConclusionList = new List<CurrentViewModel>(); + foreach (var combine in combineList) + { + var dic = new Dictionary<int, bool>(); + foreach (var pump in combine) + { + if (dic_pump.ContainsKey(pump)) + { + dic.Add(pump, dic_pump[pump]); + } + } + var runFalg = GetRunFlag(dic); + var list = _dalScheduleConclusion.GetList(runFalg, avgFlow, tagetHead, 5); + if (list != null && list.Any()) + { + var vmList = list.Select(x => new CurrentViewModel(x)).ToList(); + optimalConclusionList.AddRange(vmList); + } + } + if (optimalConclusionList == null || !optimalConclusionList.Any()) + { + return; + } + + var optimalConclusionCombineList = PermutationAndCombination<CurrentViewModel>.GetCombination(optimalConclusionList.ToArray(), 2); + var combines = new List<Combine>(); + foreach (var arr in optimalConclusionCombineList) + { + var falgs = arr.SelectMany(x => x.Flags).ToList(); + if (falgs.GroupBy(x => x).Where(x => x.Count() > 1).Count() > 0) + { + continue; + } + var combine = new Combine(); + combine.RunFlag = GetRunFlag(falgs); + combine.Power = arr.Sum(x => x.Power); + combine.Head = arr.Average(x => x.Head); + combine.Flow = arr.Sum(x => x.Flow); + combine.RunFlagList = falgs; + combines.Add(combine); + } + + var a = combines.OrderBy(x => x.Flow).ThenBy(x => x.Power).ToList(); + } + } + + private class Combine + { + public double Flow { get; set; } + public double Head { get; set; } + public double Power { get; set; } + public string RunFlag { get; set; } + public List<int> RunFlagList { get; set; } + } + + + + /// <summary> + /// 鎻掑叆鍒嗘瀽鏃ュ織 + /// </summary> + private void InsertAnaLog(string info) + { + var entity = new Entity.ScheduleAnaLog(info); + _dalAnaLog.Insert(entity); + } + + + /// <summary> + /// 鍒ゆ柇琛ㄦ槸鍚﹀瓨鍦� + /// </summary> + public bool ExistTable(string runFlag) + { + return _dal.ExistTable(runFlag); + } + + } +} diff --git a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs index 9f08205..0e9e97c 100644 --- a/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs +++ b/Schedule/IStation.Algorithm/Schedule/SchedulingHelper.cs @@ -1,21 +1,34 @@ -锘縰sing System; - -namespace IStation.Algorithm +锘縩amespace IStation.Algorithm { #region ViewModel /// <summary> + /// + /// </summary> + public class FreCombine + { + public FreCombine() { } + public List<int> Flags { get; set; } + public int RunCount { get; set; } + public double Frequency { get; set; } + public double Flow { get; set; } + public double Power { get; set; } + } + + + + /// <summary> /// 鍒嗘瀽娉甸」 /// </summary> - public class AnaItem + public class OptimalCombine { - public AnaItem() { } - public string RunFlag { get; set; } - public int RunCount { get; set; } - public List<long> PumpIds { get; set; } + public OptimalCombine() { } + public List<int> Flags { get; set; } public double Flow { get; set; } public double Head { get; set; } + public double Power { get; set; } + public List<FreCombine> Combines { get; set; } } #endregion @@ -26,9 +39,9 @@ public class SchedulingHelper { double _frequency_def = 50; - double _frequency_min = 25; - double _frequency_max = 50; - double _frequency_space = 0.1;//棰戠巼闂撮殧 + decimal _frequency_min = 25; + decimal _frequency_max = 50; + decimal _frequency_space = 0.1m;//棰戠巼闂撮殧 double _head_space = 0.1;//鎵▼闂撮殧 @@ -37,69 +50,45 @@ string _falgFixPumpTag = "G"; string _falgSpaceMark = "_"; - string GetRunFlag(List<AnaPumpItem> pumpItems) - { - var tableName = string.Empty; - var count = pumpItems.Count; - pumpItems = pumpItems.OrderBy(p => p.ID).ToList(); - for (int i = 0; i < count; i++) - { - var pumpItem = pumpItems[i]; - tableName += GetRunFlag(pumpItem); - if ((i + 1) != count) - { - tableName += _falgSpaceMark; - } - } - return tableName; - } - string GetRunFlag(AnaPumpItem pumpItem) + string GetRunFlag(int[] flags) { - return (pumpItem.IsBp ? _falgFrePumpTag : _falgFixPumpTag) + pumpItem.ID; - } - - - string GetRunFlag(Dictionary<int, bool> dic) - { - var tableName = string.Empty; + var runFlag = string.Empty; var index = 0; - var count = dic.Count; - foreach (var item in dic) - { - tableName += GetRunFlag(item.Key, item.Value); - index++; - if (index != count) - { - tableName += _falgSpaceMark; - } - } - return tableName; - } - - string GetRunFlag(long id, bool isBp) - { - return (isBp ? _falgFrePumpTag : _falgFixPumpTag) + id; - } - - string GetRunFlag(List<string> flags) - { - var tableName = string.Empty; - var count = flags.Count; - var index = 0; + var count = flags.Length; foreach (var flag in flags) { - tableName += flag; + runFlag += GetGFlag(flag); index++; if (index != count) { - tableName += _falgSpaceMark; + runFlag += _falgSpaceMark; } } - return tableName; + return runFlag; } + string GetRunFlag(List<int> flags) + { + var runFlag = string.Empty; + var index = 0; + var count = flags.Count; + foreach (var flag in flags) + { + runFlag += GetGFlag(flag); + index++; + if (index != count) + { + runFlag += _falgSpaceMark; + } + } + return runFlag; + } + string GetGFlag(int flag) + { + return _falgFrePumpTag + flag; + } #endregion @@ -108,102 +97,182 @@ DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); - public class CurrentViewModel : Entity.ScheduleConclusion + private List<int> _combineFlags1 = new List<int>() { 11, 12, 13, 14, 16, 17, 18 }; + private List<int> _combineFlags2 = new List<int>() { 15 }; + + public void Ana(List<Pump> pumps, double taget_flow, double tagetHead) { - public CurrentViewModel(Entity.ScheduleConclusion rhs) : base(rhs) + tagetHead = Math.Round(tagetHead); + var pump_flag_list = pumps.Select(x => x.ID).ToList(); + for (int pumpCount = 1; pumpCount <= pumps.Count; pumpCount++) { - this.Flags = new List<int>(); - var flags = rhs.RunFlag.Split('_'); - foreach (var item in flags) + var combine_list = PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount); + foreach (var combine in combine_list) { - if (int.TryParse(item.Substring(1), out int flag)) - { - this.Flags.Add(flag); - } + List<int> combine_flag_list_part1 = new List<int>(); + List<int> combine_flag_list_part2 = new List<int>(); - } - } - public List<int> Flags { get; set; } - } - - - public void Ana(List<Pump> pumps, double tagetFlow, double tagetHead, List<int> openPumpCombine) - { - var pumpIds = pumps.Select(x => x.ID); - var dic_pump = pumps.ToDictionary(x => x.ID, x => x.IsBp); - if (openPumpCombine != null && openPumpCombine.Any()) - { - var allCombineList = PermutationAndCombination<int>.GetCombination(pumpIds.ToArray(), 2); - var combineList = new List<List<int>>(); - foreach (var combine in allCombineList) - { - var pump1 = combine[0]; - var pump2 = combine[1]; - if (!openPumpCombine.Contains(pump1)) - continue; - if (!openPumpCombine.Contains(pump2)) - continue; - combineList.Add(combine.ToList()); - } - if (combineList.Count < 1) - return; - - var avgFlow = tagetFlow / 2; - - var optimalConclusionList = new List<CurrentViewModel>(); - foreach (var combine in combineList) - { - var dic = new Dictionary<int, bool>(); foreach (var pump in combine) { - if (dic_pump.ContainsKey(pump)) + if (_combineFlags1.Contains(pump)) { - dic.Add(pump, dic_pump[pump]); + combine_flag_list_part1.Add(pump); + } + else + { + combine_flag_list_part2.Add(pump); } } - var runFalg = GetRunFlag(dic); - var list = _dalScheduleConclusion.GetList(runFalg, avgFlow, tagetHead, 1); - if (list != null && list.Any()) + + + List<FreCombine> fre_combine_list_part1 = new List<FreCombine>(); + List<FreCombine> fre_combine_list_part2 = new List<FreCombine>(); + + if (combine_flag_list_part1.Count > 0) { - var vmList = list.Select(x => new CurrentViewModel(x)).ToList(); - optimalConclusionList.AddRange(vmList); + var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>(); + foreach (var flag in combine_flag_list_part1) + { + var runFlag = GetGFlag(flag); + if (conclusion_list_dic.ContainsKey(flag)) + continue; + var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead); + conclusion_list_dic[flag] = conclusionList; + } + + if (conclusion_list_dic.Count < 1) + { + continue; + } + + for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space) + { + var freCombine = new FreCombine(); + freCombine.Frequency = (double)fre; + freCombine.Flags = new List<int>(); + foreach (var item in conclusion_list_dic) + { + var conclusion = item.Value.Find(x => x.Pump1 == (double)fre); + if (conclusion != null) + { + freCombine.Flags.Add(item.Key); + freCombine.Flow += conclusion.Flow; + freCombine.Power += conclusion.Power; + freCombine.RunCount++; + } + } + if (freCombine.Flags.Count < 1) + continue; + fre_combine_list_part1.Add(freCombine); + } + + + + } - } - if (optimalConclusionList == null || !optimalConclusionList.Any()) - { - return; + + if (combine_flag_list_part2.Count > 0) + { + var conclusion_list_dic = new Dictionary<int, List<Entity.ScheduleConclusion>>(); + foreach (var flag in combine_flag_list_part2) + { + var runFlag = GetGFlag(flag); + if (conclusion_list_dic.ContainsKey(flag)) + continue; + var conclusionList = _dalScheduleConclusion.GetList(runFlag, tagetHead); + conclusion_list_dic[flag] = conclusionList; + } + + if (conclusion_list_dic.Count < 1) + { + continue; + } + + for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space) + { + var freCombine = new FreCombine(); + freCombine.Frequency = (double)fre; + freCombine.Flags = new List<int>(); + foreach (var item in conclusion_list_dic) + { + var conclusion = item.Value.Find(x => x.Pump1 == (double)fre); + if (conclusion != null) + { + freCombine.Flags.Add(item.Key); + freCombine.Flow += conclusion.Flow; + freCombine.Power += conclusion.Power; + freCombine.RunCount++; + } + } + if (freCombine.Flags.Count < 1) + continue; + fre_combine_list_part2.Add(freCombine); + } + } + + + var optimalCombine = AnaOptimalCombine(fre_combine_list_part1, fre_combine_list_part2, taget_flow); } - var optimalConclusionCombineList = PermutationAndCombination<CurrentViewModel>.GetCombination(optimalConclusionList.ToArray(), 2); - var combines = new List<Combine>(); - foreach (var arr in optimalConclusionCombineList) - { - var falgs = arr.SelectMany(x => x.Flags).ToList(); - if (falgs.GroupBy(x => x).Where(x => x.Count() > 1).Count() > 0) - { - continue; - } - var combine = new Combine(); - combine.Power = arr.Sum(x => x.Power); - combine.Head = arr.Average(x => x.Head); - combine.Flow = arr.Sum(x => x.Flow); - combine.RunFlagList = falgs; - combines.Add(combine); - } - - var a = combines; } + } - private class Combine + + private OptimalCombine AnaOptimalCombine(List<FreCombine> fre_combine_list_part1, List<FreCombine> fre_combine_list_part2, double target_flow) { - public double Flow { get; set; } - public double Head { get; set; } - public double Power { get; set; } - public List<int> RunFlagList { get; set; } + double flow_deviation = target_flow; + double total_power = double.MaxValue; + double total_flow = double.MaxValue; + + FreCombine optimal_combine_part1 = null; + FreCombine optimal_combine_part2 = null; + for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++) + { + for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++) + { + var fre_combine1 = fre_combine_list_part1[Index_part1]; + var fre_combine2 = fre_combine_list_part2[Index_part2]; + + var current_flow = fre_combine1.Flow + fre_combine2.Flow; + var current_power = fre_combine1.Power + fre_combine2.Power; + + var diff_flow = Math.Abs(current_flow - target_flow); + if (diff_flow < flow_deviation) + { + optimal_combine_part1 = fre_combine1; + optimal_combine_part2 = fre_combine2; + total_power = fre_combine1.Power + fre_combine2.Power; + total_flow = current_flow; + flow_deviation = diff_flow; + } + + if (diff_flow < target_flow * 0.01 && current_power < total_power) + { + optimal_combine_part1 = fre_combine1; + optimal_combine_part2 = fre_combine2; + total_power = fre_combine1.Power + fre_combine2.Power; + total_flow = current_flow; + } + + } + } + if (optimal_combine_part1 == null && optimal_combine_part2 == null) + return default; + var optimal_combine = new OptimalCombine(); + optimal_combine.Combines = new List<FreCombine>(); + if (optimal_combine_part1 != null) + { + optimal_combine.Combines.Add(optimal_combine_part1); + } + if (optimal_combine_part2 != null) + { + optimal_combine.Combines.Add(optimal_combine_part2); + } + optimal_combine.Flow = total_flow; + optimal_combine.Power = total_power; + return optimal_combine; } - - /// <summary> /// 鎻掑叆鍒嗘瀽鏃ュ織 diff --git a/Schedule/IStation.Client/Form1.cs b/Schedule/IStation.Client/Form1.cs index dbe4601..ddd2388 100644 --- a/Schedule/IStation.Client/Form1.cs +++ b/Schedule/IStation.Client/Form1.cs @@ -119,7 +119,7 @@ var ch1Pumps = JsonHelper.Json2Object<List<Model.Pump>>(ch1_json); var helper = new Algorithm.SchedulingHelper(); - helper.Ana(ch1Pumps, targetFlow, targetHead, combineList); + helper.Ana(ch1Pumps, targetFlow, targetHead); } } } \ No newline at end of file -- Gitblit v1.9.3