Generate an objective function to perform the metapopulation capacity-based conservation prioritization developed by Strimas-Mackey and Brodie (2018). This objective function maximizes the average metapopulation capacity across species for a fixed budget. There is an optional additional term, similar to the boundary term in Marxan, that can be used to favour more compact solutions.
Arguments
- pu
raster::RasterStack, sp::SpatialPolygonsDataFrame, or sf::sf object; planning units and representation levels of features as layers (raster inputs) or columns (vector inputs).
- f
named list of dispersal survival functions with names matching the layer/column names in
pu
.- budget
numeric; the target budget for the prioritization exercise.
- delta
numeric; a scale factor to apply to the budget term in the objective function that determines. To use simulated annealing for the optimization, the budget constraint must be incorporated directly into the objective function. This argument determines the relative importance to be placed on maximizing the metapopulation capacity compared to meeting the budget constraint.
- blm
numeric; a scale factor to apply to the perimeter term in the objective function that determines the relative importance to be placed on maximizing the metapopulation capacity compared to producing more compact solutions.
- scale
numeric; vales to rescale the metapopulation capacity by, e.g. to normalize them between 0-1 one can scale by the maximum, species-specific metapopulation capacity given by selecting all planning units. This should be a vector of length 1 or equal in length to the number of features.
- benefit
function; a function to apply to the scaled metapopulation capacity before averaging across species. Often a saturating function is used to ensure that less value is given to changes in metapopulation capacity for species that are already near their maximum.
- cost
name of the cost column or layer in the planning unit object,
pu
, a numeric vector of costs in the same order as the rows ofpu
(for vector planning units), or aRasterLayer
of costs (forRaster
planning units.- units
character; metapopulation capacity depends on the units used for the areas and distances, this argument determines whether these are measured in meters or kilometers.
- parallel
logical; whether to parallelize the metapopulation capacity calculations over the species. Parallelization is accomplished using
foreach::foreach()
and requires registering a parallel backend withdoParallel::registerDoParallel()
prior to calling this function.
Value
A function that, given a logical vector specifying which planning
units are selected, returns the corresponding objective function value. If
the objective function is called with components = TRUE
, then a list is
returned with the three components of the object function:
mc
: the metapoplation capacity of each species.cost
: the cost of the reserve network.perimeter
: the total perimeter length, in the specified units, of the reserve network.
Examples
# generate features
r <- raster::raster(nrows = 10, ncols = 10, crs = "+proj=laea",
vals = sample(0:1, 100, replace = TRUE))
s <- raster::stack(r, r, r)
s[[2]][] <- sample(0:1, 100, replace = TRUE, prob = c(0.6, 0.4))
s[[3]][] <- sample(0:1, 100, replace = TRUE, prob = c(0.8, 0.2))
names(s) <- c("a", "b", "c")
features <- raster::rasterToPolygons(s)
features <- sf::st_as_sf(features)
# cost
features$cost <- runif(nrow(features))
# dispersal functions
disp_f <- list(a = dispersal_negexp(1 / 0.01),
b = dispersal_negexp(1 / 0.005),
c = dispersal_negexp(1 / 0.02))
# calculate scale factors
scale_mc <- mc_reserve(features, rep(TRUE, nrow(features)), disp_f)
# set budget at 50% of total
budget <- 0.5 * sum(features$cost)
# build an objective function
objective <- generate_objective(features, disp_f, budget, delta = 0.001,
blm = 0.001)
# calculate objective
selected <- sample(c(FALSE, TRUE), 100, replace = TRUE, prob = c(0.7, 0.3))
objective(selected, components = TRUE)
#> $mc
#> a b c
#> 1.038255e-04 8.578890e-05 6.982115e-05
#>
#> $cost
#> [1] 18.27046
#>
#> $perimeter
#> [1] 2.7
#>
objective(selected)
#> [1] -0.002440564