EvolutionEval.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. using System;
  2. using System.Dynamic;
  3. using System.Linq;
  4. using WeEngine.Enum;
  5. using WeEngine.Packages;
  6. using WeEngine.Strategy.Eval;
  7. namespace WeEngine.Module
  8. {
  9. public class EvolutionEval : IEvalStrategy
  10. {
  11. /// <summary>
  12. /// 匹配关键字
  13. /// </summary>
  14. /// <param name="node"></param>
  15. public virtual void MatchKeyWord(NodeBase node)
  16. {
  17. if (node.CurPackageInfo.NodeState != NodeState.Running)
  18. {
  19. return;
  20. }
  21. string role = node.ExtendData?.BehaviorRole ?? "";
  22. string scenePath= node.ExtendData?.ScenePath ?? "";
  23. bool checkRole= node.ExtendData?.CheckRole ?? false;
  24. var keyWords = checkRole
  25. ? node.CurPackageInfo.NotMatchKeywords?.Where(a =>
  26. a.Roles.Any(s => s.Equal(role)) &&
  27. (string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList()
  28. : node.CurPackageInfo.NotMatchKeywords
  29. ?.Where(a => (string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList();
  30. string word = node.ExtendData?.BehaviorWord ?? "";
  31. if (keyWords != null && keyWords.Any() && !string.IsNullOrEmpty(word))
  32. {
  33. foreach (var keyWord in keyWords)
  34. {
  35. if (keyWord.Words.Any())
  36. {
  37. foreach (var str in keyWord.Words)
  38. {
  39. if (word.Contains(str))
  40. {
  41. dynamic obj = new ExpandoObject();
  42. obj.MatchWord = word;
  43. keyWord.ExtendData = obj;
  44. keyWord.CurPackageInfo.RunnerManager?.Instance?.Run(keyWord, OperationType.MatchSuccess);
  45. break;
  46. }
  47. }
  48. }
  49. }
  50. }
  51. }
  52. /// <summary>
  53. /// 获取当前节点评分
  54. /// </summary>
  55. /// <returns></returns>
  56. public virtual decimal GetActualScore(NodeBase node)
  57. {
  58. if (node.NodeState == NodeState.New)
  59. {
  60. return 0;
  61. }
  62. if (node.CorrectionScore > 0)
  63. {
  64. return node.CorrectionScore > node.NodeFullScore ? node.NodeFullScore : node.CorrectionScore;
  65. }
  66. decimal actualScore;
  67. switch (node.NodeType)
  68. {
  69. case NodeType.ScenePackage:
  70. actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
  71. break;
  72. case NodeType.SceneRound:
  73. actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
  74. break;
  75. case NodeType.SceneFlowBlock:
  76. actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
  77. break;
  78. case NodeType.SceneFlow:
  79. actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
  80. break;
  81. case NodeType.FlowNode:
  82. var flow = ((FlowNode)node).SelfFlow;
  83. actualScore = flow.ChildFullWeights == 0 ? 0 : flow.NodeFullScore * (node.ActualWeights / flow.ChildFullWeights);
  84. break;
  85. case NodeType.SceneInfo:
  86. actualScore = node.ChildFullWeights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.ChildFullWeights);
  87. break;
  88. case NodeType.Behavior:
  89. actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
  90. break;
  91. case NodeType.KeyWord:
  92. actualScore = ((KeywordNode)node).HasMatched ? node.NodeFullScore : 0;
  93. break;
  94. default:
  95. actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
  96. break;
  97. }
  98. actualScore = Math.Round(actualScore, 2);
  99. return actualScore;
  100. }
  101. /// <summary>
  102. /// 获取当前节点评分
  103. /// </summary>
  104. /// <returns></returns>
  105. public virtual decimal GetActualWeights(NodeBase node)
  106. {
  107. if (node.NodeState == NodeState.New)
  108. return 0;
  109. decimal actualWeights;
  110. switch (node.NodeType)
  111. {
  112. case NodeType.ScenePackage:
  113. actualWeights = 0;
  114. break;
  115. //case NodeType.SceneRound:
  116. //{
  117. // actualWeights = 0;
  118. // var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
  119. // if (node.ChildFullWeights != 0 && children != null && children.Any())
  120. // {
  121. // foreach (var child in children)
  122. // {
  123. // actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
  124. // }
  125. // }
  126. // break;
  127. //}
  128. case NodeType.SceneFlow:
  129. if (node.ChildFullWeights == 0)
  130. return 0;
  131. FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
  132. var childActualWeights = GetAllFlowNodeWeights(flowNode);
  133. actualWeights = (childActualWeights / node.ChildFullWeights) * node.Weights;
  134. break;
  135. case NodeType.FlowNode:
  136. var sceneInfos = ((FlowNode)node).SceneInfos;
  137. actualWeights = 0;
  138. if (sceneInfos != null && sceneInfos.Count > 0)
  139. {
  140. foreach (var sceneInfo in sceneInfos)
  141. {
  142. var sceneFullWeights=((FlowNode) node).SceneFullWeights;
  143. if (sceneInfo.NodeState != NodeState.New && sceneFullWeights != 0)
  144. {
  145. actualWeights += sceneInfo.ActualWeights * (sceneInfo.Weights / sceneFullWeights);
  146. }
  147. }
  148. }
  149. break;
  150. case NodeType.SceneInfo:
  151. actualWeights = 0;
  152. if (node.NodeState == NodeState.New || ((SceneNode)node).IsImportantNegative)
  153. return actualWeights;
  154. actualWeights = node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
  155. //var behaviorInfos = node.HasChild ? node.Children.Select(a => (BehaviorInfo)a).ToList() : null;
  156. //if (behaviorInfos != null && behaviorInfos.Any())
  157. //{
  158. // actualWeights = behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.ActualWeights);
  159. // actualWeights = actualWeights - behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Negative)
  160. // .Sum(a => a.ActualWeights);
  161. //}
  162. if (actualWeights < 0)
  163. {
  164. actualWeights = 0;
  165. }
  166. break;
  167. case NodeType.Behavior:
  168. actualWeights = 0;
  169. var n = (BehaviorNode)node;
  170. if (node.NodeState == NodeState.New || n.ImportantNegative)
  171. return actualWeights;
  172. else if (n.BehaviorScoreType == BehaviorScoreType.Negative)
  173. {
  174. actualWeights = node.HasChild ? 0 - node.Children.Sum(a => a.ActualWeights) : 0;
  175. }
  176. else
  177. {
  178. bool isAuto = false;
  179. if (node.CurPackageInfo.AssessAuto)
  180. {
  181. isAuto = true;
  182. foreach (var role in n.BehaviorRoles)
  183. {
  184. if (node.CurPackageInfo.AssessRoles.Any(a=>role.Equal(a)))
  185. {
  186. isAuto = false;
  187. break;
  188. }
  189. }
  190. }
  191. actualWeights = isAuto ? node.Weights : node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
  192. }
  193. break;
  194. case NodeType.KeyWord:
  195. actualWeights = node.Parent.ChildFullWeights == 0 ? 0 :
  196. ((KeywordNode)node).HasMatched
  197. ? (node.Weights / node.Parent.ChildFullWeights) * node.Parent.Weights
  198. : 0;
  199. break;
  200. default:
  201. {
  202. actualWeights = 0;
  203. var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
  204. if (node.ChildFullWeights != 0 && children != null && children.Any())
  205. {
  206. foreach (var child in children)
  207. {
  208. actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
  209. }
  210. }
  211. break;
  212. }
  213. }
  214. actualWeights = Math.Round(actualWeights, 2);
  215. return actualWeights;
  216. }
  217. /// <summary>
  218. /// 获取当前节点满分
  219. /// </summary>
  220. /// <returns></returns>
  221. public virtual decimal GetNodeFullScore(NodeBase node)
  222. {
  223. if (node.NodeState == NodeState.New)
  224. return 0;
  225. decimal fullScore;
  226. switch (node.NodeType)
  227. {
  228. case NodeType.ScenePackage:
  229. //方案包总分 为各轮次分总和
  230. fullScore = node.Children.Sum(a => a.NodeFullScore);
  231. break;
  232. case NodeType.SceneRound:
  233. fullScore = ((SceneRoundNode)node).RoundFullScore;
  234. break;
  235. case NodeType.FlowNode:
  236. var childFullWeights = ((FlowNode) node).SelfFlow.ChildFullWeights;
  237. if (childFullWeights == 0)
  238. return 0;
  239. fullScore = ((FlowNode)node).SelfFlow.NodeFullScore * (node.ChildFullWeights / childFullWeights);
  240. break;
  241. case NodeType.SceneInfo:
  242. var sceneFullWeights = ((FlowNode) node.Parent).SceneFullWeights;
  243. if (sceneFullWeights == 0)
  244. return 0;
  245. fullScore = node.Parent.NodeFullScore * (node.Weights / sceneFullWeights);
  246. break;
  247. default:
  248. if (node.Parent.ChildFullWeights == 0)
  249. return 0;
  250. fullScore = node.HasParent ? node.Parent.NodeFullScore * (node.Weights / node.Parent.ChildFullWeights) : 0;
  251. break;
  252. }
  253. fullScore = Math.Round(fullScore, 2);
  254. return fullScore;
  255. }
  256. /// <summary>
  257. /// 获取子节点权重之和
  258. /// </summary>
  259. /// <returns></returns>
  260. public virtual decimal GetChildFullWeights(NodeBase node)
  261. {
  262. if (node.NodeState == NodeState.New)
  263. {
  264. return 0;
  265. }
  266. decimal fullWeights;
  267. switch (node.NodeType)
  268. {
  269. case NodeType.SceneRound:
  270. case NodeType.SceneFlowBlock:
  271. //运行的权重总和
  272. fullWeights = node.HasChild
  273. ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.Weights)
  274. : 0;
  275. break;
  276. case NodeType.SceneFlow:
  277. FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
  278. fullWeights = GetAllFlowNodeWeights(flowNode, false);
  279. break;
  280. case NodeType.FlowNode:
  281. fullWeights = 0;
  282. var sceneInfos = ((FlowNode)node).SceneInfos;
  283. if (sceneInfos != null && sceneInfos.Count > 0)
  284. {
  285. foreach (var sceneInfo in sceneInfos)
  286. {
  287. var sceneFullWeights = ((FlowNode) node).SceneFullWeights;
  288. fullWeights += sceneFullWeights == 0
  289. ? 0
  290. : sceneInfo.ChildFullWeights * (sceneInfo.Weights / sceneFullWeights);
  291. }
  292. }
  293. break;
  294. case NodeType.SceneInfo:
  295. fullWeights = node.HasChild ? node.Children.Select(a => (BehaviorNode)a).Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.Weights) : 0;
  296. break;
  297. case NodeType.Behavior:
  298. fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
  299. break;
  300. case NodeType.KeyWord:
  301. return 0;
  302. default:
  303. fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
  304. break;
  305. }
  306. fullWeights = Math.Round(fullWeights, 2);
  307. return fullWeights;
  308. }
  309. /// <summary>
  310. /// 获取定性评估结果
  311. /// </summary>
  312. /// <returns></returns>
  313. public string GetEvalQualitativeResult(PackageNode node, string exp)
  314. {
  315. try
  316. {
  317. if (string.IsNullOrEmpty(exp) || node.Children?.Count <= 0)
  318. {
  319. return "";
  320. }
  321. decimal fullScore = node.Children?.Sum(a => a.NodeFullScore) ?? 0;
  322. if (fullScore == 0)
  323. {
  324. return "";
  325. }
  326. var per = (node.Children?.Sum(a => a.ActualScore) * 100) / fullScore;
  327. var arr1 = exp.Split('@').ToList();
  328. foreach (var s in arr1)
  329. {
  330. var arr2 = s.Split('|');
  331. if (arr2.Length > 1 && int.TryParse(arr2[0], out var resultPer))
  332. {
  333. if (per < resultPer)
  334. {
  335. return arr2[1];
  336. }
  337. }
  338. else if (arr2.Length == 1)
  339. {
  340. return arr2[0];
  341. }
  342. }
  343. }
  344. catch (Exception e)
  345. {
  346. Console.WriteLine(e);
  347. return "";
  348. }
  349. return "";
  350. }
  351. /// <summary>
  352. /// 获取节点的权重
  353. /// </summary>
  354. /// <param name="node"></param>
  355. /// <param name="isActual"></param>
  356. /// <returns></returns>
  357. private decimal GetAllFlowNodeWeights(FlowNode node, bool isActual = true)
  358. {
  359. decimal weights = 0;
  360. if (node == null || node.NodeState == NodeState.New)
  361. {
  362. return weights;
  363. }
  364. weights = isActual ? node.ActualWeights : node.ChildFullWeights;
  365. FlowNode nextNode = node.HasChild ? node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
  366. if (nextNode != null)
  367. {
  368. weights += GetAllFlowNodeWeights(nextNode, isActual);
  369. }
  370. return weights;
  371. }
  372. }
  373. }