Обеспеченность сервисами¶
Обзор¶
Анализ обеспеченности распределяет спрос зданий (например, число детей школьного возраста) между сервисами с ограниченной вместимостью (местами в школах) по матрице стоимостей пути между ними и нормативному порогу (минуты или метры). Он показывает, какие здания обслуживаются в пределах порога, какие — только более далёкими сервисами и какие сервисы перегружены или недогружены.
objectnat.get_service_provision() рассчитывает распределение и возвращает objectnat.ProvisionResult. Вспомогательные функции присоединяют показатели к зданиям и сервисам и строят геометрию связей; objectnat.recalculate_links() и objectnat.clip_provision() изменяют уже рассчитанный результат.
Входные данные¶
buildings: GeoDataFrame с числовым столбцом спроса (buildings_demand_column, по умолчанию"demand");services: GeoDataFrame с числовым столбцом вместимости (services_capacity_column, по умолчанию"capacity");distance_matrix: стоимости со строкамиbuildings.indexи столбцамиservices.indexв единицахthreshold. Это может быть плотный DataFrame (infилиNaNдля недостижимых пар) или разреженный DataFrame pandas (SparseDtypeсNaNилиinfв качестве заполнителя), который хранит только достижимые пары. Разреженные матрицы читаются поэлементно без уплотнения, поэтому большие территории помещаются в памяти. Такую разреженную матрицу возвращаетod_matrixиз IduEdu (см. Матрица времени в пути от зданий до сервисов).
Метод¶
Распределение — гравитационная вероятностная модель; оно выполняется в расширении ObjectNat на Rust по элементам (разреженной) матрицы. Спрос могут получить только пары здание–сервис с конечной стоимостью d не больше 3 * threshold. У каждой такой пары есть гравитационный вес 1 / (d + 1)²: чем ближе здание, тем больше вес, и здание вдвое ближе получает в среднем примерно вчетверо больше. Единица прибавляется, чтобы здание с нулевой стоимостью, стоящее там же, где сервис, получало конечный вес. Распределение идёт раундами:
Радиус поиска. Первый раунд рассматривает пары со стоимостью примерно до половины порога,
(threshold + 1) / 2; каждый раунд расширяет этот радиус в 1,5 раза, поэтому ближние здания обслуживаются первыми.Предложения. Каждый сервис со свободными местами берёт здания с неудовлетворённым спросом внутри радиуса, оставляет из них здания с наибольшими весами (сначала верхнюю десятую часть; доля растёт по мере выбывания зданий и сервисов) и случайно распределяет между ними свободные места пропорционально весам.
Принятие. Здание, получившее больше предложений, чем ему нужно, принимает свой неудовлетворённый спрос, случайно выбирая среди предложений пропорционально их размеру; остальные места остаются свободными.
Следующий раунд. Здания без неудовлетворённого спроса и сервисы без свободных мест выбывают, и раунды продолжаются, пока распределять нечего.
Случайные последовательности инициализируются из seed отдельно для каждого объекта и итерации, поэтому при фиксированном seed результат одинаков при любом числе ядер процессора. Разные seed дают альтернативные распределения в рамках той же модели.
Результаты¶
objectnat.ProvisionResult содержит
flow: разреженную матрицу здание × сервис с распределённым спросом;demand_rows: по каждому зданиюdemand,demand_left,supplied_demands_withinиsupplied_demands_without(спрос, полученный от сервисов в пределах / за пределамиthreshold),min_dist(стоимость пути до ближайшего сервиса),avg_dist(средняя стоимость, взвешенная по потокам) иprovision_value=supplied_demands_within / demand;capacity_rows: по каждому сервисуcapacity,capacity_left,carried_capacity_within,carried_capacity_withoutиservice_load(суммарный распределённый спрос);distance_matrixиthreshold, использованные в расчёте.
objectnat.get_provision_buildings() и objectnat.get_provision_services() присоединяют эти показатели к копиям входных GeoDataFrame; objectnat.get_provision_links() возвращает по одной прямой на каждый ненулевой поток, от характерной точки здания к сервису, со столбцами building_index, service_index, demand (распределённые единицы) и distance (стоимость).
- objectnat.get_service_provision(*, buildings, distance_matrix, services, threshold, buildings_demand_column='demand', services_capacity_column='capacity', seed=0)[исходный код]¶
Рассчитывает обеспеченность сервисами между точками спроса и объектами обслуживания.
Функция реализует гравитационную модель распределения: вместимость сервиса распределяется между ближними точками спроса с весами, которые убывают с квадратом расстояния (или обобщённой стоимости). Более близкие здания получают пропорционально большую долю доступной вместимости. В распределении участвуют только пары здание–сервис в пределах
3 * threshold; оно выполняется в расширении ObjectNat на Rust только по этим парам.- Параметры:
buildings (
GeoDataFrame) – GeoDataFrame точек спроса. Должен содержать числовой столбец спроса.distance_matrix (
DataFrame) – Матрица стоимостей OD, строки которой —buildings.index, а столбцы —services.index. Единицы должны совпадать сthreshold. Плотный DataFrame (inf/NaN— недостижимо) или, для больших территорий, разреженный DataFrame pandas (SparseDtypeс заполнителемNaNилиinf), который хранит только достижимые пары.services (
GeoDataFrame) – GeoDataFrame объектов обслуживания. Должен содержать числовой столбец вместимости.threshold (
float) – Нормативный порог стоимости. Единицы те же, что вdistance_matrix.buildings_demand_column (
str) – Имя столбца со спросом зданий. По умолчанию"demand".services_capacity_column (
str) – Имя столбца с вместимостью сервисов. По умолчанию"capacity".seed (
int) – Начальное значение генератора случайных выборок при распределении. Фиксированное значение даёт воспроизводимый результат (независимо от числа ядер процессора); меняйте его, чтобы получить альтернативные распределения. По умолчанию0.
- Результат:
Dataclass с разреженной матрицей потоков здание–сервис, показателями зданий и сервисов, согласованной матрицей расстояний и нормативным порогом.
- Тип результата:
- class objectnat.ProvisionResult(flow, demand_rows, capacity_rows, distance_matrix, threshold)[исходный код]¶
Результат расчёта обеспеченности сервисами.
- Параметры:
- flow¶
Разреженная матрица распределения здание–сервис. Строки соответствуют индексам зданий, столбцы — индексам сервисов, ненулевые значения — распределённые единицы спроса.
- demand_rows¶
Показатели зданий с индексом как у
flow.index. Включают исходный спрос, оставшийся спрос, спрос, удовлетворённый в пределах и за пределами порога, стоимость пути до ближайшего сервиса, среднюю стоимость, взвешенную по потокам, и показатель обеспеченности.
- capacity_rows¶
Показатели сервисов с индексом как у
flow.columns. Включают исходную вместимость, оставшуюся вместимость, вместимость, отданную в пределах и за пределами порога, и суммарную нагрузку сервиса.
- distance_matrix¶
Согласованная матрица стоимостей OD, использованная в расчёте (плотная или разреженная pandas, если была передана разреженная матрица). Её индекс и столбцы должны совпадать с
flow.
- threshold¶
Нормативный порог расстояния или времени, по которому потоки делятся на показатели в пределах и за пределами порога.
- objectnat.get_provision_buildings(buildings_gdf, provision_result)[исходный код]¶
Присоединяет к зданиям показатели спроса из расчёта обеспеченности.
Существующие столбцы с теми же именами, что у показателей, удаляются и заменяются. Возвращаемый объект сохраняет тип и индекс входных данных.
- Тип результата:
- Параметры:
buildings_gdf (GeoDataFrame | DataFrame)
provision_result (ProvisionResult)
- objectnat.get_provision_services(services_gdf, provision_result)[исходный код]¶
Присоединяет к сервисам показатели вместимости из расчёта обеспеченности.
Существующие столбцы с теми же именами, что у показателей, удаляются и заменяются. Возвращаемый объект сохраняет тип и индекс входных данных.
- Тип результата:
- Параметры:
services_gdf (GeoDataFrame | DataFrame)
provision_result (ProvisionResult)
- objectnat.get_provision_links(buildings_gdf, services_gdf, provision_result)[исходный код]¶
Строит геометрию связей здание–сервис по ненулевым потокам.
Сервисы перепроецируются в систему координат зданий, если у обоих наборов задана система координат и они различаются. Для пустых потоков возвращается пустой
GeoDataFrame. Связи, идентификаторов здания или сервиса которых нет в переданных GeoDataFrame, отбрасываются.- Тип результата:
- Параметры:
buildings_gdf (GeoDataFrame)
services_gdf (GeoDataFrame)
provision_result (ProvisionResult)
Показатель обеспеченности жилых зданий школами из примера с порогом 10 минут по интермодальной матрице времени в пути (seed=0); точки — школы. Нежилые здания и улицы серые; чёрная линия — граница района.¶
Тот же результат с objectnat.get_provision_links(): по одной линии на ненулевой поток, ширина пропорциональна распределённому спросу. Тёмные связи лежат в пределах порога, светлые — за ним (до 3 * threshold); по светлым связям идёт спрос, который школы в пределах 10 минут не могут принять.¶
Пересчёт и обрезка¶
objectnat.recalculate_links() удаляет потоки со стоимостью больше new_max_dist и пересчитывает сводные показатели без нового распределения. Удалённый спрос не перераспределяется на другие сервисы; для полного перераспределения снова запустите objectnat.get_service_provision().
objectnat.clip_provision() оставляет здания, пересекающие selection_zone, связи этих зданий и сервисы, на которые ссылаются эти связи. Все четыре входных набора должны быть в одной системе координат.
- objectnat.recalculate_links(provision_result, new_max_dist)[исходный код]¶
Пересчитывает результат расчёта обеспеченности с меньшей максимальной стоимостью связи.
Потоки со стоимостью больше
new_max_distудаляются, а сводные показатели зданий и сервисов пересчитываются без перераспределения удалённого спроса.- Тип результата:
- Параметры:
provision_result (ProvisionResult)
new_max_dist (float)
- objectnat.clip_provision(buildings, services, links, selection_zone)[исходный код]¶
Обрезает результаты расчёта обеспеченности по заданной границе.
Оставляет только здания, пересекающие
selection_zone, связи этих зданий и сервисы, на которые ссылаются эти связи.- Тип результата:
- Параметры:
buildings (GeoDataFrame)
services (GeoDataFrame)
links (GeoDataFrame)
selection_zone (GeoDataFrame)
recalculate_links(result, 10): связи длиннее 10 минут удалены, показатели пересчитаны; их спрос остаётся нераспределённым.¶
objectnat.clip_provision() с кругом радиусом 450 м: здания в зоне, все их связи и школы, к которым ведут эти связи, в том числе школы за пределами зоны.¶
Ограничения¶
Распределение случайно: отдельные потоки зависят от
seed; сводные показатели для больших наборов данных мало меняются от seed к seed, но для малых могут меняться.Спрос и вместимость — целые числа (распределяются поштучно); дробные значения отбрасываются.
В модели нет явного поведения выбора (качество, предпочтения, правила закрепления); спрос может получить любой достижимый сервис в пределах
3 * threshold.Результат точен настолько, насколько точна матрица стоимостей; матрица из примера содержит время в пути в минутах по интермодальному графу.
Примеры в ноутбуках¶
Матрица времени в пути от зданий до сервисов (матрица стоимостей с IduEdu) и Обеспеченность сервисами.