Set the objective of a conservation planning problem() to fulfill as many targets as possible while ensuring that the cost of the solution does not exceed a budget.

add_max_features_objective(x, budget)

## Arguments

x problem() (i.e. ConservationProblem) object. numeric value specifying the maximum expenditure of the prioritization. For problems with multiple zones, the argument to budget can be a single numeric value to specify a budget for the entire solution or a numeric vector to specify a budget for each each management zone.

## Value

Object (i.e. ConservationProblem) with the objective added to it.

## Details

A problem objective is used to specify the overall goal of the conservation planning problem. Please note that all conservation planning problems formulated in the prioritizr package require the addition of objectives---failing to do so will return an error message when attempting to solve problem.

The maximum feature representation objective is an enhanced version of the maximum coverage objective add_max_cover_objective() because targets can be used to ensure that a certain amount of each feature is required in order for them to be adequately represented (similar to the minimum set objective (see add_min_set_objective()). This objective finds the set of planning units that meets representation targets for as many features as possible while staying within a fixed budget (inspired by Cabeza and Moilanen 2001). Additionally, weights can be used add_feature_weights()). If multiple solutions can meet the same number of weighted targets while staying within budget, the cheapest solution is returned.

The maximum feature objective for the reserve design problem can be expressed mathematically for a set of planning units ($$I$$ indexed by $$i$$) and a set of features ($$J$$ indexed by $$j$$) as:

$$\mathit{Maximize} \space \sum_{i = 1}^{I} -s \space c_i \space x_i + \sum_{j = 1}^{J} y_j w_j \\ \mathit{subject \space to} \\ \sum_{i = 1}^{I} x_i r_{ij} \geq y_j t_j \forall j \in J \\ \sum_{i = 1}^{I} x_i c_i \leq B$$

Here, $$x_i$$ is the decisions variable (e.g. specifying whether planning unit $$i$$ has been selected (1) or not (0)), $$r_{ij}$$ is the amount of feature $$j$$ in planning unit $$i$$, $$t_j$$ is the representation target for feature $$j$$, $$y_j$$ indicates if the solution has meet the target $$t_j$$ for feature $$j$$, and $$w_j$$ is the weight for feature $$j$$ (defaults to 1 for all features; see add_feature_weights() to specify weights). Additionally, $$B$$ is the budget allocated for the solution, $$c_i$$ is the cost of planning unit $$i$$, and $$s$$ is a scaling factor used to shrink the costs so that the problem will return a cheapest solution when there are multiple solutions that represent the same amount of all features within the budget.

## References

Cabeza M and Moilanen A (2001) Design of reserve networks and the persistence of biodiversity. Trends in Ecology & Evolution, 16: 242--248.

add_feature_weights(), objectives.

## Examples

# load data
data(sim_pu_raster, sim_pu_zones_stack, sim_features, sim_features_zones)

# create problem with maximum features objective
p1 <- problem(sim_pu_raster, sim_features) %>%
# \dontrun{
# solve problem
s1 <- solve(p1)#> Gurobi Optimizer version 9.0.2 build v9.0.2rc0 (linux64)
#> Optimize a model with 6 rows, 95 columns and 545 nonzeros
#> Variable types: 0 continuous, 95 integer (95 binary)
#> Coefficient statistics:
#>   Matrix range     [2e-01, 2e+02]
#>   Objective range  [1e-04, 1e+00]
#>   Bounds range     [1e+00, 1e+00]
#>   RHS range        [2e+03, 2e+03]
#> Found heuristic solution: objective -0.0000000
#> Presolve time: 0.00s
#> Presolved: 6 rows, 95 columns, 545 nonzeros
#> Variable types: 0 continuous, 95 integer (95 binary)
#> Presolved: 6 rows, 95 columns, 545 nonzeros
#>
#>
#> Root relaxation: objective 4.701027e+00, 23 iterations, 0.00 seconds
#>
#>     Nodes    |    Current Node    |     Objective Bounds      |     Work
#>  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
#>
#>      0     0    4.70103    0    6   -0.00000    4.70103      -     -    0s
#>      0     0    4.70094    0    8   -0.00000    4.70094      -     -    0s
#>      0     0    4.70062    0    9   -0.00000    4.70062      -     -    0s
#>      0     0    4.69925    0   10   -0.00000    4.69925      -     -    0s
#>      0     0    4.69529    0    8   -0.00000    4.69529      -     -    0s
#>      0     0    4.69465    0    9   -0.00000    4.69465      -     -    0s
#>      0     0    4.69442    0   10   -0.00000    4.69442      -     -    0s
#>      0     0    4.69378    0   11   -0.00000    4.69378      -     -    0s
#>      0     0    4.66223    0    8   -0.00000    4.66223      -     -    0s
#>      0     0    4.66136    0    9   -0.00000    4.66136      -     -    0s
#>      0     0    4.65975    0   11   -0.00000    4.65975      -     -    0s
#>      0     0    4.65866    0   10   -0.00000    4.65866      -     -    0s
#>      0     0    4.65813    0   10   -0.00000    4.65813      -     -    0s
#>      0     0    4.65696    0   11   -0.00000    4.65696      -     -    0s
#>      0     0    4.65297    0   12   -0.00000    4.65297      -     -    0s
#>      0     0    4.65192    0   13   -0.00000    4.65192      -     -    0s
#>      0     0    4.65145    0   14   -0.00000    4.65145      -     -    0s
#>      0     0    4.65139    0   15   -0.00000    4.65139      -     -    0s
#>      0     0    4.65122    0   16   -0.00000    4.65122      -     -    0s
#>      0     0    4.65077    0   18   -0.00000    4.65077      -     -    0s
#> H    0     0                       1.9990374    4.65077   133%     -    0s
#>      0     0    4.65072    0   18    1.99904    4.65072   133%     -    0s
#>      0     0    4.56295    0    9    1.99904    4.56295   128%     -    0s
#>      0     0    4.55748    0   11    1.99904    4.55748   128%     -    0s
#>      0     0    4.52804    0   11    1.99904    4.52804   127%     -    0s
#>      0     0    4.51882    0   11    1.99904    4.51882   126%     -    0s
#>      0     0    4.51799    0   13    1.99904    4.51799   126%     -    0s
#>      0     0    4.51572    0   15    1.99904    4.51572   126%     -    0s
#>      0     0    4.51563    0   15    1.99904    4.51563   126%     -    0s
#>      0     0    4.51306    0   19    1.99904    4.51306   126%     -    0s
#>      0     0    4.51241    0   19    1.99904    4.51241   126%     -    0s
#>      0     0    4.51221    0   19    1.99904    4.51221   126%     -    0s
#>      0     0    4.51213    0   19    1.99904    4.51213   126%     -    0s
#>      0     0    4.51078    0   20    1.99904    4.51078   126%     -    0s
#>      0     0    4.51029    0   20    1.99904    4.51029   126%     -    0s
#>      0     0    4.50913    0   22    1.99904    4.50913   126%     -    0s
#>      0     0    4.50887    0   22    1.99904    4.50887   126%     -    0s
#>      0     0    4.50877    0   23    1.99904    4.50877   126%     -    0s
#>      0     0    4.50519    0   21    1.99904    4.50519   125%     -    0s
#>      0     0    4.50466    0   24    1.99904    4.50466   125%     -    0s
#>      0     0    4.50457    0   25    1.99904    4.50457   125%     -    0s
#>      0     0    4.48891    0   16    1.99904    4.48891   125%     -    0s
#>      0     0    4.48875    0   16    1.99904    4.48875   125%     -    0s
#>      0     0    4.48862    0   17    1.99904    4.48862   125%     -    0s
#>      0     0    4.48392    0   19    1.99904    4.48392   124%     -    0s
#>      0     0    4.48348    0   21    1.99904    4.48348   124%     -    0s
#>      0     0    4.47642    0   19    1.99904    4.47642   124%     -    0s
#>      0     0    4.47459    0   20    1.99904    4.47459   124%     -    0s
#>      0     0    4.47380    0   20    1.99904    4.47380   124%     -    0s
#>      0     0    4.47357    0   21    1.99904    4.47357   124%     -    0s
#>      0     0    4.47344    0   22    1.99904    4.47344   124%     -    0s
#>      0     0    4.46919    0   21    1.99904    4.46919   124%     -    0s
#>      0     0    4.46897    0   22    1.99904    4.46897   124%     -    0s
#>      0     0    4.46748    0   19    1.99904    4.46748   123%     -    0s
#>      0     2    4.44365    0   19    1.99904    4.44365   122%     -    0s
#> H    7     3                       1.9990909    3.18604  59.4%  18.3    0s
#>
#> Cutting planes:
#>   MIR: 11
#>   StrongCG: 2
#>
#> Explored 25 nodes (669 simplex iterations) in 0.15 seconds
#> Thread count was 1 (of 4 available processors)
#>
#> Solution count 3: 1.99909 1.99904 -0
#>
#> Optimal solution found (tolerance 1.00e-01)
#> Best objective 1.999090896800e+00, best bound 2.158929727285e+00, gap 7.9956%
# plot solution
plot(s1, main = "solution", axes = FALSE, box = FALSE)# }

# create multi-zone problem with maximum features objective,
# with 10 % representation targets for each feature, and set
# a budget such that the total maximum expenditure in all zones
# cannot exceed 3000
p2 <- problem(sim_pu_zones_stack, sim_features_zones) %>%
add_relative_targets(matrix(0.1, ncol = 3, nrow = 5)) %>%
# \dontrun{
# solve problem
s2 <- solve(p2)#> Gurobi Optimizer version 9.0.2 build v9.0.2rc0 (linux64)
#> Optimize a model with 106 rows, 285 columns and 1905 nonzeros
#> Model fingerprint: 0xe9518199
#> Variable types: 0 continuous, 285 integer (285 binary)
#> Coefficient statistics:
#>   Matrix range     [2e-01, 2e+02]
#>   Objective range  [3e-05, 1e+00]
#>   Bounds range     [1e+00, 1e+00]
#>   RHS range        [1e+00, 3e+03]
#> Found heuristic solution: objective -0.0000000
#> Presolve time: 0.00s
#> Presolved: 106 rows, 285 columns, 1905 nonzeros
#> Variable types: 0 continuous, 285 integer (285 binary)
#> Presolved: 106 rows, 285 columns, 1905 nonzeros
#>
#>
#> Root relaxation: objective 7.938175e+00, 248 iterations, 0.00 seconds
#>
#>     Nodes    |    Current Node    |     Objective Bounds      |     Work
#>  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
#>
#>      0     0    7.93818    0   11   -0.00000    7.93818      -     -    0s
#> H    0     0                       4.9996186    7.93818  58.8%     -    0s
#>      0     0    7.56188    0   18    4.99962    7.56188  51.2%     -    0s
#> H    0     0                       4.9996398    7.56188  51.2%     -    0s
#>      0     0    7.56101    0   19    4.99964    7.56101  51.2%     -    0s
#>      0     0    7.27065    0   11    4.99964    7.27065  45.4%     -    0s
#> H    0     0                       4.9996466    7.27065  45.4%     -    0s
#>      0     0    7.26884    0   12    4.99965    7.26884  45.4%     -    0s
#>      0     0    7.25820    0   14    4.99965    7.25820  45.2%     -    0s
#> H    0     0                       4.9996473    7.25820  45.2%     -    0s
#>      0     0    7.25660    0   16    4.99965    7.25660  45.1%     -    0s
#>      0     0    7.25580    0   18    4.99965    7.25580  45.1%     -    0s
#>      0     0    7.25572    0   19    4.99965    7.25572  45.1%     -    0s
#>      0     0    7.25341    0   21    4.99965    7.25341  45.1%     -    0s
#>      0     0    7.25246    0   22    4.99965    7.25246  45.1%     -    0s
#>      0     0    7.25219    0   23    4.99965    7.25219  45.1%     -    0s
#>      0     0    7.25144    0   24    4.99965    7.25144  45.0%     -    0s
#>      0     0    7.25144    0   24    4.99965    7.25144  45.0%     -    0s
#> H    0     0                       4.9996488    7.25144  45.0%     -    0s
#>      0     2    7.25041    0   24    4.99965    7.25041  45.0%     -    0s
#>
#> Cutting planes:
#>   Gomory: 1
#>   Cover: 10
#>   MIR: 5
#>   StrongCG: 4
#>   GUB cover: 1
#>   RLT: 6
#>
#> Explored 124 nodes (1709 simplex iterations) in 0.16 seconds
#> Thread count was 1 (of 4 available processors)
#>
#> Solution count 6: 4.99965 4.99965 4.99965 ... -0
#>
#> Optimal solution found (tolerance 1.00e-01)
#> Best objective 4.999648781179e+00, best bound 5.312475879683e+00, gap 6.2570%
# plot solution
plot(category_layer(s2), main = "solution", axes = FALSE, box = FALSE)# }
# create multi-zone problem with maximum features objective,
# with 10 % representation targets for each feature, and set
# separate budgets for each management zone
p3 <- problem(sim_pu_zones_stack, sim_features_zones) %>%
add_relative_targets(matrix(0.1, ncol = 3, nrow = 5)) %>%
# \dontrun{
# solve problem
s3 <- solve(p3)#> Gurobi Optimizer version 9.0.2 build v9.0.2rc0 (linux64)
#> Optimize a model with 108 rows, 285 columns and 1905 nonzeros
#> Model fingerprint: 0x0e0fbd30
#> Variable types: 0 continuous, 285 integer (285 binary)
#> Coefficient statistics:
#>   Matrix range     [2e-01, 2e+02]
#>   Objective range  [3e-05, 1e+00]
#>   Bounds range     [1e+00, 1e+00]
#>   RHS range        [1e+00, 3e+03]
#> Found heuristic solution: objective -0.0000000
#> Presolve time: 0.00s
#> Presolved: 108 rows, 285 columns, 1905 nonzeros
#> Variable types: 0 continuous, 285 integer (285 binary)
#> Presolved: 108 rows, 285 columns, 1905 nonzeros
#>
#>
#> Root relaxation: objective 1.499889e+01, 44 iterations, 0.00 seconds
#>
#>     Nodes    |    Current Node    |     Objective Bounds      |     Work
#>  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
#>
#>      0     0   14.99889    0    6   -0.00000   14.99889      -     -    0s
#> H    0     0                       4.9995792   14.99889   200%     -    0s
#> H    0     0                      14.9989002   14.99890  0.00%     -    0s
#>
#> Explored 1 nodes (44 simplex iterations) in 0.01 seconds
#> Thread count was 1 (of 4 available processors)
#>
#> Solution count 3: 14.9989 4.99958 -0
#>
#> Optimal solution found (tolerance 1.00e-01)
#> Best objective 1.499890022234e+01, best bound 1.499890022234e+01, gap 0.0000%
# plot solution
plot(category_layer(s3), main = "solution", axes = FALSE, box = FALSE)# }