New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MarZone type problems #14

Closed
ricschuster opened this Issue Apr 11, 2017 · 7 comments

Comments

Projects
None yet
3 participants
@ricschuster
Copy link
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.

@jeffreyhanson

This comment has been minimized.

Copy link
Contributor

jeffreyhanson commented Apr 12, 2017

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?

@mstrimas

This comment has been minimized.

Copy link
Contributor

mstrimas commented Apr 12, 2017

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.

@ricschuster

This comment has been minimized.

Copy link
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?

@jeffreyhanson

This comment has been minimized.

Copy link
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.

@jeffreyhanson

This comment has been minimized.

Copy link
Contributor

jeffreyhanson commented Mar 5, 2018

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 ([✔️])
@ricschuster

This comment has been minimized.

Copy link
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.

@jeffreyhanson

This comment has been minimized.

Copy link
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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment