-
Notifications
You must be signed in to change notification settings - Fork 0
/
CommonersFramework.nlogo
3055 lines (2716 loc) · 74.4 KB
/
CommonersFramework.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
; Developed by Dr Peter Barbrook-Johnson and Antonio Tenorio-Fornés
; Comments welcome - emails: [email protected], [email protected]
extensions [ nw ]
globals [
initial-products ;; number of initial products
contrib-distrib ;; Sorted list of contributions per commoner
dead-commoners-contribs ;; Sorted list of contributions per dead commoner
ticks-without-projects ;; ticks without projects in the model; used for a stop condition
gini-index-reserve ;; gini-index
power-law-pvalue ;; power law p-value
power-law-xmin ;; power law xmin parameter
power-law-alpha ;; power law alpha parameter
withR ;;
]
__includes["withRextension.nls"]
;__includes["withoutRextension.nls"]
breed [commoners commoner] ;; The agents representing individuals interacting (consuming/producing) in the community
breed [products product] ;; The common goods being produced and used in the community
breed [projects project] ;; The main organization of production work in the community (contains tasks)
breed [t4sks t4sk] ;; Individual units of productive work done in the projects of the community
undirected-link-breed [projecttasklinks projecttasklink] ;; represents the project-task relationships; each task belongs to a project
directed-link-breed [commonertasklinks commonertasklink] ;; represents that a task is known by a commoner; its recent-weight (a link parameter) represents the memory of recent contribution of the commoner to that task
undirected-link-breed [commonerprojectlinks commonerprojectlink] ;; represents that an commoner is aware of a project; recent-weight (a link parameter) represents the memory of recent contributions to that project;
undirected-link-breed [friendlinks friendlink] ;; represents relationships among agents that have worked in the same tasks and become "friends".
directed-link-breed [consumerlinks consumerlink] ;; represents a consumption relationhip between a commoner and a product
undirected-link-breed [projectproductlinks projectproductlink] ;; represents to which product the efforts in a project goes.
turtles-own [
repulsion ;; all agents are naturally pulled away from the center (while they are pushed towards the center when they are active) to represent the natural atrophy of a community. This parameter is used to tune the speed of this process.
]
links-own [
total-weight ;; record of the number of interactions of the interaction the link represents
recent-weight ;; the memory of recent activity from between two entities (e.g. Contributions between a commoner and a task or recent frecuency of collaboration between two friends)
max-recent-weight ;; A parameter used to cap the recent weight of links.
forget-recent-weight-prob ;; The chances a unit of recent weight is forgotten
forget-link-prob ;; The chances a link will die due to lack of recent activity. A link can only die if the recen contribution is 0.
;; ATRACTION: activities such as production and consumption brings agents towards the center of the model.
;; For instance, contributing to a task will make the task (and its project) become closer to the center
;; but also will bring the contributing commoner towards the center. The strength of this pulls is set by
;; the following parameters
target-attraction ;; attraction strength of the target node (e.g. how much a task attracts its contributing agents)
origin-attraction ;; attraction strength of the origin node (e.g. how much a commoner attracts the tasks it is contributing to)
]
commoners-own [
skills ;; The skills a commoner have. Tasks also have a skill attribute representing the skills needed to contribute to it. TODO consider to remove it from basic model
interest ;; a broad representation of the topic/area the commoner is interested in. It affects its vertical position, thus making it easier to find products and projects with similar interests.
total-contribs ;; the total number of finished contributions
]
projects-own [
interest ;; a broad representation of the topic/area the project is about. It affects its vertical position,
]
t4sks-own [
skill ;; The skills needed to contribute to this task. TODO think if keeping it in the basic model
time-required ;; How many contributions the task needs to be finished
]
products-own [
interest ;; a broad representation of the topic/area the product is about. It affects its vertical position,
]
to setup
clear-all
;; colour lines to mark projects and products spaces
ask patches with [pxcor = 0] [set pcolor white]
create-existing-products
create-existing-projects
create-existing-commoners
set ticks-without-projects 0
set contrib-distrib [total-contribs] of commoners
set contrib-distrib sort-by > contrib-distrib
;; list of contributions by dead agents
set dead-commoners-contribs (list)
r?setup
reset-ticks
end
to create-existing-products
;; create products; set their position and defeault parameters
set initial-products number-of-products
create-products initial-products [
set interest random num-interest-categories
set xcor -25 + random 25
set ycor -25 + interest
set-product-parameters
]
end
to set-product-parameters
;; Style
set size 2
set color orange
set shape "box"
;;
set repulsion product-repulsion-prob
end
to create-existing-projects
;; create projects; set their position and defeault parameters
create-projects initial-projects [
set interest random num-interest-categories
set-project-parameters
;; create a project to product link to the nearest product
;; only half of the projects have a product, the others will create a new product once they have finished.
;; TODO: change probability depending on initial number of products.
if random-float 1 < 0.5 [
let my-product min-one-of products [ distance myself ]
create-projectproductlink-with my-product [ set-projectproductlink-parameters ]
]
]
end
to set-project-parameters
;; Style
set size 2.5
set color green - 2
set shape "target"
;;
set xcor -25 + (random 25)
set ycor -25 + interest
set repulsion project-repulsion-prob
let num-tasks random 10 + 2
hatch-t4sks num-tasks [
set-task-parameters
]
end
to set-task-parameters
;; style
set size 0.7
set color green
set shape "circle"
;;
;; position
set ycor [ycor] of myself
set heading random 360
fd 1
;;
;; link to its project
create-projecttasklink-with myself [tie]
t4sk-set-skill
;; Number of contribution actions needed to finish the task
set time-required random-normal mean-time-required ( mean-time-required / 4 )
end
to t4sk-set-skill
; new tasks set their skill type
; if there are no other task in the project
; or with probability 50%
ifelse (not any? [ projecttasklink-neighbors ] of myself) or (random-float 1 < 0.5) [
; set a random skill
set skill random (num-skills - 1)
] [
; else, set the task skill equal to one of its project tasks
set skill [ skill ] of one-of [ projecttasklink-neighbors ] of myself
]
end
to create-existing-commoners
;; commoners hava a preferential attachement like structure
print commoners-num
nw:generate-preferential-attachment commoners friendlinks commoners-num 1 [set color red]
;; the majority of the community has not contributed and therefore have no firends in the model
; ask commoners with [count my-friendlinks = 1] [
; ask one-of my-friendlinks [
; die
; ]
; ]
ask commoners [
set-commoner-parameters
]
;; The number of friends is considered as a proxy of the commoner contribution activity, thus setting its horizontal position;
ask commoners [
let friends count my-friendlinks
;; commoners without friends are at the edge of the model (xcor = 25), each extra friend up to 4 brings it 5 units towards the center
set xcor max (list 1 (25 - friends ^ 2) )
]
ask friendlinks [
set-friendlink-parameters
]
end
to set-commonertasklink-parameters
set color green
set hidden? hide-commonertasklinks?
set max-recent-weight 3
set forget-recent-weight-prob 1 / contrib-recent-forg
set forget-link-prob 1 / contrib-long-forg
set origin-attraction task-commoner-attraction-prob
set target-attraction commoner-task-attraction-prob
end
to set-consumerlink-parameters
set color orange
set hidden? hide-consumerlinks?
set max-recent-weight 3
set forget-recent-weight-prob 1 / consume-recent-forg
set forget-link-prob 1 / consume-long-forg
set origin-attraction product-commoner-attraction-prob
set target-attraction commoner-product-attraction-prob
end
to set-commonerprojectlink-parameters
set color green + 3
set hidden? hide-commonerprojectlinks?
set max-recent-weight 3
set forget-recent-weight-prob 1 / project-recent-forg
set forget-link-prob 1 / project-long-forg
end
to set-friendlink-parameters
set color yellow + 3
set max-recent-weight 3
set forget-recent-weight-prob 1 / friends-recent-forg
set forget-link-prob 1 / friends-long-forg
end
to set-projectproductlink-parameters
set color red
end
to set-commoner-parameters
;; style
set size 1.5
set color blue
;;position and interest
set interest random num-interest-categories
set ycor -25 + interest
set repulsion commoner-repulsion-prob
;; commoners consume a community product
create-consumerlink-to min-one-of products [ distance myself ] [set-consumerlink-parameters]
;; 3 random skills per commoner
set skills (n-of 3 (n-values num-skills [x -> x]))
let num-friends count my-friendlinks
;; An initial project per commoner that have friends...
;; ... as having friends is considered as an initial proxy to the contribution activity of the commoner
if num-friends > 0 [
;; Commoners chose projects that contribute to the products they consume
;; if there is no projct that contributes to the commoners products, then choose the closest one
let product-projects turtle-set [ projectproductlink-neighbors ] of out-consumerlink-neighbors
ifelse any? product-projects [
create-commonerprojectlink-with min-one-of product-projects [ distance myself ] [set-commonerprojectlink-parameters]
] [
if any? projects [
create-commonerprojectlink-with min-one-of projects [ distance myself ] [set-commonerprojectlink-parameters]
]
]
]
let project-tasks (turtle-set [ projecttasklink-neighbors ] of commonerprojectlink-neighbors)
;; Make commoner-task connections with an upper bound of the number of friends.
create-commonertasklinks-to n-of random min (list count project-tasks num-friends) project-tasks [
set-commonertasklink-parameters
set recent-weight random min (list 4 num-friends)
]
set total-contribs sum [recent-weight] of my-out-commonertasklinks
end
to go
ask commoners [
;; contribution
find-project
find-task
contribute
;; friendship
find-friends
;; consumption
find-product
consume
;; bring friends
recommend
;; create project
propose-project
;; leave community
leave
]
product-death
project-death
links-decay
update-positions
update-contrib-distrib
;; Stop conditions
;; ... if there are no commoner
if not any? commoners [ stop ]
;; ... if there are no products
if not any? products [ stop ]
;; ... if there is no project for 30 ticks
ifelse not any? projects [
set ticks-without-projects ticks-without-projects + 1
] [
set ticks-without-projects 0
]
if ticks-without-projects > 30 [ print "STOP: 30 ticks without projects" stop ]
;; Power law fit calculation
if (withR and power-law-tests?)[
if not r?is-powerlaw? [print "STOP: It is not plausible that the distribution of work follows a power-law" stop]
]
if ticks >= maxTicks [ print (word "STOP: The model run for the maximum " maxTicks " ticks") stop ]
if count turtles > maxTurtles [ print (word "STOP: The model reached the maximum " maxTurtles " turtles") stop ]
tick
end
to update-contrib-distrib
set contrib-distrib sentence [total-contribs] of commoners dead-commoners-contribs
set contrib-distrib sort-by > contrib-distrib
end
to update-positions
;; each tick, agents update their positions depending on:
;; 1) the attraction affecting them from their active links: consumer/commonertask/commonerproject
attraction-movements
;; 2) the repulsion towards the edges of the model representing natural decay of activity/interest
repulsion-movements
end
to attraction-movements
;; Movements of agents toward center
;; For each link breed, weighted by number of links and their recent weights
ask turtles [
let linkbreeds (list)
;; Target attraction movements
while [any? my-in-links with [ not member? breed linkbreeds ]] [
ask one-of my-in-links with [ not member? breed linkbreeds ] [
set linkbreeds lput breed linkbreeds
]
let b last linkbreeds
if any? my-in-links with [ breed = b and target-attraction > 0] [
ask one-of my-in-links with [ breed = b and target-attraction > 0] [
if random-float 1 < count [ my-in-links with [breed = b and recent-weight > 0] ] of myself * recent-weight * target-attraction [
move-towards-center myself
]
]
]
]
;; Origin attraction movements
while [any? my-out-links with [ not member? breed linkbreeds ]] [
ask one-of my-out-links with [ not member? breed linkbreeds ] [
set linkbreeds lput breed linkbreeds
]
let b last linkbreeds
if any? my-out-links with [ breed = b and origin-attraction > 0] [
ask one-of my-out-links with [ breed = b and origin-attraction > 0] [
if random-float 1 < count [ my-out-links with [breed = b and recent-weight > 0] ] of myself * recent-weight * origin-attraction [
move-towards-center myself
]
]
]
]
]
end
to repulsion-movements
;; Movement toward edges of the model.
;; Repulsion strength depends on distance to center.
ask turtles with [random-float 1 < ((25 - abs xcor) * repulsion / 25)] [
move-towards-edges self
]
end
to links-decay
ask links with [ recent-weight > 0 and random-float 1 < forget-recent-weight-prob ] [
decrease-weight
]
ask links with [ recent-weight = 0 and random-float 1 < forget-link-prob ] [
die
]
end
to move-towards-edges [ agent ]
ask agent [
if xcor < 0 and xcor > -25 [
;; 'carefully' needed to prevent tied agents to move outside the model
;; for instance, tasks tied to projects
carefully [ set xcor xcor - 1 ] []
]
if xcor > 0 and xcor < 25 [
carefully [ set xcor xcor + 1 ] []
]
]
end
to move-towards-center [ agent ]
ask agent [
if xcor < -1 [
if not any? my-links with [tie-mode = "fixed" and [ xcor ] of other-end >= -1 ] [
set xcor xcor + 1
]
]
if xcor > 1 [
if not any? my-links with [tie-mode = "fixed" and [ xcor ] of other-end <= 1 ] [
set xcor xcor - 1
]
]
]
end
;; Link method to increase current weight
to increase-weight
set total-weight total-weight + 1
set recent-weight min (list max-recent-weight (recent-weight + 1 ))
;; make active links visible
if hidden? [
if (breed = commonertasklinks and not hide-commonertasklinks?) [
set hidden? false
]
if (breed = consumerlinks and not hide-consumerlinks?) [
set hidden? false
]
if (breed = commonerprojectlinks and not hide-commonerprojectlinks?) [
set hidden? false
]
if (breed != commonertasklinks and breed != consumerlinks and breed != commonerprojectlinks) [
set hidden? false
]
]
end
;; Link method to decrease current weight
to decrease-weight
set recent-weight max (list 0 (recent-weight - 1 ))
;; hide
if recent-weight = 0 [
set hidden? true
]
end
to-report project-friends
let me myself
report count commonerprojectlink-neighbors with [friendlink-neighbor? me]
end
to-report find-project-prob
let friends-effect project-friends * find-project-friends
report (min (list max-find-level ((1 + friends-effect) / (1 + distance myself * find-project-dist))))
end
to find-project
if any? projects with [not member? self commonerprojectlink-neighbors] [
ask one-of projects with [not member? self commonerprojectlink-neighbors] [
if random-float 1 < find-project-prob [
create-commonerprojectlink-with myself [set-commonerprojectlink-parameters]
]
]
]
end
;;
to-report task-friends
let me myself
report in-commonertasklink-neighbors with [friendlink-neighbor? me]
end
to-report find-task-prob
let friends-effect count task-friends * find-task-friends
report (min (list max-find-level ((1 + friends-effect) / (( 1 + distance myself * find-task-dist)))))
end
to find-task
let task-of-my-projects
turtle-set [ projecttasklink-neighbors ] of commonerprojectlink-neighbors
if any? task-of-my-projects [
ask one-of task-of-my-projects [
if random-float 1 < find-task-prob [
create-commonertasklink-from myself [ set-commonertasklink-parameters ]
]
]
]
end
to-report contrib-prob
;; returns the probability of the contribution, depending on total contributions, number of friends, recent contribution
let tasklinks [ my-out-commonertasklinks ] of myself
let total-contrib-effect 1 ; + (sqrt ([total-contribs] of myself) * contrib-total-weight)
let recent-contrib-effect 1 ; (ln (e + sum [recent-weight] of [my-out-commonertasklinks] of myself) * contrib-recent-weight)
let friend-task-effect 1 ; (ln (e + count task-friends) * contrib-friend-task-effect)
let total-contrib-to-task-effect 1; + [recent-weight] of in-commonertasklink-from myself
let skill-effect 1
;if (member? skill ([skills] of myself)) [set skill-effect 3]
let prob 1 / (1 + distance myself * contrib-dist)
;;if ([total-weight] of in-commonertasklink-from myself = 0) [
;; set prob min (list 0.02 prob)
;;]
;; Maxium contribution prob is 0.8
report min (list 0.8 prob)
end
to-report contrib-size
report 1
end
to contribute
let contributor self
;; A comoner may contribute to any of its tasks depending on distance
if any? out-commonertasklink-neighbors [
;; TODO: more than one contribution per commoner per tick is possible. Is this the intended behaviour?
ask out-commonertasklink-neighbors [
if random-float 1 < contrib-prob [
;; Representing a contribution happend
ask in-commonertasklink-from myself [
increase-weight
]
ask projecttasklink-neighbors [
if not commonerprojectlink-neighbor? contributor [
create-commonerprojectlink-with contributor [ set-commonerprojectlink-parameters ]
]
ask commonerprojectlink-with contributor [
increase-weight
]
]
ask myself [
set total-contribs total-contribs + 1
]
;; decreasing the ammount of work to be done in the task
set time-required time-required - contrib-size
if time-required < 0 [
;; with some probability, a task generates other task when finished
if random-float 1 < task-hatch-task-prob [
;; create another task in the same project
ask projecttasklink-neighbors [
hatch-t4sks 1 [
set-task-parameters
]
]
]
;; if the project does not have more tasks, it dies and improve its product by changing its x coordinates
ask projecttasklink-neighbors [
if count my-projecttasklinks = 1 [
;; improve product if exists
ifelse any? projectproductlink-neighbors [
ask projectproductlink-neighbors [
;; improve
set xcor min(list -1 (xcor + random 25))
]
]
;; if the project is not linked to a product, it creates a new one
[
hatch-products 1 [
set interest [interest] of myself
set xcor -25 + random 24
set ycor -25 + interest
set-product-parameters
]
]
die ;; project dying
]
]
die ;;task dying
]
]
]
]
end
to-report find-product-prob
report min (list max-find-level (1 / (1 + distance myself * find-product-dist)))
end
to find-product
;; find product probability based on distance to the product
ask one-of products with [not member? self out-consumerlink-neighbors] [
if random-float 1 < find-product-prob [
create-consumerlink-from myself [set-consumerlink-parameters]
]
]
end
to-report find-friend-prob
;; the probability of finding a friend depends on the ammount of recent contribution done to the task
;; TODO: this does no have effect, since it is always bigger than 1
report find-friend * recent-weight
end
to find-friends
;; With some probability set in the parameters,
;; create a friendship relationships with other commoners contributing to the same task
let me self
;; contribs are the active task links
let contribs my-out-commonertasklinks with [ recent-weight > 0 ]
if count contribs > 0 [
;; pick a random active task link
ask one-of contribs [
if random-float 1 < min (list max-find-level find-friend-prob) [
;; ask the task
ask other-end [
;; pick other contributor with recent contributions
if any? my-in-commonertasklinks with [recent-weight > 0 and other-end != me] [
ask one-of my-in-commonertasklinks with [recent-weight > 0 and other-end != me] [
;; ask the other contributor to become my friend
ask other-end [
;; If not a friend, create aa frienship
ifelse not friendlink-neighbor? me [
create-friendlink-with me [set-friendlink-parameters]
]
;; If already friends, increase friendship weight
[
ask friendlink-with me [
increase-weight
]
]
]
]
]
]
]
]
]
end
to-report consume-prob
;; probability of consuming a product, depends on the recent conspumtion of any product and the distance to the product
let current-consumption count my-out-consumerlinks * [recent-weight] of in-consumerlink-from myself
report min (list 0.8 ((1 + current-consumption) / ( 1 + distance myself * consume-dist) ))
end
to consume
if any? out-consumerlink-neighbors [
ask one-of out-consumerlink-neighbors [
if random-float 1 < consume-prob [
ask in-consumerlink-from myself [
increase-weight
]
]
]
]
end
to recommend
;; This is the way we include commoners in the model
;; a commoner recommends a product to a new commoner
;; with a probability that depends on the recent consumption activity of that product by that commoner
;; and the distance of the product to the center of the model
if any? my-out-consumerlinks [
ask one-of my-out-consumerlinks [
let other-product other-end
;; distance of the product to the center of the model
;; note that the other product xcor is negative
let dist 25 - [ xcor ] of other-product
if random-float 1 < min (list max-find-level (recent-weight / ( 1 + dist * recommend-dist))) [
ask myself [
hatch-commoners 1 [
;;create-friendlink-with myself [set-friendlink-parameters]
set-commoner-parameters
;; commoners appear at the edge of the model
set xcor 25
;; kill the default link to the closest product that the commoner creates
ask my-out-consumerlinks [ die ]
;; create a link to the recommended product
create-consumerlink-to other-product [set-consumerlink-parameters]
]
]
]
]
]
end
to-report propose-project-prob
;; The probability of a commoner proposing a new project depends on its recent contribution history and total contribution history
let total-contrib-effect 1 + ln (1 + [total-contribs] of myself) * prop-project-total-contrib
let recent-contrib-effect 1 + ln (1 + sum [recent-weight] of [my-out-commonertasklinks] of myself) * prop-project-recent-contrib
report (total-contrib-effect / 1000) + (recent-contrib-effect / 1000)
end
to propose-project
;; a commoner may hatch a project
if any? my-out-commonertasklinks [
ask one-of my-out-commonertasklinks [
if random-float 1 < min (list max-find-level propose-project-prob) [
ask myself [
hatch-projects 1 [
set xcor -1 * (random 20) - 5
set ycor -25 + interest
carefully [set ycor ycor + random 10 - 5][]
set-project-parameters
let my-product one-of [ projectproductlink-neighbors ] of myself
;; Half of the new projects are related to an existing product, the other half will create a new product when finished
if my-product != nobody and random-float 1 < 0.5 [
create-projectproductlink-with my-product [ set color red ]
]
]
]
]
]
]
end
to leave
;; a commoner leaves the community if it has no recent consumption or contributing activity with a small chance
if not any? my-out-consumerlinks and not any? my-out-commonertasklinks [
if random-float 1 < 0.01 [
set dead-commoners-contribs lput total-contribs dead-commoners-contribs
die
]
]
;; Thre is a small chance for all commoners to leave even if they are currently active
if random-float 1 < leave-prob [
die
]
end
to product-death
ask products with [ not any? my-in-consumerlinks ][
if random-float 1 < (1 / consume-long-forg) [
die
]
]
end
to project-death
ask projects with [ not any? my-commonerprojectlinks ][
if random-float 1 < (1 / project-long-forg) [
ask projecttasklink-neighbors [
die
]
die
]
]
end
@#$#@#$#@
GRAPHICS-WINDOW
205
15
649
460
-1
-1
8.55
1
10
1
1
1
0
0
0
1
-25
25
-25
25
0
0
1
ticks
30.0
BUTTON
25
10
98
43
NIL
setup
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
SLIDER
20
250
185
283
num-interest-categories
num-interest-categories
0
50
50.0
1
1
NIL
HORIZONTAL
SLIDER
20
210
187
243
initial-projects
initial-projects
0
100
30.0
1
1
NIL
HORIZONTAL
SLIDER
20
330
185
363
mean-time-required
mean-time-required
0
100
30.0
1
1
NIL
HORIZONTAL
SLIDER
20
290
185
323
num-skills
num-skills
0
100
50.0
1
1
NIL
HORIZONTAL
SLIDER
20
120
187
153
commoners-num
commoners-num
1
500
247.0
1
1
NIL
HORIZONTAL
BUTTON
105
45
182
78
go once
go
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL
1
BUTTON
105
10
180
43