;;;; example for multi-level simulation ;;;; interpop.lsp ;;;; basic master equation example. ;;;; Nigel Gilbert October 22, 1996 ;;;; There is a population of people each of whom may decide ;;;; either yes or no on a certain issue. At the beginning ;;;; of the simulation, the population is evenly divided. ;;;; Thereafter, opnions change depending on the influence of ;;;; others in the population, according to a transition probability (see ;;;; Troitzsch, p. 112) ;;;; to run the example, load this file, compile it and run thus: ;;;; ;;;; (load "interpop") ;;;; (compile-file "interpop" :load t) ;;;; (interpop 10) (require "mls") ;ensure the mls toolkit is loaded ; some constants for the transition probability equation (defconstant kappa 1.5) (defconstant delta 0.0) (defconstant ny 0.02) ; the population has one attribute: the proportion voting yes. (defobject pop (x)) (defmeth pop :initialise (n-persons) (create-lowers person n-persons) (send self :act)) (defmeth pop :yeses () "return the number of yes votes in the population" (count 'yes (send self :from-lowers 'att))) (defmeth pop :act () (set-attribute x (- (/ (* 2 (send self :yeses)) (send self :num-lowers)) 1))) ; a person has one attribute: the opinion, yes or no (defobject person (att)) (defmeth person :initialise () "make every other person begin by being a yesman" (set-attribute att (if (oddp (attribute id)) 'no 'yes))) (defmeth person :act () (set-attribute att (case (attribute att) (yes (if (< (uniform 0 1) (* ny (exp (- (+ delta (* kappa (prev-upper-attribute x))))))) 'no 'yes)) (no (if (< (uniform 0 1) (* ny (exp (+ delta (* kappa (prev-upper-attribute x)))))) 'yes 'no))))) (defun run (n-persons steps) "run the simulation and return the history of opinion changes" (let ((population (create pop n-persons))) (dotimes (s steps) (send population :step)) (its-history population 'x))) (defun interpop (runs &optional (steps-per-run 500)) "run the simulation RUNS times and plot the history of the opinion change for each run. The plot should show divergence from initial 50 per cent yes to either 10 or 90 percent yes" (let ((plot (plot-lines '(0) '(0) :title "Simulation results" :variable-labels '("Time" "Percentage \'Yes\'"))) (persons-in-pop 100) history-of-x) (dotimes (r runs) (setq history-of-x (run persons-in-pop steps-per-run)) (send plot :add-lines (list (iseq steps-per-run) (/ (* persons-in-pop (+ history-of-x 1)) 2))) (send plot :adjust-to-data))))