Spaces:
Running
Running
File size: 4,690 Bytes
e60e568 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
'''
This file is part of PM4Py (More Info: https://pm4py.fit.fraunhofer.de).
PM4Py is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PM4Py is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PM4Py. If not, see <https://www.gnu.org/licenses/>.
'''
from pm4py.objects.process_tree.obj import Operator
from pm4py.util import exec_utils, constants, xes_constants
from pm4py.objects.log.obj import Trace, Event
from enum import Enum
import random
import time
from typing import Optional, Dict, Any, Union
from pm4py.objects.log.obj import EventLog
from pm4py.objects.process_tree.obj import ProcessTree
class Parameters(Enum):
ACTIVITY_KEY = constants.PARAMETER_CONSTANT_ACTIVITY_KEY
NO_TRACES = "num_traces"
def apply(tree: ProcessTree, parameters: Optional[Dict[Union[str, Parameters], Any]] = None) -> EventLog:
"""
Gets the top-bottom playout of a process tree
Parameters
---------------
tree
Process tree
parameters
Parameters of the algorithm, including:
- Parameters.ACTIVITY_KEY: activity key
- Parameters.NO_TRACES: number of traces that should be returned
Returns
---------------
log
Event log
"""
if parameters is None:
parameters = {}
activity_key = exec_utils.get_param_value(Parameters.ACTIVITY_KEY, parameters, xes_constants.DEFAULT_NAME_KEY)
no_traces = exec_utils.get_param_value(Parameters.NO_TRACES, parameters, 1000)
execution_sequences = get_num_ex_sequences(tree, no_traces)
log = EventLog()
for seq in execution_sequences:
trace = Trace()
for el in seq:
if el.label is not None:
event = Event({activity_key: el.label})
trace.append(event)
log.append(trace)
return log
def get_ex_seq_in_time(tree, ex_time):
"""
Gets the maximum number of execution sequences, doing the playout,
in the given amount of time
Parameters
----------------
tree
Process tree
ex_time
Maximum execution time
Returns
----------------
ex_sec
Execution sequences
"""
ex_sec = []
aa = time.time()
while time.time() - aa < ex_time:
ex_sec.append(tuple(get_ex_seq(tree)))
return ex_sec
def get_num_ex_sequences(tree, num):
"""
Gets the specified amount of execution sequences
Parameters
---------------
tree
Process tree
num
Number of execution sequences
Returns
---------------
ex_sec
Execution sequences
"""
ret = []
for i in range(num):
ret.append(tuple(get_ex_seq(tree)))
return ret
def get_ex_seq(tree):
"""
Gets a trace from a process tree (top-bottom)
Parameters
--------------
tree
Process tree
Returns
-------------
ex_seq
Execution sequence
"""
if tree.operator is None:
return [tree]
elif tree.operator is Operator.XOR:
child = random.choice(tree.children)
return get_ex_seq(child)
elif tree.operator is Operator.SEQUENCE:
ret = []
for child in tree.children:
ret = ret + get_ex_seq(child)
return ret
elif tree.operator is Operator.INTERLEAVING:
random.shuffle(tree.children)
ret = []
for child in tree.children:
ret = ret + get_ex_seq(child)
return ret
elif tree.operator is Operator.LOOP:
ret = []
cont = True
while cont:
cont = False
ret = ret + get_ex_seq(tree.children[0])
r = random.random()
if r <= 0.5:
ret = ret + get_ex_seq(tree.children[1])
cont = True
return ret
elif tree.operator is Operator.PARALLEL:
ret = []
children_traces = []
list_choices = []
for index, child in enumerate(tree.children):
trace = get_ex_seq(child)
children_traces.append(trace)
list_choices += [index] * len(trace)
random.shuffle(list_choices)
for c in list_choices:
act = children_traces[c].pop(0)
ret.append(act)
return ret
|