#define ValDistinct #define DEBUG_TIME1 using AForge; using AForge.Genetic; using Hydro.CodeProvider; using Hydro.CommonBase; using Hydro.HydraulicHelperNS; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Threading; using System.Threading.Tasks; //using WaterDistributioinManager; namespace Hydro.ParrelControl { [Serializable] public class BigBinaryFunction : IFitnessFunctionDouble { Quene Quene; int Level; public enum Modes { Maximization, Minimization } /// /// 每一维度的取值范围区间 /// private DRange[] list_Range; /// /// 每一维度的取值范围区间 /// private double?[] list_Accuracy; /// /// 维度数 /// private int COUNT_D; /// /// 单维度长度 /// private int[] Length_Ds; ///// ///// 优选模式(0是最大值,1是最小值) ///// //private Modes mode; //增加一个依赖关系属性,用于计算 public int[] Dependencies; private int seed; //public double Evaluate(BigBinaryChromo chromosome) //{ // ReSet(chromosome); // ChromosomeBase chromosome1 = chromosome as ChromosomeBase; // lock (Quene.ResultChrome) // { // if (Quene.ResultChrome.ContainsKey(chromosome1.ID)) return 1; // Quene.ResultChrome.Add(chromosome1.ID, chromosome1); // } // double[] array = Translate(chromosome1); // chromosome1.AttemptArray = array; // double num = OptimizationFunction(array, chromosome1.ID,chromosome); // return 1; // //if (mode != 0) // //{ // // return 1.0 / num; // //} // return num; //} public double Evaluate(IChromosome chromosome) { var bi = chromosome as BigBinaryChromo; //ReSet(bi); //ReSet(chromosome, param, wParam, gParam); //ChromosomeBase chromosome1 = chromosome as ChromosomeBase; /*[Cloudflight修改]2024-6-3 解锁 */ lock (Quene.ResultChrome) { if (Quene.ResultChrome.ContainsKey(bi.ID)) return 1; Quene.ResultChrome.Add(bi.ID, bi); } //double[] array= bi.AttemptArray?? Translate(bi); double[] array = bi.AttemptArray ?? Translate(bi); bi.AttemptArray = array; double num = OptimizationFunction(array, bi.ID, bi); return 1; //if (mode != 0) //{ // return 1.0 / num; //} return num; } public double[] Translate(IChromosome chromosome) { var bi = chromosome as BigBinaryChromo; //if (bi.AttemptArray != null) return bi.AttemptArray; double[] result = new double[COUNT_D]; BigInteger value = bi.Value;//获取整数值 //int length = bi.Length;//长度 //BigBinaryNums bNum = new BigBinaryNums(value, length, BigBinaryNums.CMaxValue, BigBinaryNums.CMaxLength); //for (int i = 0; i < COUNT_D; i++) //{ // result[i] = bNum.GetDoubleValue1D(Length_Ds[i], list_Range[i], list_Accuracy[i]); //}; result = Translate(value); //bi.AttemptArray = result; return result; } public int GetSeed() { //将 seed += Environment.TickCount + DateTime.Now.Millisecond; return seed; } public void SetMutateArr(double[] AttemptArray) { if (AttemptArray==null) throw new Exception("AttemptArray is null"); double 最大突变幅度=0.3; Random rand = new Random(GetSeed()); //var value= (BigInteger)(1L << rand.Next(length)); for (int i = 0; i < AttemptArray.Length; i++) { //发生突变,根据最大突变幅度,生成突变值 double acc = (double)list_Accuracy[i]; double percent = (rand.NextDouble() - 0.5) * 2 * 最大突变幅度; double value = AttemptArray[i] + percent * list_Range[i].Length; double value0 = BigBinaryNums.getRoundByDouble(value, list_Range[i], acc); if (value0 == AttemptArray[i]) { if (value > AttemptArray[i] && value0 + acc <= list_Range[i].Max) { value0 += acc; } else if (value < AttemptArray[i] && value0 - acc >= list_Range[i].Min) { value0 -= acc; } } AttemptArray[i] = value0; } } dict dict_AttemptCount=new dict(); public bool CreateRandomArray(LogicModelParams param, WdnmoParam wParam, GeneticParams gParam,out dynamic arr,out double[] result, double[] AttemptArray=null) { #if DEBUG_TIME DateTime time = DateTime.Now; #endif Random rand = new Random(GetSeed()); //double[] result = new double[COUNT_D]; calcParam cParam = new calcParam(); cParam.vars = result; for (int i = 0; i < COUNT_D; i++) { cParam.CurrentIndex = i; var max = (1 << Length_Ds[i])+1; var min = 0; double maxValue = 0; double minValue = 0; if (AttemptArray!=null) { //if (double.IsNaN(AttemptArray[i])) AttemptArray[i] = 0; var 最大突变幅度 = 0.3; maxValue = Math.Min(list_Range[i].Max, AttemptArray[i] + 最大突变幅度 * list_Range[i].Length); maxValue=Math.Max(maxValue, list_Range[i].Min); minValue = Math.Max(list_Range[i].Min, AttemptArray[i] - 最大突变幅度 * list_Range[i].Length); minValue = Math.Min(minValue, list_Range[i].Max); max = (int)((maxValue - list_Range[i].Min) / list_Accuracy[i])+1; min = (int)((minValue - list_Range[i].Min) / list_Accuracy[i])+1; } int MaxAttempt = max * 5; //生成0~max-1的随机数(长整形,包括0,不包括max) int attempt = 0; do { var value = rand.Next(max)+min; double v = (list_Range[i].Max - list_Range[i].Min) / (double)list_Accuracy[i]; while (value > v) { value = rand.Next(max); } result[i] = value * (double)list_Accuracy[i] + list_Range[i].Min; attempt++; if (attempt >= MaxAttempt) { if (!dict_AttemptCount.ContainsKey(cParam.CurrentIndex)) dict_AttemptCount.Add(cParam.CurrentIndex, 0); dict_AttemptCount[cParam.CurrentIndex] += 1; #if DEBUG if (dict_AttemptCount[cParam.CurrentIndex] > gParam.populationSize * 10) { arr = dict_AttemptCount; return false; } #endif arr = null; return false; } } while (!GeneticCheck(param, wParam, gParam, cParam)); }; #if DEBUG_TIME HydraulicHelper.TimeSet["循环获取新数组"] += (DateTime.Now - time).TotalSeconds; HydraulicHelper.TimeSetCount["循环获取新数组"]++; #endif arr = result; return true; } bool GeneticCheck(LogicModelParams param, WdnmoParam wParam, GeneticParams gParam, calcParam cParam) { if (param.GeneFilter == null) return true; var v= param.GeneFilter; if ((v.Eval.ChangeParam(param, wParam, gParam, cParam) == 0)) return true; else return false; } #if ArrDistinct public BigBinaryChromo DisTranslate(double[] OriginValueList, LogicModelParams param, WdnmoParam wParam, GeneticParams gParam, HashSet distinctDict) #elif ValDistinct public BigBinaryChromo DisTranslate(double[] OriginValueList, LogicModelParams param, WdnmoParam wParam, GeneticParams gParam, HashSet distinctDict) #endif //public BigBinaryChromo DisTranslate(double[] OriginValueList, LogicModelParams param, WdnmoParam wParam, GeneticParams gParam, HashSet distinctDict) { BigInteger value = 0; int length = 0; //BigBinaryNums bNum = new BigBinaryNums(value, length, BigBinaryNums.CMaxValue, BigBinaryNums.CMaxLength); //double[] result = new double[COUNT_D]; //for (int i = COUNT_D - 1; i >= 0; i--) //{ // bNum.AddBinary(OriginValueList[i], Length_Ds[i], list_Range[i]); //}; var val = DisTranslate(OriginValueList); return new BigBinaryChromo(val, Length_Ds.Sum(), Level, param, wParam, gParam, this, distinctDict); } public BigInteger DisTranslate(double[] OriginValueList) { #if DEBUG_TIME DateTime time = DateTime.Now; #endif BigInteger value = 0; int length = 0; BigBinaryNums bNum = new BigBinaryNums(value, length, BigBinaryNums.CMaxValue, BigBinaryNums.CMaxLength); for (int i = COUNT_D - 1; i >= 0; i--) { bNum.AddBinary(OriginValueList[i], Length_Ds[i], list_Range[i], (double)list_Accuracy[i]); }; #if DEBUG_TIME HydraulicHelper.TimeSet["反解析"] += (DateTime.Now - time).TotalSeconds; HydraulicHelper.TimeSetCount["反解析"]++; #endif #if DEBUG var arr=SplitBigIntegerToDecimalArray(bNum.ulongValue, Length_Ds); #endif return bNum.ulongValue; } public static List SplitBigIntegerToDecimalArray(BigInteger bigInteger, int[] arr) { // Convert BigInteger to binary string //string binaryString = bigInteger.ToString(); List result = new List(); BigInteger value=bigInteger; foreach (int length in arr) { //if (currentIndex + length > binaryString.Length) break; // Avoid index out of range ulong Max1D= (1UL << length) - 1; ulong value_1D =(ulong)(value & Max1D);// binaryString.Substring(currentIndex, length); value= value>> length; result.Add(value_1D); } return result; } public double[] Translate(BigInteger value) { #if DEBUG_TIME DateTime time = DateTime.Now; #endif double[] result = new double[COUNT_D]; int length = Length_Ds.Sum();//长度 BigBinaryNums bNum = new BigBinaryNums(value, length, BigBinaryNums.CMaxValue, BigBinaryNums.CMaxLength); for (int i = 0; i < COUNT_D; i++) { result[i] = bNum.GetDoubleValue1D(Length_Ds[i], list_Range[i], list_Accuracy[i]); }; #if DEBUG_TIME HydraulicHelper.TimeSet["解析"] += (DateTime.Now - time).TotalSeconds; HydraulicHelper.TimeSetCount["解析"]++; #endif return result; } public void ReSet(BigBinaryChromo chromosome) { var arr0 = chromosome.AttemptArray.ToArray(); var val0 = DisTranslate(arr0); var arr1 = Translate(val0); var arr = Translate(chromosome.Value); //if (arr == null) return; //for (int i = 0; i < arr.Length; i++) //{ // //判断是否有依赖项 // if (Dependencies[i] >= 0 && arr[Dependencies[i]] == 0) // { // arr[i] = list_Range[i].Min; // } // //if (item == 1) return; //} var val = DisTranslate(arr); if (val != chromosome.Value) { var a = 0; } //throw new Exception("err"); chromosome.setval(val); chromosome.AttemptArray = arr; } private static DRange[] DR(List drs) { var DRS = new DRange[drs.Count]; for (int i = 0; i < DRS.Length; i++) { DRS[i] = new DRange(drs[i].Min, drs[i].Max); } return DRS; } public BigBinaryFunction(LogicModelParams param, GeneticParams gParam) { this.list_Range = DR(gParam.ranges); this.Length_Ds = gParam.DLengths.ToArray(); COUNT_D = Length_Ds.Length; this.list_Accuracy = gParam.accuracys.ToArray(); Quene = gParam.Quene; Level = gParam.Level; //this.param = param; } private void sendCalc(calcParam param) { /*[Cloudflight修改]2024-6-3 解锁 */ #if DEBUG_TIME var time = DateTime.Now; #endif lock (Quene.ResultDictionary) { if (Quene.ResultDictionary.ContainsKey(param.ID)) return; Quene.ResultDictionary.Add(param.ID, null); } /*[Cloudflight修改]2024-6-3 解锁 */ lock (Quene.MissionQuene) { Quene.MissionQuene.Add(param); //Quene.MissionQueneCount++; } #if DEBUG_TIME HydraulicHelper.TimeSet["添加计算任务"]+=(DateTime.Now-time).TotalSeconds; HydraulicHelper.TimeSetCount["添加计算任务"]++; #endif } /// /// 目标函数定义 /// /// 水泵频率的组合 /// public double OptimizationFunction(double[] array, Guid ID, IChromosome chromosome) { var cParam = new calcParam(); cParam.ID = ID; cParam.vars = array; cParam.chromosome = chromosome; sendCalc(cParam); return 0; } } }