using Hydro.HydraulicHelperNS;
|
using Hydro.ConfigModel;
|
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using Dapper;
|
using Newtonsoft.Json;
|
using Hydro.ParrelControl;
|
using System.IO;
|
using System.Collections;
|
using System.Xml.Linq;
|
using Hydro.HydraulicModel;
|
using Hydro.CommonBase;
|
using Hydro.CodeProvider;
|
using System.Runtime.CompilerServices;
|
|
namespace Hydro.HydraulicOptimizer
|
{
|
public class ChildSolutionManager
|
{
|
public List<WDNModelOptimizer> WMOs = new List<WDNModelOptimizer>();
|
public System.Collections.Generic.Queue<WdnmoParam> RequestQueues;
|
public HashSet<Guid> RequestFinished;
|
}
|
|
/// <summary>
|
/// 解决方案计算器
|
/// </summary>
|
public class WDNModelOptimizer
|
{
|
|
public static List<WDNModelOptimizer> InstanceList=null;
|
public int ID { get; set; }
|
Quene Quene;
|
|
private Thread workerThread;
|
string ModelPath;
|
//int MaxThread = 8;
|
|
public FinishEvent onFinished;
|
public FinishEvent onError;
|
public FinishEvent onReportProgress;
|
|
public Dictionary<string, ChildSolutionManager> CSM;
|
public List<string> ChildSolutionName;
|
|
public List<Solution> ChildSolutions { get { return this.gParam.GlobalConfig.Ext.ChildSolutionArr.ToList(); } }
|
|
|
|
//bool Busy { get; set; } = false;
|
bool Enabled { get; set; } = true;
|
LogicModelParams param;
|
GeneticParams gParam;
|
WdnmoParam wParam;
|
public LogicModelParams getLogicParam()
|
{
|
return param;
|
}
|
|
// bool showResult = false;
|
// bool showRunner = false;
|
//List<LogicPoint> hosts;
|
EPAParrelController EPAController;
|
|
public WdnmoParam Get设定清单()
|
{
|
return EPAController.helpers[0].Get设定清单();
|
}
|
|
public bool isStarted { get; set; } = false;
|
public bool isInited { get; set; } = false;
|
|
public string Message { get; set; } = null;
|
|
|
|
|
/// <summary>
|
/// 初始化配置,加载运算机器人
|
/// </summary>
|
/// <param name="ConfigPath">配置文件路径</param>
|
/// <param name="ModelPath">模型路径</param>
|
/// <param name="onFinished">回调函数:计算完成,回传参数类型为WdnmoParam,其中ResultPoints包含结果数值</param>
|
/// <param name="onError">回调函数:计算失败,回传参数类型为String失败原因</param>
|
/// <param name="onReportProgress">回调函数:计算进度,回传参数类型为GeneticParams,包括目标函数值、当前迭代次数、运算机器人状态</param>
|
public WDNModelOptimizer(GeneticParams gParam)
|
{
|
if (InstanceList == null) InstanceList = new List<WDNModelOptimizer>();
|
InstanceList.Add(this);
|
this.gParam = gParam;
|
}
|
/// <summary>
|
/// 初始化计算程序
|
/// </summary>
|
/// <param name="ConfigPath"></param>
|
/// <param name="ModelPath"></param>
|
/// <param name="onFinished"></param>
|
/// <param name="onError"></param>
|
/// <param name="onReportProgress"></param>
|
/// <returns></returns>
|
//public string Init(string ConfigPath = null,
|
// string ModelPath = null,
|
// FinishEvent onFinished = null,
|
// FinishEvent onError = null,
|
// FinishEvent onReportProgress = null
|
|
// )
|
//{
|
// string result = null;
|
// if (!string.IsNullOrEmpty(ConfigPath)) Db.Init(ConfigPath);
|
// this.ModelPath = ModelPath;
|
// //获取全局默认设置
|
// var globalConfig = Db.Connection.QueryFirstOrDefault<string>("SELECT FValue FROM MyConfig WHERE FKey='GlobalConfig'");
|
// GlobalConfig.Instance = JsonConvert.DeserializeObject<GlobalConfig>(globalConfig) ?? new GlobalConfig();
|
// if ((result = loadConfigToParam()) != null) return result;
|
// if ((result = loadCalcTogParam(onFinished, onError, onReportProgress)) != null) return result;
|
// if ((result = controllerInit()) != null) return result;
|
// isLoaded = true;
|
// return null;
|
//}
|
public string Init(string ConfigPath = null,
|
string ModelPath = null,
|
FinishEvent onFinished = null,
|
FinishEvent onError = null,
|
FinishEvent onReportProgress = null,
|
WdnmoParam wParam = null,
|
bool isGUI = false,
|
bool isGUILoading = false
|
)
|
{
|
//Log.Add("初始化开始");
|
string result = null;
|
//if(gParam.Level == 0)MyEval_tempCode.Clear();
|
if (!gParam.isInited) gParam.Init(ConfigPath);
|
this.ModelPath = ModelPath;
|
if (gParam.Level == 0)
|
{
|
Log.Enable = gParam.GlobalConfig.Ext.显示详细日志;
|
}
|
Quene = gParam.Quene;
|
if ((result = loadLogicParam()) != null) return result;
|
|
if (gParam.Level == 0 && !isGUILoading)
|
{
|
int count = 0;
|
if (this.param.ChildParam != null)
|
foreach (var kp in this.param.ChildParam)
|
{
|
Solution solution = ChildSolutions.Find(s => s.名称 == kp.Key);
|
count += solution.并行数;
|
}
|
|
lock (GlobalProgress.Instance)
|
{
|
GlobalProgress.MaxNum = 1 + count;
|
GlobalProgress.CurrentNum = 0;
|
}
|
|
}
|
|
|
if ((result = loadGeneticParam(onFinished, onError, onReportProgress, SetVars)) != null) { return result; }
|
|
|
if (isGUILoading) return null;
|
|
|
//Log.Add("参数读取完成");
|
|
if ((result = controllerInit(isGUI, wParam)) != null) return result;
|
|
if ((result = load试算参数_gParam()) != null) return result;
|
//StartChild
|
lock (GlobalProgress.Instance)
|
{
|
GlobalProgress.CurrentNum++;
|
}
|
|
if (this.param.ChildParam != null)
|
{
|
//BookMark :子方案初始化的地方
|
CSM = new Dictionary<string, ChildSolutionManager>();
|
ChildSolutionName = new List<string>();
|
foreach (var kp in this.param.ChildParam)
|
{
|
ChildSolutionName.Add(kp.Key);
|
var csParam = new ChildSolutionManager();
|
csParam.RequestQueues = new Queue<WdnmoParam>();
|
csParam.RequestFinished = new HashSet<Guid>();
|
csParam.WMOs = new List<WDNModelOptimizer>();
|
|
Solution solution = ChildSolutions.Find(s => s.名称 == kp.Key);
|
for (int i = 0; i < solution.并行数; i++)
|
{
|
var name = kp.Key;
|
GeneticParams gparam = new GeneticParams(gParam.Level + 1);
|
gparam.Db = new Db();
|
WDNModelOptimizer wmo = new WDNModelOptimizer(gparam);
|
csParam.WMOs.Add(wmo);
|
wmo.SetSaveName(kp.Value.childSaveName);
|
result = wmo.Init($@"{GlobalPath.configPath}\config_{name}.wdb", null, null, null, null, kp.Value.wParam, false);
|
|
if (result != null) return result;
|
wmo.Quene.RequestQueues = csParam.RequestQueues;
|
wmo.Quene.RequestFinished = csParam.RequestFinished;
|
}
|
CSM.Add(kp.Key, csParam);
|
string childSaveName = kp.Value.childSaveName;
|
|
|
|
//初始化内存存储
|
if (gParam.GlobalConfig.Ext.启用内存存储)
|
{
|
string savePath = GlobalPath.savePath + $@"\{solution.存储位置}";
|
var settings = gParam.GlobalConfig.saveSettings[kp.Key] = solution.settings;
|
//kp.Value.saveSettings = solution.settings;
|
settings.savePath = savePath;
|
if (!isGUILoading)
|
{
|
if (File.Exists(savePath))
|
{
|
settings.saveDatas =MessageCompressHelper.ReadCompressedBase64FromFile<SaveDict>(savePath);
|
}
|
else
|
{
|
settings.saveDatas = new SaveDict();
|
}
|
}
|
|
}
|
|
}
|
}
|
|
|
//初始化存储数据库
|
//if (gParam.GlobalConfig.Ext.启用数据库存储)
|
//{
|
// if (!SolutionDBHelper.isHostInited)
|
// SolutionDBHelper.Init("localhost", "selfAdpDb");
|
// string saveName = gParam.SolutionSaveName ?? gParam.GlobalConfig.ModelObjectID;
|
// gParam.SolutionDBHelper = new SolutionDBHelper(saveName);
|
// if (SolutionDBHelper.InstanceDict.ContainsKey(saveName)) SolutionDBHelper.InstanceDict.Remove(saveName);
|
// SolutionDBHelper.InstanceDict.Add(saveName, gParam.SolutionDBHelper);
|
//}
|
|
|
|
|
|
//Start();
|
this.isInited = true;
|
|
return null;
|
}
|
|
|
|
public string Start()
|
{
|
if (isStarted) return null;
|
isStarted=true;
|
string result = null;
|
if (CSM != null)
|
{
|
ChildSolutionName.ForEach(n =>
|
{
|
var wmos = CSM[n].WMOs;
|
wmos.ForEach(wmo =>
|
{
|
|
wmo.QueneRunnerEnable = true;
|
wmo.StartRunQuene();
|
wmo.Start();
|
});
|
|
});
|
}
|
|
|
EPAController.StartRobot();
|
EPAController.needToStop = false;
|
//[Cloudflight修改]2024-1-15
|
if (gParam!=null && gParam.Level==0)Thread.Sleep(500);
|
return result;
|
}
|
|
|
|
|
|
/// <summary>
|
/// 启动计算
|
/// </summary>
|
/// <param name="wParam">计算参数</param>
|
/// <param name="showLog">显示日志</param>
|
/// <param name="CallType">调用类型:0是接口,1是界面</param>
|
/// <returns></returns>
|
public string Run(WdnmoParam wParam,bool showLog=true,int CallType=0)
|
{
|
|
Start();
|
//Log.Add($"子方案计算--①开始任务");
|
//ConsoleLog("输入参数:" + JsonConvert.SerializeObject(wParam.ScadaPoints));
|
string result = null;
|
EPAController.CallBackType = CallType;
|
|
|
|
var controller = this.EPAController;
|
|
|
|
|
|
|
|
|
|
if (wParam!=null)
|
{
|
this.wParam = wParam;
|
|
//Quene.TimePoints = wParam.ScadaPoints;
|
|
|
|
|
param.预处理插件.ToList().ForEach(v =>
|
{
|
if (v.IndicatorType == "初始及运行传参" || v.IndicatorType == "运行传参")
|
v.Eval.ChangeParam(param, wParam, gParam,null);
|
});
|
|
|
|
|
|
|
|
controller.setwParam((WdnmoParam)wParam);
|
if ((result = controller.SetVals((WdnmoParam)wParam)) != null)
|
{
|
if (gParam.onError != null) gParam.onError(result);
|
return result;
|
}
|
}
|
|
workerThread = new Thread(controller.SearchSolution);
|
workerThread.Start();
|
|
return result;
|
}
|
|
|
/// <summary>
|
/// 启动计算
|
/// </summary>
|
/// <param name="wParam">计算参数</param>
|
/// <param name="showLog">显示日志</param>
|
/// <param name="CallType">调用类型:0是接口,1是界面</param>
|
/// <returns></returns>
|
public string Train(WdnmoParam wParam,bool showLog=true,int CallType=0)
|
{
|
|
Start();
|
//Log.Add($"子方案计算--①开始任务");
|
//ConsoleLog("输入参数:" + JsonConvert.SerializeObject(wParam.ScadaPoints));
|
string result = null;
|
EPAController.CallBackType = CallType;
|
|
|
|
var controller = this.EPAController;
|
|
if (wParam!=null)
|
{
|
this.wParam = wParam;
|
|
//Quene.TimePoints = wParam.ScadaPoints;
|
|
|
|
|
param.预处理插件.ToList().ForEach(v =>
|
{
|
if (v.IndicatorType == "初始及运行传参" || v.IndicatorType == "运行传参")
|
v.Eval.ChangeParam(param, wParam, gParam,null);
|
});
|
|
|
|
|
|
|
|
controller.setwParam((WdnmoParam)wParam);
|
if ((result = controller.SetVals((WdnmoParam)wParam)) != null)
|
{
|
if (gParam.onError != null) gParam.onError(result);
|
return result;
|
}
|
}
|
|
workerThread = new Thread(controller.GenerateSaveSet);
|
workerThread.Start();
|
|
return result;
|
}
|
|
|
|
|
|
public int GetMinutesFromMonday(DateTime time)
|
{
|
DateTime now = time;
|
DayOfWeek dayOfWeek = now.DayOfWeek;
|
|
DateTime monday = now.Date.AddDays(-(int)dayOfWeek + 1);
|
DateTime thisMonday = new DateTime(monday.Year, monday.Month, monday.Day, 0, 0, 0);
|
|
TimeSpan ts = now - thisMonday;
|
|
return (int)ts.TotalMinutes;
|
}
|
|
|
/// <summary>
|
/// 桌面端界面调用
|
/// </summary>
|
/// <returns></returns>
|
public string Run()
|
{
|
Start();
|
EPAController.CallBackType = 1;
|
string result = null;
|
|
var controller = EPAController.Clone();
|
this.EPAController = controller;
|
workerThread = new Thread(controller.SearchSolution);
|
workerThread.Start();
|
return result;
|
}
|
|
|
|
#region 中间过程
|
public void SetVars(string name, WdnmoParam wParam)
|
{
|
|
wParam.fullSearchMode = true;
|
|
|
|
|
var ID = wParam.ID = Guid.NewGuid();
|
lock (CSM[name].RequestQueues)
|
{
|
CSM[name].RequestQueues.Enqueue(wParam);
|
//Log.Add($"中间列表添加任务,当前{CSM[name].RequestQueues.Count}个");
|
}
|
//while (!CSM[name].RequestFinished.Contains(ID)) ;
|
//if (gParam.Level > 0) Log.Add($"子方案计算--⑥结果返回(中间队列)");
|
|
}
|
|
//System.Windows.Forms.Timer timer_requestQueneRunner;
|
public bool QueneRunnerEnable = false;
|
Thread t;
|
//private ManualResetEvent mre = new ManualResetEvent(true);
|
public void StartRunQuene()
|
{
|
//timer_requestQueneRunner = new System.Windows.Forms.Timer();
|
//timer_requestQueneRunner.Tick += OnQueneRunnerTick;
|
//timer_requestQueneRunner.Interval = 100;
|
//timer_requestQueneRunner.Start();
|
if (!QueneRunnerEnable) return;
|
t = new Thread(new ThreadStart(DoCalc));
|
t.Start();
|
//mre.WaitOne(); // 等待 DoCalc 方法完成
|
}
|
|
public void StopRunQuene()
|
{
|
//if (timer_requestQueneRunner != null)
|
//{
|
// timer_requestQueneRunner.Stop();
|
// timer_requestQueneRunner.Dispose();
|
//}
|
if (t!=null&& t.IsAlive) t.Abort();
|
QueneRunnerEnable = false;
|
|
}
|
|
|
private void DoCalc()
|
{
|
while (Enabled)
|
{
|
|
string result = null;
|
|
//if (Busy) continue;
|
|
//wParam = null;
|
if (Quene.RequestQueues == null) continue;
|
WdnmoParam wParam0 = null;
|
//[Cloudflight修改]2024-1-15 将Quene.RequestQueues.Count的判断放到lock外边
|
if (Quene.RequestQueues.Count <= 0) { /*Busy = false;*/Thread.Sleep(5); continue; }
|
lock (Quene.RequestQueues)
|
{
|
//if (Quene.RequestQueues.Count <= 0) { /*Busy = false;*/Thread.Sleep(1); continue; }
|
if ((Quene.RequestQueues.Count <= 0)) continue;
|
wParam0 = Quene.RequestQueues.Dequeue();
|
|
//Busy = true;
|
//Log.Add($"中间列表消费任务,当前{Quene.RequestQueues.Count}个");
|
}
|
gParam.Quene.ResultHash.Clear();
|
gParam.Quene.BestResult = double.MaxValue;
|
//if (wParam == null || wParam!=null && JsonConvert.SerializeObject(wParam.ToSearchDict()) != JsonConvert.SerializeObject(wParam0.ToSearchDict()))
|
//{
|
|
|
// gParam.Quene.ResultHash.Clear();
|
|
|
|
//}
|
|
wParam = wParam0;
|
//double resultValue = 0;
|
Guid ID = wParam.ID;
|
this.gParam.onFinished = null;
|
this.gParam.onFinished += (obj) =>
|
{
|
//Busy = false;
|
|
Quene.RequestFinished.Add(ID);
|
StartRunQuene();
|
};
|
this.gParam.onFinished += wParam.onFinish;
|
this.gParam.isNeedOutput = wParam.isNeedOutPut;
|
if ((result = Run(wParam, false)) == null)
|
{
|
break;
|
}
|
else
|
{
|
//[Cloudflight修改]2024-1-15
|
//MessageBox.Show(result);
|
//Busy = false;
|
//throw new Exception(result);
|
this.onError(result);
|
}
|
|
//mre.Set(); // 通知 StartRunQuene 方法完成
|
}
|
}
|
|
public void SetSaveName(string name)
|
{
|
gParam.SolutionSaveName = name;
|
}
|
#endregion
|
DateTime lastTime = DateTime.Parse("2022-01-01");
|
StringBuilder LogText =new StringBuilder();
|
public void ConsoleLog(string txt)
|
{
|
LogText.AppendLine(("------- "+txt+"\t" + "\t"));
|
var Totolsecond = (DateTime.Now - lastTime).TotalMilliseconds / 1000.0;
|
LogText.AppendLine(($"耗时:{(Totolsecond).ToString("0.00")}秒") );
|
lastTime = DateTime.Now;
|
}
|
|
public void ConsoleLog(string txt,object o)
|
{
|
|
LogText.AppendLine(("------- " + txt+JsonConvert.SerializeObject(o) + "\t" + "\t") );
|
var Totolsecond = (DateTime.Now - lastTime).TotalMilliseconds / 1000.0;
|
LogText.AppendLine(($"耗时:{(Totolsecond).ToString("0.00")}秒") );
|
lastTime = DateTime.Now;
|
|
}
|
public void OutPutLog(bool OpenFile=false)
|
{
|
|
//string Pathdir = @"Log\";
|
//string Path = @"Log\Log" + DateTime.Now.ToString("yyyyMMddHHmmss")+".txt";
|
//string Path = @"Log\Log.txt";
|
//if (!Directory.Exists(Pathdir)) Directory.CreateDirectory(Pathdir);
|
//if (File.Exists(Path)) File.Delete(Path);
|
//StreamWriter sw = new StreamWriter(Path);
|
//sw.Write(LogText);
|
//sw.Close();
|
//if (OpenFile) System.Diagnostics.Process.Start("explorer",Path);
|
Log.OpenFile();
|
|
}
|
|
/// <summary>
|
/// 单次计算,获取计算结果
|
/// </summary>
|
/// <param name="ConfigPath"></param>
|
/// <param name="ModelPath"></param>
|
/// <param name="wParam"></param>
|
/// <param name="showLog"></param>
|
/// <returns></returns>
|
public WdnmoParam GetResultByScada(string ConfigPath ,
|
string ModelPath, WdnmoParam wParam,bool showLog=false)
|
{
|
lastTime = DateTime.Now;
|
ConsoleLog("GetResultByScada开始");
|
|
string result = this.Init(ConfigPath, ModelPath, _onFinish, _onErrored,null,wParam);
|
//if ((result=this.Init(ConfigPath,ModelPath,_onFinish,_onErrored))!=null)
|
if (result != null)
|
{
|
wParam.ErrorMessage = result;
|
return wParam;
|
}
|
ConsoleLog("initGUI完成");
|
isFinished = false;
|
if ((result = this.Run(wParam, showLog)) != null)
|
{
|
wParam.ErrorMessage = result;
|
this.Close();
|
return wParam;
|
}
|
ConsoleLog("runScada完成");
|
object lockObj = new object();
|
while (true)
|
{
|
lock (lockObj) // 使用 lock 确保 isFinished 能够线程安全地更新
|
{
|
if (isFinished) break; // 如果已经完成了任务,则跳出循环
|
}
|
//Thread.Sleep(100); // 暂停一秒钟,等待状态的更新
|
}
|
ConsoleLog("计算完成");
|
if (showLog) OutPutLog();
|
return wParam;
|
}
|
bool isFinished = false;
|
WdnmoParam result_param;
|
#region 调试方法
|
void _onFinish(dynamic modelParams)
|
{
|
result_param = modelParams as WdnmoParam;
|
ConsoleLog("输出参数:" + JsonConvert.SerializeObject(result_param.ResultPoints));
|
if (Robot.Message != null)
|
ConsoleLog("计算反馈错误信息:" + Robot.Message);
|
isFinished = true;
|
}
|
void _onErrored(dynamic result)
|
{
|
result_param = new WdnmoParam() { ErrorMessage = result.ToString() };
|
ConsoleLog("错误信息" + result_param.ErrorMessage);
|
ConsoleLog("输出参数(错误):" + JsonConvert.SerializeObject(result_param.ResultPoints));
|
isFinished = true;
|
}
|
#endregion
|
|
public string ViewResultGUI()
|
{
|
EPAController.ViewResult();
|
return null;
|
}
|
|
public float GetValue(string ID, int code, bool isNode)
|
{
|
return EPAController.ViewResult(ID,code,isNode);
|
}
|
public string SetValue(string ID, int code, double value,bool isNode)
|
{
|
return EPAController.SetResult(ID, code, value, isNode);
|
}
|
public string SetValue(string ID, HydraulicInputType type, float value)
|
{
|
return EPAController.SetResult(ID, type, value);
|
}
|
public EPAParrelController epaParrelController { get { return EPAController; } }
|
|
public string manuCalc(Result resultItem = null, WdnmoParam wParam0 = null)
|
{
|
return EPAController.manuCalc(resultItem,wParam0);
|
}
|
public WdnmoParam CalcbyResult(calcParam resultItem = null, WdnmoParam wParam0 = null)
|
{
|
return EPAController.CalcbyResult(resultItem, wParam0);
|
}
|
public string Stop()
|
{
|
isStarted = false;
|
string result = null;
|
if (EPAController != null)
|
{
|
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 (CSM != null)
|
{
|
foreach (var name in ChildSolutionName)
|
{
|
CSM[name].WMOs.ForEach(w => w.Stop());
|
}
|
}
|
return result;
|
}
|
public string Close()
|
{
|
this.isInited = false;
|
//if (gParam != null)
|
// gParam.Dispose();
|
//gParam = null;
|
|
isStarted = false;
|
string result = null;
|
|
if (EPAController != null)
|
{
|
EPAController.needToStop = true;
|
EPAController.StopRobot();
|
EPAController.Close();
|
}
|
|
if (workerThread!=null)
|
workerThread.Abort();
|
|
|
if (CSM!=null)
|
{
|
foreach(var name in ChildSolutionName)
|
{
|
if (CSM.ContainsKey(name))
|
CSM[name].WMOs.ForEach(w=>w.Close());
|
}
|
CSM.Clear();
|
CSM = null;
|
ChildSolutionName = null;
|
}
|
StopRunQuene();
|
|
|
return result;
|
}
|
|
|
private string loadLogicParam()
|
{
|
|
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();
|
|
|
|
|
var hosts = (List<LogicPoint>)gParam.Db.Connection.Query<LogicPoint>(
|
$"SELECT {LogicPoint.selectColumn} FROM RemoteHost");
|
|
|
//double d=0;
|
|
|
foreach (var host in hosts.Where(x => x.LogicType == "初始条件" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x=>x.Sort))
|
{
|
param.初始条件.Add(GetVarByHost(host));
|
}
|
foreach (var host in hosts.Where(x => x.LogicType == "下阶段条件" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
param.下阶段条件.Add(GetVarByHost(host));
|
}
|
foreach (var host in hosts.Where(x => x.LogicType == "试算参数" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
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]));
|
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))
|
{
|
//var accuracy = double.Parse(host.Ext.accurary == "" ? "0.1" : host.Ext.accurary);
|
var v = GetVarByHost(host);
|
param.水量分配变量.Add(v);
|
}
|
foreach (var host in hosts.Where(x => x.LogicType == "变量" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
param.变量.Add(GetVarByHost(host));
|
}
|
foreach (var host in hosts.Where(x => x.LogicType == "约束条件" && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
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))
|
{
|
param.集合.Add(GetVarByHost(host));
|
}
|
|
foreach (var host in hosts.Where(x => (x.LogicType == "表达式") && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
param.表达式.Add(GetVarByHost(host));
|
}
|
foreach (var host in hosts.Where(x => (x.LogicType == "预处理插件") && x.ParentId != -1 && x.Ext.Enable).OrderBy(x => x.Sort))
|
{
|
param.预处理插件.Add(GetVarByHost(host));
|
}
|
|
{
|
var OBJFunctionList = hosts.FindAll(x => x.LogicType == "目标函数" && x.ParentId != -1 && x.Ext.Enable);
|
if (OBJFunctionList.Count == 0)
|
{
|
//MessageBox.Show("未设定目标函数");
|
return "未设定目标函数";
|
}
|
else if (OBJFunctionList.Count > 1)
|
{
|
//MessageBox.Show("目标函数太多,只能设定一个目标函数");
|
return "目标函数太多,只能设定一个目标函数";
|
}
|
var o = OBJFunctionList[0];
|
DRange to;
|
string[] sp;
|
try
|
{
|
if (!string.IsNullOrEmpty(o.Expression.Trim()) && (sp = o.Expression.Replace(',', ',').Split(',')).Length > 1)
|
{
|
to = new DRange(double.Parse(sp[0]), double.Parse(sp[1]));
|
}
|
else
|
{
|
to = new DRange(0,0);
|
}
|
}
|
catch
|
{
|
return "目标容许范围设置格式错误";
|
}
|
{
|
var host = o;
|
var expressType = host.LogicType;
|
|
var v = GetVarByHost(host);
|
|
|
OBJFunction OFunction = new OBJFunction()
|
{
|
Text_origin = o.ModelObjectID,
|
Name = o.Name,
|
ExpressType = o.ExpressionType,
|
tolerance = to,
|
variable = v
|
//{
|
// ID = o.Id,
|
// modelObjectID = o.ModelObjectID,
|
// Type = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == o.IndicatorType) ?? new TypeIndicator()).EpaType,
|
// isNode = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == o.IndicatorType) ?? new TypeIndicator()).isNode,
|
// Name = o.Name,
|
// ObjType = (int)(GlobalModel.DEFINE_OBJECT.Find(obj => obj.Name == o.Ext.ObjectType) ?? new TypeObject()).EPAObjType,
|
// 小数位数 = o.Ext.小数位数,
|
// SearchRange = double.TryParse(o.Ext.SaveAcc, out d) ? d : 0,
|
// isNeedToSave = o.Ext.isSave == "是" ? true : false,
|
// SaveKey = o.Ext.SaveRange,
|
// expressType = "目标函数",
|
// sort = o.Sort,
|
//}
|
};
|
param.OFunction = OFunction;
|
}
|
|
|
|
|
|
|
}
|
|
var list = param.变量全集.FindAll(v => v.childSolution != "");
|
list.Sort((a,b)=>a.sort>b.sort?1:(a.sort<b.sort?-1:(a.ID>b.ID?1:(a.ID<b.ID?-1:0))));
|
if (list.Count>0)
|
{
|
param.ChildParam = new Dictionary<string, childSolutionParam>();
|
foreach (var childSolution in gParam.GlobalConfig.Ext.ChildSolutionArr)
|
{
|
if (!childSolution.启用) continue;
|
var childSolutionName = childSolution.名称;
|
var childSolutionSaveName = childSolution.存储表名;
|
var l1 = list.FindAll(v => v.childSolution == childSolutionSaveName && v.childType == "传入");
|
|
var l2 = list.FindAll(v => v.childSolution == childSolutionSaveName && v.childType == "返回");
|
if (l1.Count > 0 && l2.Count > 0)
|
{
|
param.ChildParam.Add(childSolutionName, new childSolutionParam());
|
var cp = param.ChildParam[childSolutionName];
|
cp.childSaveName = childSolutionSaveName;
|
cp.childVars_In=l1;
|
cp.childVars_Out=l2;
|
cp.childFitness_Out=( l2.Find(v=>v.childTag.ToLower()=="fitness"));
|
WdnmoParam wparam = new WdnmoParam();
|
wparam.ScadaPoints.AddRange(l1.Select(v =>
|
{
|
|
TimePoint t = new TimePoint() {
|
Name = v.Name,
|
Key = v.childTag,
|
SearchRange=v.SearchRange,
|
|
};
|
|
return t;
|
}));
|
wparam.ResultPoints.AddRange(l2.Select(v =>
|
{
|
TimePoint t = new TimePoint()
|
{
|
Name=v.Name,
|
Key = v.childTag,
|
isNeedtoSave = v.isNeedToSave,
|
SaveKey = v.SaveKey,
|
};
|
return t;
|
}));
|
cp.wParam= wparam;
|
}
|
|
}
|
}
|
return null;
|
}
|
public static string UpdateExpress(LogicModelParams param, HashSet<int> list_express)
|
{
|
//if (host.ExpressionType == "表达式计算")
|
//{
|
// string text = HydraulicHelper.GetExVarText(s, param, result);
|
// try
|
// {
|
// Eval val = new Hydro.CodeProvider.Eval(text, s.Vars.Count);
|
// if (!val.isInit) { result.AppendLine($"表达式[{s.Name}]公式错误," + val.errString); }
|
// s.Eval = val;
|
// s.Value_Set(param.Period, double.NaN);
|
// }
|
// catch (Exception ee)
|
// {
|
// { result.AppendLine(ee.Message); }
|
// }
|
|
//}
|
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.表达式.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)
|
{
|
var v = GetVarByHost(host);
|
switch (v.logicType)
|
{
|
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;
|
}
|
|
}
|
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.ExpressionType == "表达式计算")
|
{
|
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.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;
|
}
|
return list_express;
|
}
|
public static variable GetVarByHost( LogicPoint host,double? accuracy=null,DRange doubleRange=null)
|
{
|
double d;
|
/*[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 = VarType,
|
arrgFuncType = arrgFuncType,
|
ObjType = (int)ObjType,
|
Name = host.Name,
|
expressType = host.ExpressionType,
|
expressString = host.Expression,
|
Tag = host.Ext.Tag,
|
|
defaultExpress = host.Ext.accurary,
|
isNode = isNode,
|
|
小数位数 = host.Ext.小数位数,
|
childSolution = host.Ext.childSolution,
|
childTag = host.Ext.childTag,
|
childType = host.Ext.childType,
|
SearchRange = double.TryParse(host.Ext.SaveAcc, out d) ? d : 0,
|
isNeedToSave = host.Ext.isSave == "是" ? true : false,
|
SaveKey = host.Ext.SaveRange,
|
sort = host.Sort,
|
logicType = host.LogicType,
|
accuracy = accuracy,
|
doubleRange = doubleRange,
|
};
|
|
|
|
return v;
|
}
|
public static void UpdateVarByHost(variable v,LogicPoint host, double? accuracy = null, DRange doubleRange = null)
|
{
|
double d;
|
/*[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 = "计算值";
|
}
|
}
|
|
|
//if (!GlobalModel.dict_StringToType.ContainsKey(host.IndicatorType)) GlobalModel.dict_StringToType[host.IndicatorType] = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).Type;
|
//var VarType = GlobalModel.dict_StringToType[host.IndicatorType];
|
|
//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;
|
//int ObjType =GlobalModel.dict_StringToObjType[host.Ext.ObjectType];
|
|
//if (!GlobalModel.dict_StringToisNode.ContainsKey(host.IndicatorType)) GlobalModel.dict_StringToisNode[host.IndicatorType] = (GlobalModel.DEFINE_INDICATOR.Find(ind => ind.Name == host.IndicatorType) ?? new TypeIndicator()).isNode;
|
//bool isNode = GlobalModel.dict_StringToisNode[host.IndicatorType];
|
|
//if (!GlobalModel.dict_StringToFuncType.ContainsKey(host.Ext.accurary)) GlobalModel.dict_StringToFuncType[host.Ext.accurary] = GlobalModel.DEFIND_AGGFUNC.FindIndex(func => func.Name == host.Ext.accurary);
|
//int arrgFuncType = GlobalModel.dict_StringToFuncType[host.Ext.accurary];
|
|
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;
|
}
|
|
private string loadGeneticParam(FinishEvent onFinished, FinishEvent onError, FinishEvent onReportProgress, SetEvent SetVarsMethod)
|
{
|
|
//string result = null;
|
|
|
//DLengths.ForEach(m => chromosomeLength += m);
|
|
gParam.populationSize = gParam.GlobalConfig.Ext.populationNum;
|
gParam.iterations = gParam.GlobalConfig.Ext.iterationNum;
|
gParam.populationSize_full = 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;
|
gParam.setVars = SetVarsMethod;
|
|
ChildSolutions.ForEach(solution =>
|
{
|
string key = solution.名称;
|
//初始化内存存储
|
if (gParam.GlobalConfig.Ext.启用内存存储)
|
{
|
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();
|
// }
|
//}
|
|
}
|
});
|
|
return null;
|
|
|
|
|
|
}
|
|
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 / (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;
|
}
|
|
private string controllerInit(bool isGUI=false,WdnmoParam wParam=null)
|
{
|
string result = null;
|
string inp_file=null;
|
if (gParam.GlobalConfig.Ext.isWaterModelCalc)
|
{
|
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;
|
}
|
|
}
|
|
EPAController = new EPAParrelController();
|
|
|
if ((result = EPAController.Init(inp_file, gParam.GlobalConfig.Ext.MaxThread, param, gParam, wParam, isGUI)) != null)
|
{
|
EPAController.Dispose();
|
return result;
|
}
|
|
|
|
return null;
|
}
|
}
|
|
|
}
|