Exemple #1
0
def setup(log, env, no_traces, net, initial_marking):
    """

    :param log: The input events in the form of a log
    :param env: The simulation environment
    :param no_traces: Number of traces that needs to be generated, given by the user
    :param net: The petrinet representing the process model
    :param initial_marking: The initial marking of the activities of the model
    """
    user_yn = input(
        "Do you want to configure the average arrival rate of the cases? Enter y or n "
    )
    if user_yn.lower() == "y":
        case_arrival_time = float(
            input("Enter in seconds the case arrival time "))

    else:
        case_arrival_time = get_case_arrival_avg(log)

    casegen = methods.Trace(env)

    # Create more cases while the simulation is running
    for i in range(1, no_traces + 1):
        yield env.timeout(case_arrival_time)
        env.process(
            simulation(env, 'Case %d' % i, casegen, net, initial_marking,
                       no_traces))
def execute_script():
    log_name = os.path.join("..", "tests", "input_data", "running-example.xes")
    log = xes_importer.apply(log_name, variant="nonstandard")
    print("imported log")
    # obtain a simple, sound workflow net, containing only visibile unique transitions,
    # applying the Alpha Miner to some of the top variants (methods by Ale)
    activity_key = "concept:name"
    parameters = {PARAMETER_CONSTANT_ACTIVITY_KEY: activity_key, PARAMETER_CONSTANT_ATTRIBUTE_KEY: activity_key}
    net, initial_marking, final_marking = simple_extraction_factory.apply(log, classic_output=True,
                                                                          parameters=parameters)
    print("obtained model")
    # visualize the output Petri net
    gviz = pn_vis_factory.apply(net, initial_marking, final_marking)
    del gviz
    # pn_vis_factory.view(gviz)
    # gets the average time between cases starts
    avg_time_starts = get_case_arrival_avg(log)
    print("avg_time_starts real=", avg_time_starts)
    # gets the stochastic distribution associated to the Petri net and the log
    smap = stochastic_map.get_map_from_log_and_net(log, net, initial_marking, final_marking,
                                                   force_distribution="EXPONENTIAL")
    print("smap=", smap)

    perf_bound_obj = LpPerfBounds(net, initial_marking, final_marking, smap, avg_time_starts)
    net1, imarking1, fmarking1 = perf_bound_obj.get_net()
    gviz = pn_vis_factory.apply(net1, imarking1, fmarking1)

    for var in perf_bound_obj.var_corr:
        corr = perf_bound_obj.var_corr[var]

        minimum = perf_bound_obj.solve_problem(var, maximize=False)
        maximum = perf_bound_obj.solve_problem(var, maximize=True)

        print(var, minimum[corr], maximum[corr])
Exemple #3
0
def gerar_estatisticas_model_from_log_eventos(eventLog):

    parameters_stats = {
        case_statistics.Parameters.TIMESTAMP_KEY: "time:timestamp"
    }

    # (quantidade de casos no event log)
    all_case_durations = case_statistics.get_all_casedurations(
        eventLog, parameters=parameters_stats)
    # (duração do caso mais rápido)
    min_case_duration = min(all_case_durations)
    # (duração do caso mais demorado)
    max_case_duration = max(all_case_durations)
    # (média de duração dos casos)
    median_case_duration = case_statistics.get_median_caseduration(
        eventLog, parameters=parameters_stats)

    parameters_arrival = {
        case_arrival.Parameters.TIMESTAMP_KEY: "time:timestamp"
    }

    # (distância média entre a chegada de dois casos consecutivos)
    case_arrival_ratio = case_arrival.get_case_arrival_avg(
        eventLog, parameters=parameters_arrival)
    # (distância média entre a finalização de dois casos consecutivos)
    case_dispersion_ratio = case_arrival.get_case_dispersion_avg(
        eventLog, parameters=parameters_arrival)

    previsoes = gerar_previsoes_modelo_from_log_eventos(eventLog)

    return ModeloEstatisticas(qtde_casos=len(all_case_durations),
                              caso_dur_min=min_case_duration,
                              caso_dur_max=max_case_duration,
                              caso_dur_media=median_case_duration,
                              taxa_chegada_casos=case_arrival_ratio,
                              taxa_dispersao_casos=case_dispersion_ratio,
                              previsoes_termino=previsoes)
def apply(log, net, im, fm, parameters=None):
    """
    Performs a Monte Carlo simulation of an accepting Petri net without duplicate transitions and where the preset is always
    distinct from the postset (FIFO variant; the semaphores pile up if waiting is needed, and the first in is the first to win
    the semaphore)

    Parameters
    -------------
    log
        Event log
    net
        Accepting Petri net without duplicate transitions and where the preset is always distinct from the postset
    im
        Initial marking
    fm
        Final marking
    parameters
        Parameters of the algorithm:
            PARAM_NUM_SIMULATIONS => (default: 100)
            PARAM_FORCE_DISTRIBUTION => Force a particular stochastic distribution (e.g. normal) when the stochastic map
            is discovered from the log (default: None; no distribution is forced)
            PARAM_ENABLE_DIAGNOSTICS => Enable the printing of diagnostics (default: True)
            PARAM_DIAGN_INTERVAL => Interval of time in which diagnostics of the simulation are printed (default: 32)
            PARAM_CASE_ARRIVAL_RATIO => Case arrival of new cases (default: None; inferred from the log)
            PARAM_PROVIDED_SMAP => Stochastic map that is used in the simulation (default: None; inferred from the log)
            PARAM_MAP_RESOURCES_PER_PLACE => Specification of the number of resources available per place
            (default: None; each place gets the default number of resources)
            PARAM_DEFAULT_NUM_RESOURCES_PER_PLACE => Default number of resources per place when not specified
            (default: 1; each place gets 1 resource and has to wait for the resource to finish)
            PARAM_SMALL_SCALE_FACTOR => Scale factor for the sleeping time of the actual simulation
            (default: 864000.0, 10gg)
            PARAM_MAX_THREAD_EXECUTION_TIME => Maximum execution time per thread (default: 60.0, 1 minute)

    Returns
    ------------
    simulated_log
        Simulated event log
    simulation_result
        Result of the simulation:
            Outputs.OUTPUT_PLACES_INTERVAL_TREES => inteval trees that associate to each place the times in which it was occupied.
            Outputs.OUTPUT_TRANSITIONS_INTERVAL_TREES => interval trees that associate to each transition the intervals of time
            in which it could not fire because some token was in the output.
            Outputs.OUTPUT_CASES_EX_TIME => Throughput time of the cases included in the simulated log
            Outputs.OUTPUT_MEDIAN_CASES_EX_TIME => Median of the throughput times
            Outputs.OUTPUT_CASE_ARRIVAL_RATIO => Case arrival ratio that was specified in the simulation
            Outputs.OUTPUT_TOTAL_CASES_TIME => Total time occupied by cases of the simulated log
    """
    if parameters is None:
        parameters = {}

    from intervaltree import IntervalTree, Interval

    timestamp_key = exec_utils.get_param_value(
        Parameters.TIMESTAMP_KEY, parameters,
        xes_constants.DEFAULT_TIMESTAMP_KEY)
    no_simulations = exec_utils.get_param_value(
        Parameters.PARAM_NUM_SIMULATIONS, parameters, 100)
    force_distribution = exec_utils.get_param_value(
        Parameters.PARAM_FORCE_DISTRIBUTION, parameters, None)
    enable_diagnostics = exec_utils.get_param_value(
        Parameters.PARAM_ENABLE_DIAGNOSTICS, parameters, True)
    diagn_interval = exec_utils.get_param_value(
        Parameters.PARAM_DIAGN_INTERVAL, parameters, 32.0)
    case_arrival_ratio = exec_utils.get_param_value(
        Parameters.PARAM_CASE_ARRIVAL_RATIO, parameters, None)
    smap = exec_utils.get_param_value(Parameters.PARAM_PROVIDED_SMAP,
                                      parameters, None)
    resources_per_places = exec_utils.get_param_value(
        Parameters.PARAM_MAP_RESOURCES_PER_PLACE, parameters, None)
    default_num_resources_per_places = exec_utils.get_param_value(
        Parameters.PARAM_DEFAULT_NUM_RESOURCES_PER_PLACE, parameters, 1)
    small_scale_factor = exec_utils.get_param_value(
        Parameters.PARAM_SMALL_SCALE_FACTOR, parameters, 864000)
    max_thread_exec_time = exec_utils.get_param_value(
        Parameters.PARAM_MAX_THREAD_EXECUTION_TIME, parameters, 60.0)

    if case_arrival_ratio is None:
        case_arrival_ratio = case_arrival.get_case_arrival_avg(
            log, parameters=parameters)
    if resources_per_places is None:
        resources_per_places = {}

    logging.basicConfig()
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    places_interval_trees = {}
    transitions_interval_trees = {}
    cases_ex_time = []
    list_cases = {}

    for place in net.places:
        # assign a semaphore to each place.
        if place in resources_per_places:
            place.semaphore = Semaphore(resources_per_places[place])
        else:
            # if the user does not specify the number of resources per place,
            # the default number is used
            place.semaphore = Semaphore(default_num_resources_per_places)
        place.assigned_time = []
        places_interval_trees[place] = IntervalTree()
    for trans in net.transitions:
        transitions_interval_trees[trans] = IntervalTree()

    # when the user does not specify any map from transitions to random variables,
    # a replay operation is performed
    if smap is None:
        if enable_diagnostics:
            logger.info(str(time()) + " started the replay operation.")
        if force_distribution is not None:
            smap = replay.get_map_from_log_and_net(
                log,
                net,
                im,
                fm,
                force_distribution=force_distribution,
                parameters=parameters)
        else:
            smap = replay.get_map_from_log_and_net(log,
                                                   net,
                                                   im,
                                                   fm,
                                                   parameters=parameters)
        if enable_diagnostics:
            logger.info(str(time()) + " ended the replay operation.")

    # the start timestamp is set to 1000000 instead of 0 to avoid problems with 32 bit machines
    start_time = 1000000
    threads = []
    for i in range(no_simulations):
        list_cases[i] = Trace()
        t = SimulationThread(i, net, im, fm, smap, start_time,
                             places_interval_trees, transitions_interval_trees,
                             cases_ex_time, list_cases, enable_diagnostics,
                             diagn_interval, small_scale_factor,
                             max_thread_exec_time)
        t.start()
        threads.append(t)
        start_time = start_time + case_arrival_ratio
        # wait a factor before opening a thread and the next one
        sleep(case_arrival_ratio / small_scale_factor)

    for t in threads:
        t.join()

    i = 0
    while i < len(threads):
        if threads[i].terminated_correctly is False:
            del list_cases[threads[i].id]
            del threads[i]
            del cases_ex_time[i]
            continue
        i = i + 1

    if enable_diagnostics:
        logger.info(str(time()) + " ended the Monte carlo simulation.")

    log = EventLog(list(list_cases.values()))
    min_timestamp = log[0][0][timestamp_key].timestamp()
    max_timestamp = max(y[timestamp_key].timestamp() for x in log for y in x)

    transitions_interval_trees = {
        t.name: y
        for t, y in transitions_interval_trees.items()
    }

    return log, {
        Outputs.OUTPUT_PLACES_INTERVAL_TREES.value: places_interval_trees,
        Outputs.OUTPUT_TRANSITIONS_INTERVAL_TREES.value:
        transitions_interval_trees,
        Outputs.OUTPUT_CASES_EX_TIME.value: cases_ex_time,
        Outputs.OUTPUT_MEDIAN_CASES_EX_TIME.value: median(cases_ex_time),
        Outputs.OUTPUT_CASE_ARRIVAL_RATIO.value: case_arrival_ratio,
        Outputs.OUTPUT_TOTAL_CASES_TIME.value: max_timestamp - min_timestamp
    }
def apply(log, net, im, fm, parameters=None):
    """
    Performs a Monte Carlo simulation of the Petri net

    Parameters
    -------------
    log
        Event log
    net
        Petri net
    im
        Initial marking
    fm
        Final marking
    parameters
        Parameters of the algorithm

    Returns
    ------------
    simulated_log
        Simulated event log
    simulation_result
        Result of the simulation
    """
    if parameters is None:
        parameters = {}

    parameters["business_hours"] = True
    no_simulations = parameters[
        "no_simulations"] if "no_simulations" in parameters else 100
    force_distribution = parameters[
        "force_distribution"] if "force_distribution" in parameters else None

    case_arrival_ratio = parameters[
        "case_arrival_ratio"] if "case_arrival_ratio" in parameters else case_arrival.get_case_arrival_avg(
            log, parameters=parameters)

    places_interval_trees = {}
    transitions_interval_trees = {}
    cases_ex_time = []
    list_cases = {}

    for place in net.places:
        place.semaphore = Semaphore(1)
        place.assigned_time = -1
        places_interval_trees[place] = IntervalTree()
    for trans in net.transitions:
        transitions_interval_trees[trans] = IntervalTree()

    if force_distribution is not None:
        map = mapping.get_map_from_log_and_net(
            log,
            net,
            im,
            fm,
            force_distribution=force_distribution,
            parameters=parameters)
    else:
        map = mapping.get_map_from_log_and_net(log,
                                               net,
                                               im,
                                               fm,
                                               parameters=parameters)

    start_time = 1000000
    threads = []
    for i in range(no_simulations):
        list_cases[i] = Trace()
        t = SimulationThread(i, net, im, fm, map, start_time,
                             places_interval_trees, transitions_interval_trees,
                             cases_ex_time, list_cases)
        t.start()
        threads.append(t)
        start_time = start_time + case_arrival_ratio

    for t in threads:
        t.join()

    log = EventLog(list(list_cases.values()))
    min_timestamp = log[0][0]['time:timestamp'].timestamp()
    max_timestamp = max(y['time:timestamp'].timestamp() for x in log
                        for y in x)

    transitions_interval_trees = {
        t.name: y
        for t, y in transitions_interval_trees.items()
    }

    return log, {
        "places_interval_trees": places_interval_trees,
        "transitions_interval_trees": transitions_interval_trees,
        "cases_ex_time": cases_ex_time,
        "median_cases_ex_time": median(cases_ex_time),
        "input_case_arrival_ratio": case_arrival_ratio,
        "total_time": max_timestamp - min_timestamp
    }
 def test_case_arrival(self):
     from pm4py.statistics.traces.log import case_arrival
     log = self.get_log()
     case_arrival.get_case_arrival_avg(log)
     case_arrival.get_case_dispersion_avg(log)
Exemple #7
0
gviz = dectree_visualizer.apply(clf, feature_names, classes)

#%%% Statistics

from pm4py.statistics.traces.log import case_statistics
all_case_durations = case_statistics.get_all_casedurations(log, parameters={    case_statistics.Parameters.TIMESTAMP_KEY: "time:timestamp"})

all_case_durations

from pm4py.statistics.traces.log import case_statistics
median_case_duration = case_statistics.get_median_caseduration(log, parameters={    case_statistics.Parameters.TIMESTAMP_KEY: "time:timestamp"})
median_case_duration

#Case Arrival
from pm4py.statistics.traces.log import case_arrival
case_arrival_ratio = case_arrival.get_case_arrival_avg(log, parameters={    case_arrival.Parameters.TIMESTAMP_KEY: "time:timestamp"})
case_arrival_ratio

from pm4py.statistics.traces.log import case_arrival
case_dispersion_ratio = case_arrival.get_case_dispersion_avg(log, parameters={    case_arrival.Parameters.TIMESTAMP_KEY: "time:timestamp"})
case_dispersion_ratio


#Peformance Spectrum
from pm4py.statistics.performance_spectrum import algorithm as performance_spectrum
ps = performance_spectrum.apply(log, ["register request", "decide"], parameters= {performance_spectrum.Parameters.ACTIVITY_KEY: "concept:name", performance_spectrum.Parameters.TIMESTAMP_KEY: "time:timestamp"})
ps

#Business Hours
from pm4py.util.business_hours import BusinessHours
from datetime import datetime