Ejemplo n.º 1
0
        /// <summary>
        /// Goes through the steps of the AlphaMiner Algorithm:
        /// </summary>
        /// <param Name="field">A field from the DataSelection</param>
        /// <returns>A PetriNet as a ProcessModel</returns>
        /// <exception cref="ArgumentNullException">If the field-parameter is null.</exception>
        /// <author>Krystian Zielonka, Christopher Licht</author>
        public ProcessModel Mine()
        {
            if (_field == null)
            {
                throw new ArgumentNullException("field", "The field parameter was null");
            }

            // Get parameters from MinerSettings
            String alphaMinerSettings = MinerSettings.GetAsString("Alpha Miner");

            // Start - Statistics
            TimeSpan ProcessingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            DetectActivitiySet();
            DetectStartAndEndActivitiesInTraces();

            DetectAllPlaces();

            switch (alphaMinerSettings)
            {
            case "AlphaMinerPlus":
                CorrectParallelPairs();
                break;

            case "AlphaMinerPlusPlus":
                Preprocessing();
                Postprocessing();
                CorrectParallelPairs();
                break;

            default:
                break;
            }

            AddsPlacesTogether();
            RemoveAllDuplicatePlaces();

            BuildTheNet();

            // End - Statistics
            TimeSpan ProcessingTimeEnd = Process.GetCurrentProcess().TotalProcessorTime;

            //Information about the generated petri net
            PetriNetInformation(_field, ref ProcessingTimeStart, ref ProcessingTimeEnd);

            //Check for errors in the field
            DoErrorHandling();

            return(_petriNet);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Goes through the steps of the (improved) HeuristicMiner Algorithm:
        /// Find starting-events => build adjacency-matrix => convert into petrinet
        /// </summary>
        /// <returns>A PetriNet as a ProcessModel</returns>
        /// <exception cref="ArgumentNullException">If the field-parameter is null.</exception>
        /// <author>Jannik Arndt</author>
        public ProcessModel Mine()
        {
            if (_field == null)
            {
                throw new Exception("The field parameter was null");
            }

            // Get parameters from MinerSettings
            var threshold = MinerSettings.GetAsDouble("AdjacencyThresholdSlider") / 100;
            var maxDepth  = MinerSettings.GetAsInt("MaximumRecursionDepthSlider");

            if (threshold < 0 || threshold > 1)
            {
                throw new Exception("Threshold must be between 0 and 1.");
            }
            if (maxDepth < 1)
            {
                throw new Exception("Maximum recursion depth must be more greater than 1.");
            }

            // Statistics
            var processingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            // 1. Create Adjacency Matrix
            var adjacencyMatrix = CreateAdjacencyMatrix(_field);

            // 2. Calculate the indexes of the first events
            var startindexes = GetColumnsWithOnlyNegativeEntries(adjacencyMatrix);

            // for every sub-processmodel
            foreach (var startindex in startindexes)
            {
                // 3. Create the dependency-Graph
                var rootNode = CreateDependencyGraph(_field.EventLog.ListOfUniqueEvents, adjacencyMatrix, threshold, 0.0, startindex, maxDepth);

                // 4. Turn the dependency-graph into a petri-net
                _listOfSubPetriNets.Add(CreatePetriNetFromDependencyGraph(rootNode, _field.EventLog, _field.Infotext));
            }

            // 5. Connect all Petrinets by one XOR-Split
            if (_listOfSubPetriNets.Count > 1)
            {
                // 5a. Connect all subnets to one start
                var startingPlace = _finalPetriNet.AddPlace("Start");
                foreach (var petriNet in _listOfSubPetriNets)
                {
                    var xorTransition = _finalPetriNet.AddTransition(incomingPlace: startingPlace);
                    _finalPetriNet.MergeWithPetriNet(petriNet, xorTransition);
                }
                // 5b. Add following transitions to all subnet-endings
                foreach (var openEndPlace in _finalPetriNet.GetSinks())
                {
                    if (openEndPlace.GetType() == typeof(Place))
                    {
                        _finalPetriNet.AddTransition(incomingPlace: (Place)openEndPlace);
                    }
                }
            }
            else
            {
                _finalPetriNet = _listOfSubPetriNets[0];
            }

            // 6. Connect all open endings
            _finalPetriNet = FixEnding(_finalPetriNet);

            // 7. Delete empty transitions
            _finalPetriNet = PetriNetOperation.CleanUpPetriNet(_finalPetriNet);

            // 8. Save information about the mining-process
            var processingTimeEnd = Process.GetCurrentProcess().TotalProcessorTime;
            var processingTime    = Math.Abs((processingTimeEnd - processingTimeStart).TotalMilliseconds) < 1 ? "< 15 ms" : (processingTimeEnd - processingTimeStart).TotalMilliseconds + " ms";

            _field.Information.Add("Processing Time", processingTime);
            _field.Information.Add("Number of Events", _finalPetriNet.Transitions.Count(s => s.IsLoop == false).ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Number of Transitions", _finalPetriNet.Transitions.Count.ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Number of Places", _finalPetriNet.Places.Count.ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Loops in the net", _finalPetriNet.CountLoops().ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Events used", _finalPetriNet.CountTransitionsWithoutANDs() - _finalPetriNet.CountLoops() + " of " + _field.EventLog.ListOfUniqueEvents.Count);
            _field.Information.Add("Parallel Models", startindexes.Count.ToString(CultureInfo.InvariantCulture));
            if (_listOfNodes.Count > 0)
            {
                _field.Information.Add("Minimal Adjacency", _listOfNodes.Min().ToString(CultureInfo.InvariantCulture));
                _field.Information.Add("Average Adjacency", Math.Round(_listOfNodes.Average(), 3).ToString(CultureInfo.InvariantCulture));
                if (Math.Abs(_listOfNodes.Min() - _listOfNodes.Average()) > 0.0001)
                {
                    _field.Information.Add("Standard Deviation", CalculateStandardDeviation(_listOfNodes).ToString(CultureInfo.InvariantCulture));
                }
            }

            return(_finalPetriNet);
        }