mamut_routing_tools.generation.single¶
Single-instance generation driver (selection, demands, matrices, artifacts), the port of the workbench's build_generation_selection + generate_single_instance.
GenerationRequest
dataclass
¶
GenerationRequest(city: str, osm_path: Path, method: str = 'poi_categories', n_customers: int = 50, seed: int = 0, demand_type: int = 7, avg_route_size: int = 4, depot_mode: str = 'center', customer_mode: str = 'random_clustered', cluster_seeds: int | None = None, cluster_decay_meters: float = 800.0, categories: list[str] = (lambda: list(DEFAULT_CATEGORIES))(), hybrid_poi_share: float = 0.5, only_intersections: bool = True, trim_to_connected_graph: bool = True, poi_attach_mode: str = POI_ATTACH_NEAREST_NODE, poi_attach_radius_m: float = DEFAULT_POI_ATTACH_RADIUS_M, manual_poi_ids: list[int] = list(), manual_depot_poi_id: int | None = None, manual_poi_refs: list[tuple[str, int]] = list(), manual_depot_poi_ref: tuple[str, int] | None = None)
picked_refs
¶
Every hand-picked POI as a (osm_type, osm_id) pair, in pick order.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
effective_method
¶
The method that describes what was actually selected.
A POI request the extract cannot serve is completed with parametric road
points, which makes the instance a hybrid one -- or a parametric one when no
amenity could be used at all. Naming it after the request would put _poi
on a file whose customers sit on plain intersections, so the composition has
the last word. Only the fallback direction is reclassified: a hybrid that
reaches its POI target stays hybrid, because that mix was asked for.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
graph_option_params
¶
The graph options actually in force, plus the ones that were asked for.
load_road_graph relaxes only_intersections / trim_to_connected
when the requested combination yields an empty graph, so recording the
request would make an instance claim a graph it does not have. The effective
values are the ones written to the metadata; the request is kept beside them
and the difference is what the caller warns about.
graph.loaded_with is the loader's own record. A graph built without it
went through no fallback chain, so the request stands.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
selection_composition
¶
selection_composition(*, method: str, requested: int, customer_tags: list[str], poi_stats: dict[str, Any], poi_share: float, categories: list[str], graph_options_relaxed: dict[str, Any] | None = None, effective: str | None = None, attach_mode: str = POI_ATTACH_NEAREST_NODE) -> dict[str, Any]
What the selection really is made of, versus what was asked for.
A POI-backed method that runs out of amenities keeps going with parametric
road points, which is the right fallback but changes the nature of the
instance. This record is what lets the caller say so before generating:
poi_shortfall is how many customers meant to sit on a real amenity did
not, and poi_pool_attachable is the ceiling that caused it (None
when the pool was never exhausted, so no ceiling was observed).
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
composition_notice
¶
Everything about this selection the user did not ask for, or None.
Names the final split, the pool that capped it, and the ways out (fewer customers, more categories to draw from), plus any option the loader had to relax to build the graph at all.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
poi_attributes
¶
poi_attributes(selection: Selection, index: int) -> tuple[str | None, int | None, str | None, str | None]
(category, osm_id, name, osm_type) of the POI behind a selected vertex.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
merged_poi_records
¶
The other amenities standing on this node, as plain serialisable rows.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
poi_attribute_columns
¶
poi_attribute_columns(selection: Selection, count: int) -> tuple[list[str | None], list[int | None], list[str | None], list[str | None], list[list[dict[str, Any]]], list[float]]
The six per-node POI columns in one pass over selection.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
materialize_instance
¶
materialize_instance(selection: Selection, output_root: str | Path, *, demand_type: int, avg_route_size: int, rng: Random, precomputed: dict[str, Any] | None = None, name_suffix: str = '', reserved_names: set[str] | None = None) -> dict[str, Any]
Write the 3-metric .vrp set, _meta.json, _manifest.json and .vrp.json
files for a selection; precomputed lets the bulk driver pass sliced
matrices/geometry instead of recomputing them, and name_suffix keeps
same-parameter-different-seed instances from overwriting one another.
reserved_names is the set of instance paths a caller has already written
in this run. The final name is only known here -- it encodes route_count,
which follows from the drawn demands rather than from any request field -- so
this is the only place that can guarantee two instances of one run never land
on the same files. Names claimed by earlier runs are untouched, keeping
regeneration of the same configuration idempotent.
Source code in MAMUT-routing-tools/src/mamut_routing_tools/generation/single.py
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | |