-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUrbanShrinkage.nlogo
1399 lines (1271 loc) · 31.7 KB
/
UrbanShrinkage.nlogo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
extensions [ gis csv ]
globals
[
tract ;;saptial boundary
nhhold-n1 ;;household amount in neighborhood 1
nhhold-n2 ;;household amount in neighborhood 2
nhhold-n3 ;;household amount in neighborhood 3
avg-n1 ;;average price in neighborhood 1
avg-n2 ;;average price in neighborhood 2
avg-n3 ;;average price in neighborhood 3
n-buyers ;;number of buyer
n-sellers ;;number of seller
]
patches-own
[
PID ;;Polygon ID number
OID ;;Object ID
ntype ;;neighborhood type, displyaed as different colors in the model
price ;;house price
qv ;;lower quatile price for houses
;;number of household with income info to generate households' income
ni50 ;;below 50k
ni75 ;;50-75k
ni150 ;;75-150k
nim150 ;;more 150k
centroid? ;;if it is the centroid of a polygon
occupied? ;;if it is occupied by a turtle
une ;;unemployment
myb
]
breed [households household]
;breed [developers develor]
households-own
[
hID ;;household ID
hNT ;;household neighborhood type
hPoly ;;household polygonID
hIncome ;;household income
hPrice ;;house price of current living house
hBudget ;;Add an atrribute to check affordable or not, bid price based on budget
employed?
;Roles
buyer?
seller?
;buyerl
;sellerl
askprice ;;ask price
bidprice ;;bid price
;Status of trade
trade?
;flags
flag
move?
]
;;************************;;
;;****1 Initialization****;;
;;************************;;
;1.1 Set up
to setup
clear-all
reset-ticks
;Load Vector Census Tract Data
set tract gis:load-dataset "Data/DMA_v6.shp"
end
;1.2 Draw the Doundary and Assign each Polygon ID
;;Reference this part from Yang's model, which is provided by the book of Agent-Based Modeling & Geograohic Information System
to draw
clear-drawing
reset-ticks
gis:set-world-envelope gis:envelope-of (tract)
;apply the vetor data attributes to patches
gis:apply-coverage tract "LINK" OID
gis:apply-coverage tract "NT" ntype
;number of hhousehold with income info
gis:apply-coverage tract "HU_I_50K" ni50
gis:apply-coverage tract "HU_I75_K" ni75
gis:apply-coverage tract "HU_I150_K" ni150
gis:apply-coverage tract "HU_IM150_K" nim150
;medain house price
gis:apply-coverage tract "HU_V_K" price
;lower quartile value
gis:apply-coverage tract "HU_VQ_K" qv
;unemployment status
gis:apply-coverage tract "H_EM_R" une
;house medain year built
gis:apply-coverage tract "H_MYB" myb
;Fill the Ploygon with color
foreach gis:feature-list-of tract
[
feature ->
if gis:property-value feature "NT" = 1 [ gis:set-drawing-color red gis:fill feature 2.0]
if gis:property-value feature "NT" = 2 [ gis:set-drawing-color blue gis:fill feature 2.0]
if gis:property-value feature "NT" = 3 [ gis:set-drawing-color green gis:fill feature 2.0]
]
;Draw Boundary
;gis:set-drawing-color white
;gis:draw tract 0.5
;Identify Polygon wit ID number
let x 1
foreach gis:feature-list-of tract
[
feature ->
let center-point gis:location-of gis:centroid-of feature
let x-coordinate item 0 center-point
let y-coordinate item 1 center-point
ask patch x-coordinate y-coordinate[
set PID x
set centroid? true
;set MYB myb
]
set x x + 1
]
;3.1, Create Households
create-household
;3.2, Set up housdeholds with price and budget
initialize-hprice
;3.3
set-hBudget
;3.4, Add Buyers to the model
add-buyers
update-global
;3.5, Add Sellers based on the demand and supply
add-sellers
;update again to let the monitor display the number of the sellers
update-global
do-plot
end
;;************************;;
;;****2 Model Dynamic ****;;
;;************************;;
;2.1 Main Funtion
to go
do-plot
;;move households
move
;;Main function of trade is in 3.7 of the following section
trade
;;Update and add new traders
update-household
add-buyers
;update-global
add-sellers
update-global
;; Do Plot
do-plot
tick
end
;;************************;;
;;****3, Functions ****;;
;;************************;;
;3.1 Create Households For Initilazation
to create-household
ask patches with [PID > 0] [set occupied? false ]
let y 1
while [y <= 136] [
;number of households
let ni501 [ni50] of patches with [centroid? = true and PID = y]
let ni751 [ni75] of patches with [centroid? = true and PID = y]
let ni1501 [ni150] of patches with [centroid? = true and PID = y]
let nim1501 [nim150] of patches with [centroid? = true and PID = y]
;neighborhood type
let ntype1 [ntype] of patches with [centroid? = true and PID = y]
let une1 [une] of patches with [centroid? = true and PID = y]
if ntype1 = [1][
ask patches with [PID = y and occupied? = false][
let z 1
let i item 0 ni501
let j item 0 ni751
let p item 0 ni1501
let q item 0 nim1501
let t item 0 une1
while [z <= i][sprout 1[
set breed households
set hID z
set hNT 1
set hPoly y
set shape "dot"
set hIncome 0 + random int 50
set color white
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]
while [z <= i + j][sprout 1[
set breed households
set hID z
set hNT 1
set hPoly y
set shape "dot"
set hIncome 50 + random int 25
set color white
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p][sprout 1[
set breed households
set hID z
set hNT 1
set hPoly y
set shape "dot"
set hIncome 75 + random int 75
set color white
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p + q][sprout 1[
set breed households
set hID z
set hNT 1
set hPoly y
set shape "dot"
set hIncome 150 + random int 50
set color white
set size 1
;emoplyed
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
;houseprice
ask patch-here[set occupied? true]
set z z + 1
]]
]
]]
if ntype1 = [2][
ask patches with [PID = y and occupied? = false][
let z 1
let i item 0 ni501
let j item 0 ni751
let p item 0 ni1501
let q item 0 nim1501
let t item 0 une1
while [z <= i][sprout 1[
set breed households
set hID z
set hNT 2
set hPoly y
set shape "dot"
set hIncome 0 + random int 50
set color pink
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]
while [z <= i + j][sprout 1[
set breed households
set hID z
set hNT 2
set hPoly y
set shape "dot"
set hIncome 50 + random int 25
set color pink
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p][sprout 1[
set breed households
set hID z
set hNT 2
set hPoly y
set shape "dot"
set hIncome 75 + random int 75
set color pink
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p + q][sprout 1[
set breed households
set hID z
set hNT 2
set hPoly y
set shape "dot"
set hIncome 150 + random int 50
set color pink
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
]
]]
if ntype1 = [3][
ask patches with [PID = y and occupied? = false][
let z 1
let i item 0 ni501
let j item 0 ni751
let p item 0 ni1501
let q item 0 nim1501
let t item 0 une1
while [z <= i][sprout 1[
set breed households
set hID z
set hNT 3
set hPoly y
set shape "dot"
set hIncome 0 + random int 50
set color yellow
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]
while [z <= i + j][sprout 1[
set breed households
set hID z
set hNT 3
set hPoly y
set shape "dot"
set hIncome 50 + random int 25
set color yellow
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p][sprout 1[
set breed households
set hID z
set hNT 3
set hPoly y
set shape "dot"
set hIncome 75 + random int 75
set color yellow
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
while [z <= i + j + p + q][sprout 1[
set breed households
set hID z
set hNT 3
set hPoly y
set shape "dot"
set hIncome 150 + random int 50
set color yellow
set size 1
ifelse random-float 100 < t
[set employed? false]
[set employed? true]
ask patch-here[set occupied? true]
set z z + 1
]]
]
]]
set y y + 1
]
end
;3.2 Set up households for every agents in the model
to initialize-hprice
ask n-of (count households * (balance / 100)) households
[set flag 1]
ask households[
ifelse (flag = 1)
[set hPrice [price] of patch-here + random int [qv] of patch-here]
[set hPrice [price] of patch-here - random int [qv] of patch-here]
]
end
;3.3 Set the budget for all households
;set budgets
to set-hBudget
ask households[set hBudget 0.3 * hIncome]
end
;3.4 Setup buyers
;By checking households' affordabilities to define the buyer
to add-buyers
;ask households-on patches [
ask households[
if hBudget < 0.074 * hPrice;Cannot afford current then find new house, 10% of the house price
[
set buyer? true ;become buyer
set bidprice 2.5 * hincome ;set up the max price that the household can afford 2.5 times income
set trade? false
]
]
end
;3.5 Add sellers into the model
to add-sellers
ask n-of (count households with [buyer? = true] * D-S) households with [buyer? != true] ;D-S is the slider in Inrerface
[
set seller? true ;become sellers
set shape "star"
set askprice 0.8 * hPrice + random-float 0.3 * hPrice ;set the max askprice for each seller
set trade? false
]
end
;3.6 Move
;Let the buyers move around
to move
;Move households that can not afford current houses
ask households with [(buyer? = true) and (trade? = false)][
ifelse random-float diffusion-rate + 1 > 1.2
[
let x patches with [(PID > 0) and (ntype != [ntype] of myself) and (centroid? = true) ]
move-to one-of x
set shape "square"
;after moving, set the household Neigborhood type
set hNT [ntype] of patch-here
;set polygon ID
set hPoly [PID] of patch-here
]
[
let x patches with [(PID > 0) and (ntype = [ntype] of myself) and (centroid? = true)]
move-to one-of x
set shape "square"
set hPoly [PID] of patch-here
]
]
end
;3.7 Trade
to trade
find-potiential-sellers
bid
end
;3.7.1 get potiential sellers
to find-potiential-sellers
;if in, get sellers' askprice and check own bidprices
ask households with [buyer? = true]
[
;let ptrade? false
;sellers in the same polygon
let nearseller households with [(seller? = true) and (hPoly = [hPoly] of myself)]
let askpricelist sort-by < [askprice] of nearseller
ifelse any? nearseller
[
if bidprice > mean askpricelist
[
set trade? true
]
]
[move]
]
end
;3.7.2 bid price
;if buyer's bidprice bid price is grater than 0.9 of seller's askprice and less than 1.5 of seller's askprice
;then trade
to bid
let c 0
if c = 2 [stop]
ask households with [seller? = true]
[
let ptrade false
;
let nearbuyer households with [(shape = "x") and (hpoly = [hpoly] of myself) and (buyer? = true) and (trade? = true)]
ask nearbuyer [
;if ((bidprice > 0.8 * [askprice] of myself) and (bidprice < 1.5 * [askprice] of myself) and (hBudget < 0.34 * [hprice] of myself))
if ((bidprice > [askprice] of myself) and (hBudget < 0.34 * [hprice] of myself))
[
set ptrade true
set trade? 1
set buyer? false
;set hPrice [askprice] of myself
set hPrice bidprice
set hNT [ntype] of patch-here
]
]
ifelse (ptrade = true)
[
register-trade
set seller? false
]
[move]
]
set c c + 1
show c
end
;3.8 Move in
to register-trade
update-color
set-hBudget
end
;;**************************;;
;;****4,UPDATA VARIABLES****;;
;;**************************;;
;4.1, UPDATE GLOBAL & Visual
;4.1.1 UPDATE GLOBAL
to update-global
update-num-hhold
update-avg-price
set n-buyers count households with [buyer? = true]
set n-sellers count households with [seller? = true]
end
to update-num-hhold
set nhhold-n1 count households with [hNT = 1]
set nhhold-n2 count households with [hNT = 2]
set nhhold-n3 count households with [hNT = 3]
end
to update-avg-price
set avg-n1 sum[hPrice] of households with [hNT = 1] / count households with [hNT = 1]
set avg-n2 sum[hPrice] of households with [hNT = 2] / count households with [hNT = 2]
set avg-n3 sum[hPrice] of households with [hNT = 3] / count households with [hNT = 3]
end
;;4.1.2 UPDATE COLOR
to update-color
ask households with [hNT = 1][set color white]
ask households with [hNT = 2][set color pink]
ask households with [hNT = 3][set color yellow]
end
;4.2 UPDATE Households based on economic
to update-household
update-income
update-houseprice
update-bid
update-ask
end
;4.2.1
to update-income
ask households
[
if (employed? = true)
;[set hIncome hIncome + (0.5 * ln abs economicgrowthrate / 100) * hIncome]
[set hIncome hIncome + (economicgrowthrate / 100) * 0.1 * hIncome]
if (employed? = false)
[set hIncome hIncome + (economicgrowthrate / 100) * 0.1 * hIncome]
]
end
;4. Update Houseprice Not Used
to update-houseprice
ask households
[
;houseprice change
;downtwom
if (ntype = 1)
[set hPrice hPrice - ((0.5 * economicgrowthrate) / 100) * hPrice]
;city sub
if (ntype = 2)
[set hPrice hPrice + (0.75 * economicgrowthrate / 100) * hPrice]
;far sub
if (ntype = 3)
[set hPrice hPrice - (0.25 * economicgrowthrate / 100) * hPrice]
]
end
;4. Update Bid
to update-bid
ask households with [buyer? = true and (trade? = true)]
[set bidprice hBudget / 0.05]
end
;4. Update Ask
to update-ask
ask households with [(seller? = true) and (trade? = true)]
[set askprice 0.8 * hPrice + random-float 0.3 * hPrice]
end
;4.x Do Plot
to do-plot
set-current-plot "Number of Households in Different Submarkets"
set-current-plot-pen "Downtown"
plot nhhold-n1
set-current-plot-pen "City-Sub"
plot nhhold-n2
set-current-plot-pen "Far-Sub"
plot nhhold-n3
set-current-plot "AVG Price in Different Submarkets"
set-current-plot-pen "Downtown"
plot avg-n1
set-current-plot-pen "City-Sub"
plot avg-n2
set-current-plot-pen "Far-Sub"
plot avg-n3
end
to income-csv1
export-plot "Distribution of Houseprice (k)" "income1.csv"
end
to income-csv2
export-plot "Distribution of Houseprice (k)" "income2.csv"
end
to income-csv3
export-plot "Distribution of Houseprice (k)" "income3.csv"
end
to write-households-to-csv
; we use the `of` primitive to make a list of lists and then
; use the csv extension to write that list of lists to a file.
csv:to-file "hhold-income3.csv" [ (list hIncome) ] of households
end
@#$#@#$#@
GRAPHICS-WINDOW
205
10
718
524
-1
-1
15.303030303030303
1
10
1
1
1
0
1
1
1
-16
16
-16
16
0
0
1
ticks
30.0
BUTTON
1
10
59
43
NIL
setup
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
BUTTON
62
10
125
43
NIL
draw\n
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
MONITOR
3
255
108
300
Tract Amount
count patches with [PID > 0]
17
1
11
MONITOR
753
509
858
554
Downtown
nhhold-n1
17
1
11
MONITOR
861
510
966
555
Suburban
nhhold-n2
17
1
11
MONITOR
968
510
1073
555
Far Suburban
nhhold-n3
17
1
11
MONITOR
2
304
107
349
Total households
count households
17
1
11
BUTTON
133
10
196
43
go
go
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
SLIDER
3
97
197
130
balance
balance
0
100
50.0
1
1
NIL
HORIZONTAL
SLIDER
4
135
198
168
diffusion-rate
diffusion-rate
0
1
1.0
1
1
NIL
HORIZONTAL
PLOT
733
169
1119
319
AVG Price in Different Submarkets
Transactions
NIL
0.0
10.0
0.0
150.0
true
true
"" ""
PENS
"Downtown" 1.0 0 -2674135 true "" "plot avg-n1"
"City-Sub" 1.0 0 -13345367 true "" "plot avg-n2"
"Far-Sub" 1.0 0 -13840069 true "" "plot avg-n3"
PLOT
733
12
1117
162
Number of Households in Different Submarkets
Transactions
Number
0.0
10.0
0.0
560.0
true
true
"" ""
PENS
"Downtown" 1.0 0 -2674135 true "" "plot nhhold-n1"
"City-Sub" 1.0 0 -13345367 true "" "plot nhhold-n2"
"Far-Sub" 1.0 0 -13840069 true "" "plot nhhold-n3"
BUTTON
4
52
196
85
NIL
go\n
T
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
MONITOR
122
255
197
300
No. Buyer
n-buyers
17
1
11
MONITOR
122
304
197
349
No. Seller
n-sellers
17
1
11
SLIDER
4
174
198
207
D-S
D-S
0.1
2
1.0
0.1
1
NIL
HORIZONTAL
MONITOR
3
352
113
397
Going to Trade
count households with [trade? = true]
17
1
11
MONITOR
121
353
198
398
stop trade
count households with [trade? = false]
17
1
11
SLIDER
4
211
197
244
economicgrowthrate
economicgrowthrate
-10
10
-4.0
1
1
%
HORIZONTAL
PLOT
733
324
1119
474
Income Status
Time
Avg. Income
0.0
10.0
0.0
10.0
true
true
"" ""
PENS
"Unemployed" 1.0 0 -16777216 true "" "plot sum[hIncome] of households with [employed? = false]"
"Employed" 1.0 0 -7500403 true "" "plot sum[hIncome] of households with [employed? = true]"
PLOT
1171
18
1444
168
Distribution of Houseprice (k)
Range
Number
0.0
300.0
0.0
10.0
true
false
"set-histogram-num-bars 5\nset-plot-x-range 0 300\n\n" ""
PENS
"default" 1.0 1 -16777216 true "" "histogram [hPrice] of households"
MONITOR
4
403
137