@@ -237,14 +237,40 @@ def is_strongly_connected(self) -> bool:
237237
238238 True if strongly connected, False otherwise
239239
240- """
241- import itertools
240+ """
241+ if not self .states :
242+ return True
243+
244+ # strongly connected iff some state reaches all states and is reached by
245+ # all states; two linear traversals instead of one search per state pair
246+ all_states = set (self .states )
247+ root = self .states [0 ]
248+
249+ visited = {root }
250+ stack = [root ]
251+ while stack :
252+ for successor in stack .pop ().transitions .values ():
253+ if successor not in visited and successor in all_states :
254+ visited .add (successor )
255+ stack .append (successor )
256+ if visited != all_states :
257+ return False
242258
243- state_comb_list = itertools .permutations (self .states , 2 )
244- for state_comb in state_comb_list :
245- if self .get_shortest_path (state_comb [0 ], state_comb [1 ]) is None :
246- return False
247- return True
259+ predecessors = {state : [] for state in self .states }
260+ for state in self .states :
261+ for successor in state .transitions .values ():
262+ if successor in all_states :
263+ predecessors [successor ].append (state )
264+
265+ visited = {root }
266+ stack = [root ]
267+ while stack :
268+ for predecessor in predecessors [stack .pop ()]:
269+ if predecessor not in visited :
270+ visited .add (predecessor )
271+ stack .append (predecessor )
272+
273+ return visited == all_states
248274
249275 def output_step (self , state , letter ):
250276 """
@@ -453,4 +479,4 @@ def minimize(self):
453479
454480 def __eq__ (self , other ):
455481 from aalpy .utils import bisimilar
456- return bisimilar (self , other )
482+ return bisimilar (self , other )
0 commit comments