Aid Defense Allocation Simulator
Model was written in NetLogo 6.4.0
•
Viewed 15 times
•
Downloaded 1 time
•
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
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
; IADS Missile Battery Simulation ; Based on Han, Lunday & Robbins (2016) globals [ city-size ; size of city patches initial-total-value ; store initial total value for comparison total-intercepted-missiles ; all intercepted missiles to count air defense effeciency attack-complete? ; stop flag for BehaviorSpace ] patches-own [ coverage-intensity ; for visualizing overlapping coverage damage-level ; for visualizing city damage ] breed [cities city] breed [batteries battery] breed [missiles missile] cities-own [ value ; city value/population protected? ; whether city is protected by battery ] batteries-own [ remaining-interceptors ; number of interceptors left ] missiles-own [ target ; targeted city intercepted? ; whether missile has been intercepted ] to setup clear-all setup-globals setup-cities setup-batteries set initial-total-value sum [value] of cities set total-intercepted-missiles 0 set attack-complete? false update-protection-status update-visualizations reset-ticks end to setup-globals set city-size 1 ask patches [ set coverage-intensity 0 set damage-level 0 ] end to setup-cities ; Create cities with random locations and values create-cities num-cities [ setxy random-xcor random-ycor set size city-size set shape "circle" set color blue set value 10 + random 90 ; Random value between 10-100 set protected? false set label (value) ] end to setup-batteries ask batteries [die] ; Clear any existing batteries (ifelse defender-strategy = "highest-value" [ ; Create a list of cities sorted by decreasing value let sorted-cities sort-on [(- value)] cities create-batteries num-batteries [ ; Place each battery at one of the highest-value cities let target-city item (who mod length sorted-cities) sorted-cities move-to target-city initialize-battery ] ] defender-strategy = "max-coverage" [ create-batteries num-batteries [ ; For each battery, find the position that maximizes the total value of covered cities let best-position max-one-of patches [ ; Sum the values of all cities within range of this position sum [value] of cities in-radius battery-range ] move-to best-position initialize-battery ; If batteries overlap too much, adjust position while maintaining good coverage while [any? other batteries in-radius (battery-range / 3)] [ let alternative-position max-one-of patches with [ not any? batteries in-radius (battery-range / 3) ][ sum [value] of cities in-radius battery-range ] if alternative-position != nobody [move-to alternative-position] ] ] ] defender-strategy = "choke-points" [ ; First identify strategic points that cover multiple cities let strategic-points patches with [ count cities in-radius battery-range >= 2 ; Points covering at least 2 cities ] create-batteries num-batteries [ ifelse any? strategic-points [ ; Find the strategic point that protects the highest total city value let best-point max-one-of strategic-points [ sum [value] of cities in-radius battery-range ] move-to best-point ; Remove this point and surrounding area from consideration ask strategic-points in-radius (battery-range / 2) [ set strategic-points strategic-points with [self != myself] ] ][ ; If no good strategic points left, fall back to highest-value strategy let target-city max-one-of cities [value] move-to target-city ] initialize-battery ] ] defender-strategy = "distributed" [ create-batteries num-batteries [ ; First try to cover uncovered cities let uncovered-cities cities with [ not any? batteries in-radius battery-range ] ifelse any? uncovered-cities [ ; Instead of checking each uncovered city, select from top valuable ones let target-city max-one-of (up-to-n-of 5 uncovered-cities) [value] move-to target-city ][ ; Instead of checking all patches, only check near cities let potential-positions patches with [ any? cities in-radius battery-range and not any? batteries in-radius (battery-range / 2) ] ifelse any? potential-positions [ let target-position max-one-of (up-to-n-of 10 potential-positions) [ count cities in-radius battery-range with [ count batteries in-radius battery-range < 2 ] ] move-to target-position ][ ; If no good positions found, just move to highest value city move-to max-one-of cities [value] ] ] initialize-battery ] ] defender-strategy = "mixed" [ ; Split total batteries among strategies let remaining-batteries num-batteries let base-strategies ["highest-value" "max-coverage" "choke-points" "distributed"] foreach base-strategies [strategy -> if remaining-batteries > 0 [ ; Allocate some batteries to this strategy let strategy-batteries ceiling (remaining-batteries / (length base-strategies)) set remaining-batteries remaining-batteries - strategy-batteries if strategy = "highest-value" [ let sorted-cities sort-on [(- value)] cities create-batteries strategy-batteries [ let target-city item (who mod length sorted-cities) sorted-cities move-to target-city initialize-battery ] ] if strategy = "max-coverage" [ create-batteries strategy-batteries [ let best-position max-one-of patches [ sum [value] of cities in-radius battery-range ] move-to best-position initialize-battery while [any? other batteries in-radius (battery-range / 3)] [ let alternative-position max-one-of patches with [ not any? batteries in-radius (battery-range / 3) ][ sum [value] of cities in-radius battery-range ] if alternative-position != nobody [move-to alternative-position] ] ] ] if strategy = "choke-points" [ let strategic-points patches with [ count cities in-radius battery-range >= 2 ] create-batteries strategy-batteries [ ifelse any? strategic-points [ let best-point max-one-of strategic-points [ sum [value] of cities in-radius battery-range ] move-to best-point ask strategic-points in-radius (battery-range / 2) [ set strategic-points strategic-points with [self != myself] ] ][ let target-city max-one-of cities [value] move-to target-city ] initialize-battery ] ] if strategy = "distributed" [ create-batteries strategy-batteries [ let uncovered-cities cities with [ not any? batteries in-radius battery-range ] ifelse any? uncovered-cities [ let target-city max-one-of uncovered-cities [value] move-to target-city ][ let target-position max-one-of patches [ count cities in-radius battery-range with [ count batteries in-radius battery-range < 2 ] ] move-to target-position ] initialize-battery ] ] ] ] ] ) end ; Helper procedure to set up individual battery properties to initialize-battery set shape "triangle" set color red set size 2 set remaining-interceptors num-interceptors end to update-protection-status ; Reset protection status for all cities ask cities [ set protected? false ] ; Mark cities as protected if they are within range of any battery with interceptors ask cities [ let city-batteries batteries in-radius battery-range if any? city-batteries [ if sum [remaining-interceptors] of city-batteries > 0 [ set protected? true set color green ] ] ] end to go if not attack-complete? [ ; Only launch attack if not already done launch-attack while [any? missiles] [ move-missiles intercept-missiles destroy-cities update-protection-status update-visualizations update-plots1 tick ] set attack-complete? true ; Set flag when attack is done ] end to launch-attack (ifelse attacker-strategy = "highest-value" [ ; Target the most valuable cities first let high-value-targets sort-on [(- value)] cities let missiles-remaining num-missiles foreach high-value-targets [target1 -> ; Stop if we run out of missiles if missiles-remaining > 0 [ create-missiles 1 [ setup-missile target1 set missiles-remaining missiles-remaining - 1 ] ] ] ] attacker-strategy = "spread-attack" [ ; Distribute missiles evenly across as many cities as possible let num-targets min list num-missiles count cities let target-cities n-of num-targets cities foreach sort target-cities [target1 -> create-missiles 1 [ setup-missile target1 ] ] ] attacker-strategy = "minimal-breach" [ ; Find a valuable target and concentrate enough missiles to overwhelm its defenses let target1 max-one-of cities [ value * (1 + count batteries in-radius battery-range) ; Consider both value and defense ] if target1 != nobody [ ; Calculate missiles needed to overwhelm defenses let defending-batteries batteries with [distance target1 <= battery-range] let total-interceptors sum [remaining-interceptors] of defending-batteries let missiles-needed min list (total-interceptors + 1) num-missiles ; Launch concentrated attack repeat missiles-needed [ create-missiles 1 [ setup-missile target1 ] ] ] ] attacker-strategy = "concentrated" [ let primary-target max-one-of cities [value] if primary-target != nobody [ let nearby-cities cities with [ distance primary-target <= battery-range / 2 and self != primary-target ] ; Create list of all potential targets let target-list (list primary-target) if any? nearby-cities [ set target-list sentence target-list (sort-on [(- value)] nearby-cities) ] ; Distribute missiles among targets let missiles-per-target ceiling (num-missiles / length target-list) foreach target-list [target-city -> let missiles-to-create min list missiles-per-target (num-missiles - count missiles) repeat missiles-to-create [ create-missiles 1 [ setup-missile target-city ] ] ] ] ] attacker-strategy = "mixed" [ let strategies ["highest-value" "spread-attack" "minimal-breach" "concentrated"] let remaining-missiles num-missiles ; Randomly assign missiles to different strategies while [remaining-missiles > 0] [ let current-strategy one-of strategies let missiles-for-strategy 1 + random (min list remaining-missiles (num-missiles / 2)) set remaining-missiles remaining-missiles - missiles-for-strategy ; Apply the chosen strategy for this subset of missiles if current-strategy = "highest-value" [ let high-value-targets sort-on [(- value)] cities foreach high-value-targets [target1 -> if missiles-for-strategy > 0 [ create-missiles 1 [ setup-missile target1 set missiles-for-strategy missiles-for-strategy - 1 ] ] ] ] if current-strategy = "spread-attack" [ let num-targets min list missiles-for-strategy count cities let target-cities n-of num-targets cities foreach sort target-cities [target1 -> if missiles-for-strategy > 0 [ create-missiles 1 [ setup-missile target1 set missiles-for-strategy missiles-for-strategy - 1 ] ] ] ] if current-strategy = "minimal-breach" [ let target1 max-one-of cities [ value * (1 + count batteries in-radius battery-range) ] if target1 != nobody [ let defending-batteries batteries with [distance target1 <= battery-range] let total-interceptors sum [remaining-interceptors] of defending-batteries let missiles-needed min list (min list (total-interceptors + 1) missiles-for-strategy) missiles-for-strategy repeat missiles-needed [ create-missiles 1 [ setup-missile target1 ] ] set missiles-for-strategy missiles-for-strategy - missiles-needed ] ] if current-strategy = "concentrated" [ let primary-target max-one-of cities [value] if primary-target != nobody [ let nearby-cities cities with [ distance primary-target <= battery-range / 2 and self != primary-target ] let target-list (list primary-target) if any? nearby-cities [ set target-list sentence target-list (sort-on [(- value)] nearby-cities) ] let missiles-per-target ceiling (missiles-for-strategy / length target-list) foreach target-list [target-city -> let missiles-to-create min list missiles-per-target missiles-for-strategy repeat missiles-to-create [ create-missiles 1 [ setup-missile target-city ] ] set missiles-for-strategy missiles-for-strategy - missiles-to-create ] ] ] ] ] ) end ; Helper procedure for missile setup to setup-missile [target-city] setxy random-xcor max-pycor set target target-city ifelse random 2 = 0 [ setxy random-xcor max-pycor ] ; top of screen [ setxy max-pxcor random-ycor ] ; right side set target target-city set color orange set size 1 set shape "arrow" set intercepted? false set xcor xcor + random 10 - 5 ; Add some randomness to launch position end to move-missiles ask missiles [ face target forward 1 if show-damage? [ ask patches in-radius 0.5 [ set pcolor orange - 2 ] ] ] end to intercept-missiles ask batteries [ let nearby-missiles missiles in-radius battery-range foreach sort nearby-missiles [ m -> if remaining-interceptors > 0 and not [intercepted?] of m [ if random-float 1 < intercept-prob [ ask m [ set intercepted? true set total-intercepted-missiles total-intercepted-missiles + 1 ; Track successful interceptions ; Create explosion effect ask patches in-radius 1 [ set pcolor yellow ] die ] ] set remaining-interceptors remaining-interceptors - 1 ] ] ] end to destroy-cities ask missiles [ if distance target < 1 [ ; target is single turtle not agentset ask target [ set color red set protected? false set damage-level damage-level + 1 ask patches in-radius (city-size * 2) [ set pcolor red set damage-level damage-level + 1 ] ] die ] ] end to update-visualizations ; Clear previous visualizations ask patches [ set coverage-intensity 0 if not show-damage? [set pcolor black] ] ; Update battery coverage visualization with smoother gradients if show-coverage? [ ask batteries [ let curr-battery self ask patches in-radius battery-range [ let dist distance curr-battery let intensity (1 - (dist / battery-range)) * 2 set coverage-intensity coverage-intensity + intensity set pcolor scale-color blue coverage-intensity 2 0 ] ] ] ; Update damage visualization with smoother gradients if show-damage? [ ask cities [ ifelse protected? [ set color green ][ ifelse damage-level > 0 [ set color scale-color red damage-level 5 0 set label (word "V:" value " D:" damage-level) ][ set color blue ] ] ; Show damage radius with smooth gradient if damage-level > 0 [ ask patches in-radius (city-size * 3) [ let dist distance myself let dmg-intensity (1 - (dist / (city-size * 3))) * damage-level if dmg-intensity > 0 [ set pcolor scale-color red dmg-intensity 5 0 ] ] ] ] ] ; Draw range indicators for batteries with smooth edges ask batteries [ ; Display remaining interceptors set label (word remaining-interceptors " IM") set label-color white ] ; Update display for missiles and effects ask missiles [ set color orange ] end ; Basic value reporters to-report total-city-value report sum [ifelse-value (damage-level = 0) [value] [0]] of cities end to-report protected-value report sum [ifelse-value (protected?) [value] [0]] of cities end to-report protection-percentage ifelse total-city-value > 0 [ report (protected-value / total-city-value) * 100 ] [ report 0 ] end ; Strategic effectiveness reporters to-report city-value-survival-ratio ifelse initial-total-value > 0 [ report precision ((total-city-value / initial-total-value) * 100) 2 ] [ report 0 ] end to-report defense-efficiency ; Measures how efficiently interceptors are being used let total-initial-interceptors (num-batteries * num-interceptors) let used-interceptors total-initial-interceptors - sum [remaining-interceptors] of batteries ifelse used-interceptors > 0 [ report precision ((total-intercepted-missiles / used-interceptors) * 100) 2 ] [ report 0 ] end to-report defense-coverage-ratio ; Measures what percentage of total city value is under SAM coverage let total-value sum [value] of cities let covered-value sum [value] of cities with [any? batteries in-radius battery-range] ifelse total-value > 0 [ report precision ( (covered-value / total-value) * 100) 2 ] [ report 0 ] end to-report value-loss-percentage ; Measures percentage of total value lost to successful attacks ifelse initial-total-value > 0 [ report ((initial-total-value - total-city-value) / initial-total-value) * 100 ] [ report 0 ] end to-report intercept-success-rate ; Measures percentage of missiles successfully intercepted let total-launched count missiles + count missiles with [intercepted?] ifelse total-launched > 0 [ report (count missiles with [intercepted?] / total-launched) * 100 ] [ report 0 ] end to-report defense-saturation ; Measures how close batteries are to being overwhelmed let avg-interceptors mean [remaining-interceptors] of batteries report (avg-interceptors / 20) * 100 ; 20 is initial interceptor count end to-report attack-concentration ; Measures how concentrated the attack is let targeted-cities length remove-duplicates [target] of missiles ifelse count missiles > 0 [ report (targeted-cities / count missiles) * 100 ] [ report 0 ] end to-report high-value-targeting-ratio ; Measures focus on high-value targets let top-value max [value] of cities let targeted-value mean [value] of cities with [any? missiles with [target = myself]] ifelse top-value > 0 [ report (targeted-value / top-value) * 100 ] [ report 0 ] end to update-plots1 set-current-plot "Total Cities Value" set-current-plot-pen "Total" plot total-city-value set-current-plot-pen "Protected" plot protected-value set-current-plot "Protection Metrics" set-current-plot-pen "Protection %" plot protection-percentage set-current-plot-pen "Value Loss %" plot value-loss-percentage set-current-plot "Battle Status" set-current-plot-pen "Active Missiles" plot count missiles set-current-plot-pen "Interceptors Left" plot sum [remaining-interceptors] of batteries set-current-plot-pen "Success Rate" plot intercept-success-rate end
There are 2 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Aid Defense Allocation Simulator.png | preview | Preview for 'Aid Defense Allocation Simulator' | 13 days ago, by Artem Serdyuk | Download |
This model does not have any ancestors.
This model does not have any descendants.