Ukraine's Higher Education Model
Model was written in NetLogo 6.4.0
•
Viewed 30 times
•
Downloaded 0 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
Please start the discussion about this model!
(You'll first need to log in.)
Click to Run Model
;extensions [csv] globals [ frontline-xcor ; X coordinate of the frontline city-centers ; List of city center patches war-intensity ; Overall war intensity affecting infrastructure air-raid-probability ; Probability of air raid per tick missile-attack-recovery-counter teacher-batch-size ; Size of teacjer batches (currently 20) student-batch-size ; Size of student batches (currently 100) student-total-attempts ; Total attempts a student can make across all tiers student-attempts-per-tier ; Maximum attempts per university tier air-raid? last-air-raid-tick ; When the last air raid occurred air-raid-recovery-counter ; Counter for recovery period air-raid-recovery-time ; how many ticks recovery takes ; Teacher tracking metrics teachers-initially-assigned ; Count of successful initial assignments teachers-quit ; Count of teachers who quit due to stress teachers-fired ; Count of teachers laid off due to capacity/performance teachers-rehired ; Count of unemployed teachers who found new positions ] breed [students student] breed [teachers teacher] breed [universities university] breed [cities city] patches-own [ local-war-intensity ; Local war intensity for this area ] students-own [ male? ; Gender (relevant for conscription) age ; Student's age propensity-to-study ; Natural desire to study regardless of circumstances (0-100) desire-to-study ; Motivation to study (0-100) studying? ; Whether actively studying abroad? ; Whether studying abroad program-type ; "bachelor", "master" or "phd" my-university ; The university this student attends previous-university last-application-attempt ; Tick when last attempted to enter remaining-attempts ; How many attempts they still have academic-skill ; Student's academic ability (0-100) baseline-academic-skill ; Natural academic ability before stress effects current-academic-performance ; Actual current performance (0-100) affected by stress conscription-fear ; How much they fear conscription (0-100) stress-level ; Individual stress level (0-100) stress-resilience ; How well they handle stress (0-100) max-stress-threshold min-stress-for-return ] teachers-own [ my-university ; Current university unemployed? ; Whether currently looking for work teaching-skill ; Individual teaching ability (0-100) baseline-teaching-skill stress-level ; Individual stress level (0-100) adaptation-rate ; How quickly they adapt to new stress caused by warfare of regulations ] universities-own [ ;; Capacity location-type ; "home-city" or "big-city" capacity ; How many students can enroll enrolled-students-count ; Current number of enrolled students current-teachers ; Current number of teachers teachers-needed ; How many teachers needed based on capacity ;; Quality quality ; Education quality rating (0-100) entry-barrier ; How difficult it is to enter (0-100) distance-from-front ; Distance from the front line local-risk ; Local war risk based on location infrastructure-damage ; Damage level from attacks (0-100) faculty-stress-level ; Stress level of faculty at this university (0-100) bureaucratic-load ; Bureaucratic load at this university (0-100) online-mode? ; Whether currently teaching online is-merged? ; Whether university has been merged relocated? ] cities-own [ city-type ; "big-city" or "home-city" ] to setup clear-all setup-globals setup-cities setup-universities setup-patches setup-teachers ask teachers [assign-teacher-to-university] set teachers-initially-assigned teachers-rehired set teachers-rehired 0 initialize-university-quality ; Initializes quality based on teachers setup-students reset-ticks end to setup-globals set air-raid-probability 0.2 ; once per 5 days set war-intensity 0 set frontline-xcor max-pxcor ; Start frontline in right side of map set student-batch-size 100 set teacher-batch-size 20 ; Each teacher agent represents 20 actual teachers set student-total-attempts 15 set student-attempts-per-tier 3 set air-raid? false set last-air-raid-tick 0 set air-raid-recovery-counter 0 set air-raid-recovery-time 15; how many ticks recovery takes set teachers-initially-assigned 0 set teachers-quit 0 set teachers-fired 0 set teachers-rehired 0 end to setup-cities ; Create 20-24 cities let num-cities 20 + random 4 let num-big-cities round (num-cities * 0.3) ; 30% are big cities ; Create big cities first (they need more space) create-cities num-big-cities [ setxy random-xcor random-ycor while [any? other cities in-radius 10] [ setxy random-xcor random-ycor ] set city-type "big-city" set color red set shape "circle" set size 2 ] ; Create remaining home cities create-cities (num-cities - num-big-cities) [ setxy random-xcor random-ycor while [any? other cities in-radius 7] [ setxy random-xcor random-ycor ] set city-type "home-city" set color cyan set shape "circle" set size 1.5 ] end to color-patch ; Base color from war intensity let base-color scale-color red local-war-intensity 100 0 set pcolor base-color end to setup-patches ask patches [ ; Initialize local war intensity based on distance from frontline set local-war-intensity 0 color-patch ] end to go update-war-intensity check-critical-events batch-update-universities batch-update-students batch-update-teachers tick end to setup-universities create-universities number-of-universities [ ; First determine if this will be a big-city or home-city university set location-type one-of ["big-city" "home-city"] set relocated? false ; Find appropriate city type to move to let target-cities cities with [city-type = [location-type] of myself] ifelse any? target-cities [ move-to one-of target-cities right random 360 forward random 3 ][ ; Fallback if no matching cities available move-to one-of cities set location-type [city-type] of one-of cities-here ; Adapt to the city type we landed in ] ; Set initial properties based on location type ifelse location-type = "big-city" [ set capacity round (5000 + random 15000) set quality 50 + random 30 ; Initial baseline quality for big cities ][ set capacity round (1000 + random 4000) set quality 30 + random 30 ; Initial baseline quality for smaller cities ] set entry-barrier max list 20 min list 95 (quality * 0.8 + random 20) set enrolled-students-count 0 set infrastructure-damage 0 set is-merged? false set online-mode? false set faculty-stress-level 0 set bureaucratic-load 30 + random 10 set current-teachers 0 set teachers-needed ceiling (capacity / 10) set shape "pentagon" set size 1.5 + log (capacity / 10) 10 update-university-appearance ] end to initialize-university-quality ask universities [ let my-teachers teachers with [my-university = myself] ; Keep the existing baseline but adjust based on teachers ifelse any? my-teachers [ let avg-teaching-skill mean [teaching-skill] of my-teachers ; Teaching skill influences up to ±20 points of quality let teacher-quality-impact (avg-teaching-skill - 50) * 0.4 set quality max list 0 min list 100 (quality + teacher-quality-impact) ][set quality max list 0 (quality - 10)] ; Update entry barrier based on new quality set entry-barrier max list 20 min list 95 (quality * 0.8 + random 20) update-university-appearance ] end to update-university-appearance ; University appearance set size 1.5 + log ifelse-value (enrolled-students-count > 0) [enrolled-students-count][1] 10 ifelse relocated? [ set color turquoise + 2 ][ set color ifelse-value (infrastructure-damage > 20) [ red ] [ ifelse-value is-merged? [ violet ] [ blue ] ] ] set label-color black set label "" set label enrolled-students-count end to update-war-intensity ; Update global war intensity using sine wave let time-factor ticks * 2 ; Adjust frequency set war-intensity 40 * sin time-factor + 50 ; Oscillate between 10% and 90% ; Update local war intensities and university risks ask patches [ let distance-effect abs (pxcor - frontline-xcor) set local-war-intensity max (list 0 (war-intensity * (1 - (distance-effect / (max-pxcor + 1))))) ; Update local-risk for any universities on this patch ask universities-here [set local-risk local-war-intensity] color-patch ] end to check-critical-events set air-raid? false ; Base probability calculation let raid-chance (war-intensity * air-raid-intensity) / 2000 ; Increase chance if no raids for a while let time-since-last-raid ticks - last-air-raid-tick if time-since-last-raid > 20 [ set raid-chance raid-chance * 2 ] ; Check for air raid if random-float 1 < raid-chance [ run-air-raid set last-air-raid-tick ticks set air-raid-recovery-counter air-raid-recovery-time ] if air-raid-recovery-counter > 0 [ set air-raid-recovery-counter air-raid-recovery-counter - 1 ; Change raid-marked patches to recovery color ask patches with [pcolor = red] [set pcolor orange] ] ; Clear recovery patches when done if air-raid-recovery-counter = 0 [ ask patches with [pcolor = orange] [set pcolor black] ] end to run-air-raid set air-raid? true set last-air-raid-tick ticks set air-raid-recovery-counter 15 ; Set recovery period ; Force all universities to go online during air raid ask universities [ set online-mode? true if random 100 < (10 * (air-raid-intensity / 5)) [ ; Scale hit chance by intensity set color red let impact 10 + random 20 set infrastructure-damage min list 100 (infrastructure-damage + impact) ask patches in-radius 3 [ if not any? universities-here [set pcolor red] ] ] ] ask students with [not abroad?] [ let stress-increase (25 + random 25) * (air-raid-intensity / 5) ; Up to 50 points at max intensity set stress-level min list 100 (stress-level + stress-increase) ] ask teachers [ let stress-increase (30 + random 30) * (air-raid-intensity / 5) ; Up to 60 points at max intensity set stress-level min list 100 (stress-level + stress-increase) ] end to handle-air-raid-recovery set air-raid-recovery-counter air-raid-recovery-counter - 1 ask universities [ if infrastructure-damage > 0 [ ; Scale recovery rate based on damage level let recovery-rate 0.5 + (infrastructure-damage / 25) ; Faster recovery for more damage ; Slower recovery under high war intensity if war-intensity > 50 [ set recovery-rate recovery-rate * 0.7 ] ; Apply recovery set infrastructure-damage max list 0 (infrastructure-damage - recovery-rate) ] ] ; Return from online mode if safe enough and not during active air raid if not air-raid? and infrastructure-damage < 40 and local-risk < 40 [ set online-mode? false ] ; Reset visual effects when recovery complete if air-raid-recovery-counter <= 0 and color = red [ update-university-appearance ] end to batch-update-universities ask universities [ if (enrolled-students-count <= 0) and (ticks > 10) [ ; Make sure to properly handle any teachers handle-university-closure self die ] if ((infrastructure-damage >= 70 or local-risk >= 80) and enrolled-students-count > 0) [relocate] if expel-worst-students = true [expel-poor-performers] damage-infrastructure update-bureaucratic-load update-online-mode update-faculty-stress update-university-quality update-university-capacity update-teacher-count if merge-universities? [merge-universities] update-university-appearance ] end to batch-update-students ask students [ if not studying? and not abroad? [ if age < 18 [check-abroad-opportunity] if not abroad? [ ; Continue only if didn't go abroad ifelse previous-university != nobody [check-return-to-studies] [check-retry-university-entry] ] ] if studying? = true [ update-student-stress update-desire-to-study update-student-performance ; This is where performance is affected by stress check-dropout-risk ] ] end to batch-update-teachers ask teachers [ update-teacher-stress update-teacher-skill if not unemployed? and stress-level > 80 [consider-quitting ] if unemployed? [assign-teacher-to-university] ] end to update-teacher-stress ifelse (not unemployed? and my-university != nobody) [ ; === EMPLOYED TEACHERS === let current-stress stress-level ; === SECURITY FACTOR === let security-stress ( ([local-risk] of my-university * (war-intensity / 100)) + [infrastructure-damage] of my-university ) * 0.05 ; Scale factor to keep impact reasonable set current-stress max list 0 min list 100 (current-stress + security-stress) ; === STUDENT FACTOR === let student-impact 0 if any? students with [my-university = [my-university] of myself] [ let avg-desire mean [desire-to-study] of students with [my-university = [my-university] of myself] let avg-performance mean [current-academic-performance] of students with [my-university = [my-university] of myself] set student-impact ( ifelse-value (avg-desire < 40 or avg-performance < 40) [5] ; High stress if either metric is poor [ifelse-value (avg-desire > 70 and avg-performance > 70) [-3] ; Stress reduction if both metrics are good [0] ; Neutral impact otherwise ] ) ] set current-stress max list 0 min list 100 (current-stress + student-impact) ; === TEACHING FACTOR === let teaching-impact ( ifelse-value (teaching-skill > 70 and [quality] of my-university > 70) [-5] ; Significant stress reduction for skilled teachers at good universities [ifelse-value (teaching-skill < 30 or [quality] of my-university < 30) [5] ; Increased stress for poor skill match [0] ; Neutral otherwise ] ) set current-stress max list 0 min list 100 (current-stress + teaching-impact) ; === BUREAUCRATIC FACTOR === let bureaucracy-impact ([bureaucratic-load] of my-university - 50) * 0.1 set current-stress max list 0 min list 100 (current-stress + bureaucracy-impact) ; === RECOVERY === let recovery-amount current-stress * adaptation-rate set current-stress max list 0 min list 100 (current-stress - recovery-amount) ; Set final stress level set stress-level current-stress ][ ; === UNEMPLOYED TEACHERS === ; Only affected by local security situation let security-stress [local-war-intensity] of patch-here * (war-intensity / 100) let recovery-amount stress-level * adaptation-rate set stress-level max list 0 min list 100 ( stress-level + (security-stress * 0.1) - recovery-amount ) ] end to update-teacher-skill if not unemployed? and my-university != nobody [ ifelse stress-level > 60 [ ; High stress causes skill deterioration let stress-impact (stress-level - 60) * 0.02 set teaching-skill max list 0 (teaching-skill * (1 - stress-impact)) ][ ; Low stress allows recovery based on teacher's adaptation rate if teaching-skill < baseline-teaching-skill [ let skill-gap (baseline-teaching-skill - teaching-skill) let recovery-amount skill-gap * adaptation-rate set teaching-skill min list baseline-teaching-skill (teaching-skill + recovery-amount) ] ] ] end ; This helper procedure should be called whenever a university is about to die to handle-university-closure [closing-university] ask teachers with [my-university = closing-university] [ set unemployed? true set my-university nobody set color orange show-turtle ] set current-teachers 0 ; Reset teacher count end to update-student-stress if not abroad? [ ; Initialize local variables let is-online? false let war-exposure 0 let teacher-support 0 let stress-change 0 let recovery-rate 0 ; Get environmental conditions if student is at university if my-university != nobody [ set is-online? [online-mode?] of my-university set war-exposure [local-risk] of my-university * (war-intensity / 100) let my-teachers teachers with [my-university = [my-university] of myself] if any? my-teachers [ set teacher-support ((mean [teaching-skill] of my-teachers) - 50) / 50 ] ] ; === CALCULATE STRESSORS === set stress-change (war-exposure * 0.7) if is-online? [ set stress-change stress-change + 30 ] ; === CALCULATE RECOVERY === ; Base recovery increases with higher current stress set recovery-rate 5 + (stress-resilience * 0.1) + (stress-level * 0.1) if not is-online? [ set recovery-rate recovery-rate + 5 ] set recovery-rate recovery-rate + (10 * teacher-support) ; === UPDATE FINAL STRESS LEVEL === set stress-level max list 0 (min list 100 (stress-level + stress-change - recovery-rate)) ] end to update-student-performance if studying? [ let stress-impact 0 ; Calculate stress impact on performance ; High stress (>50) starts to negatively affect performance if stress-level > 50 [ set stress-impact (stress-level - 50) * 0.02 ; Each point of stress above 50 reduces performance by 2% ] ; Teacher quality can help mitigate stress effects let teacher-support 0 if my-university != nobody [ let my-teachers teachers with [my-university = [my-university] of myself] if any? my-teachers [ set teacher-support mean [teaching-skill] of my-teachers / 200 ; Max 50% stress reduction ] ] ; Calculate final performance ; Base it on natural ability but reduce by stress let stress-modifier (1 - (stress-impact * (1 - teacher-support))) ; Online mode has additional negative impact let online-penalty 0 if my-university != nobody and [online-mode?] of my-university [ set online-penalty 0.1 ; 10% performance reduction in online mode ] ; Update current performance set current-academic-performance max list 0 ( baseline-academic-skill * (stress-modifier * (1 - online-penalty)) ) ] end to update-desire-to-study ; Cache the calculation let base-desire max list 0 (propensity-to-study * (1 - (stress-level / 150))) if male? and age >= 18 and age <= 45 [ let conscription-motivation conscription-fear * (war-intensity / 100) set desire-to-study min list 100 (base-desire + conscription-motivation) ] end to check-dropout-risk let quit-threshold ifelse-value (male? and age >= 18 and age <= 45) [20] [30] if (desire-to-study < quit-threshold and studying? = true) [ if random 100 < (quit-threshold - desire-to-study) * 2 [ handle-dropout ] ] end to handle-dropout if my-university != nobody [ ask my-university [ set enrolled-students-count enrolled-students-count - student-batch-size ] set previous-university my-university ; Store the university before dropping out set my-university nobody ] set studying? false show-turtle set color black right random 360 forward random 3 end ; procedure for retrying university entry to check-retry-university-entry ; Only try if they have attempts left and enough time has passed if remaining-attempts > 0 and (ticks - last-application-attempt) > 30 [ ; Wait 30 ticks between attempts ; Recalculate study motivation let study-motivation 0 ; Base motivation from propensity to study (decreases with age) let age-factor max list 0 (1 - (age - 17) / 43) set study-motivation propensity-to-study * age-factor ; Add conscription avoidance motivation if male? [ let conscription-motivation conscription-fear * (war-intensity / 100) ifelse age >= 18 and age <= 45 [ set study-motivation study-motivation + conscription-motivation ][ set study-motivation study-motivation + (conscription-motivation * 0.5) ] ] ; Additional motivation if stress is low if stress-level < 50 [ set study-motivation study-motivation + (50 - stress-level) / 2 ] ; Normalize motivation and update desire-to-study set study-motivation min list 100 study-motivation set desire-to-study study-motivation ; If motivated enough, try to enter university again if desire-to-study > 60 [ ; Only retry if highly motivated set last-application-attempt ticks set remaining-attempts remaining-attempts - 1 choose-university ; Try to enter university again ] ] end to check-abroad-opportunity if not studying? and not abroad? and age < 18 [ let my-skill academic-skill let abroad-chance calculate-entry-chance my-skill 70 if abroad-chance > (100 - random abroad-entry-chance) [ set abroad? true set studying? true set my-university nobody setxy (min-pxcor + 3 + random 5) (max-pycor - 3 - random 5) set color yellow ] ] end ;; Modified check-return-to-studies to use previous-university to check-return-to-studies ; Only consider returning if stress is below threshold and has a previous university if stress-level < min-stress-for-return and previous-university != nobody [ ; Calculate return probability based on multiple factors let return-chance 0 ; Base chance increases as stress decreases set return-chance (min-stress-for-return - stress-level) / 2 ; Additional motivation from conscription fear if male? and age >= 18 and age <= 45 [ let conscription-motivation conscription-fear * (war-intensity / 100) set return-chance return-chance + conscription-motivation / 2 ] ; Check university conditions if [infrastructure-damage] of previous-university < 50 and [local-risk] of previous-university < 50 and [enrolled-students-count] of previous-university < [capacity] of previous-university [ ; Make the decision if random 100 < return-chance [ set studying? true set my-university previous-university ; Return to previous university set previous-university nobody ; Clear previous university as they're now enrolled ask my-university [ set enrolled-students-count enrolled-students-count + student-batch-size ] hide-turtle ] ] ] end to update-university-quality let quality-change 0 let my-students students with [my-university = myself] let my-teachers teachers with [my-university = myself] ; Base rate of change - slower changes let change-rate 0.1 ; 10% change per tick ; === 1. TEACHER FACTORS === ifelse any? my-teachers [ let avg-teaching-skill mean [teaching-skill] of my-teachers let avg-teacher-stress mean [stress-level] of my-teachers ; Teacher impact: skill reduced by stress let effective-skill avg-teaching-skill * (1 - (avg-teacher-stress / 200)) let teaching-impact (effective-skill - quality) * 0.3 ; Reduced effectiveness during disruptions if online-mode? or relocated? [ set teaching-impact teaching-impact * 0.7 ] set quality-change quality-change + teaching-impact ][ set quality-change quality-change - 1 ; Simple penalty for no teachers ] ; === 2. STUDENT FACTORS === if any? my-students [ let avg-performance mean [current-academic-performance] of my-students let avg-student-stress mean [stress-level] of my-students let avg-desire mean [desire-to-study] of my-students ; Performance impact adjusted by desire to study let performance-impact (avg-performance - quality) * (avg-desire / 100) * 0.2 ; Stress penalty when high let stress-impact 0 if avg-student-stress > 50 [ set stress-impact (50 - avg-student-stress) * 0.1 ] set quality-change quality-change + performance-impact + stress-impact ] ; === 3. INFRASTRUCTURE IMPACT === let infrastructure-impact (50 - infrastructure-damage) * 0.1 set quality-change quality-change + infrastructure-impact ; === 4. EVENT IMPACTS === ; Major events amplify changes if is-merged? or relocated? [ set quality-change quality-change * 1.3 ] ; Apply gradual change set quality-change quality-change * change-rate ; === APPLY FINAL CHANGES === set quality max (list 0 (min (list 100 (quality + quality-change)))) update-university-appearance end ;;=========================================================================== to setup-students create-students initial-students / student-batch-size [ ; Try to place more students (50%) near big cities ifelse random-float 1 < 0.5 [ let big-cities cities with [city-type = "big-city"] ifelse any? big-cities [ move-to one-of big-cities ] [move-to one-of cities] ] [move-to one-of cities] right random 360 forward random 5 ; Rest of student setup set male? random 2 = 0 set age fat-tailed-age set shape "person" set color green set studying? false set abroad? false set previous-university nobody set last-application-attempt 0 set remaining-attempts student-total-attempts set stress-level random 50 set desire-to-study 20 + random 80 set max-stress-threshold 80 set min-stress-for-return 40 set academic-skill random-normal 50 30 set academic-skill max list 0 min list 100 academic-skill set propensity-to-study random-normal (100 - (age - 17) * 2) 15 set propensity-to-study max list 0 min list 100 propensity-to-study set baseline-academic-skill academic-skill set current-academic-performance academic-skill set stress-resilience random-normal 50 40 set stress-resilience max list 0 min list 100 stress-resilience ifelse male? [ ifelse age >= 18 and age <= 45 [set conscription-fear random-normal 70 15] [set conscription-fear random-normal 30 15] ] [set conscription-fear 0] set conscription-fear max list 0 min list 100 conscription-fear calculate-desire-to-study if not studying? [choose-university] ] end to calculate-desire-to-study let study-motivation 0 if not studying? [ ; Base motivation from propensity to study (decreases with age) let age-factor max list 0 (1 - (age - 17) / 43) ; Scales from 1 at 17 to 0 at 60 set study-motivation propensity-to-study * age-factor ; Add conscription avoidance motivation for males if male? [ let conscription-motivation conscription-fear * (war-intensity / 100) ifelse age >= 18 and age <= 45 [ ; Peak conscription motivation for military age set study-motivation study-motivation + conscription-motivation ][ ; Reduced effect outside prime military age set study-motivation study-motivation + (conscription-motivation * 0.5) ] ] ; Normalize motivation to 0-100 scale set study-motivation min list 100 study-motivation set desire-to-study study-motivation ; Update desire-to-study for other procedures ; Always try to enter, but success depends on skills and barriers ] end to choose-university let my-skill academic-skill ; Check for studying abroad let abroad-chance calculate-entry-chance my-skill 70 if (abroad-chance > random (100 - random abroad-entry-chance)) and age < 18 [ set abroad? true set studying? true set my-university nobody setxy (min-pxcor + 3 + random 5) (max-pycor - 3 - random 5) set color yellow stop ] ; === Try Elite Universities === let elite-universities universities with [ infrastructure-damage < 70 and local-risk < 70 and quality > 50 and enrolled-students-count < capacity ] if any? elite-universities and remaining-attempts > 0 [ let tries min list student-attempts-per-tier remaining-attempts repeat tries [ let target max-one-of elite-universities [quality - (distance myself * 2)] if target != nobody [ let entry-chance calculate-entry-chance my-skill [quality] of target if entry-chance > random 90 [ enroll-in-university target set remaining-attempts remaining-attempts - 1 stop ] ] set remaining-attempts remaining-attempts - 1 ] ] ; === Try Mid-tier Universities === let mid-universities universities with [ infrastructure-damage < 70 and local-risk < 70 and quality <= 50 and quality > 30 and enrolled-students-count < capacity ] if any? mid-universities and remaining-attempts > 0 [ let tries min list student-attempts-per-tier remaining-attempts repeat tries [ let target max-one-of mid-universities [quality - (distance myself * 2)] if target != nobody [ let entry-chance calculate-entry-chance my-skill [quality] of target if entry-chance > random 80 [ enroll-in-university target set remaining-attempts remaining-attempts - 1 stop ] ] set remaining-attempts remaining-attempts - 1 ] ] ; === Try Easy Universities === let easy-universities universities with [ infrastructure-damage < 60 and local-risk < 70 and enrolled-students-count < capacity ] if any? easy-universities and remaining-attempts > 0 [ repeat remaining-attempts [ let target max-one-of easy-universities [quality - (distance myself * 2)] if target != nobody [ let entry-chance calculate-entry-chance my-skill [quality] of target if entry-chance > random 40 [ enroll-in-university target set remaining-attempts remaining-attempts - 1 stop ] ] set remaining-attempts remaining-attempts - 1 ] ] ; Mark as unsuccessful if all attempts failed if not studying? [ set my-university nobody set color red ] end to-report calculate-entry-chance [skill barrier] let base-chance 100 * (skill / 100) * (1 - (barrier / 200)) ; Reduced barrier impact let bonus random 20 ; Only positive random bonus report max list 0 min list 100 (base-chance + bonus) end to enroll-in-university [uni] set abroad? false set my-university uni set studying? true ifelse age < 22 [ set program-type "bachelor" ][ifelse age < 25 [ set program-type one-of ["bachelor" "master" "master"] ][set program-type one-of ["master" "master" "phd"] ] ] ask uni [set enrolled-students-count enrolled-students-count + student-batch-size] hide-turtle end ;; ==================================================================== to setup-teachers create-teachers (sum [ceiling (capacity / 10)] of universities / teacher-batch-size) [ ; Try to place more teachers (80%) near big cities ifelse random-float 1 < 0.8 [ let big-cities cities with [city-type = "big-city"] ifelse any? big-cities [move-to one-of big-cities] [move-to one-of cities] ][move-to one-of cities] right random 360 forward random 5 ; Rest of teacher setup set shape "person" set color orange set teaching-skill min list 100 (max list 0 (random-normal 70 20)) set baseline-teaching-skill teaching-skill set stress-level random 30 set adaptation-rate random-float 0.1 set unemployed? true set my-university nobody assign-teacher-to-university ] end to assign-teacher-to-university if not unemployed? [ stop ] ; Don't try to assign if already employed ; Only look at universities that need teachers let potential-universities universities with [current-teachers < teachers-needed] if any? potential-universities [ ; Group universities by quality let high-quality-unis potential-universities with [quality >= 70] let other-unis potential-universities with [quality < 70] ; Good teachers (skill >= 70) try high quality universities first ifelse teaching-skill >= 70 and any? high-quality-unis [ let best-university min-one-of high-quality-unis [distance myself] try-join-university best-university ][ ; Everyone else just picks closest university let best-university min-one-of potential-universities [distance myself] try-join-university best-university ] ] end ; Helper procedure for joining university to try-join-university [university1] if university1 != nobody [ if random 100 < 90 [ ; Keep the high hiring chance set my-university university1 set unemployed? false ask university1 [ set current-teachers current-teachers + teacher-batch-size ] hide-turtle ] ] end to update-teacher-count set teachers-needed ceiling (capacity / 10) ; Actual number of teachers needed set current-teachers (count teachers with [my-university = myself] * teacher-batch-size) ; If too many teachers, lay off some - but only if there are teachers to lay off while [current-teachers > teachers-needed and any? teachers with [my-university = myself]] [ let teacher-to-layoff nobody ifelse (fire-worst-teachers = true) [set teacher-to-layoff min-one-of teachers with [my-university = myself] [teaching-skill / (stress-level + 1)]] [set teacher-to-layoff one-of teachers with [my-university = myself]] if teacher-to-layoff != nobody [ ask teacher-to-layoff [ set unemployed? true set my-university nobody set color orange show-turtle ] set current-teachers current-teachers - teacher-batch-size set teachers-fired teachers-fired + 1 ] ] end to consider-quitting if not unemployed? [ ; High stress gives 30% chance of quitting if stress-level > 80 [ if random 100 < (20 + 100 - stress-level) [ ; Leave current position set teachers-quit teachers-quit + teacher-batch-size ask my-university [ set current-teachers current-teachers - teacher-batch-size ] ; Update teacher status set unemployed? true set my-university nobody set color orange show-turtle ] ] ] end ;; ======================================================= to damage-infrastructure ; Use patch's local-war-intensity directly let current-intensity [local-war-intensity] of patch-here ; Damage chance based directly on local war intensity if random-float 100 < current-intensity [ if random-float 100 < 15 [ ; Base 15% chance of attack let damage-amount random 50 * (current-intensity / 50) set infrastructure-damage min list 100 (infrastructure-damage + damage-amount) ] ] ; Repair functionality when conditions are favorable if current-intensity < 50 [ ; Only repair when relatively safe let repair-chance (50 - current-intensity) / 50 ; Higher chance of repair when safer if random-float 1 < repair-chance [ let repair-amount 2 + random 3 set infrastructure-damage max (list 0 (infrastructure-damage - repair-amount)) ] ] end to update-online-mode ifelse local-risk > 40 [set online-mode? true] [set online-mode? false] end to merge-universities if (infrastructure-damage > 80 or quality < 10) or (enrolled-students-count < 200) [ let potential-partners other universities in-radius 20 if any? potential-partners [ let merger-candidate max-one-of potential-partners [ (1 / (distance myself + 1)) * ((100 - infrastructure-damage) / 100) * (quality / 100) * (enrolled-students-count / 10) ] if merger-candidate != nobody [ let my-strength ( ((100 - infrastructure-damage) / 100) * (quality / 100) * (enrolled-students-count / 10) ) let their-strength ( ([100 - infrastructure-damage] of merger-candidate / 100) * ([quality] of merger-candidate / 100) * ([enrolled-students-count] of merger-candidate / 10) ) ifelse my-strength > their-strength [ ; We absorb them set capacity (capacity + [capacity] of merger-candidate) * 0.8 set is-merged? true ask students with [my-university = merger-candidate] [ set my-university myself move-to myself set stress-level min list 100 (stress-level + 25) ; adding merger stress hide-turtle ] set enrolled-students-count enrolled-students-count + [enrolled-students-count] of merger-candidate ask teachers with [my-university = merger-candidate] [ set my-university myself move-to myself set stress-level min list 100 (stress-level + 30) ; adding merger stress hide-turtle ] set current-teachers current-teachers + [current-teachers] of merger-candidate handle-university-closure merger-candidate ask merger-candidate [ die ] update-university-appearance ] [ ; They absorb us ask merger-candidate [ set capacity (capacity + [capacity] of myself) * 0.8 set is-merged? true set enrolled-students-count enrolled-students-count + [enrolled-students-count] of myself set current-teachers current-teachers + [current-teachers] of myself update-university-appearance ] ask students with [my-university = myself] [ set my-university merger-candidate move-to merger-candidate set stress-level min list 100 (stress-level + 25) ; adding merger stress hide-turtle ] ask teachers with [my-university = myself] [ set my-university merger-candidate move-to merger-candidate set stress-level min list 100 (stress-level + 30) ; adding merger stress hide-turtle ] handle-university-closure self die ] ] ] ] end to update-university-capacity let target-capacity enrolled-students-count ; Don't let capacity drop below a minimum based on university type let min-capacity ifelse-value (location-type = "big-city") [1000] ; Minimum for big city universities [500] ; Minimum for other universities set target-capacity max list target-capacity min-capacity ; Gradual adjustment toward target (5% per tick) let capacity-difference target-capacity - capacity let adjustment-rate 0.05 ; Apply the change set capacity round(capacity + (capacity-difference * adjustment-rate)) end to update-faculty-stress let my-teachers teachers with [my-university = myself] ifelse any? my-teachers [ ; Set faculty stress as average of teacher stress set faculty-stress-level min list 100 (mean [stress-level] of my-teachers) ][ ; If no teachers, base stress on environmental factors set faculty-stress-level min list 100 ( (infrastructure-damage + bureaucratic-load + local-risk) / 3) ] end to update-bureaucratic-load let regulation-chance 30 * (new-regulation-intensity / 5) if random 100 < regulation-chance [ ifelse random 100 < 20 [ ; 20% chance of positive reform set bureaucratic-load max (list 0 (bureaucratic-load - 5 - random 10)) ] [set bureaucratic-load bureaucratic-load + random 10] ] ; Gradual improvement as university adapts if bureaucratic-load > 50 and random 100 < 30 [set bureaucratic-load bureaucratic-load - 2] set bureaucratic-load max list 0 min list bureaucratic-load 100 end ;; ================================================================= to add-new-regulation ; Sudden increase in bureaucratic load ask universities [ ; Significant increase in bureaucratic load (20-40%) let regulation-impact 30 + random 40 set bureaucratic-load min list 100 (bureaucratic-load + regulation-impact) ] end to run-missile-attack ; Air raid set missile-attack-recovery-counter 10 ; Affect universities based on their location and chance ask universities [ ; Calculate chance of being hit based on distance from front let hit-chance 20 + random 20 ; Base 20-40% chance if distance-from-front < 20 [ set hit-chance hit-chance * 1.2 ] ; Only apply damage if university is actually hit if random 100 < hit-chance [ ; Much milder impact - infrastructure damage capped at 50 let impact 5 + random 10 set infrastructure-damage min list 50 (infrastructure-damage + impact) ; Force online mode only if significant damage if infrastructure-damage > 30 [ set online-mode? true ] ; Visual effect without size change set color red ] ] ; Affect students - using more efficient checks ask students with [not abroad?] [set stress-level min list 100 (stress-level + 20)] ; Schedule cleanup of visual effects set missile-attack-recovery-counter 5 end to handle-missile-recovery ; Gradually recover from missile attack effects set missile-attack-recovery-counter missile-attack-recovery-counter - 1 if missile-attack-recovery-counter <= 0 [ ; Reset war intensity to normal levels set war-intensity war-intensity * 0.9 ; Help universities recover ask universities [ ; Gradual infrastructure recovery if infrastructure-damage > 0 [ let recovery-rate 2 + random 3 set infrastructure-damage max list 0 (infrastructure-damage - recovery-rate) ] ; Return from online mode if safe if local-risk < 40 [ set online-mode? false ] ; Faculty stress recovery set faculty-stress-level max list 0 (faculty-stress-level - 1) ] ] end to-report fat-tailed-age ifelse random-float 1 < 0.8 [ ; First peak (power law for younger students) let alpha 1.5 let u random-float 1 let x (1 - u) ^ (-1 / alpha) report min (list 55 (max (list 17 (17 + (x - 1) * 38 / 8)))) ][ ; Second peak (normal distribution for mature students) let mu 37 let sigma 4 let age1 round (mu + (sqrt (-2 * ln random-float 1) * cos (360 * random-float 1)) * sigma) report min (list 55 (max (list 17 age1))) ] end to relocate ; Attempt emergency relocation let safe-locations patches with [ local-war-intensity < 30 and not any? universities-here and any? cities in-radius 5 and ; Add boundary checks to keep universities visible pxcor > min-pxcor + 5 and pxcor < max-pxcor - 5 and pycor > min-pycor + 5 and pycor < max-pycor - 5 ] if any? safe-locations [ ; Find best new location near a city let new-location min-one-of safe-locations [distance myself + (local-war-intensity / 10)] ; Relocate university move-to new-location set infrastructure-damage 30 ; Some damage from relocation set faculty-stress-level min list 100 (faculty-stress-level + 30) set bureaucratic-load min list 100 (bureaucratic-load + 20) set online-mode? true ; Temporary online mode during transition set relocated? true ; Mark as relocated ; Update stress for students and teachers without moving them ask students with [my-university = myself] [ move-to new-location set stress-level min list 100 (stress-level + 25) ] ask teachers with [my-university = myself] [ move-to new-location set stress-level min list 100 (stress-level + 30) ] update-university-appearance ] end to expel-poor-performers let poor-performers students with [ my-university = myself and current-academic-performance < 20 ] if any? poor-performers [ ask poor-performers [ ; Store university before expulsion for potential return set previous-university my-university set my-university nobody set studying? false show-turtle set color black ] ; Update university enrollment count set enrolled-students-count enrolled-students-count - (count poor-performers * student-batch-size) ] end to add-student-stress ask students [ set stress-level min list 100 (stress-level + additional-stress) ] end to add-teacher-stress ask teachers [ set stress-level min list 100 (stress-level + additional-stress) ] end
There is only one version of this model, created 12 days ago by Artem Serdyuk.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Ukraine's Higher Education Model.png | preview | Preview for 'Ukraine's Higher Education Model' | 12 days ago, by Artem Serdyuk | Download |
This model does not have any ancestors.
This model does not have any descendants.