/// <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>
        ///     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);
        }
Ejemplo n.º 3
0
            /// <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);
            }
Ejemplo n.º 4
0
            /// <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);
            }