@@ -251,41 +251,46 @@ public AcceptingPetriNet apply(PluginContext context, XLog eventLog, ProcessTree
251251 + (System .currentTimeMillis () - time ) + " milliseconds." );
252252 }
253253
254- int nofA = 0 ;
255- int nofI = 0 ;
256- for (Transition t : apn .getNet ().getTransitions ()) {
257- if (!t .isInvisible () || t .getLabel ().equals (ActivityAlphabet .START )
258- || t .getLabel ().equals (ActivityAlphabet .END )) {
259- nofA ++;
260- } else {
261- nofI ++;
262- }
263- }
264- // Let's try to aim for less silent transitions then other transitions.
265- while (nofI > nofA ) {
266- ReduceUsingMurataRulesAlgorithm redAlgorithm = new ReduceUsingMurataRulesAlgorithm ();
267- ReduceUsingMurataRulesParameters redParameters = new ReduceUsingMurataRulesParameters ();
268- System .out .println ("[DiscoverPetriNetAlgorithm] Reducing clusters" );
269- reduceSilentClusters (apn );
270- System .out .println ("[DiscoverPetriNetAlgorithm] Reducing using rules..." );
271- apn = redAlgorithm .apply (context , apn , redParameters );
272- int nofA2 = 0 ;
273- int nofI2 = 0 ;
254+ if (parameters .getMaxNofRoutingTransitions () > 0 ) {
255+ int nofNonRoutingTransitions = 0 ;
256+ int nofRoutingTransitions = 0 ;
274257 for (Transition t : apn .getNet ().getTransitions ()) {
275258 if (!t .isInvisible () || t .getLabel ().equals (ActivityAlphabet .START )
276259 || t .getLabel ().equals (ActivityAlphabet .END )) {
277- nofA2 ++;
260+ nofNonRoutingTransitions ++;
278261 } else {
279- nofI2 ++;
262+ nofRoutingTransitions ++;
280263 }
281264 }
282- if (nofA2 == nofA && nofI2 == nofI ) {
283- // No reductions possible anymore.
284- nofI = -1 ;
285- } else {
286- // Some reductions were done, try next iteration.
287- nofA = nofA2 ;
288- nofI = nofI2 ;
265+ // Let's try to aim for less silent transitions then other transitions.
266+ while (nofRoutingTransitions > parameters .getMaxNofRoutingTransitions ()) {
267+ ReduceUsingMurataRulesAlgorithm redAlgorithm = new ReduceUsingMurataRulesAlgorithm ();
268+ ReduceUsingMurataRulesParameters redParameters = new ReduceUsingMurataRulesParameters ();
269+ System .out .println ("[DiscoverPetriNetAlgorithm] Reducing clusters" );
270+ reduceSilentClusters (apn , parameters );
271+ System .out .println ("[DiscoverPetriNetAlgorithm] Reducing using rules..." );
272+ apn = redAlgorithm .apply (context , apn , redParameters );
273+ int nofNonRoutingTransitions2 = 0 ;
274+ int nofRoutingTransitions2 = 0 ;
275+ for (Transition t : apn .getNet ().getTransitions ()) {
276+ if (!t .isInvisible () || t .getLabel ().equals (ActivityAlphabet .START )
277+ || t .getLabel ().equals (ActivityAlphabet .END )) {
278+ nofNonRoutingTransitions2 ++;
279+ } else {
280+ nofRoutingTransitions2 ++;
281+ }
282+ }
283+ if (nofNonRoutingTransitions2 == nofNonRoutingTransitions
284+ && nofRoutingTransitions2 == nofRoutingTransitions ) {
285+ // No reductions possible anymore.
286+ System .out .println ("[DiscoverPetriNetAlgorithm] No more reductions possible" );
287+ nofRoutingTransitions = -1 ;
288+ } else {
289+ // Some reductions were done, try next iteration.
290+ nofNonRoutingTransitions = nofNonRoutingTransitions2 ;
291+ nofRoutingTransitions = nofRoutingTransitions2 ;
292+ }
293+ System .out .println ("[DiscoverPetriNetAlgorithm] Continuing with " + nofRoutingTransitions + " routing transitions" );
289294 }
290295 }
291296// fixEnhancements(context, apn, parameters);
@@ -1069,7 +1074,15 @@ private boolean areEquivalent(List<List<String>> playOut, String source, String
10691074 return true ;
10701075 }
10711076
1072- private void reduceSilentClusters (AcceptingPetriNet apn ) {
1077+ private void reduceSilentClusters (AcceptingPetriNet apn , DiscoverPetriNetParameters parameters ) {
1078+ int nofRoutingTransitions = 0 ;
1079+ for (Transition t : apn .getNet ().getTransitions ()) {
1080+ if (!t .isInvisible () || t .getLabel ().equals (ActivityAlphabet .START )
1081+ || t .getLabel ().equals (ActivityAlphabet .END )) {
1082+ } else {
1083+ nofRoutingTransitions ++;
1084+ }
1085+ }
10731086 Map <PetrinetNode , Set <PetrinetNode >> preset = new HashMap <PetrinetNode , Set <PetrinetNode >>();
10741087 Map <PetrinetNode , Set <PetrinetNode >> postset = new HashMap <PetrinetNode , Set <PetrinetNode >>();
10751088 for (PetrinetNode node : apn .getNet ().getNodes ()) {
@@ -1082,108 +1095,115 @@ private void reduceSilentClusters(AcceptingPetriNet apn) {
10821095 }
10831096 Set <Place > places = new HashSet <Place >();
10841097 Set <List <Transition >> clusters = new HashSet <List <Transition >>();
1085- for (Transition t1 : apn .getNet ().getTransitions ()) {
1086- if (!t1 .isInvisible () || t1 .getLabel ().equals (ActivityAlphabet .START )
1087- || t1 .getLabel ().equals (ActivityAlphabet .END )) {
1088- continue ;
1089- }
1090- Place pre_t1 = (Place ) preset .get (t1 ).iterator ().next ();
1091- Place post_t1 = (Place ) postset .get (t1 ).iterator ().next ();
1092- if (pre_t1 == post_t1 ) {
1093- continue ;
1094- }
1095- if (places .contains (pre_t1 ) || places .contains (post_t1 )) {
1096- continue ;
1097- }
1098- for (PetrinetNode n2 : postset .get (pre_t1 )) {
1099- Transition t2 = (Transition ) n2 ;
1100- if (t2 == t1 ) {
1098+ if (nofRoutingTransitions > parameters .getMaxNofRoutingTransitions ()) {
1099+ for (Transition t1 : apn .getNet ().getTransitions ()) {
1100+ if (!t1 .isInvisible () || t1 .getLabel ().equals (ActivityAlphabet .START )
1101+ || t1 .getLabel ().equals (ActivityAlphabet .END )) {
11011102 continue ;
11021103 }
1103- if (!t2 .isInvisible () || t2 .getLabel ().equals (ActivityAlphabet .START )
1104- || t2 .getLabel ().equals (ActivityAlphabet .END )) {
1104+ Place pre_t1 = (Place ) preset .get (t1 ).iterator ().next ();
1105+ Place post_t1 = (Place ) postset .get (t1 ).iterator ().next ();
1106+ if (pre_t1 == post_t1 ) {
11051107 continue ;
11061108 }
1107- Place post_t2 = (Place ) postset .get (t2 ).iterator ().next ();
1108- if (post_t2 == pre_t1 || post_t2 == post_t1 ) {
1109+ if (places .contains (pre_t1 ) || places .contains (post_t1 )) {
11091110 continue ;
11101111 }
1111- if (places .contains (post_t2 )) {
1112- continue ;
1113- }
1114- for (PetrinetNode n3 : preset .get (post_t1 )) {
1115- Transition t3 = (Transition ) n3 ;
1116- if (t3 == t2 || t3 == t1 ) {
1112+ for (PetrinetNode n2 : postset .get (pre_t1 )) {
1113+ Transition t2 = (Transition ) n2 ;
1114+ if (t2 == t1 ) {
11171115 continue ;
11181116 }
1119- if (!t3 .isInvisible () || t3 .getLabel ().equals (ActivityAlphabet .START )
1120- || t3 .getLabel ().equals (ActivityAlphabet .END )) {
1117+ if (!t2 .isInvisible () || t2 .getLabel ().equals (ActivityAlphabet .START )
1118+ || t2 .getLabel ().equals (ActivityAlphabet .END )) {
11211119 continue ;
11221120 }
1123- Place pre_t3 = (Place ) preset .get (t3 ).iterator ().next ();
1124- if (pre_t3 == pre_t1 || pre_t3 == post_t1 || pre_t3 == post_t2 ) {
1121+ Place post_t2 = (Place ) postset .get (t2 ).iterator ().next ();
1122+ if (post_t2 == pre_t1 || post_t2 == post_t1 ) {
11251123 continue ;
11261124 }
1127- if (places .contains (pre_t3 )) {
1125+ if (places .contains (post_t2 )) {
11281126 continue ;
11291127 }
1130- for (PetrinetNode n4 : postset .get (pre_t3 )) {
1131- Transition t4 = (Transition ) n4 ;
1132- if (t4 == t3 || t4 == t2 || t4 == t1 ) {
1128+ for (PetrinetNode n3 : preset .get (post_t1 )) {
1129+ Transition t3 = (Transition ) n3 ;
1130+ if (t3 == t2 || t3 == t1 ) {
11331131 continue ;
11341132 }
1135- if (!t4 .isInvisible () || t4 .getLabel ().equals (ActivityAlphabet .START )
1136- || t4 .getLabel ().equals (ActivityAlphabet .END )) {
1133+ if (!t3 .isInvisible () || t3 .getLabel ().equals (ActivityAlphabet .START )
1134+ || t3 .getLabel ().equals (ActivityAlphabet .END )) {
11371135 continue ;
11381136 }
1139- if (postset .get (t4 ).iterator ().next () != post_t2 ) {
1137+ Place pre_t3 = (Place ) preset .get (t3 ).iterator ().next ();
1138+ if (pre_t3 == pre_t1 || pre_t3 == post_t1 || pre_t3 == post_t2 ) {
11401139 continue ;
11411140 }
1142- List <Transition > cluster = new ArrayList <Transition >();
1143- cluster .add (t1 );
1144- cluster .add (t2 );
1145- cluster .add (t3 );
1146- cluster .add (t4 );
1147- clusters .add (cluster );
1148- places .add (pre_t1 );
1149- places .add (post_t1 );
1150- places .add (post_t2 );
1151- places .add (pre_t3 );
1141+ if (places .contains (pre_t3 )) {
1142+ continue ;
1143+ }
1144+ for (PetrinetNode n4 : postset .get (pre_t3 )) {
1145+ Transition t4 = (Transition ) n4 ;
1146+ if (t4 == t3 || t4 == t2 || t4 == t1 ) {
1147+ continue ;
1148+ }
1149+ if (!t4 .isInvisible () || t4 .getLabel ().equals (ActivityAlphabet .START )
1150+ || t4 .getLabel ().equals (ActivityAlphabet .END )) {
1151+ continue ;
1152+ }
1153+ if (postset .get (t4 ).iterator ().next () != post_t2 ) {
1154+ continue ;
1155+ }
1156+ List <Transition > cluster = new ArrayList <Transition >();
1157+ cluster .add (t1 );
1158+ cluster .add (t2 );
1159+ cluster .add (t3 );
1160+ cluster .add (t4 );
1161+ clusters .add (cluster );
1162+ places .add (pre_t1 );
1163+ places .add (post_t1 );
1164+ places .add (post_t2 );
1165+ places .add (pre_t3 );
1166+ }
11521167 }
11531168 }
11541169 }
1155- }
1156- for (List <Transition > cluster : clusters ) {
1157- System .out .println ("[DiscoverPetriNetAlgorithm] Reducing " + cluster );
1158- Transition t1 = cluster .get (0 );
1159- Place p1 = (Place ) preset .get (t1 ).iterator ().next ();
1160- Place p2 = (Place ) postset .get (t1 ).iterator ().next ();
1161- Transition t2 = cluster .get (3 );
1162- Place p3 = (Place ) preset .get (t2 ).iterator ().next ();
1163- Place p4 = (Place ) postset .get (t2 ).iterator ().next ();
1164- // Remove transitions (and edges connected to them)
1165- apn .getNet ().removeTransition (cluster .get (1 ));
1166- apn .getNet ().removeTransition (cluster .get (2 ));
1167- apn .getNet ().removeTransition (cluster .get (3 ));
1168- // Reroute arcs from p3/p4 to p1/p2
1169- for (PetrinetEdge <? extends PetrinetNode , ? extends PetrinetNode > edge : apn .getNet ().getEdges ()) {
1170- if (edge .getSource () == t1 || edge .getTarget () == t1 ) {
1171- continue ;
1172- }
1173- if (edge .getSource () == p3 ) {
1174- apn .getNet ().addArc (p1 , (Transition ) edge .getTarget ());
1175- } else if (edge .getSource () == p4 ) {
1176- apn .getNet ().addArc (p2 , (Transition ) edge .getTarget ());
1170+ for (List <Transition > cluster : clusters ) {
1171+ System .out .println ("[DiscoverPetriNetAlgorithm] Reducing " + cluster );
1172+ Transition t1 = cluster .get (0 );
1173+ Place p1 = (Place ) preset .get (t1 ).iterator ().next ();
1174+ Place p2 = (Place ) postset .get (t1 ).iterator ().next ();
1175+ Transition t2 = cluster .get (3 );
1176+ Place p3 = (Place ) preset .get (t2 ).iterator ().next ();
1177+ Place p4 = (Place ) postset .get (t2 ).iterator ().next ();
1178+ // Remove transitions (and edges connected to them)
1179+ apn .getNet ().removeTransition (cluster .get (1 ));
1180+ apn .getNet ().removeTransition (cluster .get (2 ));
1181+ apn .getNet ().removeTransition (cluster .get (3 ));
1182+ // Reroute arcs from p3/p4 to p1/p2
1183+ for (PetrinetEdge <? extends PetrinetNode , ? extends PetrinetNode > edge : apn .getNet ().getEdges ()) {
1184+ if (edge .getSource () == t1 || edge .getTarget () == t1 ) {
1185+ continue ;
1186+ }
1187+ if (edge .getSource () == p3 ) {
1188+ apn .getNet ().addArc (p1 , (Transition ) edge .getTarget ());
1189+ } else if (edge .getSource () == p4 ) {
1190+ apn .getNet ().addArc (p2 , (Transition ) edge .getTarget ());
1191+ }
1192+ if (edge .getTarget () == p3 ) {
1193+ apn .getNet ().addArc ((Transition ) edge .getSource (), p1 );
1194+ } else if (edge .getTarget () == p4 ) {
1195+ apn .getNet ().addArc ((Transition ) edge .getSource (), p2 );
1196+ }
11771197 }
1178- if (edge .getTarget () == p3 ) {
1179- apn .getNet ().addArc ((Transition ) edge .getSource (), p1 );
1180- } else if (edge .getTarget () == p4 ) {
1181- apn .getNet ().addArc ((Transition ) edge .getSource (), p2 );
1198+ // Remove places (and edges connected to them)
1199+ apn .getNet ().removePlace (p3 );
1200+ apn .getNet ().removePlace (p4 );
1201+ nofRoutingTransitions -= 3 ;
1202+ if (nofRoutingTransitions <= parameters .getMaxNofRoutingTransitions ()) {
1203+ System .out .println ("[DiscoverPetriNetAlgorithm] Reduced to " + nofRoutingTransitions + " routing transitions" );
1204+ return ;
11821205 }
11831206 }
1184- // Remove places (and edges connected to them)
1185- apn .getNet ().removePlace (p3 );
1186- apn .getNet ().removePlace (p4 );
11871207 }
11881208 }
11891209}
0 commit comments