# MarZone type problems #14

Closed
opened this Issue Apr 11, 2017 · 7 comments

Projects
None yet
3 participants
Member

### ricschuster commented Apr 11, 2017

 As I never work with MarZone type problems, I hadn't even thought about needing to implement them in `prioritizr`. @jeffreyhanson or @mstrimas have you thought about the implementation of this already? If not, we could probably build off code that @mattwatts produced.
Contributor

### jeffreyhanson commented Apr 12, 2017 • edited

 Yeah, I've been thinking about this for a while. I haven't used MarZone, but it seems to be pretty commonly used, so it would be great to have zone-style functionality in the package. From what I understand, Marxan-style problems are basically MarZone with 1 zone. The main issues I see standing in the way of implementing multiple zones are: Generalising all objective, constraint, target and penalty functions to accommodate n zones. This gets tricky for constraints dealing with connectivity (eg. BLM). How is the boundary treated if unit 1 is in zone 1 and unit 2 is in zone 2? Does each zone get its own BLM? Internal data structures. At the moment, the package uses 2-dimensional `rij_matrix` (`Matrix::dgCMatrix`) objects to store the amount of each feature in each planning unit. I chose to represent the data using this class because it has lots of optimised functions in R and the objects can easily be interacted with in C++ using the RcppArmadillo package. From what I understand, we would have to use 3-dimensional `rijz_matrix` objects to store the amount of each feature in planning unit for each zone. This means we would probably have to find other matrix libraries for handling matrices, since the `Matrix` and `RcppArmadillo` packages don't implement sparse 3-d matrices as far as I know. Or, we just implement it as a list of `rij_matrix` objects to represent the third zonal dimension. We would also have to come up with a consistent interface for building problems with 1 zone and n zones. To allow users to specify multiple zone problems, we could allow users to input `RasterStack` for `x` in `problem` and a list of `RasterStack` objects for `features`. ``````problem(x = RasterStack, features = list(RasterStack, RasterStack)) `````` For `Spatial*DataFrame` objects, use a list of `RasterStack` objects for `features` and a vector of length >1 for `cost_column`. ``````problem(x = SpatialPolygonsDataFrame, features = list(RasterStack, RasterStack), cost_column = c("zone1", "zone2", "zone3")) `````` We could do one better and create a `zones` class that represents a `list` of `RasterStack` objects but runs sanity checks to ensure they all share the same spatial properties (ie. coordinate reference system, dimensions, resolution, etc). So users could do this: ``````problem(x = RasterStack, features = zones(RasterStack, RasterStack)) `````` What do you think? Can you think of any more issues?
Contributor

### mstrimas commented Apr 12, 2017 • edited

 I'm in the same boat as both of you, I haven't used MarZone but did think about implementing it in my original package. In the end I didn't pursue it because I wasn't sure of the best interface for specifying these types of problems, and I didn't have the time to figure it out. Seems to me it would be cool to add this functionality, but maybe it's best to get the 1-zone version released and leave MarZone for a later version. Also, I think it would be important to ensure adding MarZone functionality didn't complicate the interface for users just wanting to solve Marxan-type problems. Looks the approach Jeff suggested, i.e. allowing arguments to `problem` to be lists/vectors, would accomplish this nicely.
Member

### ricschuster commented Apr 12, 2017

 Jeff, I think you covered the important issues. As for matrices, I think I would go with a list of `rij matrices` and avoid `rijz matrices`. I'm pretty tied up until mid July, so wont have much time to dedicate to this. That being said, I just got a script that Matt Watts wrote, that implements a MarZone type problem with Gurobi, that I could share with you if useful. Matt, I agree with you re: releasing the 1-zone version first and implementing MarZone in a later version. I'm also making ridiculously slow progress on the Shiny interface, so maybe once Nina is done with the documentation bits she is working on we can release prioritizr to CRAN and supply those additional bits over time?
Contributor

### jeffreyhanson commented Apr 12, 2017

 Yeah, that would be great if you could send a a script that implements MarZone - thanks! Yeah, I agree with releasing the 1-zone version after Nina's added the documentation.

Contributor

### jeffreyhanson commented Mar 5, 2018 • edited

I thought it might be a good idea to document progress on adding zones functionality to prioritizr (in the zones branch). That way, I can keep track of what needs to be done because I'm starting to find it hard to remember everything. Additionally, the people (i.e. @lizlaw and @ricschuster?) interested in trying out the developmental version of prioritizr with zones functionality can see what has been updated and what still remains.

To help make this list comprehensive, I've provided a list below with all the functions/classes/items that need updating for the entire code-based to be compatible with problems associated with multiple zones. Each item has three elements (each represented by an icon): code (💻), unit tests (🔧), and documentation (📘). I will place a check mark next to an item if I think I have completed it. When all of the items have been addressed, I can begin the process of merging this into the master branch.

Please let me know if you can think of any more items that should be added to the list, and if you can think of any further enhancements for items marked as complete.

### Internal functions and classes 🎉

• ConservationProblem ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• OptimimizationProblem ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• OPTIMIZATIONPROBLEM (C++ class) ([✔️] 💻; [✔️] 🔧)
• add_rij_data (C++) ([✔️] 💻; [✔️] 🔧)
• add_zones_constraints (C++) ([✔️] 💻; [✔️] 🔧)

### Core functions 🎉

• problem ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• compile ([✔️] 💻; [✔️] 🔧)
• solve ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Targets 🎉

• add_relative_targets ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_absolute_targets ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_loglinear_targets ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_manual_targets ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Decisions 🎉

• add_binary_decisions ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_proportion_decisions ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_semicontinuous_decisions ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Objectives 🎉

• add_min_set_objective ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_max_cover_objective ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_max_utility_objective ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_max_features_objective ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_max_phylo_objective ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Constraints 🎉

• add_locked_in_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_locked_out_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_manual_locked_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_connected_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_corridor_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_neighbor_constraints ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Penalties 🎉

• add_boundary_penalties ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_connectivity_penalties ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Portfolios 🎉

• add_shuffle_portfolio ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_cuts_portfolio ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Miscellaneous functions 🎉

• zones ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• binary_stack ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• category_layer ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• category_vector ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• add_feature_weights ([✔️] 💻; [✔️] 🔧; [✔️] 📘)
• marxan_problem ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Data 🎉

• built-in data objects ([✔️] 💻; [✔️] 🔧; [✔️] 📘)

### Vignettes 🎉

• tutorial on creating and solving problems with multiple zones ([✔️])
Member

### ricschuster commented Mar 5, 2018

 @jeffreyhanson this is a great idea and I can't think of anything that needs to be added at the moment.
Contributor

### jeffreyhanson commented Apr 24, 2018

 Since I've addressed the items on the list, I've merged the zones branch with the master branch (5761891)