/// <summary> /// Resets the index of each node according to Deepth-First Search. /// </summary> /// <param name="node">Starting node to search.</param> /// <param name="childsProperty">Property to return child node.</param> /// <returns></returns> public static void RenumberIndicesOfBpmTree(this BpmGene node, Func <BpmGene, IEnumerable <BpmGene> > childsProperty) { Debug.WriteLine("Renumbering the following gene: " + node); var counter = 0; var stack = new Stack <BpmGene>(); node.Index = counter; stack.Push(node); while (stack.Count > 0) { var thisNode = stack.Pop(); if (childsProperty(thisNode) != null) { foreach (var child in childsProperty(thisNode)) { child.Index = ++counter; stack.Push(child); } } } }
/// <summary> /// sucht und findet Blätter mit dem speziellen Index, ansonsten return null /// </summary> /// <param name="index">Gene index</param> /// <param name="gene">starting gene</param> /// <returns></returns> public static BpmGene FindLeaf(this BpmGene gene, int index) { if (gene.Index == index) { if (gene.GetType() == typeof(BpmnActivity)) { return(gene); } else { return(null); } } // falsches blatt gefunden if (gene.Children == null || gene.Children.Count == 0) { return(null); } for (var i = gene.Children.Count - 1; i >= 0; i--) { if (gene.Children[i].Index <= index) { return(gene.Children[i].FindLeaf(index)); } } return(null); }
/// <summary> /// counts the appearance of same activities in single nodes /// </summary> /// <param name="gene">gene to check</param> /// <param name="count">so far found appearances</param> /// <returns></returns> public static int CheckForMultipleEqualActivitiesInSameNode(BpmGene gene, int count = 0) { if (gene is BpmnActivity) { return(count); } var list = new List <string>(); foreach (var child in gene.Children) { if (child is BpmnActivity) { if (list.Contains(((BpmnActivity)child).Name)) { count++; } else { list.Add(((BpmnActivity)child).Name); } } else { count += CheckForMultipleEqualActivitiesInSameNode(child); } } return(count); }
private void CalculatePath(BpmnProcessAttribute bpa, BpmGene gene, List <BpmnActivity> path) { if (gene == null) { return; } if (gene is BpmnActivity) { path.Add(gene as BpmnActivity); } else if (gene is BpmnSeq || gene is BpmnAnd) { foreach (var child in gene.Children) { CalculatePath(bpa, child, path); } } else if (gene is BpmnXor) { if ((gene as BpmnXor).ToProcessAttribute().Equals(bpa)) { if (gene.Children.Count > 0) { CalculatePath(bpa, gene.Children[0], path); } } else { if (gene.Children.Count > 1) { CalculatePath(bpa, gene.Children[1], path); } } } }
/// <summary> /// Count number of nodes in tree /// </summary> /// <param name="root">root node from tree</param> /// <param name="nodeType">node type looking for</param> /// <returns></returns> public static int CountSpecificNodes(this BpmGene root, Type nodeType) { if (root == null) { return(0); } var sum = 0; if (root.GetType() == nodeType) { sum++; } if (root is BpmnActivity) { return(sum); } if (root is BpmnAnd || root is BpmnSeq) { return(sum + root.Children.Sum(x => CountSpecificNodes(x, nodeType))); } // XOR return(sum + root.Children.Sum(x => CountSpecificNodes(x, nodeType))); }
/// <summary> /// Creates a new BPMN-XOR-Gateway /// </summary> /// <param name="index">i dof node</param> /// <param name="parent">parent node</param> /// <param name="decisionId">id of decision</param> /// <param name="decisionValue">value of decision</param> /// <param name="executionProbability">probability of execution</param> public BpmnXor(int index, BpmGene parent, string decisionId, string decisionValue, double executionProbability = 1.0) : base(index, parent) { DecisionId = decisionId; DecisionValue = decisionValue; ExecutionProbability = executionProbability; }
private XmlElement Activity(BpmGene gene) { var Activity = doc.OwnerDocument.CreateElement("bpmndi", "BPMNShape", BpmndiUri); Activity.SetAttribute("id", "Task_" + gene.Id + "_di"); Activity.SetAttribute("bpmnElement", "Task_" + gene.Id); return(Activity); }
public void auto(BpmGene gene, XmlElement start, XmlElement end) { matrix[0][0] = Start(start); AddColumn(); var d = AddGene(gene, 0, 1); AddColumn(); matrix[0][d.width + 1] = End(end); SetPositions(); }
private static void ListActivities(BpmGene gene, List <BpmnActivity> list) { if (gene is BpmnActivity) { list.Add((BpmnActivity)gene); } else { foreach (var g in gene.Children) { ListActivities(g, list); } } }
/// <summary> /// Counts number of hops to root node, alias depth /// </summary> /// <param name="gene">the gene to calculate for</param> /// <returns></returns> public static int CalculateNodeDepth(this BpmGene gene) { var parent = gene; var count = 0; while (parent != null) { parent = parent.Parent; count++; } return(count); }
private double CalculateTime(BpmnProcessAttribute bpa, BpmGene gene) { if (gene == null) { return(0); } if (gene is BpmnActivity) { return(DataHelper.ActivityHelper.Instance().GetTime((gene as BpmnActivity).Name)); } if (gene is BpmnAnd) { var max = 0.0; foreach (var child in gene.Children) { max = Math.Max(max, CalculateTime(bpa, child)); } return(max); } if (gene is BpmnSeq) { var sum = 0.0; foreach (var child in gene.Children) { sum += CalculateTime(bpa, child); } return(sum); } if ((gene as BpmnXor).ToProcessAttribute().Equals(bpa)) { if (gene.Children == null || gene.Children.Count == 0) { return(0); } else { return(CalculateTime(bpa, gene.Children[0])); } } if (gene.Children.Count > 1) { return(CalculateTime(bpa, gene.Children[1])); } return(0); }
// berechnen der Wahrscheinlichkeit, das Aktivität a & b im gleichen Prozess sind über die generierten Pfade und Pfadwahrscheinlichkeiten private static double CalculateProbabilities2ProcessActivities(BpmGene a, BpmGene b, List <Path> paths) { var probability = 0.0; foreach (var path in paths) { if (path.path.Contains(a) && path.path.Contains(b)) { probability += path.Probability; } } return(probability); }
/// <summary> /// checks for too much equal activities in one gateway /// </summary> /// <param name="gene"></param> /// <returns></returns> public static int CheckForTooMuchActivities(BpmGene gene) { // TODO stimmt nicht if (gene is BpmnActivity) { return(1); } var count = 0; foreach (var child in gene.Children) { count += CheckForTooMuchActivities(child); } return(count); }
private XmlElement And(BpmGene gene, bool open = true) { var And = doc.OwnerDocument.CreateElement("bpmndi", "BPMNShape", BpmndiUri); if (open) { And.SetAttribute("id", "ParallelGateway_open_" + gene.Id + "_di"); And.SetAttribute("bpmnElement", "ParallelGateway_open_" + gene.Id); } else { And.SetAttribute("id", "ParallelGateway_close_" + gene.Id + "_di"); And.SetAttribute("bpmnElement", "ParallelGateway_close_" + gene.Id); } return(And); }
private bool CheckActivityAttributeCovering(BpmGene root) { var decisions = DataHelper.ActivityAttributeHelper.Instance().GetAll(); foreach (var decision in decisions) { var decisionValues = DataHelper.ActivityAttributeHelper.Instance() .GetDecisionValues(decision.DecisionId); if (CheckActivityAttributeCovering(decision, decisionValues, root) == false) { return(false); } } return(true); }
/// <summary> /// Calculates the index of the specified child in parents children /// </summary> /// <param name="parent">the parent where to look</param> /// <param name="child">the child which to look for</param> /// <returns></returns> public static int GetChildIndex(BpmGene parent, BpmGene child) { if (parent == null) { return(-1); } for (var i = 0; i < parent.Children.Count; i++) { if (parent.Children[i].Index == child.Index) { return(i); } } return(-1); }
private XmlElement Xor(BpmGene gene, bool open = true) { var Xor = doc.OwnerDocument.CreateElement("bpmndi", "BPMNShape", BpmndiUri); Xor.SetAttribute("isMarkerVisible", "true"); if (open) { Xor.SetAttribute("id", "ExclusiveGateway_open_" + gene.Id + "_di"); Xor.SetAttribute("bpmnElement", "ExclusiveGateway_open_" + gene.Id); } else { Xor.SetAttribute("id", "ExclusiveGateway_close_" + gene.Id + "_di"); Xor.SetAttribute("bpmnElement", "ExclusiveGateway_close_" + gene.Id); } return(Xor); }
/// <summary> /// counts appearances of concatenating same gateways with having multiple children SEQ(SEQ(xxx)) /// </summary> /// <param name="gene"></param> /// <param name="count"></param> /// <returns></returns> public static int CheckForConcatenatingGatewaysWithSingleChild(BpmGene gene, int count = 0) { if (gene is BpmnActivity) { return(count); } if (gene.Children.Count == 1 && gene.Children[0].GetType() == gene.GetType()) { return(count + 1); } foreach (var child in gene.Children) { count += CheckForConcatenatingGatewaysWithSingleChild(child); } return(count); }
/// <summary> /// counts appearances of empty gateways /// </summary> /// <param name="gene"></param> /// <param name="count"></param> /// <returns></returns> public static int CheckForEmptyGateways(BpmGene gene, int count = 0) { if (gene is BpmnActivity) { return(count); } if (gene.Children.Count == 0) { return(count + 1); } foreach (var child in gene.Children) { count += CheckForEmptyGateways(child); } return(count); }
public PathSplitter(BpmGenome genome) { _root = genome.RootGene; if (DataHelper.ActivityAttributeHelper.Instance().GetAll().Count <= 0) { List <BpmnActivity> path = TreeHelper.ListActivities(genome); paths.Add(new Path { Probability = 1, path = path }); } foreach (var bpa in DataHelper.ActivityAttributeHelper.Instance().GetAll()) { var path = new List <BpmnActivity>(); CalculatePath(bpa, _root, path); paths.Add(new Path { Probability = bpa.DecisionProbability, path = path }); } }
/// <summary> /// checks for concatenating xors inside each other /// </summary> /// <param name="gene"></param> /// <param name="maxNumberOfXors"></param> /// <param name="count"></param> /// <returns></returns> public static int CheckForSeveralXorsInLine(BpmGene gene, int maxNumberOfXors, int count = 0) { var parent = gene; for (var i = 0; i < maxNumberOfXors; i++) { if (parent == null) { break; } if (parent is BpmnXor) { parent = parent.Parent; } else { break; } if (i == 2) { count++; } } if (parent is BpmnActivity) { return(count); } foreach (var child in gene.Children) { count += CheckForSeveralXorsInLine(child, maxNumberOfXors); } return(count); }
/// <summary> /// checks wheter xors have more than 2 children /// </summary> /// <param name="gene"></param> /// <returns></returns> public static bool CheckForBpmnXorFailture(BpmGene gene) { if (gene == null || gene is BpmnActivity) { return(true); } if (gene is BpmnAnd || gene is BpmnSeq || gene is BpmnXor && gene.Children.Count <= 2) { foreach (var geneForCheck in gene.Children) { var check = CheckForBpmnXorFailture(geneForCheck); if (!check) { return(false); } } return(true); } return(false); }
public static double CalculateLongestTime(BpmGene rootGene) { if (rootGene is BpmnSeq) { var time = 0.0; rootGene.Children.ForEach(x => time += CalculateLongestTime(x)); return(time); } if (rootGene is BpmnAnd) { if (rootGene.Children.Count <= 0) { return(0); } return(rootGene.Children.Max(x => CalculateLongestTime(x))); } return(DataHelper.ActivityHelper.Instance().GetTime((rootGene as BpmnActivity).Name)); }
private static XmlElement GeneToXml(XmlElement process, BpmGene gene, XmlElement incomingSequence) { if (gene is BpmnActivity) { var activity = process.OwnerDocument.CreateElement("bpmn", "task", BpmnUri); activity.SetAttribute("id", "Task_" + gene.Id); activity.SetAttribute("name", (gene as BpmnActivity).Name); process.AppendChild(activity); var incoming = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); incoming.InnerText = incomingSequence.GetAttribute("id"); activity.AppendChild(incoming); incomingSequence.SetAttribute("targetRef", activity.GetAttribute("id")); var outgoing = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); outgoing.InnerText = "SequenceFlow_" + Guid.NewGuid(); activity.AppendChild(outgoing); var sequenceFlow = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); sequenceFlow.SetAttribute("id", outgoing.InnerText); sequenceFlow.SetAttribute("sourceRef", activity.GetAttribute("id")); process.AppendChild(sequenceFlow); return(sequenceFlow); } if (gene is BpmnAnd) { var attributeName = "ParallelGateway_"; var localName = "parallelGateway"; // Open Gateway var gatewayOpen = process.OwnerDocument.CreateElement("bpmn", localName, BpmnUri); gatewayOpen.SetAttribute("id", attributeName + "open_" + gene.Id); process.AppendChild(gatewayOpen); // Gateway open incoming var gatewayOpenIncoming = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayOpenIncoming.InnerText = incomingSequence.GetAttribute("id"); gatewayOpen.AppendChild(gatewayOpenIncoming); // Incoming Sequence incomingSequence.SetAttribute("targetRef", gatewayOpen.GetAttribute("id")); // Close Gateway var gatewayClose = process.OwnerDocument.CreateElement("bpmn", localName, BpmnUri); gatewayClose.SetAttribute("id", attributeName + "close_" + gene.Id); process.AppendChild(gatewayClose); // Gateway close outgoing var gatewayCloseOutgoing = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); gatewayCloseOutgoing.InnerText = "SequenceFlow_" + Guid.NewGuid(); gatewayClose.AppendChild(gatewayCloseOutgoing); // Outgoing Sequence var sequenceFlow = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); sequenceFlow.SetAttribute("id", gatewayCloseOutgoing.InnerText); sequenceFlow.SetAttribute("sourceRef", gatewayClose.GetAttribute("id")); process.AppendChild(sequenceFlow); foreach (var child in gene.Children) { // Gateway open outgoing var gatewayOpenOutgoing = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); gatewayOpenOutgoing.InnerText = "SequenceFlow_" + Guid.NewGuid(); gatewayOpen.AppendChild(gatewayOpenOutgoing); // Gateway open outgoing sequence var innerSequenceFlow = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); innerSequenceFlow.SetAttribute("id", gatewayOpenOutgoing.InnerText); innerSequenceFlow.SetAttribute("sourceRef", gatewayOpen.GetAttribute("id")); process.AppendChild(innerSequenceFlow); innerSequenceFlow = GeneToXml(process, child, innerSequenceFlow); // gateway close incoming var gatewayCloseIncoming = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayCloseIncoming.InnerText = innerSequenceFlow.GetAttribute("id"); gatewayClose.AppendChild(gatewayCloseIncoming); // gateway close incoming sequence innerSequenceFlow.SetAttribute("targetRef", gatewayClose.GetAttribute("id")); } return(sequenceFlow); } if (gene is BpmnXor) { var attributeName = "ExclusiveGateway_"; var localName = "exclusiveGateway"; // Open Gateway var gatewayOpen = process.OwnerDocument.CreateElement("bpmn", localName, BpmnUri); gatewayOpen.SetAttribute("id", attributeName + "open_" + gene.Id); process.AppendChild(gatewayOpen); // add name/id to gateway gatewayOpen.SetAttribute("name", "v[" + (gene as BpmnXor).ToProcessAttribute().DecisionId + "]"); // Gateway open incoming var gatewayOpenIncoming = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayOpenIncoming.InnerText = incomingSequence.GetAttribute("id"); gatewayOpen.AppendChild(gatewayOpenIncoming); // Incoming Sequence incomingSequence.SetAttribute("targetRef", gatewayOpen.GetAttribute("id")); // Close Gateway var gatewayClose = process.OwnerDocument.CreateElement("bpmn", localName, BpmnUri); gatewayClose.SetAttribute("id", attributeName + "close_" + gene.Id); process.AppendChild(gatewayClose); // Gateway close outgoing var gatewayCloseOutgoing = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); gatewayCloseOutgoing.InnerText = "SequenceFlow_" + Guid.NewGuid(); gatewayClose.AppendChild(gatewayCloseOutgoing); // Outgoing Sequence var sequenceFlow = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); sequenceFlow.SetAttribute("id", gatewayCloseOutgoing.InnerText); sequenceFlow.SetAttribute("sourceRef", gatewayClose.GetAttribute("id")); process.AppendChild(sequenceFlow); #region XOR-if // Gateway open outgoing var gatewayOpenOutgoingIf = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); gatewayOpenOutgoingIf.InnerText = "SequenceFlow_" + Guid.NewGuid(); gatewayOpen.AppendChild(gatewayOpenOutgoingIf); // Gateway open outgoing sequence var innerSequenceFlowIf = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); innerSequenceFlowIf.SetAttribute("id", gatewayOpenOutgoingIf.InnerText); innerSequenceFlowIf.SetAttribute("sourceRef", gatewayOpen.GetAttribute("id")); process.AppendChild(innerSequenceFlowIf); // add name/decision to sequenceFlow innerSequenceFlowIf.SetAttribute("name", "==" + (gene as BpmnXor).ToProcessAttribute().DecisionValue); if (gene.Children == null || gene.Children.Count == 0 || gene.Children[0] == null) { // gateway close incoming var gatewayCloseIncomingIf = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayCloseIncomingIf.InnerText = innerSequenceFlowIf.GetAttribute("id"); gatewayClose.AppendChild(gatewayCloseIncomingIf); // gateway close incoming sequence innerSequenceFlowIf.SetAttribute("targetRef", gatewayClose.GetAttribute("id")); } else { innerSequenceFlowIf = GeneToXml(process, gene.Children[0], innerSequenceFlowIf); // gateway close incoming var gatewayCloseIncomingIf = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayCloseIncomingIf.InnerText = innerSequenceFlowIf.GetAttribute("id"); gatewayClose.AppendChild(gatewayCloseIncomingIf); // gateway close incoming sequence innerSequenceFlowIf.SetAttribute("targetRef", gatewayClose.GetAttribute("id")); } #endregion #region XOR-else // Gateway open outgoing var gatewayOpenOutgoingElse = process.OwnerDocument.CreateElement("bpmn", "outgoing", BpmnUri); gatewayOpenOutgoingElse.InnerText = "SequenceFlow_" + Guid.NewGuid(); gatewayOpen.AppendChild(gatewayOpenOutgoingElse); // Gateway open outgoing sequence var innerSequenceFlowElse = process.OwnerDocument.CreateElement("bpmn", "sequenceFlow", BpmnUri); innerSequenceFlowElse.SetAttribute("id", gatewayOpenOutgoingElse.InnerText); innerSequenceFlowElse.SetAttribute("sourceRef", gatewayOpen.GetAttribute("id")); process.AppendChild(innerSequenceFlowElse); // add name/decision to sequenceFlow innerSequenceFlowElse.SetAttribute("name", "<>" + (gene as BpmnXor).ToProcessAttribute().DecisionValue); if (gene.Children == null || gene.Children.Count < 2 || gene.Children[1] == null) { // gateway close incoming var gatewayCloseIncomingElse = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayCloseIncomingElse.InnerText = innerSequenceFlowElse.GetAttribute("id"); gatewayClose.AppendChild(gatewayCloseIncomingElse); // gateway close incoming sequence innerSequenceFlowElse.SetAttribute("targetRef", gatewayClose.GetAttribute("id")); } else { innerSequenceFlowElse = GeneToXml(process, gene.Children[1], innerSequenceFlowElse); // gateway close incoming var gatewayCloseIncomingElse = process.OwnerDocument.CreateElement("bpmn", "incoming", BpmnUri); gatewayCloseIncomingElse.InnerText = innerSequenceFlowElse.GetAttribute("id"); gatewayClose.AppendChild(gatewayCloseIncomingElse); // gateway close incoming sequence innerSequenceFlowElse.SetAttribute("targetRef", gatewayClose.GetAttribute("id")); } #endregion return(sequenceFlow); } foreach (var child in gene.Children) { incomingSequence = GeneToXml(process, child, incomingSequence); } return(incomingSequence); }
private static void ValidateGenome(BpmGene gene, ref int failures, HashSet <BpmnObject> currentAvailableInput, HashSet <BpmnProcessAttribute> currentCoveredAttributes, int pathId, int numberOfPaths, int passedXors) { if (gene == null) { return; } if (gene is BpmnActivity) { var matchingAttributes = DataHelper.CoverHelper.Instance().CoveredAttributes(((BpmnActivity)gene).Name); var tmp = failures; failures += currentCoveredAttributes.Count(x => !matchingAttributes.Contains(x)); if (tmp != failures) { return; } var input = DataHelper.ActivityInputHelper.Instance().RequiredInputObjects((BpmnActivity)gene); failures += input.Count(x => !currentAvailableInput.Contains(x)); var output = DataHelper.ActivityOutputHelper.Instance().ProvidedOutputObjects((BpmnActivity)gene); currentAvailableInput.UnionWith(output); return; } if (gene is BpmnSeq) { foreach (var child in gene.Children) { ValidateGenome(child, ref failures, currentAvailableInput, currentCoveredAttributes, pathId, numberOfPaths, passedXors); } } if (gene is BpmnAnd) { var preAndAvailableInput = new HashSet <BpmnObject>(currentAvailableInput); var postAndAvailableInput = new HashSet <BpmnObject>(currentAvailableInput); foreach (var child in gene.Children) { var cloneCurrentAvailableInput = new HashSet <BpmnObject>(preAndAvailableInput); var cloneCurrentCoveredAttributes = new HashSet <BpmnProcessAttribute>(currentCoveredAttributes); ValidateGenome(child, ref failures, cloneCurrentAvailableInput, cloneCurrentCoveredAttributes, pathId, numberOfPaths, passedXors); postAndAvailableInput.UnionWith(cloneCurrentAvailableInput); } currentAvailableInput.UnionWith(postAndAvailableInput); } if (gene is BpmnXor) { var xor = gene as BpmnXor; // found XOR, follow decision by pathId and passedXors var decisionBase = Convert.ToString(pathId, 2).PadLeft((int)Math.Log(numberOfPaths, 2), '0'); var decision = decisionBase[passedXors] - '0'; // dirty trick var attribute = new BpmnProcessAttribute(xor.DecisionId, xor.DecisionValue, DataHelper.ActivityAttributeHelper.Instance() .GetDecisionProbability(xor.DecisionId, xor.DecisionValue)); passedXors++; var ifCase = new HashSet <BpmnProcessAttribute>(); ifCase.Add(attribute); var elseCase = new HashSet <BpmnProcessAttribute>(currentCoveredAttributes); elseCase.Remove(attribute); if (decision == 0) { ValidateGenome(gene.Children.ElementAtOrDefault(decision), ref failures, currentAvailableInput, ifCase, pathId, numberOfPaths, passedXors); } if (decision == 1) { ValidateGenome(gene.Children.ElementAtOrDefault(decision), ref failures, currentAvailableInput, elseCase, pathId, numberOfPaths, passedXors); } } }
/// <summary> /// Generates a valid random BpmnGenome. /// </summary> /// <returns>random tree.</returns> public static void GenerateRandomValidBpmGenome(int maxDepth, BpmGene parent, BpmGenome genome, double executionProbability = 1) { if (parent is BpmnXor && parent.Children.Count > 2) { Debug.WriteLine("halt stop! BpmnXor error"); } BpmnXor xor = null; var allDecisions = DataHelper.ActivityAttributeHelper.Instance().GetAll(); if (allDecisions.Count > 0) { var selected = allDecisions.ElementAt(TreeHelper.RandomGenerator.Next(allDecisions.Count)); xor = new BpmnXor(-1, parent, selected.DecisionId, selected.DecisionValue); } // Choose a random gene from all available var gateways = new List <BpmGene>(); if (xor != null) { gateways.Add(xor); } gateways.Add(new BpmnAnd(-1, parent)); gateways.Add(new BpmnSeq(-1, parent)); var activities = new List <BpmnActivity>(); foreach (var model in DataHelper.ActivityHelper.Instance().Models) { activities.Add(new BpmnActivity(-1, parent, model.name)); } var randomGene = ChooseRandomBpmnGene(gateways, activities); // Create genome if parent is null. if (parent == null) { genome.RootGene = randomGene; GenerateRandomValidBpmGenome(maxDepth - 1, randomGene, genome); } // Handle Gateways else if ((parent is BpmnAnd || parent is BpmnSeq || parent is BpmnXor) && maxDepth > 1) { // Handle the deeper levels in the tree if (parent is BpmnAnd) { // Add the random gene to parents children parent.Children.Add(randomGene); randomGene.Parent = parent; // Choose a random number inclusive lower bound, exclusive upper bound. var numberOfChildren = TreeHelper.RandomGenerator.Next(2, Math.Max(2, activities.Count)); // Recursive call for randomly chosen number. for (var i = numberOfChildren - parent.Children.Count; i > 0; i--) { GenerateRandomValidBpmGenome(maxDepth - 1, randomGene, genome); } } else if (parent is BpmnSeq) { // Add the random gene to parents children parent.Children.Add(randomGene); randomGene.Parent = parent; // Choose a random number inclusive lower bound, exclusive upper bound. var numberOfChildren = TreeHelper.RandomGenerator.Next(2, Math.Max(2, activities.Count)); // Recursive call for randomly chosen number. for (var i = numberOfChildren - parent.Children.Count; i > 0; i--) { GenerateRandomValidBpmGenome(maxDepth - 1, randomGene, genome); } } // BPMN-XOR else if (parent is BpmnXor) { // TODO: At the moment only one Decision available. // Get all available decision values. var descitionValues = DataHelper.ActivityAttributeHelper.Instance() .GetDecisionValues( DataHelper.ActivityAttributeHelper.Instance().GetAll().FirstOrDefault().DecisionId); // Choos a random decision value. var rand = TreeHelper.RandomGenerator.Next(descitionValues.Count); // Get the probability of the randomly chosen value. var randomExecProb = DataHelper.ActivityAttributeHelper.Instance() .GetDecisionProbability( DataHelper.ActivityAttributeHelper.Instance().GetAll().FirstOrDefault().DecisionId, descitionValues.ElementAt(rand)); if (parent.Children.Count < 2) { // Add the random gene to parents children parent.Children.Add(randomGene); randomGene.Parent = parent; } if (parent.Children.Count < 2) { GenerateRandomValidBpmGenome(maxDepth, parent, genome, randomExecProb); } GenerateRandomValidBpmGenome(maxDepth, randomGene, genome, randomExecProb); } } else if ((parent is BpmnAnd || parent is BpmnSeq || parent is BpmnXor) && maxDepth == 1) { if (parent is BpmnXor && parent.Children.Count < 2) { // Reached the maximum number of hirarchies. Leafs only can be Actions. var activity = activities[TreeHelper.RandomGenerator.Next(activities.Count - 1)]; parent.Children.Add(activity); activity.Parent = parent; } } if (genome.RootGene.Children != null && maxDepth < 1) { genome.RootGene.RenumberIndicesOfBpmTree(gen => gen.Children); } }
/// <summary> /// generates a random valid bpm genome, using the greedy-algo. /// activities creating new objects are prefered over the rest /// </summary> /// <param name="maxDepth"></param> /// <param name="parent"></param> /// <param name="availableBpmnObjects"></param> /// <param name="currentAttributesToCover"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static BpmGene GenerateRandomValidBpmGenome2(int maxDepth, BpmGene parent, HashSet <BpmnObject> availableBpmnObjects = null, HashSet <BpmnProcessAttribute> currentAttributesToCover = null) { if (parent == null) { availableBpmnObjects = DataHelper.ObjectHelper.Instance().GetProcessInput(); currentAttributesToCover = DataHelper.ActivityAttributeHelper.Instance().GetAll(); } if (availableBpmnObjects == null || currentAttributesToCover == null) { throw new ArgumentNullException(nameof(availableBpmnObjects) + " or " + nameof(currentAttributesToCover)); } var currentDepth = parent.CalculateNodeDepth(); BpmGene randomGene = null; do { if (currentDepth == maxDepth) { randomGene = GenerateRandomActivity(availableBpmnObjects, currentAttributesToCover); } else { randomGene = GenerateRandomBpmGene(availableBpmnObjects, currentAttributesToCover); } } while (parent == null && randomGene == null); if (randomGene == null) { return(null); } randomGene.Parent = parent; if (randomGene is BpmnActivity) { var output = DataHelper.ActivityOutputHelper.Instance() .ProvidedOutputObjects((BpmnActivity)randomGene); availableBpmnObjects.UnionWith(output); } var numberOfChildren = randomGene.GetType().CalculateRandomNumberOfChildren(); if (randomGene is BpmnXor && numberOfChildren > 0) { // randomly xor created var xor = randomGene as BpmnXor; // divide attributes by this ID and Value var selectiveAttribute = new BpmnProcessAttribute(xor.DecisionId, xor.DecisionValue, xor.ExecutionProbability); var attributesIfCase = new HashSet <BpmnProcessAttribute>(); var attributesElseCase = new HashSet <BpmnProcessAttribute>(); // divide attributes into two buckets for ongoing process foreach (var attribute in currentAttributesToCover) { if (selectiveAttribute.DecisionId.Equals(attribute.DecisionId) && !selectiveAttribute.DecisionValue.Equals(attribute.DecisionValue)) { attributesElseCase.Add(attribute); } else { attributesIfCase.Add(attribute); } } // create new sets of bpmnobjects for both cases var availableBpmnObjectsIf = new HashSet <BpmnObject>(availableBpmnObjects); var availableBpmnObjectsElse = new HashSet <BpmnObject>(availableBpmnObjects); // add the first child var randomSubtreeIf = GenerateRandomValidBpmGenome2(maxDepth, randomGene, availableBpmnObjectsIf, attributesIfCase); xor.Children.Add(randomSubtreeIf); if (numberOfChildren > 1) { // add a second child var randomSubtreeElse = GenerateRandomValidBpmGenome2(maxDepth, randomGene, availableBpmnObjectsElse, attributesElseCase); xor.Children.Add(randomSubtreeElse); } // collect the available objects from both paths // TODO possible logic error, if both paths do not create the same output availableBpmnObjects.UnionWith(availableBpmnObjectsIf); availableBpmnObjects.UnionWith(availableBpmnObjectsElse); } if (randomGene is BpmnSeq || randomGene is BpmnAnd) { for (var i = 0; i < numberOfChildren; i++) { var availableBpmnObjectsChild = new HashSet <BpmnObject>(availableBpmnObjects); var createdSubTree = GenerateRandomValidBpmGenome2(maxDepth, randomGene, availableBpmnObjectsChild, currentAttributesToCover); if (createdSubTree == null) { Debug.WriteLine("halt"); } randomGene.Children.Add(createdSubTree); if (randomGene is BpmnSeq) { availableBpmnObjects.UnionWith(availableBpmnObjectsChild); } } } if (parent == null) { randomGene.RenumberIndicesOfBpmTree(gene => gene.Children); } return(randomGene); }
private Dimension AddGene(BpmGene gene, int x, int y) { if (gene is BpmnAnd) { var dim = new Dimension(); var and = And(gene); matrix[x][y] = and; AddColumn(); AddRow(gene.Children.Count - 1); foreach (var child in gene.Children) { var d = AddGene(child, x + dim.height, y + 1); dim.width = Math.Max(dim.width, d.width); dim.height += d.height; } AddColumn(); var and2 = And(gene, false); matrix[x][y + 1 + dim.width] = and2; dim.width += 2; return(dim); } if (gene is BpmnXor) { var dim = new Dimension(); var xor = Xor(gene); matrix[x][y] = xor; AddColumn(); AddRow(1); if (gene.Children == null || gene.Children.Count == 0) { // nothind to do } else if (gene.Children.Count == 1) { // only one child -> first the empty one dim.height += 1; // add empty row for straight line // now the regular genes var d = AddGene(gene.Children[0], x + dim.height, y + 1); dim.width = Math.Max(dim.width, d.width); dim.height += d.height; } else if (gene.Children[0] != null && gene.Children[1] != null) { // if var d1 = AddGene(gene.Children[0], x + dim.height, y + 1); dim.width = Math.Max(dim.width, d1.width); dim.height += d1.height; // else var d2 = AddGene(gene.Children[1], x + dim.height, y + 1); dim.width = Math.Max(dim.width, d2.width); dim.height += d2.height; } else { // if == null && else != null // only one child -> first the empty one dim.height += 1; // add empty row for straight line // now the regular genes var d = AddGene(gene.Children[0], x + dim.height, y + 1); dim.width = Math.Max(dim.width, d.width); dim.height += d.height; } AddColumn(); var xor2 = Xor(gene, false); matrix[x][y + 1 + dim.width] = xor2; dim.width += 2; return(dim); } if (gene is BpmnSeq) { var dim = new Dimension(); foreach (var child in gene.Children) { var d = AddGene(child, x, y + dim.width); dim.width += d.width; dim.height = Math.Max(dim.height, d.height); AddColumn(); } return(dim); } var activity = Activity(gene); matrix[x][y] = activity; return(new Dimension { width = 1, height = 1 }); }
public BpmnSeq(int index, BpmGene parent) : base(index, parent) { }
public BpmnSeq(int index, BpmGene parent, double executionProbability) : base(index, parent) { ExecutionProbability = executionProbability; }