Set the objective of a conservation planning problem
to
secure as much of the features as possible without exceeding a budget. This
type of objective does not use targets, and feature weights should be used
instead to increase the representation of different features in solutions.
Note that this objective does not aim to maximize as much of each feature as
possible and so often results in solutions that are heavily biased towards
specific features.
add_max_utility_objective(x, budget)
x 


budget 

ConservationProblemclass
object with the objective
added to it.
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 objectivesfailing to do so will return an error message when attempting to solve problem.
The maximum utility objective seeks to find the set of planning units that
maximizes the overall level of representation across a suite of
conservation features, while keeping cost within a fixed budget.
Additionally, weights can be used to favor the
representation of certain features over other features (see
add_feature_weights
). This objective 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} a_j w_j \\ \mathit{subject \space to} \\ a_j = \sum_{i = 1}^{I} x_i r_{ij} \space \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\), \(A_j\) is the amount of feature \(j\)
represented in in the solution, 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.
Please note that in versions prior to 3.0.0.0, this objective function was
implemented in the
add_max_cover_objective
but has since been renamed as
add_max_utility_objective
to avoid confusion with historical
formulations of the maximum coverage problem.
# load data data(sim_pu_raster, sim_pu_zones_stack, sim_features, sim_features_zones) # create problem with maximum utility objective p1 < problem(sim_pu_raster, sim_features) %>% add_max_utility_objective(5000) %>% add_binary_decisions() %>% add_default_solver(gap = 0)#> Optimize a model with 6 rows, 95 columns and 545 nonzeros #> Variable types: 5 continuous, 90 integer (90 binary) #> Coefficient statistics: #> Matrix range [2e01, 2e+02] #> Objective range [1e04, 1e+00] #> Bounds range [1e+00, 7e+01] #> RHS range [5e+03, 5e+03] #> Found heuristic solution: objective 0.0000000 #> Presolve removed 5 rows and 5 columns #> Presolve time: 0.00s #> Presolved: 1 rows, 90 columns, 90 nonzeros #> Variable types: 0 continuous, 90 integer (90 binary) #> Presolved: 1 rows, 90 columns, 90 nonzeros #> #> #> Root relaxation: objective 7.435117e+01, 1 iterations, 0.00 seconds #> #> Nodes  Current Node  Objective Bounds  Work #> Expl Unexpl  Obj Depth IntInf  Incumbent BestBd Gap  It/Node Time #> #> 0 0 74.35117 0 1 0.00000 74.35117   0s #> H 0 0 74.2352258 74.35117 0.16%  0s #> H 0 0 74.2714723 74.35117 0.11%  0s #> 0 0 74.28961 0 2 74.27147 74.28961 0.02%  0s #> 0 0 74.28961 0 1 74.27147 74.28961 0.02%  0s #> 0 0 74.28961 0 2 74.27147 74.28961 0.02%  0s #> 0 0 74.28596 0 2 74.27147 74.28596 0.02%  0s #> 0 0 74.28596 0 2 74.27147 74.28596 0.02%  0s #> 0 2 74.28417 0 2 74.27147 74.28417 0.02%  0s #> #> Cutting planes: #> Cover: 2 #> #> Explored 14 nodes (32 simplex iterations) in 0.01 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 3: 74.2715 74.2352 0 #> #> Optimal solution found (tolerance 0.00e+00) #> Best objective 7.427147227067e+01, best bound 7.427147227067e+01, gap 0.0000%# create multizone problem with maximum utility objective that # has a single budget for all zones p2 < problem(sim_pu_zones_stack, sim_features_zones) %>% add_max_utility_objective(5000) %>% add_binary_decisions() %>% add_default_solver(gap = 0)#> Optimize a model with 106 rows, 285 columns and 1905 nonzeros #> Variable types: 15 continuous, 270 integer (270 binary) #> Coefficient statistics: #> Matrix range [2e01, 2e+02] #> Objective range [3e05, 1e+00] #> Bounds range [1e+00, 8e+01] #> RHS range [1e+00, 5e+03] #> Found heuristic solution: objective 0.0000000 #> Presolve removed 105 rows and 195 columns #> Presolve time: 0.00s #> Presolved: 1 rows, 90 columns, 90 nonzeros #> Variable types: 0 continuous, 90 integer (90 binary) #> Presolved: 1 rows, 90 columns, 90 nonzeros #> #> #> Root relaxation: objective 7.691841e+01, 1 iterations, 0.00 seconds #> #> Nodes  Current Node  Objective Bounds  Work #> Expl Unexpl  Obj Depth IntInf  Incumbent BestBd Gap  It/Node Time #> #> 0 0 76.91841 0 1 0.00000 76.91841   0s #> H 0 0 74.5659436 76.91841 3.15%  0s #> 0 0 76.90382 0 2 74.56594 76.90382 3.14%  0s #> H 0 0 76.8663921 76.90382 0.05%  0s #> 0 0 76.88964 0 3 76.86639 76.88964 0.03%  0s #> 0 0 76.88964 0 1 76.86639 76.88964 0.03%  0s #> 0 0 76.88964 0 1 76.86639 76.88964 0.03%  0s #> 0 0 76.88964 0 3 76.86639 76.88964 0.03%  0s #> 0 0 76.88964 0 4 76.86639 76.88964 0.03%  0s #> 0 0 76.88964 0 4 76.86639 76.88964 0.03%  0s #> 0 0 76.88723 0 5 76.86639 76.88723 0.03%  0s #> 0 0 76.88701 0 6 76.86639 76.88701 0.03%  0s #> 0 0 76.87946 0 7 76.86639 76.87946 0.02%  0s #> 0 0 76.87927 0 7 76.86639 76.87927 0.02%  0s #> 0 0 76.87904 0 8 76.86639 76.87904 0.02%  0s #> 0 0 76.87904 0 8 76.86639 76.87904 0.02%  0s #> 0 2 76.87645 0 8 76.86639 76.87645 0.01%  0s #> #> Cutting planes: #> Cover: 4 #> MIR: 2 #> StrongCG: 1 #> #> Explored 6 nodes (43 simplex iterations) in 0.01 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 3: 76.8664 74.5659 0 #> #> Optimal solution found (tolerance 0.00e+00) #> Best objective 7.686639207002e+01, best bound 7.686639207002e+01, gap 0.0000%# create multizone problem with maximum utility objective that # has separate budgets for each zone p3 < problem(sim_pu_zones_stack, sim_features_zones) %>% add_max_utility_objective(c(1000, 2000, 3000)) %>% add_binary_decisions() %>% add_default_solver(gap = 0)#> Optimize a model with 108 rows, 285 columns and 1905 nonzeros #> Variable types: 15 continuous, 270 integer (270 binary) #> Coefficient statistics: #> Matrix range [2e01, 2e+02] #> Objective range [3e05, 1e+00] #> Bounds range [1e+00, 8e+01] #> RHS range [1e+00, 3e+03] #> Found heuristic solution: objective 0.0000000 #> Presolve removed 15 rows and 15 columns #> Presolve time: 0.00s #> Presolved: 93 rows, 270 columns, 540 nonzeros #> Variable types: 0 continuous, 270 integer (270 binary) #> Presolved: 93 rows, 270 columns, 540 nonzeros #> #> #> Root relaxation: objective 8.792265e+01, 9 iterations, 0.00 seconds #> #> Nodes  Current Node  Objective Bounds  Work #> Expl Unexpl  Obj Depth IntInf  Incumbent BestBd Gap  It/Node Time #> #> 0 0 87.92265 0 3 0.00000 87.92265   0s #> H 0 0 86.3712662 87.92265 1.80%  0s #> H 0 0 86.4414936 87.92265 1.71%  0s #> 0 0 86.48574 0 4 86.44149 86.48574 0.05%  0s #> 0 0 86.47613 0 4 86.44149 86.47613 0.04%  0s #> 0 0 86.47613 0 4 86.44149 86.47613 0.04%  0s #> 0 0 86.47613 0 1 86.44149 86.47613 0.04%  0s #> 0 0 86.47613 0 4 86.44149 86.47613 0.04%  0s #> 0 0 86.47613 0 4 86.44149 86.47613 0.04%  0s #> 0 0 86.47595 0 6 86.44149 86.47595 0.04%  0s #> 0 0 86.47594 0 7 86.44149 86.47594 0.04%  0s #> 0 0 86.47594 0 7 86.44149 86.47594 0.04%  0s #> H 0 0 86.4493810 86.47594 0.03%  0s #> H 0 0 86.4735470 86.47594 0.00%  0s #> 0 0 86.47594 0 2 86.47355 86.47594 0.00%  0s #> H 0 0 86.4735471 86.47594 0.00%  0s #> 0 0 cutoff 0 86.47355 86.47355 0.00%  0s #> #> Cutting planes: #> Gomory: 1 #> Cover: 2 #> #> Explored 1 nodes (131 simplex iterations) in 0.02 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 6: 86.4735 86.4735 86.4494 ... 0 #> #> Optimal solution found (tolerance 0.00e+00) #> Best objective 8.647354705008e+01, best bound 8.647354705008e+01, gap 0.0000%