Least-Cost Allocation ===================== ``Network.allocate`` assigns OD demand to least-cost paths over the network. The result contains allocated OD paths, aggregate edge flows, and any unassigned OD demand. Single OD pair -------------- This network has a direct ``A -> B`` edge with cost ``10`` and an indirect ``A -> C -> B`` path with total cost ``8``. Allocation chooses the lower-cost indirect path. >>> import pandas as pd >>> from transport_flow_model.model import Network, OD >>> network = Network( ... pd.DataFrame( ... { ... "edge_from": ["A", "A", "C"], ... "edge_to": ["B", "C", "B"], ... "edge_id": ["AB", "AC", "CB"], ... "cost": [10, 3, 5], ... "capacity": [100, 100, 100], ... } ... ) ... ) >>> od = OD( ... pd.DataFrame( ... { ... "origin_id": ["A"], ... "destination_id": ["B"], ... "flow": [7], ... } ... ) ... ) >>> result = network.allocate(od, directed=True) ``result.od_flows`` records the path, path cost, and assigned flow. >>> result.od_flows.to_dataframe().to_dict("records") [{'origin_id': 'A', 'destination_id': 'B', 'flow': 7, 'edge_path': ['AC', 'CB'], 'cost': 8}] ``result.network_flows`` aggregates those path flows onto every edge. The direct edge is retained with zero flow because it was unused. >>> result.network_flows.to_dataframe().set_index("edge_id")["flow"].to_dict() {'AB': 0, 'AC': 7, 'CB': 7} All demand was assigned, so ``unassigned_od`` is empty. >>> result.unassigned_od.to_dataframe().empty True