| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- using System;
- using System.Dynamic;
- using System.Linq;
- using WeEngine.Enum;
- using WeEngine.Packages;
- using WeEngine.Strategy.Eval;
- namespace WeEngine.Module
- {
- public class EvolutionEval : IEvalStrategy
- {
- /// <summary>
- /// 匹配关键字
- /// </summary>
- /// <param name="node"></param>
- public virtual void MatchKeyWord(NodeBase node)
- {
- if (node.CurPackageInfo.NodeState != NodeState.Running)
- {
- return;
- }
- string role = node.ExtendData?.BehaviorRole ?? "";
- string scenePath= node.ExtendData?.ScenePath ?? "";
- bool checkRole= node.ExtendData?.CheckRole ?? false;
- var keyWords = checkRole
- ? node.CurPackageInfo.NotMatchKeywords?.Where(a =>
- a.Roles.Any(s => s.Equal(role)) &&
- (string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList()
- : node.CurPackageInfo.NotMatchKeywords
- ?.Where(a => (string.IsNullOrEmpty(scenePath) || a.NodePath.StartsWith(scenePath))).ToList();
- string word = node.ExtendData?.BehaviorWord ?? "";
- if (keyWords != null && keyWords.Any() && !string.IsNullOrEmpty(word))
- {
- foreach (var keyWord in keyWords)
- {
- if (keyWord.Words.Any())
- {
- foreach (var str in keyWord.Words)
- {
- if (word.Contains(str))
- {
- dynamic obj = new ExpandoObject();
- obj.MatchWord = word;
- keyWord.ExtendData = obj;
- keyWord.CurPackageInfo.RunnerManager?.Instance?.Run(keyWord, OperationType.MatchSuccess);
- break;
- }
- }
- }
- }
- }
- }
- /// <summary>
- /// 获取当前节点评分
- /// </summary>
- /// <returns></returns>
- public virtual decimal GetActualScore(NodeBase node)
- {
- if (node.NodeState == NodeState.New)
- {
- return 0;
- }
- if (node.CorrectionScore > 0)
- {
- return node.CorrectionScore > node.NodeFullScore ? node.NodeFullScore : node.CorrectionScore;
- }
- decimal actualScore;
- switch (node.NodeType)
- {
- case NodeType.ScenePackage:
-
- actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
- break;
- case NodeType.SceneRound:
- actualScore = node.HasChild ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.ActualScore) : 0;
- break;
- case NodeType.SceneFlowBlock:
- actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
- break;
- case NodeType.SceneFlow:
- actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
- break;
- case NodeType.FlowNode:
- var flow = ((FlowNode)node).SelfFlow;
- actualScore = flow.ChildFullWeights == 0 ? 0 : flow.NodeFullScore * (node.ActualWeights / flow.ChildFullWeights);
- break;
- case NodeType.SceneInfo:
- actualScore = node.ChildFullWeights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.ChildFullWeights);
- break;
- case NodeType.Behavior:
- actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
- break;
- case NodeType.KeyWord:
- actualScore = ((KeywordNode)node).HasMatched ? node.NodeFullScore : 0;
- break;
- default:
- actualScore = node.Weights == 0 ? 0 : node.NodeFullScore * (node.ActualWeights / node.Weights);
- break;
- }
- actualScore = Math.Round(actualScore, 2);
- return actualScore;
- }
- /// <summary>
- /// 获取当前节点评分
- /// </summary>
- /// <returns></returns>
- public virtual decimal GetActualWeights(NodeBase node)
- {
- if (node.NodeState == NodeState.New)
- return 0;
- decimal actualWeights;
- switch (node.NodeType)
- {
- case NodeType.ScenePackage:
- actualWeights = 0;
- break;
- //case NodeType.SceneRound:
- //{
- // actualWeights = 0;
- // var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
- // if (node.ChildFullWeights != 0 && children != null && children.Any())
- // {
- // foreach (var child in children)
- // {
- // actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
- // }
- // }
- // break;
- //}
- case NodeType.SceneFlow:
- if (node.ChildFullWeights == 0)
- return 0;
- FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
- var childActualWeights = GetAllFlowNodeWeights(flowNode);
- actualWeights = (childActualWeights / node.ChildFullWeights) * node.Weights;
- break;
- case NodeType.FlowNode:
- var sceneInfos = ((FlowNode)node).SceneInfos;
- actualWeights = 0;
- if (sceneInfos != null && sceneInfos.Count > 0)
- {
- foreach (var sceneInfo in sceneInfos)
- {
- var sceneFullWeights=((FlowNode) node).SceneFullWeights;
- if (sceneInfo.NodeState != NodeState.New && sceneFullWeights != 0)
- {
- actualWeights += sceneInfo.ActualWeights * (sceneInfo.Weights / sceneFullWeights);
- }
- }
- }
- break;
- case NodeType.SceneInfo:
- actualWeights = 0;
- if (node.NodeState == NodeState.New || ((SceneNode)node).IsImportantNegative)
- return actualWeights;
- actualWeights = node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
- //var behaviorInfos = node.HasChild ? node.Children.Select(a => (BehaviorInfo)a).ToList() : null;
- //if (behaviorInfos != null && behaviorInfos.Any())
- //{
- // actualWeights = behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.ActualWeights);
- // actualWeights = actualWeights - behaviorInfos.Where(a => a.BehaviorScoreType == BehaviorScoreType.Negative)
- // .Sum(a => a.ActualWeights);
- //}
- if (actualWeights < 0)
- {
- actualWeights = 0;
- }
- break;
- case NodeType.Behavior:
- actualWeights = 0;
- var n = (BehaviorNode)node;
- if (node.NodeState == NodeState.New || n.ImportantNegative)
- return actualWeights;
- else if (n.BehaviorScoreType == BehaviorScoreType.Negative)
- {
- actualWeights = node.HasChild ? 0 - node.Children.Sum(a => a.ActualWeights) : 0;
- }
- else
- {
- bool isAuto = false;
- if (node.CurPackageInfo.AssessAuto)
- {
- isAuto = true;
- foreach (var role in n.BehaviorRoles)
- {
- if (node.CurPackageInfo.AssessRoles.Any(a=>role.Equal(a)))
- {
- isAuto = false;
- break;
- }
- }
- }
- actualWeights = isAuto ? node.Weights : node.HasChild ? node.Children.Sum(a => a.ActualWeights) : 0;
- }
- break;
- case NodeType.KeyWord:
- actualWeights = node.Parent.ChildFullWeights == 0 ? 0 :
- ((KeywordNode)node).HasMatched
- ? (node.Weights / node.Parent.ChildFullWeights) * node.Parent.Weights
- : 0;
- break;
- default:
- {
- actualWeights = 0;
- var children = node.Children?.Where(a => a.NodeState != NodeState.New).ToList();
- if (node.ChildFullWeights != 0 && children != null && children.Any())
- {
- foreach (var child in children)
- {
- actualWeights += child.ActualWeights * (child.Weights / node.ChildFullWeights);
- }
- }
- break;
- }
- }
- actualWeights = Math.Round(actualWeights, 2);
- return actualWeights;
- }
- /// <summary>
- /// 获取当前节点满分
- /// </summary>
- /// <returns></returns>
- public virtual decimal GetNodeFullScore(NodeBase node)
- {
- if (node.NodeState == NodeState.New)
- return 0;
- decimal fullScore;
- switch (node.NodeType)
- {
- case NodeType.ScenePackage:
- //方案包总分 为各轮次分总和
- fullScore = node.Children.Sum(a => a.NodeFullScore);
- break;
- case NodeType.SceneRound:
- fullScore = ((SceneRoundNode)node).RoundFullScore;
- break;
- case NodeType.FlowNode:
- var childFullWeights = ((FlowNode) node).SelfFlow.ChildFullWeights;
- if (childFullWeights == 0)
- return 0;
- fullScore = ((FlowNode)node).SelfFlow.NodeFullScore * (node.ChildFullWeights / childFullWeights);
- break;
- case NodeType.SceneInfo:
- var sceneFullWeights = ((FlowNode) node.Parent).SceneFullWeights;
- if (sceneFullWeights == 0)
- return 0;
- fullScore = node.Parent.NodeFullScore * (node.Weights / sceneFullWeights);
- break;
- default:
- if (node.Parent.ChildFullWeights == 0)
- return 0;
- fullScore = node.HasParent ? node.Parent.NodeFullScore * (node.Weights / node.Parent.ChildFullWeights) : 0;
- break;
- }
- fullScore = Math.Round(fullScore, 2);
- return fullScore;
- }
- /// <summary>
- /// 获取子节点权重之和
- /// </summary>
- /// <returns></returns>
- public virtual decimal GetChildFullWeights(NodeBase node)
- {
- if (node.NodeState == NodeState.New)
- {
- return 0;
- }
- decimal fullWeights;
- switch (node.NodeType)
- {
- case NodeType.SceneRound:
- case NodeType.SceneFlowBlock:
- //运行的权重总和
- fullWeights = node.HasChild
- ? node.Children.Where(a => a.NodeState != NodeState.New).Sum(a => a.Weights)
- : 0;
- break;
- case NodeType.SceneFlow:
- FlowNode flowNode = node.HasChild ? (FlowNode)node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
- fullWeights = GetAllFlowNodeWeights(flowNode, false);
- break;
- case NodeType.FlowNode:
- fullWeights = 0;
- var sceneInfos = ((FlowNode)node).SceneInfos;
- if (sceneInfos != null && sceneInfos.Count > 0)
- {
- foreach (var sceneInfo in sceneInfos)
- {
- var sceneFullWeights = ((FlowNode) node).SceneFullWeights;
- fullWeights += sceneFullWeights == 0
- ? 0
- : sceneInfo.ChildFullWeights * (sceneInfo.Weights / sceneFullWeights);
- }
- }
- break;
- case NodeType.SceneInfo:
- fullWeights = node.HasChild ? node.Children.Select(a => (BehaviorNode)a).Where(a => a.BehaviorScoreType == BehaviorScoreType.Normal).Sum(a => a.Weights) : 0;
- break;
- case NodeType.Behavior:
- fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
- break;
- case NodeType.KeyWord:
- return 0;
- default:
- fullWeights = node.HasChild ? node.Children.Sum(a => a.Weights) : 0;
- break;
- }
- fullWeights = Math.Round(fullWeights, 2);
- return fullWeights;
- }
-
- /// <summary>
- /// 获取定性评估结果
- /// </summary>
- /// <returns></returns>
- public string GetEvalQualitativeResult(PackageNode node, string exp)
- {
- try
- {
- if (string.IsNullOrEmpty(exp) || node.Children?.Count <= 0)
- {
- return "";
- }
- decimal fullScore = node.Children?.Sum(a => a.NodeFullScore) ?? 0;
- if (fullScore == 0)
- {
- return "";
- }
- var per = (node.Children?.Sum(a => a.ActualScore) * 100) / fullScore;
- var arr1 = exp.Split('@').ToList();
- foreach (var s in arr1)
- {
- var arr2 = s.Split('|');
- if (arr2.Length > 1 && int.TryParse(arr2[0], out var resultPer))
- {
- if (per < resultPer)
- {
- return arr2[1];
- }
- }
- else if (arr2.Length == 1)
- {
- return arr2[0];
- }
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- return "";
- }
- return "";
- }
- /// <summary>
- /// 获取节点的权重
- /// </summary>
- /// <param name="node"></param>
- /// <param name="isActual"></param>
- /// <returns></returns>
- private decimal GetAllFlowNodeWeights(FlowNode node, bool isActual = true)
- {
- decimal weights = 0;
- if (node == null || node.NodeState == NodeState.New)
- {
- return weights;
- }
- weights = isActual ? node.ActualWeights : node.ChildFullWeights;
- FlowNode nextNode = node.HasChild ? node.Children.FirstOrDefault(a => a.NodeState != NodeState.New) : null;
- if (nextNode != null)
- {
- weights += GetAllFlowNodeWeights(nextNode, isActual);
- }
- return weights;
- }
- }
- }
|