def test_bfs_multiple_nodes(): dg, all_ns = _setup_unsigned_graph() # Run regular bfs search for nodes separately paths = [p for p in bfs_search(dg, 'C1', depth_limit=2, reverse=True)] assert len(paths) == 7, len(paths) paths = [p for p in bfs_search(dg, 'D1', depth_limit=2, reverse=True)] assert len(paths) == 4, len(paths) # number of paths with several nodes bfs should be a sum of separate runs paths = [ p for p in bfs_search_multiple_nodes( dg, ['C1', 'D1'], depth_limit=2, reverse=True) ] assert len(paths) == 11, len(paths) # Path limit should limit the number of paths (both across all paths and # within one node search) paths = [ p for p in bfs_search_multiple_nodes( dg, ['C1', 'D1'], depth_limit=2, reverse=True, path_limit=9) ] assert len(paths) == 9, len(paths) paths = [ p for p in bfs_search_multiple_nodes( dg, ['C1', 'D1'], depth_limit=2, reverse=True, path_limit=5) ] assert len(paths) == 5, len(paths)
def test_signed_bfs(): seg, sng, all_ns = _setup_signed_graph() # D1 being upregulated: 13 paths paths = [ p for p in bfs_search(g=sng, source_node=('D1', INT_PLUS), reverse=True, depth_limit=5, node_filter=all_ns, sign=INT_PLUS) ] assert len(paths) == 13, len(paths)
def find_paths(hashes): def allow_edge(u, v): try: return len(set(hashes).intersection(edge_hashes[(u, v)])) except KeyError: return False return list( bfs_search(dg, 'C1', depth_limit=6, reverse=True, strict_mesh_id_filtering=True, hashes=hashes, allow_edge=allow_edge))
def test_bfs(): dg, all_ns = _setup_unsigned_graph() # Test basic part of algorithm paths = [p for p in bfs_search(dg, 'C1', depth_limit=1, reverse=True)] assert len(paths) == 3, len(paths) paths = [p for p in bfs_search(dg, 'C1', depth_limit=2, reverse=True)] assert len(paths) == 7, len(paths) paths = [ p for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, path_limit=4) ] assert len(paths) == 4, len(paths) # Test ns allowance list ans = ['c', 'b'] assert len([ p for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, node_filter=ans) ]) == 3 assert all( len(p) < 3 for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, node_filter=ans)) # Test longer paths assert len([p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True) ]) == 9 # Test node blacklist assert len([ p for p in bfs_search( dg, 'D1', depth_limit=5, reverse=True, node_blacklist={'Z1'}) ]) == 8 # Test max per node option # Should get 4 paths with max_per_node=1 expected_paths = {('D1', 'C1'), ('D1', 'C1', 'B1'), ('D1', 'C1', 'B1', 'A1'), ('D1', 'C1', 'B1', 'A1', 'Z1')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, max_per_node=1, node_filter=all_ns) ] assert len(paths) == 4, len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Test terminal NS # Terminate on 'b' expected_paths = {('D1', 'C1', 'B1'), ('D1', 'C1', 'B2'), ('D1', 'C1', 'B3')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, terminal_ns=['b'], node_filter=all_ns) ] assert len(paths) == len(expected_paths), len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Terminate on 'a' expected_paths = {('D1', 'C1', 'B1', 'A1'), ('D1', 'C1', 'B1', 'A2'), ('D1', 'C1', 'B2', 'A3'), ('D1', 'C1', 'B2', 'A4')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, terminal_ns=['a'], node_filter=all_ns) ] assert len(paths) == len(expected_paths), len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Test memory limit; a very low number should yield one path error = False gen = bfs_search(dg, 'D1', depth_limit=5, reverse=True, max_memory=16) _ = next(gen) try: _ = next(gen) except (RuntimeError, StopIteration): error = True assert error # Test edge filter # With belief cutoff at 0.75, we should remove: # ('A2', 'B1'), ('A3', 'B2'), ('A4', 'B2'), ('B2', 'C1'), ('B3', 'C1') def _filter_func(g, u, v): return g.edges[u, v]['belief'] > 0.75 expected_paths = {('D1', 'C1'), ('D1', 'C1', 'B1'), ('D1', 'C1', 'B1', 'A1'), ('D1', 'C1', 'B1', 'A1', 'Z1')} gen = bfs_search(g=dg, source_node='D1', depth_limit=5, reverse=True, edge_filter=_filter_func) paths = list(gen) assert len(paths) == len(expected_paths), f'Expected ' \ f'{len(expected_paths)}, ' \ f'got {len(paths)} paths' assert set(paths) == expected_paths # Test edge_filter and allowed_edges def _alwd_edges(u, v): # Edges should not be reversed! return (u, v) in {('C1', 'D1'), ('B1', 'C1'), ('A1', 'B1')} expected_paths = {('D1', 'C1'), ('D1', 'C1', 'B1'), ('D1', 'C1', 'B1', 'A1')} some_new_gen = bfs_search(g=dg, source_node='D1', depth_limit=5, reverse=True, edge_filter=_filter_func, allow_edge=_alwd_edges, hashes=[123456897], strict_mesh_id_filtering=True) paths = list(some_new_gen) assert len(paths) == len(expected_paths), f'Expected ' \ f'{len(expected_paths)}, ' \ f'got {len(paths)} paths' assert set(paths) == expected_paths
def test_bfs(): dg, all_ns = _setup_unsigned_graph() # Test basic part of algorithm paths = [p for p in bfs_search(dg, 'C1', depth_limit=1, reverse=True)] assert len(paths) == 3, len(paths) paths = [p for p in bfs_search(dg, 'C1', depth_limit=2, reverse=True)] assert len(paths) == 7, len(paths) paths = [ p for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, path_limit=4) ] assert len(paths) == 4, len(paths) # Test ns allowance list ans = ['c', 'b'] assert len([ p for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, node_filter=ans) ]) == 3 assert all( len(p) < 3 for p in bfs_search( dg, 'C1', depth_limit=2, reverse=True, node_filter=ans)) # Test longer paths assert len([p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True) ]) == 9 # Test node blacklist assert len([ p for p in bfs_search( dg, 'D1', depth_limit=5, reverse=True, node_blacklist={'Z1'}) ]) == 8 # Test max per node option # Should get 4 paths with max_per_node=1 expected_paths = {('D1', 'C1'), ('D1', 'C1', 'B1'), ('D1', 'C1', 'B1', 'A1'), ('D1', 'C1', 'B1', 'A1', 'Z1')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, max_per_node=1, node_filter=all_ns) ] assert len(paths) == 4, len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Test terminal NS # Terminate on 'b' expected_paths = {('D1', 'C1', 'B1'), ('D1', 'C1', 'B2'), ('D1', 'C1', 'B3')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, terminal_ns=['b'], node_filter=all_ns) ] assert len(paths) == len(expected_paths), len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Terminate on 'a' expected_paths = {('D1', 'C1', 'B1', 'A1'), ('D1', 'C1', 'B1', 'A2'), ('D1', 'C1', 'B2', 'A3'), ('D1', 'C1', 'B2', 'A4')} paths = [ p for p in bfs_search(dg, 'D1', depth_limit=5, reverse=True, terminal_ns=['a'], node_filter=all_ns) ] assert len(paths) == len(expected_paths), len(paths) assert set(paths) == expected_paths, 'sets of paths not equal' # Test memory limit; a very low number should yield one path error = False gen = bfs_search(dg, 'D1', depth_limit=5, reverse=True, max_memory=16) _ = next(gen) try: _ = next(gen) except (RuntimeError, StopIteration): error = True assert error