Using max_coverage_relocation
Nicholas Tierney
2024-11-26
Source:vignettes/using_max_coverage_relocation.Rmd
using_max_coverage_relocation.Rmd
This vignette provides a guide to using maxcovr
to solve
the maximum covering location problem, assuming that you can relocate
facilities.
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
The “fixed location” method provided in max_coverage
is
limited in that it assumes that you cannot move existing facilities.
max_coverage_relocation
assumes that you can move already
existing facilities, but that there is some cost of removal, and a cost
of installation.
To illustrate the benefits of relocation, we are first going to consider an example where the existing facilities provide no coverage to users. We identify facility locations that are really far away.
york_selected_worst_id <- york_crime %>%
nearest(york) %>%
arrange(-distance) %>%
slice(1:20) %>%
select(desig_id) %>%
distinct(desig_id)
# york_worst <- york_selected_worst_id %>%
york_existing_worst <- york_selected_worst_id %>%
left_join(york,
by = "desig_id")
Then we identify some really ideal locations.
york_not_selected_worst <- york %>%
anti_join(york_existing_worst,
by = "desig_id")
york_proposed_best <-
york_crime %>%
nearest(york_not_selected_worst) %>%
arrange(distance) %>%
slice(1:100) %>%
select(desig_id) %>%
distinct(desig_id) %>%
left_join(york,
by = "desig_id")
york_proposed_best
## # A tibble: 101 × 7
## desig_id long lat object_id pref_ref name grade
## <chr> <dbl> <dbl> <int> <int> <chr> <chr>
## 1 DYO788 -1.09 54.0 3362 463995 NA II*
## 2 DYO857 -1.08 54.0 5549 463864 UNIVERSITY COLLEGE OF RIPON AN… II
## 3 DYO857 -1.08 54.0 4212 463864 UNIVERSITY COLLEGE OF RIPON AN… II
## 4 DYO1212 -1.08 54.0 5843 463237 NA II
## 5 DYO1212 -1.08 54.0 4506 463237 NA II
## 6 DYO862 -1.08 54.0 5554 463874 NA II
## 7 DYO862 -1.08 54.0 4217 463874 NA II
## 8 DYO1146 -1.08 54.0 5793 463399 NA II
## 9 DYO1146 -1.08 54.0 4456 463399 NA II
## 10 DYO1078 -1.09 54.0 5730 463443 THE ADELPHI HOTEL AND THE RAIL… II
## # ℹ 91 more rows
york_existing_worst
## # A tibble: 21 × 7
## desig_id long lat object_id pref_ref name grade
## <chr> <dbl> <dbl> <int> <int> <chr> <chr>
## 1 DYO91 -0.980 54.0 3545 328688 SANDBURN CROSS IN GROUNDS OF … II
## 2 DYO91 -0.980 54.0 4882 328688 SANDBURN CROSS IN GROUNDS OF … II
## 3 DYO222 -1.20 54.0 3720 331644 PEAR TREE FARMHOUSE II
## 4 DYO222 -1.20 54.0 5057 331644 PEAR TREE FARMHOUSE II
## 5 DYO1477 -0.983 54.0 6043 328687 MILEPOST APPROXIMATELY 75 MET… II
## 6 DYO1477 -0.983 54.0 4707 328687 MILEPOST APPROXIMATELY 75 MET… II
## 7 DYO138 -1.21 54.0 3591 331645 CROFT FARMHOUSE II
## 8 DYO138 -1.21 54.0 4928 331645 CROFT FARMHOUSE II
## 9 DYO137 -1.19 54.0 3590 331701 BOUNDARY POST AT SE 5303 5336 II
## 10 DYO137 -1.19 54.0 4927 331701 BOUNDARY POST AT SE 5303 5336 II
## # ℹ 11 more rows
Let’s look at the coverage of these places,
coverage(york_existing_worst,
york_crime,
distance_cutoff = 100)
## # A tibble: 1 × 7
## distance_within n_cov n_not_cov prop_cov prop_not_cov dist_avg dist_sd
## <dbl> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 100 0 1814 0 1 5674. 1040.
So these are worst placements - we should choose some better
facilities. However, if we consider the possibility that we could move
these existing facilities to better locations, then we might be able to
save a lot of money! We can do this with
max_coverage_relocation
.
Here we use max_coverage_relocation
, which is similar in
form to max_coverage
.
Here, we specify:
-
existing_facility
withyork_existing_worst
-
proposed_facility
withyork_proposed_best
-
user
isyork_crime
, -
distance_cutoff
is 100 - for 100m
instead of specifying n_added
, as in
max_coverage
, we specify three cost_
parameters:
-
cost_install
is the cost of buying a new facility and installing it -
cost_removal
is the cost of removing a facility and installing it in a new location -
cost_total
is the total available money to spend.
Here we state that the installation cost is 10, the remocal cost is 1, and the total available cost is 10. There is only enough total resources to install one facility.
system.time(
mc_relocate_worst <- max_coverage_relocation(
existing_facility = york_existing_worst,
proposed_facility = york_proposed_best,
user = york_crime,
distance_cutoff = 100,
cost_install = 500,
cost_removal = 100,
cost_total = 1000)
)
## user system elapsed
## 0.462 0.011 0.474
mc_relocate_worst
##
## -----------------------------------------
## Model Fit: maxcovr relocation model
## -----------------------------------------
## model_used: max_coverage_relocation
## existing_facility: york_existing_worst
## proposed_facility: york_proposed_best
## user: york_crime
## distance_cutoff: 100
## cost_install: 500
## cost_removal: 100
## cost_total: 1000
## solver: lpSolve
## -----------------------------------------
summary(mc_relocate_worst)
##
## ---------------------------------------
## Model Fit: maxcovr relocation model
## ---------------------------------------
## Distance Cutoff: 100m
## Facilities:
## Added: 10
## Removed: 10L
## Coverage (Previous):
## # Users: 260 (0)
## Proportion: 0.1433 (0)
## Distance (m) to Facility (Previous):
## Avg: 1720 (5674)
## SD: 1542 (1040)
## Costs:
## Total: 1000
## Install: 500
## Removal: 100
## ---------------------------------------
dim(york_existing_worst)
## [1] 21 7
dim(york_proposed_best)
## [1] 101 7
mc_relocate_worst$existing_facility[[1]]
## # A tibble: 21 × 8
## desig_id long lat object_id pref_ref name grade is_relocated
## <chr> <dbl> <dbl> <int> <int> <chr> <chr> <lgl>
## 1 DYO91 -0.980 54.0 3545 328688 SANDBURN CROSS I… II FALSE
## 2 DYO91 -0.980 54.0 4882 328688 SANDBURN CROSS I… II FALSE
## 3 DYO222 -1.20 54.0 3720 331644 PEAR TREE FARMHO… II FALSE
## 4 DYO222 -1.20 54.0 5057 331644 PEAR TREE FARMHO… II FALSE
## 5 DYO1477 -0.983 54.0 6043 328687 MILEPOST APPROXI… II FALSE
## 6 DYO1477 -0.983 54.0 4707 328687 MILEPOST APPROXI… II FALSE
## 7 DYO138 -1.21 54.0 3591 331645 CROFT FARMHOUSE II FALSE
## 8 DYO138 -1.21 54.0 4928 331645 CROFT FARMHOUSE II FALSE
## 9 DYO137 -1.19 54.0 3590 331701 BOUNDARY POST AT… II FALSE
## 10 DYO137 -1.19 54.0 4927 331701 BOUNDARY POST AT… II FALSE
## # ℹ 11 more rows
mc_relocate_worst$proposed_facility[[1]]
## # A tibble: 101 × 8
## desig_id long lat object_id pref_ref name grade is_installed
## <chr> <dbl> <dbl> <int> <int> <chr> <chr> <dbl>
## 1 DYO788 -1.09 54.0 3362 463995 NA II* 0
## 2 DYO857 -1.08 54.0 5549 463864 UNIVERSITY COLLEG… II 0
## 3 DYO857 -1.08 54.0 4212 463864 UNIVERSITY COLLEG… II 0
## 4 DYO1212 -1.08 54.0 5843 463237 NA II 1
## 5 DYO1212 -1.08 54.0 4506 463237 NA II 0
## 6 DYO862 -1.08 54.0 5554 463874 NA II 0
## 7 DYO862 -1.08 54.0 4217 463874 NA II 0
## 8 DYO1146 -1.08 54.0 5793 463399 NA II 1
## 9 DYO1146 -1.08 54.0 4456 463399 NA II 0
## 10 DYO1078 -1.09 54.0 5730 463443 THE ADELPHI HOTEL… II 0
## # ℹ 91 more rows
mc_relocate_worst$facilities_selected[[1]]
## # A tibble: 21 × 7
## desig_id long lat object_id pref_ref name grade
## <chr> <dbl> <dbl> <int> <int> <chr> <chr>
## 1 DYO91 -0.980 54.0 3545 328688 SANDBURN CROSS IN GROUNDS OF … II
## 2 DYO91 -0.980 54.0 4882 328688 SANDBURN CROSS IN GROUNDS OF … II
## 3 DYO222 -1.20 54.0 3720 331644 PEAR TREE FARMHOUSE II
## 4 DYO222 -1.20 54.0 5057 331644 PEAR TREE FARMHOUSE II
## 5 DYO1477 -0.983 54.0 6043 328687 MILEPOST APPROXIMATELY 75 MET… II
## 6 DYO1477 -0.983 54.0 4707 328687 MILEPOST APPROXIMATELY 75 MET… II
## 7 DYO138 -1.21 54.0 3591 331645 CROFT FARMHOUSE II
## 8 DYO138 -1.21 54.0 4928 331645 CROFT FARMHOUSE II
## 9 DYO137 -1.19 54.0 3590 331701 BOUNDARY POST AT SE 5303 5336 II
## 10 DYO137 -1.19 54.0 4927 331701 BOUNDARY POST AT SE 5303 5336 II
## # ℹ 11 more rows
You can then start to toy with the different pricings if you like.
system.time(
mc_relocate_worst_eq <- max_coverage_relocation(
existing_facility = york_existing_worst,
proposed_facility = york_proposed_best,
user = york_crime,
distance_cutoff = 100,
cost_install = 10,
cost_removal = 100,
cost_total = 10)
)
## user system elapsed
## 0.279 0.020 0.299
mc_relocate_worst_eq
##
## -----------------------------------------
## Model Fit: maxcovr relocation model
## -----------------------------------------
## model_used: max_coverage_relocation
## existing_facility: york_existing_worst
## proposed_facility: york_proposed_best
## user: york_crime
## distance_cutoff: 100
## cost_install: 10
## cost_removal: 100
## cost_total: 10
## solver: lpSolve
## -----------------------------------------
summary(mc_relocate_worst_eq)
##
## ---------------------------------------
## Model Fit: maxcovr relocation model
## ---------------------------------------
## Distance Cutoff: 100m
## Facilities:
## Added: 1
## Removed: 0L
## Coverage (Previous):
## # Users: 44 (0)
## Proportion: 0.0243 (0)
## Distance (m) to Facility (Previous):
## Avg: 2071 (5674)
## SD: 1521 (1040)
## Costs:
## Total: 10
## Install: 10
## Removal: 100
## ---------------------------------------