Exemplo n.º 1
0
 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);
             }
         }
     }
 }
        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);
        }
Exemplo n.º 3
0
            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);
                    }
                }
            }
Exemplo 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);
            }
        /// <summary>
        ///     Checks, wheter all attributes are covered
        /// </summary>
        /// <param name="decision"></param>
        /// <param name="attributes"></param>
        /// <param name="gene"></param>
        /// <returns>false - not all attributes are covered, true - all attributes are covered</returns>
        private bool CheckActivityAttributeCovering(BpmnProcessAttribute decision, List <string> attributes,
                                                    BpmGene gene)
        {
            if (gene == null)
            {
                return(true);
            }

            // in case of an gateway, with does not seperate attributes
            if (gene is BpmnAnd || gene is BpmnSeq)
            {
                foreach (var child in gene.Children)
                {
                    if (CheckActivityAttributeCovering(decision, attributes, child) == false)
                    {
                        return(false);
                    }
                }

                return(gene.Children.Count > 0);
            }

            // in case of an gateway, seperating attributes (like XOR)
            if (gene is BpmnXor)
            {
                var xor           = (BpmnXor)gene;
                var decisionId    = xor.DecisionId;
                var decisionValue = xor.DecisionValue;

                var seperate = new List <string> {
                    decisionValue
                };

                attributes.Remove(decisionValue);

                if (xor.Children == null || xor.Children.Count < 2)
                {
                    return(false);
                }

                // if-case
                if (CheckActivityAttributeCovering(decision, seperate, xor.Children.ElementAtOrDefault(0)) == false)
                {
                    return(false);
                }
                // else-case
                if (CheckActivityAttributeCovering(decision, attributes, xor.Children.ElementAtOrDefault(1)) == false)
                {
                    return(false);
                }
            }

            // in case of an activity, checking if all necessary attributes are covered
            if (gene is BpmnActivity)
            {
                foreach (var attribute in attributes)
                {
                    var activity   = gene as BpmnActivity;
                    var isCovering =
                        DataHelper.CoverHelper.Instance()
                        .CheckIfActivityCoversAttribute(decision.DecisionId,
                                                        attribute,
                                                        activity.Name);
                    if (!isCovering)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }