Congressional Redistricting
Model was written in NetLogo 6.1.1
•
Viewed 385 times
•
Downloaded 45 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Click to Run Model
patches-own [patch_pop district state counted] to show_population_density_map ; clear world and import population density map ; map should be grayscale of population ca import-pcolors file-name ; initialize districts based on highest-population patches let num_districts 0 ask patches [ set patch_pop 100 * (10 - pcolor) set counted False ] ; determine points of highest population from density map let peak_pop_points [] ask patches [ if max [patch_pop] of neighbors < patch_pop [ set peak_pop_points lput self peak_pop_points ] ] ; sort list by patch population in descending order set peak_pop_points sort-by [ [patch1 patch2] -> [patch_pop] of patch1 > [patch_pop] of patch2 ] peak_pop_points ; determine district centers, ensuring that neither the list of points nor the user-set max-districts is exceeded while [num_districts < length peak_pop_points and num_districts < max-districts] [ ask item num_districts peak_pop_points [ set num_districts num_districts + 1 set district num_districts set state "edge" set pcolor yellow ] ] end to generate_districts ; generate imported map of population density show_population_density_map let num_districts max ([district] of patches) ; expand districts to fill entire map while [any? patches with [state = 0]] [ wait .1 ask patches with [state = "edge"] [ if any? neighbors4 with [state = 0] [ ask one-of neighbors4 with [state = 0] [ set district [district] of myself set state "edge" set pcolor yellow ] ] determine-state ] ] ; adjust districts to equalize population let total_pop sum ([patch_pop] of patches) let max_difference .05 ; districts can only be +/- this percent let done False while [not done] [ wait .001 ; cycle through districts let x 1 while [x <= num_districts] [ let district_pop sum ([patch_pop] of patches with [district = x]) ; determine patch asking behavior depending on specified adjust-mode let selection [] if adjust-mode = "smooth" [ set selection patches with [state = "edge" and district = x] ] if adjust-mode = "jagged" [ set selection one-of patches with [state = "edge" and district = x] ] ; increase district size if population is too low if district_pop < total_pop / num_districts * (1 - max_difference) [ ask selection [ let y neighbors4 with [state = "edge" and district != x] if any? y [ ask one-of y [ change-to x ask neighbors4 [determine-state] determine-state ] ] ] ] ; decrease district size if population is too high if district_pop > total_pop / num_districts * (1 + max_difference) [ ask selection [ change-to [district] of one-of neighbors4 ask neighbors4 [determine-state] determine-state ] ] ; increment to next district set x x + 1 ] ; check if districts are within population bounds ; i.e. if they have similar populations set done True set x 1 while [x <= num_districts] [ let district_pop sum ([patch_pop] of patches with [district = x]) if district_pop < total_pop / num_districts * (1 - max_difference) or district_pop > total_pop / num_districts * (1 + max_difference) [ set done False ] ; increment to next district set x x + 1 ] ] ; show districts by color ask patches [ set pcolor district * 20 - 1 - patch_pop / 120 ] ; output district sizes let x 1 output-print "Districts:" while [x <= num_districts] [ let district_pop sum ([patch_pop] of patches with [district = x]) output-print (word "D" x " - " district_pop " - " (int(district_pop / total_pop * 10000) / 100) "%") set x x + 1 ] output-print "Total Population:" output-print total_pop end to determine-state if-else any? neighbors4 with [district != [district] of myself] [ set state "edge" set pcolor yellow ] [ set state "done" set pcolor 9 - patch_pop / 120 ] end ; have patch change to "new_district" ; checks if change keeps district continuous to change-to [new_district] let original_district district set district new_district let remain_continuous True ask self [set remain_continuous check-continuous] if not remain_continuous [ set district original_district ] end ; checks if the district(s) of the patches affected are continuous ; i.e. all patches in the district are connected to-report check-continuous let report_bool True let affected_patches (patch-set self (neighbors4 with [district != [district] of myself])) ask affected_patches [ ; define district and patches in district let district_name district let district_patches patches with [district = district_name] ; calculate district patches that are continuous with current patch ask district_patches [set counted False] let continuous_size 0 ask one-of district_patches [ set counted True set continuous_size count-continuous-patches ] ; calculate total patches in district let district_size count district_patches ; if the previous 2 calculations don't match, the district is not continuous if district_size != continuous_size [set report_bool False stop] ] report report_bool end ; recursive function that calculates the number of connected patches within district of patch to-report count-continuous-patches let district_size 1 let x neighbors4 with [not counted and district = [district] of myself] if any? x [ ask x [set counted True] ask x [set district_size district_size + count-continuous-patches] ] report district_size end
There are 7 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Congressional Redistricting.png | preview | Example output of model. | over 4 years ago, by Luke Elissiry | Download |
state 1.png | png | Example 1 of population density map. | over 4 years ago, by Luke Elissiry | Download |
state 2.png | png | Example 2 of population density map. | over 4 years ago, by Luke Elissiry | Download |
This model does not have any ancestors.
This model does not have any descendants.
Abe Barranca
import-pcolors error (Question)
When I try to run the model with either the "Generate" or "District" buttons I get the error: "import-pcolors: The following file is not in a supported image format:" I took a look at the file, which appears to be a text file whereas Netlogo expects an image file. Can you advise how to amend? I am hoping to adapt your code (credited of course!) into a model I'm constructing that includes randomly generated districts.
Posted over 4 years ago
Luke Elissiry
Regarding importing colors from file
Hi Abe, Thanks for taking a look at this model! It has been quite a while since I last worked on it, and the code needed an update because newer versions of Netlogo had altered the import-pcolors feature to only accept images. The image files ("state 1" and "state 2") are now in the "Files" tab, and I can send you the model I used to generate the images if desired. Make sure to put the images in the same folder as the model. I also reworked the code to make it more readable and improved a lot of the mechanics so that districts remain continuous when redistricting. The largest assumption this model makes for districting is to base districts around the patches of highest population (as indicated by a darker color). This can be easily modified to make random if desired. My rationale behind this choice was that areas of higher population density (i.e. cities and towns) have similar political interests, and therefore should be represented as a unit, rather than being split up into multiple districts. If you have any further questions, please feel free to leave another comment or contact me at ljelissiry[at]gmail[dot]com, or leave a comment. Also, please send me your model if you pursue one!
Posted over 4 years ago
Abe Barranca
Following Up
Hey Luke, I figured out the source of the error, which was entirely technical (but the info may be of use to anyone else who is interested in adapting your model). The zip file download when expanded (at least on a Mac) produces the "state 1" and "state 2" png files in some kind of corrupted format. Downloading those files directly solves the error I described in my previous comment. Best, Abe
Posted about 4 years ago