#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;
}
}
}