-
Notifications
You must be signed in to change notification settings - Fork 2
/
gp.nls
608 lines (534 loc) · 20.6 KB
/
gp.nls
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
breed [ codeturtles codeturtle ]
globals
[
TYPE_COMMANDBLOCK
TYPE_COMMAND
TYPE_OPERATOR
TYPE_REPORTER
RTYPE_ANY ; used for functions like "tree-count-nodes", to match any node return type
RTYPE_VOIDBLOCK
RTYPE_VOID
RTYPE_NUMERIC
RTYPE_BOOLEAN
gp-syntaxlist-void
gp-syntaxlist-numeric
gp-syntaxlist-boolean
gp-randseed
gp-generation
gp-best-fitness-this-gen
;; add your own global variables here...
weightsum
lastgenlist
fitnesslist
bestfitness
avgfitness
worstfitness
gp-current-stock
]
codeturtles-own
[
gp-codetree
gp-compiledcode
gp-raw-fitness
l-step ; learning-step
;; add your own codeturtle variables here
expectation
p-price ; a list restore past projections of stock price
my-cycle ;
]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; START OF GP LIBRARY CODE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IMPORTANT: To create your own genetic programming model, you shouldn't need to
;; modify any of the GP Library Code. Instead, you should just change the
;; following procedures, which are found after the end of the gp library section:
;; gpuser-setup-syntax (determines the ingredients for randomlly generated code trees)
;; gpuser-run-codeturtles (determines what happens to the codeturtles during a generation)
;; gpuser-initialize-codeturtle (run when each codeturtle that is created, sets initial variables, etc)
;; gpuser-calculate-raw-fitness (reports some measure analogous to "distance to goal", where 0 is perfection)
;; gpuser-calculate-adjusted-fitness (reports a value between 0 and 1, where 1 is perfection)
;;
;; In addition, your setup should call "gp-setup" and your go should call "gp-go"
;;
;; Notes
;;
;; Structure of a tree node:
;; ["NODE_VALUE" RTYPE_* TYPE_* CHILD1 CHILD2 ... ]
;;
to gp-setup
;; these are just constants -- they could just as easily be set to unique integers
;; however, making them abbreviated strings makes debugging easer.
set TYPE_COMMANDBLOCK "cb"
set TYPE_COMMAND "c"
set TYPE_OPERATOR "o"
set TYPE_REPORTER "r"
set RTYPE_ANY ""
set RTYPE_VOIDBLOCK "vb"
set RTYPE_VOID "v"
set RTYPE_NUMERIC "n"
set RTYPE_BOOLEAN "b"
gpuser-setup-syntax
set gp-randseed randomseed
if (fix-random-seed?)
[ random-seed gp-randseed ]
ask codeturtles [die]
create-codeturtles population-size [
set gp-codetree (gp-tree-random RTYPE_VOIDBLOCK initial-code-max-depth branch-chance)
set gp-compiledcode (gp-tree-compile gp-codetree)
set p-price n-values 10 [last h-prices + random 10 - random 10]
set my-cycle 2 + random 8
gpuser-initialize-codeturtle
;set gp-raw-fitness gp-calculate-fitness my-cycle
]
end
;; reports the sum of the weights from a weighted list...
to-report gp-weight-sum-from-weighted-list [ thelist onlyterminals? ]
let thesum 0
foreach thelist
[
if (not onlyterminals? or (length ? <= 3))
[ set thesum (thesum + (last ?)) ]
]
report thesum
end
;; reports a random entry from a syntaxlist, where the chance of an entry being chosen
;; is weighted by the number that is the last entry of the element
;; if onlyterminals is true, then it only chooses from terminals
to-report gp-random-from-weighted-list [ thelist thesum onlyterminals?]
if (thesum <= 0) ;; if it can't find any terminals in the list, then choose a random nonterminal
[
if-else (onlyterminals?)
[ report (gp-random-from-weighted-list thelist (gp-weight-sum-from-weighted-list thelist false) false) ]
[ report [] ]
]
let choice (random-float thesum)
let partsum 0
foreach thelist
[
if (not onlyterminals? or (length ? <= 3))
[ set partsum (partsum + (last ?)) ]
if (partsum >= choice)
[ report ? ]
]
end
;; creates a random code tree
;; -- used to generate the initial population, and to create mutations
to-report gp-tree-random [node_rtype depthlimit branch_chance ]
if (node_rtype = RTYPE_VOIDBLOCK)
[
if (depthlimit <= 1)
[ report (list "[]" RTYPE_VOIDBLOCK TYPE_COMMANDBLOCK) ]
if (depthlimit <= 3)
[ set branch_chance 0 ]
ifelse (random-float 1.0 < branch_chance)
[
report (sentence (list "[]" RTYPE_VOIDBLOCK TYPE_COMMANDBLOCK )
(n-values 2 [ (gp-tree-random RTYPE_VOIDBLOCK (depthlimit - 1) (branch_chance * .90)) ]))
]
[
report (sentence (list "[]" RTYPE_VOIDBLOCK TYPE_COMMANDBLOCK )
(n-values 3 [ (gp-tree-random RTYPE_VOID (depthlimit - 1) (branch_chance * .90)) ]))
]
]
let syntaxlist []
ifelse (node_rtype = RTYPE_VOID)
[ set syntaxlist gp-syntaxlist-void ]
[ifelse (node_rtype = RTYPE_NUMERIC)
[ set syntaxlist gp-syntaxlist-numeric ]
[if (node_rtype = RTYPE_BOOLEAN)
[ set syntaxlist gp-syntaxlist-boolean ]]]
let onlyterminals? false
if (depthlimit <= 1 or branch_chance < .01 )
[ set onlyterminals? true ]
let lRecord (gp-random-from-weighted-list syntaxlist (gp-weight-sum-from-weighted-list syntaxlist onlyterminals?) onlyterminals?)
report (sentence (list (item 0 lRecord) node_rtype (item 1 lRecord))
(n-values (length lRecord - 3) [ (gp-tree-random (item (? + 2) lRecord) (depthlimit - 1) branch_chance) ]))
end
;; recursive routine to compile a codetree into valid netlogo code that can be run.
to-report gp-tree-compile-rec [ tree parenttype indent]
let node_type (item 2 tree)
if (length tree <= 3)
[
ifelse (node_type = TYPE_COMMANDBLOCK and parenttype = TYPE_COMMANDBLOCK)
[ report "" ]
[ report (item 0 tree) ]
]
ifelse (node_type = TYPE_OPERATOR)
[
report (word "(" gp-tree-compile-rec (item 3 tree) node_type (indent + 1) " " item 0 tree " "
gp-tree-compile-rec (item 4 tree) node_type (indent + 1) ")")
][
ifelse (node_type = TYPE_REPORTER)
[
report (word "(" (item 0 tree) " " (reduce [ (word ?1 " " ?2) ] (map [gp-tree-compile-rec ? node_type (indent + 1)] (sublist tree 3 (length tree)))) ")")
][
ifelse (node_type = TYPE_COMMAND)
[
report (word (item 0 tree) " " (reduce [ (word ?1 " " ?2) ] (map [gp-tree-compile-rec ? node_type (indent + 1)] (sublist tree 3 (length tree)))) " ")
][
ifelse (node_type = TYPE_COMMANDBLOCK)
[
let indentstr "" ;; how far to indent the code, as a result of nested blocks.
if (parenttype = TYPE_COMMANDBLOCK)
[ set indent (indent - 1) ]
if (indent > 0)
[ set indentstr (reduce [ (word ?1 ?2) ] (n-values indent [ " " ])) ]
let compiledargs (map [gp-tree-compile-rec ? node_type (indent + 1) ] (sublist tree 3 (length tree)))
ifelse (parenttype = TYPE_COMMANDBLOCK)
[ report (reduce [ (word ?1 "\n" indentstr ?2) ] compiledargs) ]
[ report (word "[\n" indentstr (reduce [ (word ?1 "\n" indentstr ?2) ] compiledargs) "\n" indentstr "]") ]
][
report []
]]]]
end
;; routine to compile a codetree into valid netlogo code that can be run.
to-report gp-tree-compile [ tree ]
report gp-tree-compile-rec tree TYPE_COMMANDBLOCK 0
end
;; reports the number of nodes (with a given RTYPE) in a code tree
to-report gp-tree-count-nodes [ tree rtype-filter ]
let childcount 0
if (length tree > 3) ; if node has children
[ set childcount (reduce [ ?1 + ?2 ] (map [gp-tree-count-nodes ? rtype-filter] (sublist tree 3 (length tree)))) ]
report childcount + (ifelse-value (rtype-filter = RTYPE_ANY or rtype-filter = (item 1 tree)) [ 1 ] [ 0 ])
end
;; recursive routine to report a chosen (choice) node of a given RTYPE from a code tree
to-report gp-tree-getnode-rec [ tree choice rtype-filter counter]
if (rtype-filter = RTYPE_ANY or rtype-filter = (item 1 tree))
[
if (counter = choice)
[ report (list tree (counter + 1)) ]
set counter counter + 1
]
if (length tree <= 3) ; terminal
[ report (list [] counter) ]
let pair []
let mysublist (sublist tree 3 (length tree))
let n 0
while [ n < length mysublist ]
[
set pair (gp-tree-getnode-rec (item n mysublist) choice rtype-filter counter)
set counter (item 1 pair)
if (counter > choice)
[ report pair ]
set n (n + 1)
]
report (list [] counter)
end
;; routine to report a chosen (choice) node of a given RTYPE from a code tree
to-report gp-tree-getnode [ tree choice rtype-filter]
report (item 0 (gp-tree-getnode-rec tree choice rtype-filter 0))
end
;; recursive routine that replaces a chosen node with a given subtree, and reports the resulting tree
to-report gp-tree-replacenode-rec [ tree choice subtree rtype-filter counter ]
if (rtype-filter = RTYPE_ANY or rtype-filter = (item 1 tree))
[
if (counter = choice)
[ report (list subtree (counter + 1)) ]
set counter counter + 1
]
if (length tree <= 3) ; terminal
[ report (list tree counter) ]
let resulttree (sublist tree 0 3)
let pair []
let mysublist (sublist tree 3 (length tree))
let n 0
while [ n < length mysublist ]
[
set pair (gp-tree-replacenode-rec (item n mysublist) choice subtree rtype-filter counter)
set counter (item 1 pair)
set resulttree (lput (item 0 pair) resulttree)
set n (n + 1)
]
report (list resulttree counter)
end
;; routine that replaces a chosen node with a given subtree, and reports the resulting tree
to-report gp-tree-replacenode [ tree choice subtree rtype-filter]
report (item 0 (gp-tree-replacenode-rec tree choice subtree rtype-filter 0))
end
;; recursive routine that reports a mutated version of a code tree
to-report gp-tree-mutate-rec [ tree choice counter ]
if (counter = choice)
[ report (list (gp-tree-random (item 1 tree) (initial-code-max-depth * .50) (branch-chance * .75)) counter) ]
if (length tree <= 3) ; terminal
[ report (list tree counter)]
let resulttree (sublist tree 0 3)
let pair []
let mysublist (sublist tree 3 (length tree))
let n 0
while [ n < length mysublist ]
[
set pair (gp-tree-mutate-rec (item n mysublist) choice (counter + 1))
set counter (item 1 pair)
set resulttree (lput (item 0 pair) resulttree)
set n (n + 1)
]
report (list resulttree counter)
end
;; routine that reports a mutated version of a code tree
to-report gp-tree-mutate [ tree ]
let choice random (gp-tree-count-nodes tree RTYPE_ANY)
report (item 0 (gp-tree-mutate-rec tree choice 0))
end
;; routine that reports a new tree, generated by crossing tree1 with tree2
to-report gp-tree-crossover [ tree1 tree2 ]
let choice random (gp-tree-count-nodes tree1 RTYPE_ANY)
let subtree (gp-tree-getnode tree1 choice RTYPE_ANY)
;;debug;;
if show-debug? = TRUE [ print (word "choice= " choice " subt= " subtree ) ]
let num-attach-points (gp-tree-count-nodes tree2 (item 1 subtree))
if (num-attach-points <= 0)
[ report tree2 ]
let attach-choice random num-attach-points
report (gp-tree-replacenode tree2 attach-choice subtree (item 1 subtree))
end
;; routine that creates a new codetree, given all of the code from the
to gp-breed-new-codeturtle ;[ lastgenlist weightsum ]
let gen-op-choice random-float (clone-chance + mutate-chance + crossover-chance)
let the-random-list (gp-random-from-weighted-list lastgenlist weightsum false)
if not empty? the-random-list [
let ct1 (first the-random-list)
ifelse (gen-op-choice < clone-chance)
[
create-codeturtles 1 [
set p-price n-values 100 [last h-prices + random 10 - random 10]
set my-cycle 2 + random 9
gpuser-initialize-codeturtle
set gp-codetree ([gp-codetree] of ct1)
set gp-compiledcode ([gp-compiledcode] of ct1)
set color [color] of ct1
]
][
ifelse (gen-op-choice < clone-chance + mutate-chance)
[
create-codeturtles 1 [
set p-price n-values 100 [last h-prices + random 10 - random 10]
set my-cycle 2 + random 9
gpuser-initialize-codeturtle
set gp-codetree (gp-tree-mutate ([gp-codetree] of ct1))
set gp-compiledcode (gp-tree-compile gp-codetree)
;;set color color-of ct1
]
][
;; otherwise, do crossover
let ct2 (first (gp-random-from-weighted-list lastgenlist weightsum false))
create-codeturtles 1 [
gpuser-initialize-codeturtle
set p-price n-values 100 [last h-prices + random 10 - random 10]
set my-cycle 2 + random 9
set gp-codetree (gp-tree-crossover ([gp-codetree] of ct1) ([gp-codetree] of ct2))
set gp-compiledcode (gp-tree-compile gp-codetree)
let rgbvector (map [ (?1 + ?2) / 2 ] (extract-rgb ([color] of ct1)) (extract-rgb ([color] of ct2)))
set color approximate-rgb (item 0 rgbvector) (item 1 rgbvector) (item 2 rgbvector) ]
]
] ]
end
;; routine that creates a new generation of codeturtles
to gp-create-next-generation
set gp-generation (gp-generation + 1)
ask codeturtles [ set gp-raw-fitness gp-calculate-fitness my-cycle ]
set lastgenlist [ (list self gp-fitness) ] of codeturtles
let popsize max-popsize - (count codeturtles)
if popsize > 0 [
set weightsum (gp-weight-sum-from-weighted-list lastgenlist false)
repeat population-size
[ gp-breed-new-codeturtle ];lastgenlist weightsum ]
]
; foreach lastgenlist
; [ ask first ? [ die print "die" ] ]
end
;; This is the main "go" procedure for the gp-library.
;; Run iteratively, this procedure performs genetic programming.
to gp-go
if (fix-random-seed?)[
set gp-randseed gp-randseed + 1
random-seed gp-randseed
]
gpuser-run-codeturtles
ask codeturtles [
set p-price but-first lput expectation p-price
set gp-raw-fitness gp-calculate-fitness my-cycle
set l-step l-step + 1 ]
if any? codeturtles [gp-plot]
ask codeturtles with [l-step > max-learning-step or gp-raw-fitness > avgfitness * 1.2 or expectation < 1][ die ]
ifelse any? codeturtles
[ gp-create-next-generation ]
[ gp-setup ]
end
;; plot the fitnesses of the current generation, and update the gp-best-fitness-this-gen variable
to gp-plot
set fitnesslist [ gp-raw-fitness ] of codeturtles
set bestfitness min fitnesslist
set avgfitness mean fitnesslist
set worstfitness max fitnesslist
set gp-best-fitness-this-gen bestfitness
set-current-plot "Fitness Plot"
set-current-plot-pen "avg"
plot avgfitness
set-current-plot-pen "best"
plot bestfitness
set-current-plot-pen "worst"
plot worstfitness
end
;; show the behavior of the last generation of codeturtles again
to gp-replay
ask codeturtles
[
let savetree gp-codetree
let savecompiled gp-compiledcode
let savecolor color
pu
gpuser-initialize-codeturtle
set gp-codetree savetree
set gp-compiledcode savecompiled
set color savecolor
]
if (fix-random-seed?)
[ random-seed gp-randseed ]
gpuser-run-codeturtles
end
;; displays the code of the best-this-gen codeturtle in the output box
to gp-showbest
clear-output
ask one-of (codeturtles with-min [ gp-raw-fitness ])
[ print (word self "\n expectation: " expectation "\n" gp-compiledcode ) ]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; END OF GP LIBRARY CODE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; These are codeturtle procedures and reporters, that help form the DNA of the codeturtles.
;; (See the gp-setup-syntax procedure below for exactly what the DNA is made of.)
;;
;["price" "intrinsic price" "dealed-volume" "l-buy" "l-sell" "p_lin5" "p_lin30" "sd" ]
; 1 2 3 4 5 6 7 8
to-report prev-price [prev]
let pp stats:get-observations ([d-table] of gp-current-stock) "price"
; report item (length pp - prev) pp
report last pp
end
to-report mean-price
let pp stats:get-observations ([d-table] of gp-current-stock) "price"
report mean sublist pp (length pp - 5) (length pp)
end
to-report intr-value
report last stats:get-observations ([d-table] of gp-current-stock) "intr-value"
end
to-report stock-dealed-volume
report last stats:get-observations ([d-table] of gp-current-stock) "dealed-volume"
end
to-report stock-long-orders
report last stats:get-observations ([d-table] of gp-current-stock) "l-buy"
end
to-report stock-short-orders
report last stats:get-observations ([d-table] of gp-current-stock) "l-sell"
end
to-report stock-p_lin_5
report round last stats:get-observations ([d-table] of gp-current-stock) "p_lin5"
end
to-report stock-p_lin_30
report round last stats:get-observations ([d-table] of gp-current-stock) "p_lin30"
end
to-report stock-sd
report round last stats:get-observations ([d-table] of gp-current-stock) "sd"
end
to set-expectation+ [n]
set expectation (prev-price 1) + n
end
to set-expectation- [n]
set expectation (prev-price 1) - n
end
to tech-proj
set expectation stock-p_lin_30
end
to fund-proj
set expectation intr-value
end
to gpuser-setup-syntax
;; Void ingredients for codeturtle's random code generation
;; This list contains procedures (which do not report a value) that code turtles can use.
;; (They can be either built-in NetLogo primitives or user-defined procedures in this model)
set gp-syntaxlist-void (list
; (list "if" TYPE_COMMAND RTYPE_BOOLEAN RTYPE_VOIDBLOCK 10)
(list "ifelse" TYPE_COMMAND RTYPE_BOOLEAN RTYPE_VOIDBLOCK RTYPE_VOIDBLOCK 10)
(list "set-expectation+" TYPE_COMMAND RTYPE_NUMERIC 5)
(list "set-expectation-" TYPE_COMMAND RTYPE_NUMERIC 5)
; (list "tech-proj" TYPE_COMMAND 10)
; (list "fund-proj" TYPE_COMMAND 10)
)
;; Numeric ingredients for codeturtle's random code generation
;; This list contains reporters and operators which return numeric values
set gp-syntaxlist-numeric (list
(list "+" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list "-" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list "*" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 5) ;; weighted less
;(list "safediv" TYPE_REPORTER RTYPE_NUMERIC RTYPE_NUMERIC 1) ;; weighted even less
(list "expectation" TYPE_REPORTER 10)
(list "random" TYPE_REPORTER RTYPE_NUMERIC 10)
(list "intr-value" TYPE_REPORTER 10)
(list "prev-price" TYPE_REPORTER RTYPE_NUMERIC 10)
;; (list "stock-dealed-volume" TYPE_REPORTER 5)
;; (list "stock-long-orders" TYPE_REPORTER 5)
;; (list "stock-short-orders" TYPE_REPORTER 5)
;; (list "stock-sd" TYPE_REPORTER 5)
(list "mean-price" TYPE_REPORTER 10)
(list "stock-p_lin_5" TYPE_REPORTER 20)
(list "stock-p_lin_30" TYPE_REPORTER 10)
; (list "0" TYPE_REPORTER 10)
(list "1" TYPE_REPORTER 5)
(list "2" TYPE_REPORTER 5)
(list "3" TYPE_REPORTER 5)
(list "4" TYPE_REPORTER 5)
(list "5" TYPE_REPORTER 5)
(list "8" TYPE_REPORTER 5)
(list "16" TYPE_REPORTER 1)
(list "32" TYPE_REPORTER 1)
;(list "random-float" TYPE_REPORTER RTYPE_NUMERIC 1) ;; used very infrequently
)
;; Boolean ingredients for codeturtle's random code generation
;; This list contains reporters and operators which return boolean values
set gp-syntaxlist-boolean (list
(list "true" TYPE_REPORTER 1)
(list "false" TYPE_REPORTER 1)
;; (list ">" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
;; (list "<" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list ">=" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list "<=" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list "=" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
; (list "!=" TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC 10)
(list "and" TYPE_OPERATOR RTYPE_BOOLEAN RTYPE_BOOLEAN 5)
(list "or" TYPE_OPERATOR RTYPE_BOOLEAN RTYPE_BOOLEAN 5)
)
end
;; whenever codeturtles are created (at the beginning of each generation) this procedure is run
to gpuser-initialize-codeturtle
set size 1
set gp-raw-fitness 100 ; large number (very unfit)
; this color may not always stick, since codeturtles pass color
; from one generation to the next, in a hereditary way (somewhat)
set color (who * 10 - 5)
set expectation random 20
set xcor random-xcor ; find the start patch
;set heading 0
end
;; This procedure controls what the codeturtles do during a given generation.
;;
to gpuser-run-codeturtles
ask codeturtles
[
; the result of running (gp-compiledcode) is a new expectation price
carefully [ run (gp-compiledcode) ] [ print error-message print gp-compiledcode ]
]
end
;; codeturtles procedure
;; Think of this reporter as "how far am I from my goal?"
;; Thus, a perfect codeturtle has a raw fitness of 0
;; a bad codeturtle has an arbitrarily large raw fitness
;;
to-report gp-calculate-fitness [cycle]
; let f variance (map [?1 - ?2] (sublist p-price (length p-price - cycle) (length p-price)) (sublist h-prices (length h-prices - 1 - cycle) (length h-prices - 1)))
let f variance (map [(last h-prices - item ?1 p-price) * ?2] (sublist [0 1 2 3 4 5 6 7 8 9 ] 0 cycle) (sublist (read-from-string cross_fitness_weight) 0 cycle))
report ifelse-value (f > 100) [100][f]
end
to-report gp-fitness
report 1 / (1 + gp-raw-fitness)
end