Create a conservation planning problem following the mathematical formulations used in Marxan (detailed in Beyer et al. 2016).

marxan_problem(x, ...)

# S3 method for default
marxan_problem(x, ...)

# S3 method for data.frame
marxan_problem(x, spec, puvspr, bound = NULL,
  blm = 0, ...)

# S3 method for character
marxan_problem(x, ...)

Arguments

x

character file path for a Marxan input file (typically called "input.dat"), or data.frame containing planning unit data (typically called "pu.dat"). If the argument to x is a data.frame, then each row corresponds to a different planning unit, and it must have the following columns:

"id"

integer unique identifier for each planning unit. These identifiers are used in the argument to puvspr.

"cost"

numeric cost of each planning unit.

"status"

integer indicating if each planning unit should not be locked in the solution (0) or if it should be locked in (2) or locked out (3) of the solution. Although Marxan allows planning units to be selected in the initial solution (using values of 1), these values have no effect here. This column is optional.

...

not used.

spec

data.frame containing information on the features. The argument to spec must follow the conventions used by Marxan for the species data file (conventionally called "spec.dat"). Each row corresponds to a different feature and each column corresponds to different information about the features. It must contain the columns listed below. Note that the argument to spec must contain at least one column named "prop" or "amount"---but not both columns with both of these names---to specify the target for each feature.

"id"

integer unique identifier for each feature These identifiers are used in the argument to puvspr.

"name"

character name for each feature.

"prop"

numeric relative target for each feature (optional).

'
"amount"

numeric absolute target for each feature (optional).

puvspr

data.frame containing information on the amount of each feature in each planning unit. The argument to puvspr must follow the conventions used in the Marxan input data file (conventionally called "puvspr.dat"). It must contain the following columns:

"pu"

integer planning unit identifier.

"species"

integer feature identifier.

"amount"

numeric amount of the feature in the planning unit.

bound

NULL object indicating that no boundary data is required for the conservation planning problem, or a data.frame containing information on the planning units' boundaries. The argument to bound must follow the conventions used in the Marxan input data file (conventionally called "bound.dat"). It must contain the following columns:

"id1"

integer planning unit identifier.

"id2"

integer planning unit identifier.

"boundary"

numeric length of shared boundary between the planning units identified in the previous two columns.

blm

numeric boundary length modifier. This argument only has an effect when argument to x is a data.frame. The default argument is zero.

Value

ConservationProblem-class object.

Details

This function is provided as a convenient wrapper for solving Marxan problems using prioritizr. Although this function could accommodate asymmetric connectivity in earlier versions of the prioritizr package, this functionality is no longer available. Please see the add_connectivity_penalties function for adding asymmetric connectivity penalties to a conservation planning problem. For more information on the correct formats for Marxan input data, see the official Marxan website and Ball et al. (2009).

References

Ball IR, Possingham HP, and Watts M (2009) Marxan and relatives: Software for spatial conservation prioritisation in Spatial conservation prioritisation: Quantitative methods and computational tools. Eds Moilanen A, Wilson KA, and Possingham HP. Oxford University Press, Oxford, UK.

Beyer HL, Dujardin Y, Watts ME, and Possingham HP (2016) Solving conservation planning problems with integer linear programming. Ecological Modelling, 228: 14--22.

Examples

# create Marxan problem using Marxan input file input_file <- system.file("extdata/input.dat", package = "prioritizr") p1 <- marxan_problem(input_file)
# solve problem s1 <- solve(p1)
#> Optimize a model with 10075 rows, 6780 columns and 24778 nonzeros #> Variable types: 0 continuous, 6780 integer (6780 binary) #> Coefficient statistics: #> Matrix range [5e-01, 4e+07] #> Objective range [8e+03, 4e+07] #> Bounds range [1e+00, 1e+00] #> RHS range [5e+07, 3e+09] #> Warning: Model contains large rhs #> Consider reformulating model or setting NumericFocus parameter #> to avoid numerical issues. #> Found heuristic solution: objective 1.221531e+10 #> Presolve removed 2499 rows and 1614 columns #> Presolve time: 0.05s #> Presolved: 7576 rows, 5166 columns, 17226 nonzeros #> Variable types: 0 continuous, 5166 integer (5166 binary) #> Presolved: 7576 rows, 5166 columns, 17226 nonzeros #> #> #> Root relaxation: objective 9.568885e+09, 496 iterations, 0.01 seconds #> #> Nodes | Current Node | Objective Bounds | Work #> Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time #> #> 0 0 9.5689e+09 0 20 1.2215e+10 9.5689e+09 21.7% - 0s #> H 0 0 9.594148e+09 9.5689e+09 0.26% - 0s #> #> Explored 1 nodes (496 simplex iterations) in 0.09 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 2: 9.59415e+09 1.22153e+10 #> #> Optimal solution found (tolerance 1.00e-01) #> Best objective 9.594148369417e+09, best bound 9.568884517812e+09, gap 0.2633%
# print solution head(s1)
#> id cost status xloc yloc locked_in locked_out solution_1 #> 1 3 0.0 0 1116623 -4493479 FALSE FALSE 0 #> 2 30 752727.5 3 1110623 -4496943 FALSE TRUE 0 #> 3 56 3734907.5 0 1092623 -4500408 FALSE FALSE 1 #> 4 58 1695902.1 0 1116623 -4500408 FALSE FALSE 0 #> 5 84 3422025.6 0 1098623 -4503872 FALSE FALSE 0 #> 6 85 17890758.4 0 1110623 -4503872 FALSE FALSE 0
# create Marxan problem using data.frames that have been loaded into R ## load in planning unit data pu_path <- system.file("extdata/input/pu.dat", package = "prioritizr") pu_dat <- data.table::fread(pu_path, data.table = FALSE) head(pu_dat)
#> id cost status xloc yloc #> 1 3 0.0 0 1116623 -4493479 #> 2 30 752727.5 3 1110623 -4496943 #> 3 56 3734907.5 0 1092623 -4500408 #> 4 58 1695902.1 0 1116623 -4500408 #> 5 84 3422025.6 0 1098623 -4503872 #> 6 85 17890758.4 0 1110623 -4503872
## load in feature data spec_path <- system.file("extdata/input/spec.dat", package = "prioritizr") spec_dat <- data.table::fread(spec_path, data.table = FALSE) head(spec_dat)
#> id prop spf name #> 1 10 0.3 1 bird1 #> 2 11 0.3 1 nvis2 #> 3 12 0.3 1 nvis8 #> 4 13 0.3 1 nvis9 #> 5 14 0.3 1 nvis14 #> 6 15 0.3 1 nvis20
## load in planning unit vs feature data puvspr_path <- system.file("extdata/input/puvspr.dat", package = "prioritizr") puvspr_dat <- data.table::fread(puvspr_path, data.table = FALSE) head(puvspr_dat)
#> species pu amount #> 1 26 56 1203448.84 #> 2 26 58 451670.10 #> 3 26 84 680473.75 #> 4 26 85 97356.24 #> 5 26 86 78034.76 #> 6 26 111 4783274.17
## load in the boundary data bound_path <- system.file("extdata/input/bound.dat", package = "prioritizr") bound_dat <- data.table::fread(bound_path, data.table = FALSE) head(bound_dat)
#> id1 id2 boundary #> 1 3 3 16000 #> 2 3 30 4000 #> 3 3 58 4000 #> 4 30 30 12000 #> 5 30 58 4000 #> 6 30 85 4000
# create problem without the boundary data p2 <- marxan_problem(pu_dat, spec_dat, puvspr_dat)
# solve problem s2 <- solve(p2)
#> Optimize a model with 17 rows, 1751 columns and 4662 nonzeros #> Variable types: 0 continuous, 1751 integer (1751 binary) #> Coefficient statistics: #> Matrix range [5e-01, 4e+07] #> Objective range [4e+02, 4e+07] #> Bounds range [1e+00, 1e+00] #> RHS range [5e+07, 3e+09] #> Warning: Model contains large rhs #> Consider reformulating model or setting NumericFocus parameter #> to avoid numerical issues. #> Found heuristic solution: objective 1.219799e+10 #> Presolve removed 7 rows and 756 columns #> Presolve time: 0.01s #> Presolved: 10 rows, 995 columns, 1984 nonzeros #> Variable types: 0 continuous, 995 integer (992 binary) #> Presolve removed 0 rows and 2 columns #> Presolved: 10 rows, 993 columns, 1982 nonzeros #> #> #> Root relaxation: objective 9.564575e+09, 23 iterations, 0.00 seconds #> #> Nodes | Current Node | Objective Bounds | Work #> Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time #> #> 0 0 9.5646e+09 0 9 1.2198e+10 9.5646e+09 21.6% - 0s #> H 0 0 9.584380e+09 9.5646e+09 0.21% - 0s #> #> Explored 1 nodes (23 simplex iterations) in 0.01 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 2: 9.58438e+09 1.2198e+10 #> #> Optimal solution found (tolerance 1.00e-01) #> Best objective 9.584379906156e+09, best bound 9.564574962832e+09, gap 0.2066%
# print solution head(s2)
#> id cost status xloc yloc locked_in locked_out solution_1 #> 1 3 0.0 0 1116623 -4493479 FALSE FALSE 0 #> 2 30 752727.5 3 1110623 -4496943 FALSE TRUE 0 #> 3 56 3734907.5 0 1092623 -4500408 FALSE FALSE 1 #> 4 58 1695902.1 0 1116623 -4500408 FALSE FALSE 0 #> 5 84 3422025.6 0 1098623 -4503872 FALSE FALSE 0 #> 6 85 17890758.4 0 1110623 -4503872 FALSE FALSE 0
# create problem with the boundary data and a boundary length modifier # set to 5 p3 <- marxan_problem(pu_dat, spec_dat, puvspr_dat, bound_dat, 5)
# solve problem s3 <- solve(p3)
#> Optimize a model with 10075 rows, 6780 columns and 24778 nonzeros #> Variable types: 0 continuous, 6780 integer (6780 binary) #> Coefficient statistics: #> Matrix range [5e-01, 4e+07] #> Objective range [4e+04, 4e+07] #> Bounds range [1e+00, 1e+00] #> RHS range [5e+07, 3e+09] #> Warning: Model contains large rhs #> Consider reformulating model or setting NumericFocus parameter #> to avoid numerical issues. #> Found heuristic solution: objective 1.222917e+10 #> Presolve removed 2499 rows and 1614 columns #> Presolve time: 0.06s #> Presolved: 7576 rows, 5166 columns, 17226 nonzeros #> Variable types: 0 continuous, 5166 integer (5166 binary) #> Presolved: 7576 rows, 5166 columns, 17226 nonzeros #> #> #> Root relaxation: objective 9.586123e+09, 535 iterations, 0.02 seconds #> #> Nodes | Current Node | Objective Bounds | Work #> Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time #> #> 0 0 9.5861e+09 0 20 1.2229e+10 9.5861e+09 21.6% - 0s #> H 0 0 9.611012e+09 9.5861e+09 0.26% - 0s #> #> Explored 1 nodes (535 simplex iterations) in 0.09 seconds #> Thread count was 1 (of 4 available processors) #> #> Solution count 2: 9.61101e+09 1.22292e+10 #> #> Optimal solution found (tolerance 1.00e-01) #> Best objective 9.611012369417e+09, best bound 9.586122737736e+09, gap 0.2590%
# print solution head(s3)
#> id cost status xloc yloc locked_in locked_out solution_1 #> 1 3 0.0 0 1116623 -4493479 FALSE FALSE 0 #> 2 30 752727.5 3 1110623 -4496943 FALSE TRUE 0 #> 3 56 3734907.5 0 1092623 -4500408 FALSE FALSE 1 #> 4 58 1695902.1 0 1116623 -4500408 FALSE FALSE 0 #> 5 84 3422025.6 0 1098623 -4503872 FALSE FALSE 0 #> 6 85 17890758.4 0 1110623 -4503872 FALSE FALSE 0