using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AForge; using System.Drawing; using System.Text.RegularExpressions; using AForge.Genetic; //using NPOI.SS.Formula.Eval; using System.Runtime.Serialization; using Newtonsoft.Json; using Hydro.Core.Model; namespace Hydro.CommonBase { public class GeneticParams { static int Count = 0; public GeneticParams(int Level) { this.Level = Level; this.ID = Count; Count++; } public void Dispose() { onReportProgress = null; Db.Close(); Db = null; } public List list_BestEnerge; public List list_AvgHz; public List ranges; public List DLengths; public List accuracys; public double[] list_AtemtpArr; public string SolutionSaveName; public int populationSize; public int iterations; public int populationSize_full; public int iterations_full; public int selectionMethod; public int optimizationMode; public bool 强制重计算; public int iterations_min; public double accuracyNum; //public int MultiTimes=0; public int MaxRobot; public int RuningRobot; public int num; public double BestOptValue; public DoubleRange tolerance; public FinishEvent onFinished; public FinishEvent onError; public FinishEvent onReportProgress; public SetEvent setVars; public Db Db; //public SolutionDBHelper SolutionDBHelper = null; public GlobalConfig GlobalConfig; public Quene Quene; public int Level; public int ID; public bool isNeedOutput = true; public double CurrentTotalDemand = -1; } [Serializable] public class DRange { private double min; private double max; public double Min { get { return min; } set { min = value; } } public double Max { get { return max; } set { max = value; } } public double Length => max - min; public DRange(double min, double max) { this.min = min; this.max = max; } } public class Result { public double[] arrayTryValue = null; public float Demand; public double ObjFunctionValue; public int it_Times = 0; } public class Quene { public System.Collections.Generic.Queue RequestQueues; public HashSet RequestFinished; public Dictionary ResultHash; public int Level; public Dictionary ResultDictionary; public Dictionary ResultChrome; public int MissionQueneCount; public List MissionQuene; public DateTime ScadaTime; public List TimePoints; public double BestResult=double.MaxValue; } [Serializable] public class WdnmoParam { public List results; public double DistriDemand; public Guid ID; public List ScadaPoints { get; set; } = new List(); public List ConfigPoints { get; set; } = new List(); public List ResultPoints { get; set; } = new List(); public double Fitness = -1; public DateTime time { get; set; } = default(DateTime); public int RunTimes = 0; public int Period { get; set; } = 0; public string ErrorMessage { get; set; } = null; public bool fullSearchMode = false; public FinishEvent onFinish; public bool isNeedOutPut = false; public Dictionary ToSearchDict() { Dictionary dict = new Dictionary(); foreach (var point in ScadaPoints) { if (!dict.ContainsKey(point.Key)) dict.Add(point.Key, new double[] { point.Value - point.SearchRange / 2, point.Value + point.SearchRange / 2 }); else dict[point.Key] = new double[] { point.Value - point.SearchRange / 2, point.Value + point.SearchRange / 2 }; } if (!dict.ContainsKey("period")) dict.Add("period", new double[] { Period - 8, Period + 8 }); else dict["period"] = new double[] { Period - 8, Period + 8 }; return dict; } //public ulong Toulong(string childSaveName) //{ //} public string ToSearchSring() { Dictionary dict = new Dictionary(); foreach (var point in ScadaPoints) { if (!dict.ContainsKey(point.Key)) dict.Add(point.Key, point.Value); else dict[point.Key] = point.Value; } if (!dict.ContainsKey("period")) dict.Add("period", Period); StringBuilder sb = new StringBuilder(); foreach (var point in dict) { sb.AppendLine(point.Key + "\t" + point.Value); } // List ListTemp = new List(); // var di = this.ToSearchDict(); // foreach (var kp in di) // { // ListTemp.Add( //$@"{{ {kp.Key}: {{ ""$gte"": {kp.Value[0]},""$lte"": {kp.Value[1]} }}}}"); // } // sb.AppendLine("--------------搜索表达式-------------"); // sb.AppendLine( //$@" //{{ // ""$and"": // [ // {string.Join(",", ListTemp)} // ] //}} //"); return sb.ToString(); } public Dictionary ToResultDict() { Dictionary dict = new Dictionary(); foreach (var point in ScadaPoints) { if (!dict.ContainsKey(point.Key)) dict.Add(point.Key, point.Value); else dict[point.Key] = point.Value; } if (!dict.ContainsKey("period")) dict.Add("period", Period); else dict["period"] = Period; foreach (var point in ResultPoints) { if (!point.isNeedtoSave) continue; if (!CheckExpandoVariableName(point.SaveKey)) continue; if (!dict.ContainsKey(point.SaveKey)) { dict.Add(point.SaveKey, point.Value); } else dict[point.SaveKey] = point.Value; } return dict; // 重载 == 运算符 } private bool CheckExpandoVariableName(string name) { if (name == null) return false; // 正则表达式:以字母或下划线开头,后面跟着任意个字母、数字或下划线 string pattern = @"^[a-zA-Z_]\w*$"; return Regex.IsMatch(name, pattern); } public void Dispose() { results?.Clear(); ScadaPoints?.Clear(); ConfigPoints?.Clear(); ResultPoints?.Clear(); onFinish = null; } } public class calcParam { public double[] vars; public Guid ID; public IChromosome chromosome; public List setVars = new List(); } public class SetVar { public string ID; public bool isNode = true; public int type; public float value; public SetVar(string ID,bool isNode,int type,float value) { this.ID= ID; this.isNode = isNode; this.type = type; this.value = value; } } //[Serializable] //public class TimePoint //{ // public TimePoint() // { // } // public TimePoint(string key, double value) // { // Key = key; // Value = value; // } // public string Name; // public DateTime ValueTime { get; set; } // public string Key { get; set; } // public double Value { get; set; } // public double[] Pattern { get; set; } = null; // public string ModelObjectID { get; set; } // public SettingCalcType CType { get; set; } = SettingCalcType.Add; // public double SearchRange = 0; // public bool isNeedtoSave = false; // public string SaveKey = null; // public override string ToString() // { // return $"{Name}\t[{Key}]\t{Value}"; // } //} [Serializable] public delegate void FinishEvent(dynamic txt); public delegate void SetEvent(string name, WdnmoParam param); //public event FinishEvent ss; [Serializable] public enum SettingCalcType { Add = 0, Const = 1 } [Serializable] public class LogicModelParams { public Guid ID = new Guid(); public List 集合 = new List(); public List 初始条件 = new List(); public List 下阶段条件 = new List(); public List 约束变量 = new List(); public List 试算变量 = new List(); public List 水量分配变量 = new List(); public List 变量 = new List(); public List 表达式 = new List(); public List 预处理插件 = new List(); public List 接口变量 { get { List all = new List(); all.AddRange(变量); all.AddRange(初始条件); all.AddRange(下阶段条件); all.AddRange(表达式); return all; } } public List 设定变量 { get { List all = new List(); all.AddRange(初始条件); all.AddRange(下阶段条件); return all; } } public List 变量全集 { get { List all = new List(); all.AddRange(初始条件); all.AddRange(下阶段条件); all.AddRange(变量); all.AddRange(试算变量); all.AddRange(集合); all.AddRange(表达式); all.AddRange(约束变量); if (OFunction?.variable!=null) all.Add(OFunction.variable); return all; } } [NonSerialized] public Dictionary dict_Name; public Dictionary dict_ID; public string inputFileString; public void buildDict() { dict_Name = new Dictionary(); dict_ID=new Dictionary(); 变量全集.ForEach(vv => { if (!string.IsNullOrEmpty(vv.Name) && !dict_Name.ContainsKey(vv.Name)) dict_Name.Add(vv.Name, vv); }); 变量全集.ForEach(vv => { if (!dict_ID.ContainsKey(vv.ID)) dict_ID.Add(vv.ID, vv); }); } [NonSerialized] public Dictionary ChildParam = new Dictionary(); public OBJFunction OFunction; public EN_Times 时间刻度; public List results = new List(); public int times; public LogicModelParams CloneResult() { var param_new = new LogicModelParams(); 初始条件.ForEach(v => param_new.初始条件.Add(new variable {ID=v.ID,CalcValue=v.CalcValue,LogicValue=v.LogicValue,objListString=v.objListString })) ; 下阶段条件.ForEach(v => param_new.下阶段条件.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 约束变量.ForEach(v => param_new.约束变量.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 试算变量.ForEach(v => param_new.试算变量.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 水量分配变量.ForEach(v => param_new.水量分配变量.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 变量.ForEach(v => param_new.变量.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 集合.ForEach(v => param_new.集合.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); 表达式.ForEach(v => param_new.表达式.Add(new variable { ID = v.ID, CalcValue = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString })); param_new.OFunction = new OBJFunction(); param_new.OFunction.value = OFunction.value; param_new.buildDict(); return param_new; } } /// /// 子方案参数集 /// public class childSolutionParam { /// ///计算参数 /// public WdnmoParam wParam; public List childVars_In; public List childVars_Out; public string childSaveName; public variable childFitness_Out; //public SaveSettings saveSettings; //public string savePath; } public class EN_Times { public int duration; public int step; public int Ntimes; } [Serializable] public class variable { public static List listUsedInitValue = new List() { "初始计算值", "变化值", "绝对变化值" }; public static List list_输入值 = new List() { "基准值(界面)", "定义值", "基准值(接口)", "定义值" }; public static List listUsedScadaValue = new List { "定义值", "基准值(接口)" }; public static List list_接口输出值 = new List() { "表达式计算", "计算值", "变化值", "初始计算值", "子方案值" }; public static List list_接口输入值 = new List() { "基准值(接口)", "模式系数(接口)" }; public static List list_NoNeedModelIndex = new List() { "基准值(界面)", "定义值", "基准值(接口)", "模式系数(界面)", "模式系数(接口)" }; public int ID; public string modelObjectID; public string Name; public int modelIndex; public int maxTimes = 1; //CF修订 2023年7月10日 处理序列化失败的问题 [NonSerialized] public List Vars = null; // public int ParentID; public bool isNode; //public bool? isOutput; public dynamic Type; public dynamic resultType; public DRange doubleRange; public double? accuracy = null; public string expressString; public string expressType; //public string expressType //{ // get { return _expressType; } // set // { // if (expressString == "tagfenghuang_shuiwei" && value=="0.01") // { // var a = 0; // } // _expressType = value; // } //} public string defineType; public string IndicatorType; public int ObjType; public string logicType; /// /// 设定值 /// public double? LogicValue = null; /// /// 设定模式 /// public double[] LogicPattern = null; /// /// 初始状态计算值 /// public double CalcValue_Init; ///// ///// 目标状态计算值 ///// //public double? CalcValue_Calc = null; public double CalcValue_Set { set { lock(this) { this.CalcValue = value; } } } /// /// 数学模型目标值 /// public double? CalcValue { get; set; }=null; /// /// 数学模型目标值多时刻 /// public double[] CalcValue_Arr = null; /// /// 显示的小数位数 /// public int 小数位数 = 3; /// /// 标高 /// public double elevation = -9099; public int sort = 0; public string childSolution = ""; public string childTag = ""; public string childType = "传入"; public double SearchRange = -1; public bool isNeedToSave = false; public string SaveKey = null; /// /// 是否是虚拟变量(由集合产生) /// public bool virturl = false; [NonSerialized] public dynamic Eval = null; /// /// 对象清单 /// public string objListString; /// /// 对象编号(最优) /// public string obj_Best; public double ErrNum = -9999999; private int _level = 0; [JsonIgnore] public int Level { get { if (_level!=0) return _level; int tempLevel = 1; if (Vars!=null) foreach (var v in Vars) { if (tempLevel < v.Level + 1) tempLevel = v.Level + 1; } _level= tempLevel; return _level; } } public override string ToString() { string value = CalcValue == null ? LogicValue.ToString() : CalcValue.ToString(); return $"[{Name}]{value}"; } public double GetValue(Func GetCalcValue = null, int? period = 0, bool is清除缓存 = false) { double Value; var v = this; // is double dd if (v.expressType == "子方案值" || v.expressType=="目标函数") { lock(v) { if (!v.CalcValue.HasValue) throw (new Exception("异常")); else Value = (double)v.CalcValue;//v.GetCalcValue(GetCalcValue, period, false); } } else if (variable.list_输入值.IndexOf(v.expressType) < 0) { Value = v.GetCalcValue(GetCalcValue, period, is清除缓存); } else { double? d; if ((d = v.GetLogicValue()) == null) { //result = $"变量[{v.Name}]配置错误,编号[{v.modelObjectID}]取值失败"; Value = (ErrNum); } else { Value = (double)(v.GetLogicValue() ?? (ErrNum)); } } return Value; } public double GetCalcValue(Func GetCalcValue = null, int? period = 0, bool is清除缓存 = false) { //if (CalcValue != null) return (double)CalcValue; //double CalcValue_Calc; if (is清除缓存) { CalcValue = null; } else { if (CalcValue!=null) return (double)CalcValue; } double CalcValue_Calc; double result; if (expressType == listUsedInitValue[0])//初始计算值 { result = CalcValue_Init; } else if (expressType == listUsedInitValue[1])//变化值 { CalcValue_Calc = GetCalcValue(this); result = CalcValue_Calc - CalcValue_Init; } else if (expressType == listUsedInitValue[2])//绝对变化值 { CalcValue_Calc = GetCalcValue(this); result = CalcValue_Calc - CalcValue_Init; if (result < 0) result *= -1; } else { CalcValue_Calc = GetCalcValue(this); result = CalcValue_Calc; }//计算值 CalcValue = result; return result; } public double? GetLogicValue() { if (LogicValue != null) return (double)LogicValue; return null; } public double[] GetShowValue_Arr() { if (list_输入值.IndexOf(expressType) >= 0) //return LogicPattern; return CalcValue_Arr; else return CalcValue_Arr; } /// /// 获取页面显示的结果值及样式 /// /// public string GetShowValue(bool showString = false) { //,Color.Red,Color.Blue,Color.Orange double? result; string Result; if (list_输入值.IndexOf(expressType) >= 0) result = LogicValue; else result = CalcValue; Result = result == null ? "-" : Math.Round(Double.Parse(result.ToString()), 小数位数).ToString(); if (showString) { if (!string.IsNullOrEmpty(obj_Best)) { Result += $" [{obj_Best}]"; } } else if (Type.ToString().ToLower()== "initstatus")// is EPAModelNameSpace.EPAModelOutput.eType.INITSTATUS || Type is EPAModelNameSpace.EPAModelInput.eType.initStatus) { if (result == 0) Result = "关|Yellow"; else Result = "开|DarkGreen"; } else { if (list_输入值.IndexOf(expressType) >= 0) Result += "|Blue"; else Result += "|White";// Color.DarkGreen } return Result; } } [Serializable] public class OBJFunction { public string Text_origin; public string Text; public string ExpressType; public string Name; public double value; public DoubleRange tolerance; public variable variable; public List paramVariables; public List paramValues; [NonSerialized] public dynamic eval; public bool isUseOriginValue = false; /// /// true:使用表达式模式,false:使用编号模式 /// public bool? isUseExpression = true; public bool isUseScadaValue = false; } }