def test_strongly_connected_components(): assert strongly_connected_components(([], [])) == [] assert strongly_connected_components(([1, 2, 3], [])) == [[1], [2], [3]] V = [1, 2, 3] E = [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1)] assert strongly_connected_components((V, E)) == [[1, 2, 3]] V = [1, 2, 3, 4] E = [(1, 2), (2, 3), (3, 2), (3, 4)] assert strongly_connected_components((V, E)) == [[4], [2, 3], [1]] V = [1, 2, 3, 4] E = [(1, 2), (2, 1), (3, 4), (4, 3)] assert strongly_connected_components((V, E)) == [[1, 2], [3, 4]]
def _strongly_connected_components(M): """Returns the list of strongly connected vertices of the graph when a square matrix is viewed as a weighted graph. Examples ======== >>> from sympy import Matrix >>> A = Matrix([ ... [44, 0, 0, 0, 43, 0, 45, 0, 0], ... [0, 66, 62, 61, 0, 68, 0, 60, 67], ... [0, 0, 22, 21, 0, 0, 0, 20, 0], ... [0, 0, 12, 11, 0, 0, 0, 10, 0], ... [34, 0, 0, 0, 33, 0, 35, 0, 0], ... [0, 86, 82, 81, 0, 88, 0, 80, 87], ... [54, 0, 0, 0, 53, 0, 55, 0, 0], ... [0, 0, 2, 1, 0, 0, 0, 0, 0], ... [0, 76, 72, 71, 0, 78, 0, 70, 77]]) >>> A.strongly_connected_components() [[0, 4, 6], [2, 3, 7], [1, 5, 8]] """ if not M.is_square: raise NonSquareMatrixError V = range(M.rows) E = sorted(M.todok().keys()) return strongly_connected_components((V, E))
def limits_sort(limits_dict): G = {x: set() for x in limits_dict} for kinder in G: if not limits_dict[kinder]: continue for parent in limits_dict[kinder].free_symbols: if parent in G: G[parent].add(kinder) from sympy.utilities.iterables import topological_sort_depth_first, strongly_connected_components g = topological_sort_depth_first(G) if g is None: g = strongly_connected_components(G) for components in g: limit = And(*(limits_dict[v] for v in components)).latex # latex = r"\%s_{%s}{%s}" % (clause, limit, latex) # return latex return g limits = [] for x in g: domain = limits_dict[x] if not domain: limit = (x, ) elif domain.is_Range: limit = (x, domain.min(), domain.max() + 1) else: limit = (x, domain) limits.append(limit) return limits
def _component_division(eqs, funcs, t): from sympy.utilities.iterables import connected_components, strongly_connected_components # Assuming that each eq in eqs is in canonical form, # that is, [f(x).diff(x) = .., g(x).diff(x) = .., etc] # and that the system passed is in its first order eqsmap, eqsorig = _eqs2dict(eqs, funcs) subsystems = [] for cc in connected_components(_dict2graph(eqsmap)): eqsmap_c = {f: eqsmap[f] for f in cc} sccs = strongly_connected_components(_dict2graph(eqsmap_c)) subsystem = [[eqsorig[f] for f in scc] for scc in sccs] subsystem = _combine_type1_subsystems(subsystem, sccs, t) subsystems.append(subsystem) return subsystems