cloudflight
2024-07-27 49eb2a09634e439090d4a2b13ec7d6f911d3deaf
Hydraulic/Hydro.HydraulicOptimizer/WDNModelOptimizer.cs
@@ -14,7 +14,9 @@
using System.Xml.Linq; 
using Hydro.HydraulicModel; 
using Hydro.CommonBase; 
using Hydro.CodeProvider;
using Hydro.CodeProvider;
using System.Runtime.CompilerServices;
using System.Collections.Concurrent;
namespace Hydro.HydraulicOptimizer
{
@@ -134,7 +136,7 @@
            //Log.Add("初始化开始");
            string result = null;
            //if(gParam.Level == 0)MyEval_tempCode.Clear();
            gParam=new GeneticParams(ConfigPath,gParam);
            if (!gParam.isInited) gParam.Init(ConfigPath);
            this.ModelPath = ModelPath;
            if (gParam.Level == 0)
            {
@@ -160,9 +162,11 @@
                }
            }
#if DEBUG
            Eval.本地项目编译 = gParam.GlobalConfig.Ext.本地项目编译;
#endif
            if ((result = loadGeneticParam(onFinished, onError, onReportProgress, SetVars)) != null) { return result; }
            if ((result = gParam.Load_Settings(param,onFinished, onError, onReportProgress, SetVars)) != null) { return result; }
            if (isGUILoading) return null;
@@ -172,7 +176,7 @@
            
            if ((result = controllerInit(isGUI, wParam)) != null) return result;
            if ((result = load试算参数_gParam()) != null) return result;
            if ((result = gParam.Load_GeneticSettings(param)) != null) return result;
            //StartChild
            lock (GlobalProgress.Instance)
            {
@@ -680,7 +684,7 @@
        {
            return EPAController.SetResult(ID, code, value, isNode);
        }
        public string SetValue(string ID, EPAModelInput.eType type, float value)
        public string SetValue(string ID, HydraulicInputType type, float value)
        {
            return EPAController.SetResult(ID, type, value);
        }
@@ -702,12 +706,12 @@
            {
                EPAController.needToStop = true;
                EPAController.StopRobot();
            }
            }
            if (workerThread != null)
                workerThread.Abort();
            StopRunQuene();
            if (Quene.RequestQueues!=null) Quene.RequestQueues.Clear();
            if (Quene.MissionQuene!=null)Quene.MissionQuene.Clear();
            if (Quene.MissionQuene != null) Quene.MissionQuene = new ConcurrentQueue<calcParam>();//.Clear();
            if (CSM != null)
            {
                foreach (var name in ChildSolutionName)
@@ -720,9 +724,9 @@
        public string Close()
        {
            this.isInited = false;
            if (gParam!=null)
                gParam.Dispose();
            gParam = null;
            //if (gParam != null)
            //    gParam.Dispose();
            //gParam = null;
            isStarted = false;
            string result = null;
@@ -734,8 +738,8 @@
                EPAController.Close();
            }
            
            if (workerThread!=null)
            workerThread.Abort();
            //if (workerThread!=null)
            //workerThread.Abort();
            
            
            if (CSM!=null)
@@ -758,8 +762,34 @@
        private string loadLogicParam()
        {
            string result = null;
            GlobalModel.dict_StringToType = new Dictionary<string, dynamic>();
            GlobalModel.dict_StringToObjType = new Dictionary<string, int>();
            GlobalModel.dict_StringToisNode = new Dictionary<string, bool>();
            GlobalModel.dict_StringToFuncType = new Dictionary<string, int>();
            GlobalModel.DEFINE_INDICATOR.ForEach(ind =>
            {
                GlobalModel.dict_StringToType[ind.Name] = ind.Type;
                GlobalModel.dict_StringToisNode[ind.Name] = ind.isNode;
            });
            GlobalModel.DEFINE_OBJECT.ForEach(obj =>
            {
                GlobalModel.dict_StringToObjType[obj.Name] = (int)obj.Type;
            });
            for(int i=0;i< GlobalModel.DEFIND_AGGFUNC.Count;i++)
            {
                var func = GlobalModel.DEFIND_AGGFUNC[i];
                GlobalModel.dict_StringToFuncType[func.Name] = i;
            }
            //if (!GlobalModel.dict_StringToType.ContainsKey(host.IndicatorType)) GlobalModel.dict_StringToType[host.IndicatorType] = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).Type;
            //if (!GlobalModel.dict_StringToObjType.ContainsKey(host.Ext.ObjectType)) GlobalModel.dict_StringToObjType[host.Ext.ObjectType] = (int)(GlobalModel.DEFINE_OBJECT.Find(obj => obj.Name == host.Ext.ObjectType) ?? new TypeObject()).Type;
            //if (!GlobalModel.dict_StringToisNode.ContainsKey(host.IndicatorType)) GlobalModel.dict_StringToisNode[host.IndicatorType] = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).isNode;
            //if (!GlobalModel.dict_StringToFuncType.ContainsKey(host.Ext.accurary)) GlobalModel.dict_StringToFuncType[host.Ext.accurary] = GlobalModel.DEFIND_AGGFUNC.FindIndex(func => func.Name == host.Ext.accurary);
            //string result = null;
            //(LogicPoint)((LogicTile)sender).Tag;
            //variable.list_indicatorTypeName=GlobalModel.DEFINE_INDICATOR.Select(ind => ind.Name).ToList();
            param = new LogicModelParams();
@@ -769,7 +799,7 @@
                $"SELECT {LogicPoint.selectColumn} FROM RemoteHost");
            double d=0;
            //double d=0;
            foreach (var host in hosts.Where(x => x.LogicType == "初始条件" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x=>x.Sort))
@@ -782,10 +812,16 @@
            }
            foreach (var host in hosts.Where(x => x.LogicType == "试算参数" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
            {
                var accuracy = double.Parse(host.Ext.accurary == "" ? "0.1" : host.Ext.accurary);
                var doubleRange = new DRange(double.Parse(host.Expression.Split(',')[0]), double.Parse(host.Expression.Split(',')[1]));
                var v = GetVarByHost(host, accuracy, doubleRange);
                param.试算变量.Add(v);
                try
                {
                    var accuracy = double.Parse(host.Ext.accurary == "" ? "0.1" : host.Ext.accurary);
                    var doubleRange = new DRange(double.Parse(host.Expression.Split(',')[0]), double.Parse(host.Expression.Split(',')[1]));
                    host.Ext.doubleRange = doubleRange;
                    var v = GetVarByHost(host, accuracy, doubleRange);
                    param.试算变量.Add(v);
                }
                catch { }
            }
            foreach (var host in hosts.Where(x => x.LogicType == "水量分配"  && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
            {
@@ -802,7 +838,7 @@
                param.约束变量.Add(GetVarByHost(host));
            }
            foreach (var host in hosts.Where(x => (x.LogicType == "集合" || x.LogicType == "选择集" && x.Ext.Enable) && x.ParentId != -1).OrderBy(x=>x.Sort))
            foreach (var host in hosts.Where(x => ((x.LogicType == "集合" || x.LogicType == "选择集") && x.Ext.Enable) && x.ParentId != -1).OrderBy(x=>x.Sort))
            {
                param.集合.Add(GetVarByHost(host));
            }
@@ -875,6 +911,7 @@
                        //    sort = o.Sort,
                        //}
                    };
                    param.表达式.Add(v);
                    param.OFunction = OFunction;
                }
                
@@ -937,73 +974,192 @@
            }
            return null;
        }
        public static void UpdateVarByHost(variable s,LogicPoint host,LogicModelParams param)
        {
            StringBuilder result = new StringBuilder();
            var v = GetVarByHost(host);
            //按照v更新s
            s.ID = v.ID;
            s.modelObjectID = v.modelObjectID;
            s.IndicatorType = v.IndicatorType;
            s.Type = v.Type;
            s.isNode = v.isNode;
            s.Name = v.Name;
            s.ObjType = v.ObjType;
            s.小数位数 = v.小数位数;
            s.SearchRange = v.SearchRange;
            s.isNeedToSave = v.isNeedToSave;
            s.SaveKey = v.SaveKey;
            s.expressType = v.expressType;
            s.sort = v.sort;
            s.logicType = v.logicType;
            s.accuracy = v.accuracy;
            s.doubleRange = v.doubleRange;
            if (host.ExpressionType == "表达式计算")
        public static string UpdateExpress(LogicModelParams param, HashSet<int> list_express)
        {
            return HydraulicHelper.CreateExpressAssembly(param);
            //var resultBuilder=new StringBuilder();
            //var flag=true;
            //param.表达式.ForEach(s =>
            //{
            //    if (!list_express.Contains(s.ID)) return;
            //    string text = HydraulicHelper.GetExVarText(s, param, resultBuilder);
            //    if (resultBuilder.Length != 0)
            //    {
            //        flag = false;
            //        return;
            //    }
            //    try
            //    {
            //        Eval val = new Hydro.CodeProvider.Eval(text, s.Vars.Count);
            //        if (!val.isInit) { resultBuilder.AppendLine($"表达式[{s.Name}]公式错误," + val.errString); }
            //        s.Eval = val;
            //        s.Value_Set(param.Period, double.NaN);
            //    }
            //    catch (Exception e)
            //    {
            //        resultBuilder.AppendLine(e.Message);
            //        flag = false;
            //        return;
            //    }
            //});
            //param.预处理插件.ForEach(v =>
            //{
            //    //BookMark    :处理预处理插件
            //    if (!flag) return;
            //    Eval val;
            //    val = new Eval(v.modelObjectID, EvalTemplate.TempCode_PreTreat);
            //    if (val.errString != null) { resultBuilder.AppendLine( $"预处理插件[{v.Name}]函数编写错误," + val.errString); flag = false; return; }
            //    v.Eval = val;
            //});
            //param.表达式.Sort((a, b) => a.Level > b.Level ? 1 : (a.Level == b.Level ? 0 : -1));
            //return resultBuilder.ToString();
        }
        public static HashSet<int> UpdateVarByHost(variable s,LogicPoint host,LogicModelParams param,bool isDelete=false)
        {
            HashSet<int> list_express = new HashSet<int>();
            StringBuilder result = new StringBuilder();
            //
            if (isDelete)
            {
                string text=HydraulicHelper.GetExVarText(s, param, result);
                try
                var v = GetVarByHost(host);
                switch (v.logicType)
                {
                    Eval val = new Hydro.CodeProvider.Eval(text, s.Vars.Count);
                    if (!val.isInit) { result.AppendLine($"表达式[{s.Name}]公式错误," + val.errString);  }
                    s.Eval = val;
                    s.CalcValue_Set = null;
                }
                catch (Exception ee)
                {
                    { result.AppendLine(ee.Message); }
                    case "变量":
                        param.变量.Remove(s);
                        break;
                    case "试算参数":
                        param.试算变量.Remove(s);
                        break;
                    case "水量分配":
                        param.水量分配变量.Remove(s);
                        break;
                    case "约束条件":
                        param.约束变量.Remove(s);
                        break;
                    case "集合":
                        param.集合.Remove(s);
                        break;
                    case "表达式":
                        param.表达式.Remove(s);
                        break;
                    case "预处理插件":
                        param.预处理插件.Remove(s);
                        break;
                }
                
            }
            else if (host.ExpressionType=="基准值(界面)")
            if (s==null)
            {
                s = GetVarByHost(host);
                //根据s的logicType判断是哪种变量
                switch(s.logicType)
                {
                    case "变量":
                        param.变量.Add(s);
                        break;
                    case "试算参数":
                        param.试算变量.Add(s);
                        break;
                    case "水量分配":
                        param.水量分配变量.Add(s);
                        break;
                    case "约束条件":
                        param.约束变量.Add(s);
                        break;
                    case "集合":
                        param.集合.Add(s);
                        break;
                    case "表达式":
                        param.表达式.Add(s);
                        break;
                    case "预处理插件":
                        param.预处理插件.Add(s);
                        break;
                }
            }
            else
            {
                UpdateVarByHost(s, host);
            }
            if (host.LogicType == "表达式" || host.LogicType=="预处理插件")
            {
                list_express.Add(s.ID);
            }
            else
            if (host.ExpressionType=="基准值(界面)")
            {
                if ( double.TryParse( host.Expression,out double d)) s.LogicValue =d;
            }
            else if (host.ExpressionType == "模式系数(界面)")
            {
                s.LogicPattern= host.Expression.Split(',').ToList().Select(str => { if (double.TryParse(str, out double dd)) return dd; else return 0; }).ToArray();
                s.LogicValues= host.Expression.Split(',').ToList().Select(str => { if (double.TryParse(str, out double dd)) return dd; else return 0; }).ToArray();
                s.Values_Set = s.LogicValues;
            }
            else
            {
                s.CalcValue_Set = null;
            }
            return list_express;
        }
        public static variable GetVarByHost( LogicPoint host,double? accuracy=null,DRange doubleRange=null)
        {
            double d;
            return new variable()
            /*[Cloudflight修改]2024-5-21
             * 迁移方法--集合
             */
            dynamic VarType = HydraulicInputType.None;
            if (GlobalModel.dict_StringToType.TryGetValue(host.IndicatorType,out dynamic vartype))
                VarType=vartype;
            int ObjType = 0;
            if (GlobalModel.dict_StringToObjType.TryGetValue(host.Ext.ObjectType, out int objType))
                ObjType = objType;
            bool isNode = true;
            if (GlobalModel.dict_StringToisNode.TryGetValue(host.IndicatorType, out bool isnode))
                isNode = isnode;
            int arrgFuncType = -1;
            if (GlobalModel.dict_StringToFuncType.TryGetValue(host.Ext.accurary, out int FuncInt))
                arrgFuncType=FuncInt;
            var v = new variable()
            {
                ID = host.Id,
                modelObjectID = host.ModelObjectID,
                IndicatorType = host.IndicatorType,
                Type = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).EpaType,
                Type = VarType,
                arrgFuncType = arrgFuncType,
                ObjType = (int)ObjType,
                Name = host.Name,
                expressType = host.ExpressionType,
                expressString = host.Expression,
                defineType = host.Ext.accurary,
                isNode = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).isNode,
                ObjType = (int)(GlobalModel.DEFINE_OBJECT.Find(obj => obj.Name == host.Ext.ObjectType) ?? new TypeObject()).EPAObjType,
                Tag = host.Ext.Tag,
                defaultExpress = host.Ext.accurary,
                isNode = isNode,
                小数位数 = host.Ext.小数位数,
                childSolution = host.Ext.childSolution,
                childTag = host.Ext.childTag,
@@ -1012,43 +1168,140 @@
                isNeedToSave = host.Ext.isSave == "是" ? true : false,
                SaveKey = host.Ext.SaveRange,
                sort = host.Sort,
                logicType =host.LogicType,
                logicType = host.LogicType,
                accuracy = accuracy,
                doubleRange=doubleRange,
                doubleRange = doubleRange,
                isInput = variable.list_输入值.Contains(host.ExpressionType),
                AnFrom  = host.Ext.AnFrom,
                AnValue =host.Ext.AnValue,
                MuRange =host.Ext.MuRange,
                MuRate =host.Ext.MuRate,
            };
            return v;
        }
        public static void UpdateVarByHost(variable v,LogicPoint host, double? accuracy = null, DRange doubleRange = null)
        {
            double d;
            var s= GetVarByHost(host, accuracy, doubleRange);
            v.ID = s.ID;
            v.modelObjectID = s.modelObjectID;
            v.IndicatorType = s.IndicatorType;
            v.Type = s.Type;
            v.Name = s.Name;
            v.expressType = s.expressType;
            v.expressString = s.expressString;
            v.Tag = s.Tag;
            v.arrgFuncType = s.arrgFuncType;
            v.defaultExpress = s.defaultExpress;
            v.isNode = s.isNode;
            v.ObjType = s.ObjType;
            v.小数位数 = s.小数位数;
            v.childSolution = s.childSolution;
            v.childTag = s.childTag;
            v.childType = s.childType;
            v.SearchRange = s.SearchRange;
            v.isNeedToSave = s.isNeedToSave;
            v.SaveKey = s.SaveKey;
            v.sort = s.sort;
            v.logicType = s.logicType;
            v.accuracy = s.accuracy;
            v.doubleRange = s.doubleRange;
            v.isInput = s.isInput;
            v.AnFrom = s.AnFrom;
            v.AnValue = s.AnValue;
            v.MuRange = s.MuRange;
            v.MuRate = s.MuRate;
            /*[Cloudflight修改]2024-5-21
             * 迁移方法--集合
             */
            //if (host.LogicType == "集合")
            //{
            //    List<string> list = new List<string>() { "最大值", "最小值", "平均值", "累计值", "计数" };
            //    if (list.IndexOf(host.ExpressionType) >= 0)
            //    {
            //        host.accurary = host.ExpressionType;
            //        host.ExpressionType = "计算值";
            //    }
            //}
            //dynamic VarType = HydraulicInputType.None;
            //if (GlobalModel.dict_StringToType.TryGetValue(host.IndicatorType, out dynamic vartype))
            //    VarType = vartype;
            //int ObjType = 0;
            //if (GlobalModel.dict_StringToObjType.TryGetValue(host.Ext.ObjectType, out int objType))
            //    ObjType = objType;
            //bool isNode = true;
            //if (GlobalModel.dict_StringToisNode.TryGetValue(host.IndicatorType, out bool isnode))
            //    isNode = isnode;
            //int arrgFuncType = -1;
            //if (GlobalModel.dict_StringToFuncType.TryGetValue(host.Ext.accurary, out int FuncInt))
            //    arrgFuncType = FuncInt;
            //v.ID = host.Id;
            //v.modelObjectID = host.ModelObjectID;
            //v.IndicatorType = host.IndicatorType;
            //v.Type = VarType;
            //v.Name = host.Name;
            //v.expressType = host.ExpressionType;
            //v.expressString = host.Expression;
            //v.Tag = host.Ext.Tag;
            //v.arrgFuncType = arrgFuncType;
            //v.defaultExpress = host.Ext.accurary;
            //v.isNode = isNode;
            //v.ObjType = (int)ObjType;
            //v.小数位数 = host.Ext.小数位数;
            //v.childSolution = host.Ext.childSolution;
            //v.childTag = host.Ext.childTag;
            //v.childType = host.Ext.childType;
            //v.SearchRange = double.TryParse(host.Ext.SaveAcc, out d) ? d : 0;
            //v.isNeedToSave = host.Ext.isSave == "是" ? true : false;
            //v.SaveKey = host.Ext.SaveRange;
            //v.sort = host.Sort;
            //v.logicType = host.LogicType;
            //v.accuracy = accuracy;
            //v.doubleRange = doubleRange;
            //v.isInput = variable.list_输入值.Contains(host.ExpressionType);
            //v.AnFrom = host.Ext.AnFrom;
            //v.AnValue=host.Ext.AnValue;
            //v.MuRange=host.Ext.MuRange;
            //v.MuRate=host.Ext.MuRate;
        }
        private string loadGeneticParam(FinishEvent onFinished, FinishEvent onError, FinishEvent onReportProgress, SetEvent  SetVarsMethod)
        {
            string result = null;
            //string result = null;
            //DLengths.ForEach(m => chromosomeLength += m);
#if DEBUG
            Eval.本地项目编译=gParam.GlobalConfig.Ext.本地项目编译;
#endif
            gParam.populationSize = gParam.GlobalConfig.Ext.populationNum;
            gParam.iterations = gParam.GlobalConfig.Ext.iterationNum;
            gParam.populationSize_full = gParam.GlobalConfig.Ext.populationNum_full;
            gParam.populationSize_min = gParam.GlobalConfig.Ext.populationNum_full;
            gParam.iterations_full = gParam.GlobalConfig.Ext.iterationNum_full;
            gParam.selectionMethod = 0;
            gParam.optimizationMode = param.OFunction.ExpressType=="最大"?1:0;
            gParam.强制重计算 = gParam.GlobalConfig.Ext.是否优选方案;
            gParam.iterations_min = gParam.GlobalConfig.Ext.iterationNum_Min;
            //gParam.MultiTimes = gParam.GlobalConfig.Ext.MultiTimes;
            //gParam.accuracyNum = accuracyNum;
            //gParam.onReportProgress += OnReportProgress;
            //gParam.onFinished += ControlunLocking;
            //gParam.onError += ControlunLocking;
            //EPAController = new EPAParrelController();
            //EPAController.gParam = gParam;
            //Ehelper.SearchSolution();
            gParam.onReportProgress = onReportProgress;
            gParam.onFinished = onFinished;
            gParam.onError = onError;
@@ -1062,19 +1315,8 @@
                {
                    string savePath = GlobalPath.savePath + $@"\{solution.存储位置}";
                    var settings = gParam.GlobalConfig.saveSettings[key] = solution.settings;
                    //kp.Value.saveSettings = solution.settings;
                    settings.savePath = savePath;
                    //if (!isGUILoading)
                    //{
                    //    if (File.Exists(savePath))
                    //    {
                    //        settings.saveDatas = Base64Helper.ReadCompressedBase64FromFile<SaveDict>(savePath);
                    //    }
                    //    else
                    //    {
                    //        settings.saveDatas = new SaveDict();
                    //    }
                    //}
                    
                }
            });
@@ -1087,52 +1329,32 @@
            
        }
        private string load试算参数_gParam()
        {
            var ranges = new List<DRange>();
            var accuracys = new List<Double?>();
            var DLengths = new List<int>();
            //chromosomeLength = 0;
            param.试算变量.ForEach(v => { ranges.Add(v.doubleRange); DLengths.Add(getDLength(v.doubleRange, v.accuracy)); accuracys.Add(v.accuracy); });
            gParam.ranges = ranges;
            gParam.DLengths = DLengths;
            gParam.accuracys = accuracys;
            return null;
        }
        int getDLength(DRange dr, double? accur)
        {
            if (accur == null) accur = 0.1;
            var num_Total = dr.Length / accur;
            var Dlength = 0;
            var value = 1;
            var i = 0;
            while (value <= num_Total && i < 1000)
            {
                value *= 2;
                Dlength += 1;
                i++;
            }
            return Dlength;
        }
       
        private string controllerInit(bool isGUI=false,WdnmoParam wParam=null)
        {
            string result = null;
            string inp_file;
            if (string.IsNullOrEmpty(ModelPath))
            string inp_file=null;
            if (gParam.GlobalConfig.Ext.isWaterModelCalc)
            {
                inp_file = (gParam.GlobalConfig.ModelFilePath[0] == '\\' ? GlobalPath.Path : "") + gParam.GlobalConfig.ModelFilePath; //System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"\model\pump.inp");
                if (string.IsNullOrEmpty(ModelPath))
                {
                    inp_file = (gParam.GlobalConfig.ModelFilePath[0] == '\\' ? GlobalPath.Path : "") + gParam.GlobalConfig.ModelFilePath; //System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"\model\pump.inp");
            }
            else
            {
                inp_file = ModelPath;
            }
            if (!System.IO.File.Exists(inp_file))
            {
                //MessageBox.Show();
                return "文件未找到\r\n" + inp_file;
                }
                else
                {
                    inp_file = ModelPath;
                }
                if (!System.IO.File.Exists(inp_file))
                {
                    //MessageBox.Show();
                    return "文件未找到\r\n" + inp_file;
                }
            }
            EPAController = new EPAParrelController();
@@ -1148,6 +1370,8 @@
            return null;
        }
    }