def test_solving_problem_with_isolated_catchments(mocker, network, network_spatial_tree): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1', 6: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'link_1_2_car', 5: 'link_1_2_bus', 6: 'link_2_3_car'} }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}) mss.solve() assert mss.solution == {'stop_1': 'link_1_2_bus', 'stop_2': 'link_4_5_car', 'stop_3': 'link_7_8_car'} assert_semantically_equal(mss.artificial_stops, { 'stop_1.link:link_1_2_bus': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_1.link:link_1_2_bus', 'x': 1.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557148552832129, 'lat': 49.76683027967191, 's2_id': 5205973754090340691, 'linkRefId': 'link_1_2_bus', 'stop_id': 'stop_1'}, 'stop_2.link:link_4_5_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_2.link:link_4_5_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'linkRefId': 'link_4_5_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}})
def test_problem_with_isolated_catchment_finds_solution_for_viable_stops(mocker, network): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'isolated_link_1', 5: 'isolated_link_2'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) network.add_nodes({'node_iso_1': {'id': 'node_iso_1', 'x': 10, 'y': 20, 'lat': 49.8, 'lon': -7.5, 's2_id': 5205973754090365183}, 'node_iso_2': {'id': 'node_iso_2', 'x': 10, 'y': 30, 'lat': 49.9, 'lon': -7.6, 's2_id': 5205973754090333257}}) network.add_link('isolated_link_1', u='node_iso_1', v='node_iso_2', attribs={'modes': {'car', 'bus'}}) network.add_link('isolated_link_2', u='node_iso_2', v='node_iso_1', attribs={'modes': {'car', 'bus'}}) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=spatial.SpatialTree(network), modes={'car', 'bus'}, distance_threshold=10, step_size=10) mss.solve() assert mss.solution == {'stop_2': 'link_5_6_car', 'stop_3': 'link_7_8_car'} assert_semantically_equal(mss.artificial_stops, { 'stop_2.link:link_5_6_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_2.link:link_5_6_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'linkRefId': 'link_5_6_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_2', 'service_1_route_1'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}})
def test_artificially_filling_in_solution_for_partial_pt_routing_problem_results_in_correct_solution_and_routed_path( mocker, test_network, test_spatialtree): df = DataFrame({ 'index_left': {4: 4611, 5: 2836, 6: 1620, 7: 1619, 8: 4612, 9: 4611, 10: 1929, 11: 17, 12: 18, 13: 2291, 14: 17, 15: 2804, 16: 3361}, 'link_id': {4: '5221390698590575489_5221390721979501095', 5: '52213908340665748775221390828301496736', 6: '5221390721979501095_5221390721979501095', 7: '5221390721979501095_5221390721985855617', 8: '5221390698590575489_5221390698590575489', 9: '5221390698590575489_5221390721979501095', 10: '5221390698557344687_5221390698590575489', 11: '5221390688502743083_5221390698590575489', 12: '5221390688502743083_5221390688502743083', 13: '5221390319100521975_5221390688502743083', 14: '5221390688502743083_5221390698590575489', 15: '5221390319261602009_5221390688502743083', 16: '5221390688613602227_5221390688502743083'}, 'id': {4: '5221390721979501095', 5: '5221390721979501095', 6: '5221390721979501095', 7: '5221390721979501095', 8: '5221390698590575489', 9: '5221390698590575489', 10: '5221390698590575489', 11: '5221390698590575489', 12: '5221390688502743083', 13: '5221390688502743083', 14: '5221390688502743083', 15: '5221390688502743083', 16: '5221390688502743083'}, 'catchment': {4: 5, 5: 5, 6: 5, 7: 5, 8: 5, 9: 5, 10: 5, 11: 5, 12: 5, 13: 5, 14: 5, 15: 5, 16: 5}, 'problem_nodes': { 4: '5221390721979501095.link:5221390698590575489_5221390721979501095', 5: '5221390721979501095.link:52213908340665748775221390828301496736', 6: '5221390721979501095.link:5221390721979501095_5221390721979501095', 7: '5221390721979501095.link:5221390721979501095_5221390721985855617', 8: '5221390698590575489.link:5221390698590575489_5221390698590575489', 9: '5221390698590575489.link:5221390698590575489_5221390721979501095', 10: '5221390698590575489.link:5221390698557344687_5221390698590575489', 11: '5221390698590575489.link:5221390688502743083_5221390698590575489', 12: '5221390688502743083.link:5221390688502743083_5221390688502743083', 13: '5221390688502743083.link:5221390319100521975_5221390688502743083', 14: '5221390688502743083.link:5221390688502743083_5221390698590575489', 15: '5221390688502743083.link:5221390319261602009_5221390688502743083', 16: '5221390688502743083.link:5221390688613602227_5221390688502743083'}}).set_index('id', drop=False) df.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=df) mss = MaxStableSet(pt_graph=test_network.schedule.route('40230_1').graph(), network_spatial_tree=test_spatialtree, modes={'car', 'bus'}, distance_threshold=5, step_size=5) assert not mss.all_stops_have_nearest_links() mss.solve() assert mss.unsolved_stops == {'5221390319100521975'} mss.route_edges() mss.fill_in_solution_artificially() art_link = 'artificial_link===from:5221390319100521975===to:5221390319100521975' assert mss.solution['5221390319100521975'] == art_link art_stop = '5221390319100521975.link:artificial_link===from:5221390319100521975===to:5221390319100521975' assert art_stop in mss.artificial_stops assert mss.artificial_stops[art_stop]['linkRefId'] == art_link assert mss.artificial_stops[art_stop]['stop_id'] == '5221390319100521975' assert mss.artificial_stops[art_stop]['id'] == art_stop assert mss.routed_path( ['5221390319100521975', '5221390688502743083', '5221390698590575489', '5221390721979501095']) == [ 'artificial_link===from:5221390319100521975===to:5221390319100521975', 'artificial_link===from:5221390319100521975===to:5221390688502743083', '5221390688502743083_5221390698590575489', '5221390698590575489_5221390721979501095']
def test_stops_missing_nearest_links_identifies_stops_with_missing_closest_links(mocker, network, network_spatial_tree): mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car'}, })) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}) assert mss.stops_missing_nearest_links() == {'stop_1'}
def test_detects_stops_that_lack_nearest_links(mocker, network, network_spatial_tree): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}, step_size=10, distance_threshold=10 ) assert not mss.all_stops_have_nearest_links()
def test_problem_with_distinct_catchments_is_viable(mocker, network, network_spatial_tree): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1', 6: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'link_1_2_car', 5: 'link_1_2_bus', 6: 'link_2_3_car'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}, distance_threshold=10, step_size=10) assert mss.is_viable()
def test_snapping_pt_route_results_in_all_stops_with_link_references_and_routes_between_them( test_network, test_spatialtree): mss = MaxStableSet(pt_graph=test_network.schedule.route('40230_1').graph(), network_spatial_tree=test_spatialtree.modal_subtree(modes={'car', 'bus'}), modes={'bus'}, distance_threshold=10, step_size=10) mss.solve() assert mss.all_stops_solved() mss.route_edges() assert mss.pt_edges['shortest_path'].notna().all()
def partial_mss(network): mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=spatial.SpatialTree(network), modes={'car', 'bus'}, distance_threshold=10, step_size=10) mss.solution = {'stop_2': 'link_5_6_car', 'stop_3': 'link_7_8_car', 'stop_1': 'artificial_link===from:stop_1===to:stop_1'} mss.artificial_stops = { 'stop_2.link:link_5_6_car': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_2.link:link_5_6_car', 'x': 2.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557134732217642, 'lat': 49.76683094462549, 's2_id': 5205973754090230267, 'additional_attributes': set(), 'linkRefId': 'link_5_6_car', 'stop_id': 'stop_2'}, 'stop_3.link:link_7_8_car': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_3.link:link_7_8_car', 'x': 5.5, 'y': 2.0, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.55708584676138, 'lat': 49.76682879603468, 's2_id': 5205973754096513977, 'additional_attributes': set(), 'linkRefId': 'link_7_8_car', 'stop_id': 'stop_3'}, 'stop_1.link:artificial_link===from:stop_1===to:stop_1': {'services': {'bus_service'}, 'routes': {'service_1_route_1', 'service_1_route_2'}, 'id': 'stop_1.link:artificial_link===from:stop_1===to:stop_1', 'x': 1.0, 'y': 2.5, 'epsg': 'epsg:27700', 'name': '', 'lon': -7.557148552832129, 'lat': 49.76683027967191, 's2_id': 5205973754090340691, 'additional_attributes': set(), 'linkRefId': 'artificial_link===from:stop_1===to:stop_1', 'stop_id': 'stop_1'}} mss.artificial_links = { 'artificial_link===from:stop_1===to:stop_1': {'from': 'stop_1', 'to': 'stop_1', 'modes': {'bus'}}, 'artificial_link===from:node_6===to:stop_1': {'from': 'node_6', 'to': 'stop_1', 'modes': {'bus'}}, 'artificial_link===from:stop_1===to:node_5': {'from': 'stop_1', 'to': 'node_5', 'modes': {'bus'}}} mss.pt_edges = DataFrame( {'services': {0: {'bus_service'}, 1: {'bus_service'}, 2: {'bus_service'}, 3: {'bus_service'}}, 'routes': {0: {'service_1_route_2'}, 1: {'service_1_route_2'}, 2: {'service_1_route_1'}, 3: {'service_1_route_1'}}, 'u': {0: 'stop_3', 1: 'stop_2', 2: 'stop_2', 3: 'stop_1'}, 'v': {0: 'stop_2', 1: 'stop_1', 2: 'stop_3', 3: 'stop_2'}, 'key': {0: 0, 1: 0, 2: 0, 3: 0}, 'linkRefId_u': {0: 'link_7_8_car', 1: 'link_5_6_car', 2: 'link_5_6_car', 3: 'artificial_link===from:stop_1===to:stop_1'}, 'linkRefId_v': {0: 'link_5_6_car', 1: 'artificial_link===from:stop_1===to:stop_1', 2: 'link_7_8_car', 3: 'link_5_6_car'}, 'shortest_path': {0: ['link_7_8_car', 'link_8_7_car', 'link_7_6_car', 'link_6_5_car', 'link_5_6_car'], 1: ['link_5_6_car', 'artificial_link===from:node_6===to:stop_1', 'artificial_link===from:stop_1===to:stop_1'], 2: ['link_5_6_car', 'link_6_7_car', 'link_7_8_car'], 3: ['artificial_link===from:stop_1===to:stop_1', 'artificial_link===from:stop_1===to:node_5', 'link_5_6_car']}}) mss.unsolved_stops = {'stop_1'} return mss
def test_problem_with_isolated_catchment_is_partially_viable(mocker, network): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'isolated_link_1', 5: 'isolated_link_2'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) network.add_nodes({'node_iso_1': {'id': 'node_iso_1', 'x': 10, 'y': 20, 'lat': 49.8, 'lon': -7.5, 's2_id': 5205973754090365183}, 'node_iso_2': {'id': 'node_iso_2', 'x': 10, 'y': 30, 'lat': 49.9, 'lon': -7.6, 's2_id': 5205973754090333257}}) network.add_link('isolated_link_1', u='node_iso_1', v='node_iso_2', attribs={'modes': {'car', 'bus'}}) network.add_link('isolated_link_2', u='node_iso_2', v='node_iso_1', attribs={'modes': {'car', 'bus'}}) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=spatial.SpatialTree(network), modes={'car', 'bus'}, distance_threshold=10, step_size=10) assert mss.is_partially_viable()
def test_snapping_disconnected_partial_pt_route_results_in_all_stops_with_link_references_and_routes_between_viable_catchments( mocker, test_network, test_spatialtree): df = DataFrame({ 'index_left': {0: 2291, 1: 2290, 2: 2292, 3: 5178, 4: 4611, 5: 2836, 6: 1620, 7: 1619, 8: 4612, 9: 4611, 10: 1929, 11: 17, 12: 18, 13: 2291, 14: 17, 15: 2804, 16: 3361}, 'link_id': {0: '5221390319100521975_5221390688502743083', 1: '5221390319100521975_5221390319062365867', 2: '5221390319100521975_5221390319100521975', 3: '5221390319091334983_5221390319100521975', 4: '5221390698590575489_5221390721979501095', 5: '52213908340665748775221390828301496736', 6: '5221390721979501095_5221390721979501095', 7: '5221390721979501095_5221390721985855617', 12: '5221390688502743083_5221390688502743083', 13: '5221390319100521975_5221390688502743083', 14: '5221390688502743083_5221390698590575489', 15: '5221390319261602009_5221390688502743083', 16: '5221390688613602227_5221390688502743083'}, 'id': {0: '5221390319100521975', 1: '5221390319100521975', 2: '5221390319100521975', 3: '5221390319100521975', 4: '5221390721979501095', 5: '5221390721979501095', 6: '5221390721979501095', 7: '5221390721979501095', 12: '5221390688502743083', 13: '5221390688502743083', 14: '5221390688502743083', 15: '5221390688502743083', 16: '5221390688502743083'}, 'catchment': {0: 5, 1: 5, 2: 5, 3: 5, 4: 5, 5: 5, 6: 5, 7: 5, 12: 5, 13: 5, 14: 5, 15: 5, 16: 5}, 'problem_nodes': { 0: '5221390319100521975.link:5221390319100521975_5221390688502743083', 1: '5221390319100521975.link:5221390319100521975_5221390319062365867', 2: '5221390319100521975.link:5221390319100521975_5221390319100521975', 3: '5221390319100521975.link:5221390319091334983_5221390319100521975', 4: '5221390721979501095.link:5221390698590575489_5221390721979501095', 5: '5221390721979501095.link:52213908340665748775221390828301496736', 6: '5221390721979501095.link:5221390721979501095_5221390721979501095', 7: '5221390721979501095.link:5221390721979501095_5221390721985855617', 12: '5221390688502743083.link:5221390688502743083_5221390688502743083', 13: '5221390688502743083.link:5221390319100521975_5221390688502743083', 14: '5221390688502743083.link:5221390688502743083_5221390698590575489', 15: '5221390688502743083.link:5221390319261602009_5221390688502743083', 16: '5221390688502743083.link:5221390688613602227_5221390688502743083'}}).set_index('id', drop=False) df.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=df) mss = MaxStableSet(pt_graph=test_network.schedule.route('40230_1').graph(), network_spatial_tree=test_spatialtree, modes={'car', 'bus'}, distance_threshold=5, step_size=5) assert not mss.all_stops_have_nearest_links() mss.solve() assert mss.unsolved_stops == {'5221390698590575489', '5221390721979501095'} mss.route_edges() assert set(mss.pt_edges[mss.pt_edges['shortest_path'].isna()]['u']) == {'5221390698590575489', '5221390688502743083'} assert set(mss.pt_edges[mss.pt_edges['shortest_path'].isna()]['v']) == {'5221390698590575489', '5221390721979501095'}
def test_build_graph_for_maximum_stable_set_problem_with_no_path_between_isolated_node(mocker, network): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1', 6: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'isolated_link', 5: 'link_1_2_bus', 6: 'link_2_3_car'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) network.add_nodes({'node_iso_1': {'id': 'node_iso_1', 'x': 10, 'y': 20, 'lat': 49.8, 'lon': -7.5, 's2_id': 5205973754090365183}, 'node_iso_2': {'id': 'node_iso_2', 'x': 10, 'y': 30, 'lat': 49.9, 'lon': -7.6, 's2_id': 5205973754090333257}}) network.add_link('isolated_link', u='node_iso_1', v='node_iso_2', attribs={'modes': {'car', 'bus'}}) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=spatial.SpatialTree(network), modes={'car', 'bus'}, distance_threshold=10, step_size=10) assert_semantically_equal(dict(mss.problem_graph.nodes()), {'stop_2.link:link_4_5_car': {'id': 'stop_2', 'link_id': 'link_4_5_car', 'catchment': 10, 'coeff': 0.26666666666666666}, 'stop_2.link:link_5_6_car': {'id': 'stop_2', 'link_id': 'link_5_6_car', 'catchment': 10, 'coeff': 0.26666666666666666}, 'stop_3.link:link_7_8_car': {'id': 'stop_3', 'link_id': 'link_7_8_car', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_3.link:link_8_9_car': {'id': 'stop_3', 'link_id': 'link_8_9_car', 'catchment': 10, 'coeff': 0.2222222222222222}, 'stop_1.link:link_1_2_bus': {'id': 'stop_1', 'link_id': 'link_1_2_bus', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_1.link:link_2_3_car': {'id': 'stop_1', 'link_id': 'link_2_3_car', 'catchment': 10, 'coeff': 0.2857142857142857}}) assert_semantically_equal(list(mss.problem_graph.edges()), [('stop_2.link:link_4_5_car', 'stop_2.link:link_5_6_car'), ('stop_3.link:link_7_8_car', 'stop_3.link:link_8_9_car'), ('stop_1.link:link_1_2_bus', 'stop_1.link:link_2_3_car')])
def test_build_graph_for_maximum_stable_set_problem_with_non_trivial_closest_link_selection_pool(mocker, network, network_spatial_tree): closest_links = DataFrame({ 'id': {0: 'stop_2', 1: 'stop_2', 2: 'stop_3', 3: 'stop_3', 4: 'stop_1', 5: 'stop_1', 6: 'stop_1'}, 'link_id': {0: 'link_4_5_car', 1: 'link_5_6_car', 2: 'link_7_8_car', 3: 'link_8_9_car', 4: 'link_1_2_car', 5: 'link_1_2_bus', 6: 'link_2_3_car'}, }).set_index('id', drop=False) closest_links.index.rename(name='index', inplace=True) mocker.patch.object(spatial.SpatialTree, 'closest_links', return_value=closest_links) mss = MaxStableSet(pt_graph=network.schedule['bus_service'].graph(), network_spatial_tree=network_spatial_tree, modes={'car', 'bus'}, distance_threshold=10, step_size=10) assert_semantically_equal(dict(mss.problem_graph.nodes()), {'stop_2.link:link_4_5_car': {'id': 'stop_2', 'link_id': 'link_4_5_car', 'catchment': 10, 'coeff': 0.2777777777777778}, 'stop_2.link:link_5_6_car': {'id': 'stop_2', 'link_id': 'link_5_6_car', 'catchment': 10, 'coeff': 0.2631578947368421}, 'stop_3.link:link_7_8_car': {'id': 'stop_3', 'link_id': 'link_7_8_car', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_3.link:link_8_9_car': {'id': 'stop_3', 'link_id': 'link_8_9_car', 'catchment': 10, 'coeff': 0.2222222222222222}, 'stop_1.link:link_1_2_car': {'id': 'stop_1', 'link_id': 'link_1_2_car', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_1.link:link_1_2_bus': {'id': 'stop_1', 'link_id': 'link_1_2_bus', 'catchment': 10, 'coeff': 0.2857142857142857}, 'stop_1.link:link_2_3_car': {'id': 'stop_1', 'link_id': 'link_2_3_car', 'catchment': 10, 'coeff': 0.2857142857142857}}) assert_semantically_equal(list(mss.problem_graph.edges()), [('stop_2.link:link_4_5_car', 'stop_2.link:link_5_6_car'), ('stop_3.link:link_7_8_car', 'stop_3.link:link_8_9_car'), ('stop_1.link:link_1_2_car', 'stop_1.link:link_1_2_bus'), ('stop_1.link:link_1_2_car', 'stop_1.link:link_2_3_car'), ('stop_1.link:link_1_2_bus', 'stop_1.link:link_2_3_car')])