cloudflight
2024-07-27 49eb2a09634e439090d4a2b13ec7d6f911d3deaf
Hydraulic/Hydro.CommonBase/ParamModel.cs
@@ -13,9 +13,13 @@
using Newtonsoft.Json;
using System.Collections.Concurrent;
using Dapper;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.Eval;
//using NPOI.Util.Collections;
namespace Hydro.CommonBase
{
    [Serializable]
    public class GeneticParams
    {
        static int Count = 0;
@@ -33,12 +37,78 @@
            if (Quene!=null) Quene.Dispose();
            Quene = new Quene();
            this.Quene= Quene;
            //获取全局默认设置
            var globalConfig = Db.Connection.QueryFirstOrDefault<string>("SELECT FValue FROM MyConfig WHERE FKey='GlobalConfig'");
            GlobalConfig = JsonConvert.DeserializeObject<GlobalConfig>(globalConfig) ?? new GlobalConfig();
            this.GlobalConfig = GlobalConfig;
            if (ConfigPath!=null)
            {
                //获取全局默认设置
                var globalConfig = Db.Connection.QueryFirstOrDefault<string>("SELECT FValue FROM MyConfig WHERE FKey='GlobalConfig'");
                GlobalConfig = JsonConvert.DeserializeObject<GlobalConfig>(globalConfig) ?? new GlobalConfig();
                this.GlobalConfig = GlobalConfig;
            }
            isInited = true;
            //return gParam;
        }
        public string Load_GeneticSettings(LogicModelParams param)
        {
            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);
            });
            this.ranges = ranges;
            this.DLengths = DLengths;
            this.accuracys = accuracys;
            return null;
        }
        public string Load_Settings(LogicModelParams param, FinishEvent onFinished, FinishEvent onError, FinishEvent onReportProgress, SetEvent SetVarsMethod)
        {
            //string result = null;
            //DLengths.ForEach(m => chromosomeLength += m);
            this.populationSize = this.GlobalConfig.Ext.populationNum;
            this.iterations = this.GlobalConfig.Ext.iterationNum;
            this.populationSize_min = this.GlobalConfig.Ext.populationNum_full;
            this.iterations_full = this.GlobalConfig.Ext.iterationNum_full;
            this.selectionMethod = 0;
            this.optimizationMode = param.OFunction.ExpressType == "最大" ? 1 : 0;
            this.强制重计算 = this.GlobalConfig.Ext.是否优选方案;
            this.iterations_min = this.GlobalConfig.Ext.iterationNum_Min;
            this.onReportProgress = onReportProgress;
            this.onFinished = onFinished;
            this.onError = onError;
            this.setVars = SetVarsMethod;
            return null;
        }
        int getDLength(DRange dr, double? accur)
        {
            if (accur == null) accur = 0.1;
            var num_Total = dr.Length / (double)accur;
            var Dlength = 0;
            var value = 1;
            var i = 0;
            //判断需要多少位二进制数
            //Dlength=Math.Log(num_Total, 2) > 0 ? (int)Math.Ceiling( Math.Log(num_Total, 2)) : 0;
            while (value <= num_Total && i < 1000)
            {
                value *= 2;
                Dlength += 1;
                i++;
            }
            return Dlength;
        }
        public void Dispose()
        {
@@ -48,19 +118,23 @@
        }
        
        //世代最优解列表
        public List<double> list_FitnessByItera;
        public List<double> list_BestEnerge;
        public List<double> list_AvgHz;
        #region 解析参数
        public List<DRange> ranges;
        public List<int> DLengths;
        public List<double?> accuracys;
        public List<int> Dependencies;
        public double[] list_AtemtpArr;
        #endregion
        //public double[] list_AtemtpArr;
        public string SolutionSaveName;
        public int populationSize;
        public int iterations;
        public int populationSize_full;
        public int populationSize_min;
        public int iterations_full;
        public List<ulong> Upopulations = null;
@@ -79,15 +153,20 @@
        public int num;
        public double BestOptValue;
        public DRange tolerance;
        [JsonIgnore]
        public FinishEvent onFinished;
        [JsonIgnore]
        public FinishEvent onError;
        [JsonIgnore]
        public FinishEvent onReportProgress;
        [JsonIgnore]
        public SetEvent setVars;
        public Db Db;
        public dynamic SolutionDBHelper = null;
        public GlobalConfig GlobalConfig;
        public bool isInited=false;
        [JsonIgnore]
        public Quene Quene;
        public int Level;
        public int ID;
@@ -95,6 +174,46 @@
        public bool isNeedOutput = true;
        public double CurrentTotalDemand = -1;
        //public GeneticParams DeepCopy()
        //{
        //    var copy = new GeneticParams(this.Level);
        //    copy.list_FitnessByItera = this.list_FitnessByItera?.ToList();
        //    copy.ranges = this.ranges?.Select(range => new DRange(range.Min, range.Max))?.ToList();
        //    copy.DLengths = this.DLengths?.ToList();
        //    copy.accuracys = this.accuracys?.ToList();
        //    //copy.list_AtemtpArr = this.list_AtemtpArr?.ToArray();
        //    copy.SolutionSaveName = this.SolutionSaveName;
        //    copy.populationSize = this.populationSize;
        //    copy.iterations = this.iterations;
        //    copy.populationSize_min = this.populationSize_min;
        //    copy.iterations_full = this.iterations_full;
        //    copy.Upopulations = this.Upopulations?.ToList();
        //    copy.selectionMethod = this.selectionMethod;
        //    copy.optimizationMode = this.optimizationMode;
        //    copy.强制重计算 = this.强制重计算;
        //    copy.iterations_min = this.iterations_min;
        //    copy.accuracyNum = this.accuracyNum;
        //    copy.MaxRobot = this.MaxRobot;
        //    copy.RuningRobot = this.RuningRobot;
        //    copy.num = this.num;
        //    copy.BestOptValue = this.BestOptValue;
        //    copy.tolerance = tolerance==null?null: new DRange(this.tolerance.Min, this.tolerance.Max);
        //    copy.onFinished = this.onFinished;
        //    copy.onError = this.onError;
        //    copy.onReportProgress = this.onReportProgress;
        //    copy.setVars = this.setVars;
        //    copy.Db = this.Db; // Assuming Db is a reference type
        //    copy.SolutionDBHelper = this.SolutionDBHelper; // Assuming SolutionDBHelper is a reference type
        //    copy.GlobalConfig = this.GlobalConfig;//.DeepCopyByBin<GlobalConfig>(); // Assuming GlobalConfig has a copy constructor
        //    copy.isInited = this.isInited;
        //    copy.Quene = this.Quene; // Assuming Quene has a copy constructor
        //    copy.ID = this.ID;
        //    copy.isNeedOutput = this.isNeedOutput;
        //    copy.CurrentTotalDemand = this.CurrentTotalDemand;
        //    return copy;
        //}
    }
    public class Result
    {
@@ -102,19 +221,30 @@
        public float Demand;
        public double ObjFunctionValue;
        public int it_Times = 0;
        public int[] unitNum = null;
        public dict<long, int> unitNum = null;
    }
    public class uvalue
    {
        public uvalue(int UID, double value)
        {
            this.UID = UID;
            this.value = value;
        }
        public int UID;
        public double value;
    }
    public class Quene
    {
        public System.Collections.Generic.Queue<WdnmoParam> RequestQueues;
        public HashSet<Guid> RequestFinished;
        public Dictionary<ulong, double> ResultHash;
        public ConcurrentDictionary<ulong, double> ResultHash;
        public int Level;
        public Dictionary<Guid, double?> ResultDictionary;
        public Dictionary<Guid, ChromosomeBase> ResultChrome;
        public ConcurrentDictionary<Guid, double?> ResultDictionary;
        public ConcurrentDictionary<Guid, ChromosomeBase> ResultChrome;
        public int MissionQueneCount;
        public List<calcParam> MissionQuene;
        //public  List<calcParam> MissionQuene;
        public ConcurrentQueue<calcParam> MissionQuene;
        public DateTime ScadaTime;
        //public List<TimePoint> TimePoints;
        public double BestResult=double.MaxValue;
@@ -148,7 +278,7 @@
            }
            if (MissionQuene != null)
            {
                MissionQuene.Clear();
                //MissionQuene.Clear();
                MissionQuene = null;
            }
@@ -156,14 +286,47 @@
        }
    }
    [Serializable]
    public class UvalueSetting
    {
        public UvalueSetting(long uID, double min, double max)
        {
            this.ID = uID;
            Min = min;
            Max = max;
        }
        public double Min;
        public double Max;
        public long ID;
    }
    public class USetting
    {
        public string Name;
        public int ID;
        public List<Ivariable> VSet;
        public List<UvalueSetting> UList;
        public float TotalDemand;
    }
    public class vSet
    {
        public string Name;
        public string Tag;
        public bool isNode=true;
        public List<string> IDs;
        public int ID;
        public string defaultExpress;
        public string IndicatorType;
        public string ObjectType;
    }
    public class WdnmoParam
    {
        public List<Result> results;
        public double DistriDemand;
        public List<vSet> VarSets_Import = new List<vSet>();
        public List<variable> Vars_Import = new List<variable>();
        public Guid ID;
        public List<TimePoint> ScadaPoints { get; set; } = new List<TimePoint>();
        public List<TimePoint> ConfigPoints { get; set; } = new List<TimePoint>();
@@ -364,6 +527,8 @@
        public List<SetVar> setVars = new List<SetVar>();
        public int CurrentIndex = -1;
    }
    public class SetVar
    {
@@ -402,7 +567,7 @@
            this.SearchRange = point.SearchRange;
            this.isNeedtoSave = point.isNeedtoSave; 
            this.SaveKey = point.SaveKey;
            if (point.Pattern!=null) this.Pattern= point.Pattern.ToList().ToArray();
            if (point.Pattern!=null) this.Pattern= point.Pattern.ToArray();
        }
        public string Name;
@@ -452,10 +617,28 @@
        public List<variable> 约束变量 = new List<variable>();
        public List<variable> 试算变量 = new List<variable>();
        public List<variable> 水量分配变量 = new List<variable>();
        public List<variable> 水量分配集合 = new List<variable>();
        //public List<variable> 水量分配集合 = new List<variable>();
        public List<variable> 变量 = new List<variable>();
        public List<variable> 表达式 = new List<variable>();
        public List<variable> 预处理插件 = new List<variable>();
        public variable ChromeFilter = null;
        public variable GeneFilter = null;
        [JsonIgnore]
        public List<variable> 输出变量
        {
            get
            {
                List<variable> all = new List<variable>();
                all.AddRange(变量);
                all.AddRange(初始条件);
                all.AddRange(下阶段条件);
                all.AddRange(表达式);
                all.AddRange(水量分配变量);
                all.AddRange(集合);
                return all;
            }
        }
        [JsonIgnore]
        public List<variable> 接口变量
        {
            get
@@ -469,7 +652,7 @@
                return all;
            }
        }
        [JsonIgnore]
        public List<variable> 设定变量
        {
            get
@@ -480,7 +663,7 @@
                return all;
            }
        }
        [JsonIgnore]
        public List<variable> 变量全集
        {
            get
@@ -493,6 +676,9 @@
                all.AddRange(集合);
                all.AddRange(表达式);
                all.AddRange(约束变量);
                all.AddRange(水量分配变量);
                //all.AddRange(水量分配集合);
                all.AddRange(预处理插件);
                if (OFunction?.variable!=null) all.Add(OFunction.variable);
                return all;
@@ -504,15 +690,25 @@
        //[NonSerialized]
        [JsonIgnore]
        public Dictionary<int, variable> dict_ID { get; set; }
        [JsonIgnore]
        public Dictionary<string, variable> dict_Tag { get; private set; }
        //[NonSerialized]
        /// <summary>
        /// 存储输出变量的索引,如果Value的长度>1,则Value[0]为父节点变量,Value[1]为子节点变量
        /// </summary>
        [JsonIgnore] 
        public Dictionary<string, variable> dict_OutPut { get; set; }
        public Dictionary<string, Ivariable[]> dict_OutPut { get; set; }
        //public string inputFileString;
        [JsonIgnore]
        public dict<string,dict> map_node { get;set;}
        [JsonIgnore]
        public dict<string, dict> map_link { get; set; }
        /// <summary>
        /// 当前计算时刻,默认值为0;拖动进度条控件时,会修改当前计算时刻;
        /// </summary>
        public int Period { get; set; } = 0;
        public void buildDict()
        {
@@ -520,10 +716,28 @@
            //BookMark    :建立变量字典
            dict_Name = new Dictionary<string, variable>();
            dict_ID=new Dictionary<int, variable>();
            dict_OutPut = new Dictionary<string, variable>();
            dict_Tag=new Dictionary<string, variable>();
            //dict_OutPut = new Dictionary<string, Ivariable[]>();
            变量全集.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); });
            接口变量.ForEach(vv => { if (!string.IsNullOrEmpty(vv.Name) && !dict_OutPut.ContainsKey(vv.expressString)) dict_OutPut.Add(vv.expressString, vv); });
            变量全集.ForEach(vv => { if (!string.IsNullOrEmpty(vv.Tag) && !dict_Tag.ContainsKey(vv.Tag)) dict_Tag.Add(vv.Tag, vv); });
            //输出变量.ForEach(vv =>
            //{
            //    if (!string.IsNullOrEmpty(vv.Tag) &&  !dict_OutPut.ContainsKey(vv.Tag))
            //        dict_OutPut.Add(vv.Tag, new Ivariable[] { vv });
            //    if (!string.IsNullOrEmpty(vv.expressString) &&!dict_OutPut.ContainsKey(vv.expressString))
            //        dict_OutPut.Add(vv.expressString,new Ivariable[] { vv });
            //});
            预处理插件.ForEach(vv =>
            {
                if (vv.IndicatorType=="方案筛选器")
                    ChromeFilter = vv;
                if (vv.IndicatorType == "基因筛选器")
                    GeneFilter = vv;
            });
        }
@@ -540,15 +754,16 @@
        public LogicModelParams CloneResult()
        {
            var param_new = new LogicModelParams();
            初始条件.ForEach(v => param_new.初始条件.Add(new variable {ID=v.ID,CalcValue_Set=v.CalcValue,LogicValue=v.LogicValue,objListString=v.objListString })) ;
            下阶段条件.ForEach(v => param_new.下阶段条件.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            约束变量.ForEach(v => param_new.约束变量.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            试算变量.ForEach(v => param_new.试算变量.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            水量分配变量.ForEach(v => param_new.水量分配变量.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            水量分配集合.ForEach(v => param_new.水量分配集合.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            变量.ForEach(v => param_new.变量.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            集合.ForEach(v => param_new.集合.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            表达式.ForEach(v => param_new.表达式.Add(new variable { ID = v.ID, CalcValue_Set = v.CalcValue, LogicValue = v.LogicValue, objListString = v.objListString }));
            变量全集.ForEach(v => param_new.变量全集.Add(new variable(v.PeriodCount) { ID = v.ID, Values_Set = v.Values, LogicValues = v.LogicValues, objListString = v.objListString }));
            //初始条件.ForEach(v => param_new.初始条件.Add(new variable(v.PeriodCount) {ID=v.ID,Values_Set=v.Values,LogicValues=v.LogicValues,objListString=v.objListString })) ;
            //下阶段条件.ForEach(v => param_new.下阶段条件.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //约束变量.ForEach(v => param_new.约束变量.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //试算变量.ForEach(v => param_new.试算变量.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //水量分配变量.ForEach(v => param_new.水量分配变量.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //水量分配集合.ForEach(v => param_new.水量分配集合.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //变量.ForEach(v => param_new.变量.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //集合.ForEach(v => param_new.集合.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            //表达式.ForEach(v => param_new.表达式.Add(new variable(v.PeriodCount) { ID = v.ID, Value_Set = v.Value0, LogicValue = v.LogicValue, objListString = v.objListString }));
            param_new.OFunction = new OBJFunction();
            param_new.OFunction.value = OFunction.value;
            param_new.buildDict();
@@ -578,13 +793,55 @@
        public int step;
        public int Ntimes;
    }
    [Serializable]
    public class variable
    public interface Ivariable
    {
        //bool isNode { get; set; }
        //string modelObjectID { get; set; }
        int modelIndex { get; set; }
        //string expressType { get; set; }
    }
    public class VarSimple: Ivariable
    {
        //public bool isNode { get; set; }
        //public string modelObjectID { get;set;  }
        public int modelIndex { get; set; }
        //public string expressType { get; set; }
    }
    public class VarDistri : Ivariable
    {
        public string modelObjectID { get; set; }
        public int modelIndex { get; set; }
        //public bool isNode { get; set; }
        public List<uvalue> uvalues { get; set; } = null;
    }
    [Serializable]
    public class variable: Ivariable
    {
        public static List<string> list_indicatorTypeName
        {
            get
            {
                if (_list_indicatorTypeName==null)
                {
                    _list_indicatorTypeName =new List<string>() { "已知压力", "节点用水量", "节点用水模式", "水池水位", "水泵转速比", "管线阻力系数", "阀门开度", "水泵开关", "阀门开关", "管线开关", "管线直径", "管线长度", "总水量", "节点压力", "节点自由压力", "节点需水量", "节点标高", "节点水龄", "节点水质", "管线流量", "管线流速", "水头损失", "当前状态", "水泵能耗", "水泵开关", "水泵转速比", "初始化","初始及运行传参", "初始传参", "运行传参", "种群生成器", "方案筛选器", "基因筛选器", "计算前处理", "输出计算处理", "结果处理", "当量分配", "随机分配" };
                }
                return _list_indicatorTypeName;
            }
        }
        private static List<string> _list_indicatorTypeName = null;
        public static List<string> listUsedInitValue = new List<string>() { "初始计算值", "变化值", "绝对变化值" };
        public static List<string> list_输入值 = new List<string>() { "基准值(界面)", "定义值", "基准值(接口)",  "模式系数(界面)", "模式系数(接口)" };
        //public static List<string> list_输入值 = new List<string>() { "基准值(界面)", "定义值", "基准值(接口)",  "模式系数(界面)", "模式系数(接口)" };
        public static HashSet<string> list_输入值 = new HashSet<string>() { "基准值(界面)", "定义值", "基准值(接口)", "模式系数(界面)", "模式系数(接口)" };
        public static List<string> listUsedScadaValue = new List<string> { "定义值", "基准值(接口)" };
        public static List<string> list_接口输出值 = new List<string>() { "表达式计算", "计算值", "变化值", "初始计算值", "子方案值" };
@@ -592,75 +849,213 @@
        public static List<string> list_NoNeedModelIndex = new List<string>() { "基准值(界面)", "定义值", "基准值(接口)", "模式系数(界面)",  "模式系数(接口)" };
        public int ID;
        public string modelObjectID;
        public string modelObjectID { get; set; }
        public string Name;
        public int modelIndex;
        public int maxTimes = 1;
        public int modelIndex { get; set; }
        public int PeriodCount
        {
            get
            {
                return _Values.Length;
            }
            set
            {
                LogicValues=new double[value];
                //初始值设置为double.NaN
                for (int i = 0; i < value; i++)
                {
                    LogicValues[i] = double.NaN;
                }
                _Values = new double[value];
                //初始值设置为double.NaN
                for (int i = 0; i < value; i++)
                {
                    _Values[i] = double.NaN;
                }
            }
        }
        
        public variable(int maxTimes=1)
        {
            this.PeriodCount = maxTimes;
        }
        //CF修订 2023年7月10日 处理序列化失败的问题
        [NonSerialized]
        public List<variable> Vars = new List<variable>();
        public List<Ivariable> Vars = new List<Ivariable>();
        /// <summary>
        /// 用来作为变量的偏移索引的静态值,例如fixNum+1,fixNum+2,fixNum+3分别代表后一位、后两位、后三位,fixNum-1代表前一位
        /// </summary>
        public static int fixNum { get; set; } = -1000000;
        /// <summary>
        /// 作为PatternVars的索引
        /// </summary>
        [NonSerialized]
        public Dictionary<int, int> VarIndexs = new Dictionary<int, int>();
        /// <summary>
        /// 记录需要调用的PatternVars
        /// </summary>
        [NonSerialized]
        public List<variable> PatternVars = new List<variable>();
        // public int ParentID;
        public bool isNode;
        public bool isInput
        {
            get;
            set;
        } = false;
        public bool isNode { get; set; }
        //public bool? isOutput;
        public dynamic Type;
        public dynamic Type { get; set; }
        public dynamic resultType;
        public DRange doubleRange;      
        
        public double? accuracy = null;
        public string expressString;
        public string expressType;
        public string defineType;
        public string IndicatorType;
        public string expressType { get; set; }
        public int arrgFuncType;
        public string defaultExpress;
        private int _indicatorType;
        public string IndicatorType
        {
            get
            {
                if (_indicatorType<0)
                {
                    return list_indicatorTypeName[0];
                }
                else
                    return list_indicatorTypeName[_indicatorType];
            }
            set
            {
                if (list_indicatorTypeName == null) return;
                _indicatorType = list_indicatorTypeName.IndexOf(value);
            }
        }
        /// <summary>
        /// 值的类型,是单值还是数组,仅针对初始条件
        /// </summary>
        public bool isArrInput { get; set; } = false;
        public int ObjType;
        public string logicType;
        #region 核心承载变量
        /// <summary>
        /// 设定值
        /// 数学模型目标值多时刻
        /// </summary>
        public double? LogicValue = null;
        /// <summary>
        /// 设定模式
        /// </summary>
        public double[] LogicPattern = null;
        private double[] _Values = null;
        public double[] Values
        {
            get
            {
                return _Values;
            }
            set
            {
                _Values = value;
            }
        }
        /// <summary>
        /// 初始状态计算值
        /// </summary>
        public double CalcValue_Init;
        ///// <summary>
        ///// 目标状态计算值
        ///// </summary>
        //public double? CalcValue_Calc = null;
        public double CalcValue_Init { get; set; }
        #endregion
        public double? CalcValue_Set
        #region 辅助变量属性
        /// <summary>
        /// 设定值(不修改的静态值)
        /// </summary>
        public double? LogicValue
        {
            set
            {
                lock(this)
                {
                    this.CalcValue = value;
                }
            get
            {
                return LogicValues[0];
            }
            set
            {
                if (value==null)
                    LogicValues[0]=double.NaN;
                else
                    LogicValues[0] = (double)value;
            }
        }
        /// <summary>
        /// 设定模式
        /// </summary>
        public double[] LogicValues
        {
            get;set;
        }
        /// <summary>
        /// 需要添加函数
        /// </summary>
        public string Value_Set(int period,double value)
        {
            if (_Values!=null && period < _Values.Length)
                _Values[period] = value;
            return null;
            string result = null;
            double formatValue = value;
            //if (value!=double.NaN) formatValue = Math.Round(value, 小数位数);
            /*[Cloudflight修改]2024-6-3
                    解锁
                    */
            //lock (this)
            {
                _Values[period] = formatValue;
            }
            return result;
        }
        /// <summary>
        /// 需要添加函数
        /// </summary>
        public double[] Values_Set
        {
            set
            {
                //lock (this)
                //{
                //    _Values = value;
                //}
                _Values = value;
            }
        }
        /// <summary>
        /// 数学模型目标值
        /// </summary>
        public double? CalcValue { get;private set; }=null;
        public double? Value0
        {
            get
            {
                return _Values[0];
            }
            private set
            {
                if (value == null)
                    _Values[0] = double.NaN;
                else
                    _Values[0] = (double)value;
            }
        }
        #endregion
        /// <summary>
        /// 数学模型目标值多时刻
        /// </summary>
        public double[] CalcValue_Arr = null;
        #region 设置变量
        /// <summary>
        /// 显示的小数位数
        /// </summary>
@@ -672,6 +1067,8 @@
        public double elevation = -9099;
        public int sort = 0;
        #endregion
        public string childSolution = "";
@@ -718,9 +1115,11 @@
                if (_level!=0) return _level;
                int tempLevel = 1;
                if (Vars!=null)
                foreach (var v in Vars)
                for (int i=0;i<Vars.Count;i++)
                {
                    if (tempLevel < v.Level + 1) tempLevel = v.Level + 1;
                    var v = Vars[i];
                    if (!VarIndexs.ContainsKey(i) && v !=this && v is variable vv && tempLevel < vv.Level + 1) tempLevel = vv.Level + 1;
                }
                _level= tempLevel;
                return _level;
@@ -728,187 +1127,148 @@
            
        }
        public string Tag { get; set; }
        public string AnFrom { get; set; }
        public string AnValue { get; set; }
        public double MuRange { get; set; }
        public double MuRate { get; set; }
        public override string ToString()
        {
            string value = CalcValue == null ? LogicValue.ToString() : CalcValue.ToString();
            string value = Value0 == null ? LogicValue.ToString() : Value0.ToString();
            return $"[{Name}]{value}";
        }
        public double GetValue(Func<variable, double> GetCalcValue = null, int? period = 0, bool is清除缓存 = false)
        {
            double Value;
            var v = this;
            // is double dd
            if (v.expressType == "子方案值"|| v.logicType=="目标函数" )
            {
                if (!v.CalcValue.HasValue)
                    Value = ErrNum; //throw (new Exception("异常"));
                else
                    Value = (double)v.CalcValue;//v.GetCalcValue(GetCalcValue, period, false);
            }
            else if(v.logicType=="试算参数")//不清除缓存
            {
                if (!v.CalcValue.HasValue)
                    Value = variable.ErrNum;
                else
                    Value = (double)v.CalcValue;//v.GetCalcValue(GetCalcValue, period, false);
        //public double GetValue(Func<variable,  double> GetModelValue = null, int? period = 0, bool forceReCalc = false)
        //{
        //    double Value;
        //    var v = this;
        //    // is double dd
        //    if (v.expressType == "子方案值"|| v.logicType=="目标函数" )
        //    {
        //        if (!v.Value0.HasValue)
        //            Value = ErrNum; //throw (new Exception("异常"));
        //        else
        //            Value = (double)v.Value0;//v.GetCalcValue(GetCalcValue, period, false);
        //    }
        //    else if(v.logicType=="试算参数")//不清除缓存
        //    {
        //        if (!v.Value0.HasValue)
        //            Value = variable.ErrNum;
        //        else
        //            Value = (double)v.Value0;//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 = variable.ErrNum;
                }
                else
                {
                    Value = (double)(v.GetLogicValue() ?? (variable.ErrNum));
                }
            }
            return Value;
        }
        public double GetCalcValue(Func<variable, double> GetCalcValue = null, int? period = 0, bool is清除缓存 = false)
        //    else if (variable.list_输入值.IndexOf(v.expressType) < 0)
        //    {
        //        Value = v.GetCalcValue(GetModelValue,  forceReCalc);
        //    }
        //    else
        //    {
        //        double? d;
        //        if ((d = v.GetLogicValue(period)) == null)
        //        {
        //            //result = $"变量[{v.Name}]配置错误,编号[{v.modelObjectID}]取值失败";
        //            Value = variable.ErrNum;
        //        }
        //        else
        //        {
        //            Value = (double)(v.GetLogicValue(period) ?? (variable.ErrNum));
        //        }
        //    }
        //    return Value;
        //}
        //public double GetCalcValue(Func<variable, double> GetModelValue = null,  bool forceReCalc = false)
        //{
        //    if (forceReCalc)
        //    {
        //        Value0 = null;
        //    }
        //    else
        //    {
        //        if (Value0!=null) return (double)Value0;
        //    }
        //    double CalcValue_Calc;
        //    double result;
        //    if (expressType == listUsedInitValue[0])//初始计算值
        //    {
        //        result = CalcValue_Init;
        //    }
        //    else if (expressType == listUsedInitValue[1])//变化值
        //    {
        //        CalcValue_Calc = GetModelValue(this);
        //        result = CalcValue_Calc - CalcValue_Init;
        //    }
        //    else if (expressType == listUsedInitValue[2])//绝对变化值
        //    {
        //        CalcValue_Calc = GetModelValue(this);
        //        result = CalcValue_Calc - CalcValue_Init;
        //        if (result < 0) result *= -1;
        //    }
        //    else
        //    {
        //        CalcValue_Calc = GetModelValue(this);
        //        result = CalcValue_Calc;
        //    }//计算值
        //    Value0 = result;
        //    return result;
        //}
        public double GetLogicValue(int period=0)
        {
            if (is清除缓存)
            {
                CalcValue = null;
            }
            if ( period >= 0 && period<LogicValues.Length)
                return LogicValues[period];
            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;
                return double.NaN;
        }
        public double[] GetShowValue_Arr()
        {
            if (list_输入值.IndexOf(expressType) >= 0)
            if (variable.list_输入值.Contains(expressType))
                //return LogicPattern;
                return CalcValue_Arr;
                return Values;
            else
                return CalcValue_Arr;
                return Values;
        }
        /// <summary>
        /// 获取页面显示的结果值及样式
        /// </summary>
        /// <returns></returns>
        public string GetShowValue(bool showString = false)
        {
            //,Color.Red,Color.Blue,Color.Orange
            double? result;
            string Result;
            if (expressType!=null && expressType.Contains("ģʽ"))
            {
                if (LogicPattern!=null)
                {
                    int LengthLimit = 16; //GlobalConfig.LengthLimit??16;
                    string txt= LogicPattern.ToList().Select(v=>v.ToString()).Aggregate((a, b) => a + "," + b);
                    //最长保留16个字符
                    if (txt.Length > LengthLimit) txt = txt.Substring(0, LengthLimit) + "...";
                    return txt;
                }
                result = 0;
            }
            else 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;
        }
        public variable Copy()
        {
            //获取一个新的实例,将这个类的属性值赋值给新实例
            variable v = new variable();
            variable v = new variable(this.PeriodCount);
            v.ID = this.ID;
            v.IndicatorType = this.IndicatorType;
            v.Type = this.Type;
            v.expressType = this.expressType;
            v.expressString = this.expressString;
            v.defineType = this.defineType;
            v.Tag=this.Tag;
            v.arrgFuncType = this.arrgFuncType;
            v.isNode = this.isNode;
            v.ObjType = this.ObjType;
            v.logicType = this.logicType;
            v.LogicValue = this.LogicValue;
            v.LogicPattern = this.LogicPattern;
            v.LogicValues = this.LogicValues.ToArray();
            v.Values_Set = this.Values.ToArray();
            v.小数位数 = this.小数位数;
            v.defaultExpress=this.defaultExpress;
            v.sort = this.sort;
            v.isInput = this.isInput;
            v.virturl = this.virturl;
            v.doubleRange =new DRange( this.doubleRange);
            if (this.doubleRange == null) v.doubleRange = null;
            else v.doubleRange =new DRange( this.doubleRange);
            v.accuracy = this.accuracy;
            //v.Vars = this.Vars;
            v.Name = this.Name;
            v.modelObjectID = this.modelObjectID;
            v.modelIndex = this.modelIndex;
            v.maxTimes = this.maxTimes;
            //v.PeriodCount = this.PeriodCount;
            v.childSolution = this.childSolution;
            v.childTag = this.childTag;
            v.childType = this.childType;
@@ -917,6 +1277,10 @@
            v.objListString = this.objListString;
            v.obj_Best=this.obj_Best;
            v._level=this._level;
            v.AnFrom=this.AnFrom;
            v.AnValue=this.AnValue;
            v.MuRange=this.MuRange;
            v.MuRate=this.MuRate;
            return v;
        }
    }
@@ -942,7 +1306,7 @@
        /// true:使用表达式模式,false:使用编号模式
        /// </summary>
        public bool? isUseExpression = true;
        public bool isUseScadaValue = false;
        //public bool isUseScadaValue = false;
    }