📄 ---charityworld-nl.nlogo
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GNU GENERAL PUBLIC LICENSE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CharityWorld-NL;; CharityWorld-NL is a model designed to show the emergent effects ;; of floating-point errors in agent-based models.;; Copyright (C) 2005 Luis R. Izquierdo;; ;; This program is free software; you can redistribute it and/or;; modify it under the terms of the GNU General Public License;; as published by the Free Software Foundation; either version 2;; of the License, or (at your option) any later version.;; ;; This program is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; ;; You should have received a copy of the GNU General Public License;; along with this program; if not, write to the Free Software;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DECLARATION OF VARIABLES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; globals [ time-step ]patches-own [ ; patches are the agents. We do not use turtles here wealth my-neighbors ; these are the 8 neighbours in the Moore neighbourhood of radius 1];;;;;;;;;;;;;;;;;;;;;;;;;; CORE PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;to setup clear-all-plots clear-patches ; we do not clear all to keep the random seed inputted by the user output-print "Coin value: " + coin-value output-print "Type of agent: " + type-of-agent setup-patches set time-step 0 update-graphs endto setup-patches ask patches [ set wealth coin-value set wealth (wealth + coin-value) ] ; give 2 coins to everyone ask patches [ set my-neighbors values-from neighbors [self] ] ; convert the agentset primitive "neighbors" into a list output-print "Every agent starts with 2 coins"endto conduct-lottery ; everyone gives two coins to the agent in the centre ask patches [ give-one-coin-to patch 0 0 give-one-coin-to patch 0 0 ] update-graphs output-print "Every agent has given 2 coins to\n\tthe agent in the centre"endto go let rich-agents patches with [ locally-rich ] ; identify the agents who are locally rich ifelse not any? rich-agents [ ; if there's no rich agents, finish the simulation output-print "No more locally-rich agents!\nEnd of simulation.\nTime-steps: " + time-step stop ] [ ; if there are, choose one of them at random and tell it to conduct one cycle of redistribution ask random-one-of rich-agents [conduct-cycle-of-redistribution] update-graphs set time-step (time-step + 1) ]endto conduct-cycle-of-redistribution ; Give one coin to each of your neighbours in ascending order of wealth as long as: ; 1. You are locally rich ; 2. Your neighbour isn't set my-neighbors shuffle my-neighbors ; make sure there's no bias in ties when we sort the list set my-neighbors sort-by [ wealth-of ?1 < wealth-of ?2 ] my-neighbors ; sort the list in ascending order of wealth foreach my-neighbors [ if locally-rich and (not value-from ? [locally-rich]) [ give-one-coin-to ? ] ]endto give-one-coin-to [ recipient ] set wealth (wealth - coin-value) set wealth-of recipient (wealth-of recipient + coin-value)end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PROCEDURES TO DETERMINE WHETHER AN AGENT IS LOCALLY RICH, AVERAGE, OR POOR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;to-report locally-rich ; Four different ways of assessing whether an agent is locally rich or not. ; The four of them are mathematically equivalent in real arithmetic, ; but can give different results in floating-point arithmetic. if type-of-agent = "inclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) + wealth ifelse 9 * wealth > nbrTotal [ report true ] [ report false ] ] if type-of-agent = "inclusive mean" [ let nbrMean ((sum values-from neighbors [wealth]) + wealth) / 9 ifelse wealth > nbrMean [ report true ] [ report false ] ] if type-of-agent = "exclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) ifelse 8 * wealth > nbrTotal [ report true ] [ report false ] ] if type-of-agent = "exclusive mean" [ let nbrMean (sum values-from neighbors [wealth]) / 8 ifelse wealth > nbrMean [ report true ] [ report false ] ] endto-report locally-average ; Four different ways of assessing whether an agent is locally average or not. ; The four of them are mathematically equivalent in real arithmetic, ; but can give different results in floating-point arithmetic. if type-of-agent = "inclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) + wealth ifelse 9 * wealth = nbrTotal [ report true ] [ report false ] ] if type-of-agent = "inclusive mean" [ let nbrMean ((sum values-from neighbors [wealth]) + wealth) / 9 ifelse wealth = nbrMean [ report true ] [ report false ] ] if type-of-agent = "exclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) ifelse 8 * wealth = nbrTotal [ report true ] [ report false ] ] if type-of-agent = "exclusive mean" [ let nbrMean (sum values-from neighbors [wealth]) / 8 ifelse wealth = nbrMean [ report true ] [ report false ] ] endto-report locally-poor ; Four different ways of assessing whether an agent is locally poor or not. ; The four of them are mathematically equivalent in real arithmetic, ; but can give different results in floating-point arithmetic. if type-of-agent = "inclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) + wealth ifelse 9 * wealth < nbrTotal [ report true ] [ report false ] ] if type-of-agent = "inclusive mean" [ let nbrMean ((sum values-from neighbors [wealth]) + wealth) / 9 ifelse wealth < nbrMean [ report true ] [ report false ] ] if type-of-agent = "exclusive total" [ let nbrTotal (sum values-from neighbors [wealth]) ifelse 8 * wealth < nbrTotal [ report true ] [ report false ] ] if type-of-agent = "exclusive mean" [ let nbrMean (sum values-from neighbors [wealth]) / 8 ifelse wealth < nbrMean [ report true ] [ report false ] ] end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GRAPH-RELATED PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;to update-graphs ask patches [ update-colour ] set-current-plot-pen "locally-rich" plot count patches with [locally-rich] set-current-plot-pen "locally-average" plot count patches with [locally-average] set-current-plot-pen "locally-poor" plot count patches with [locally-poor]end to update-colour if display-mode = "Relative (local) wealth" [ if locally-rich [ set pcolor green ] if locally-average [ set pcolor yellow ] if locally-poor [ set pcolor red ] ] if display-mode = "Absolute wealth" [ if wealth > 2 * coin-value [ set pcolor (50 + 7 * (((2 * screen-size-x * screen-size-y) - wealth) / (2 * screen-size-x * screen-size-y - 2 * coin-value)) ^ 30) ] ; I raise to the power of 30 to make the colour scale finer when the wealth is close to 2 coins if wealth < 2 * coin-value [ set pcolor (15 + 5 * wealth / (2 * coin-value)) ] ifelse wealth = 2 * coin-value [ set pcolor yellow ] ; This final condition, implemented to detect floating-point errors, overrides the previous conditions. [ if wealth > 1.5 * coin-value and wealth < 2.5 * coin-value [ set pcolor blue ] ] ]end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RANDOM SEED RELATED PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Use a seed created by the new-seed reporterto use-generated-seed output-print "-----NEW RANDOM SEED-----" let my-seed new-seed ; generate a new seed output-print "Generated seed: " + my-seed ; print it out random-seed my-seed ; use the new seedend; Use a seed entered by the userto use-seed-from-user output-print "-----NEW RANDOM SEED-----" let my-seed read-from-string user-input "Enter a random seed (an integer):" output-print "User entered seed: " + my-seed ; print it out random-seed my-seed ; use the new seedend@#$#@#$#@GRAPHICS-WINDOW322115222327712.71101110111CC-WINDOW5506709601Command Center0BUTTON511568148NILsetupNIL1TOBSERVERTNILBUTTON518968222NILgoT1TOBSERVERTNILSLIDER510177
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -