GEP-in-netlogo

GEP-in-netlogo preview image

1 collaborator

Jihe_gao Jihe Gao (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.0 • Viewed 174 times • Downloaded 21 times • Run 0 times
Download the 'GEP-in-netlogo' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Gene expression programming in NetLogo

WHAT IS IT?

https://en.wikipedia.org/wiki/Gene_expression_programming]">Gene expression programming (GEP) is an evolutionary algorithm that creates computer programs or models. These computer programs are complex tree structures that learn and adapt by changing their sizes, shapes, and composition, much like a living organism. And like living organisms, the computer programs of GEP are also encoded in simple linear chromosomes of fixed length. Thus, GEP is a genotype-phenotype system, benefiting from a simple genome to keep and transmit the genetic information and a complex phenotype to explore the environment and adapt to it.

HOW IT WORKS

You can find details in http://www.gene-expression-programming.com/webpapers/GEP.pdf

HOW TO USE IT

0, (optional) modify "gp-target-answer" in code tab, which is by default

to-report gp-target-answer report ticks * 3 end

gp-target-answer is the target function which is the goal for the GEP to find out.

1, click "setup" button (or run "setup" in command-center) 2, click "gp-episode" 3, Observe the GEP process by watching "Fitness Plot", or hit "gp-show-all", "gp-showbest" or "select-one" to see code(s) and code tree(s). If the plot line "best" reached and stablized at 1, then there is some codeturtles successfully invented the target function. If the "best", "avg" is far below 1 at long run, you may change the option in "breed_option" chooser to see if there is some improvement. If still

CREDITS AND REFERENCES

https://github.com/jihegao/NetLogo_GEP

contact: jihe.gao(at)jiejiaotech.com

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

; ------------------------------------------------------------------------------------------
;
; An example of Genetic Expression Programming in NetLogo
;
; Author:   jihe.Gao@jiejiaotech.com
;
; ------------------------------------------------------------------------------------------
extensions [csv table time]

breed [ Stocks stock ]
breed [ Investors investor ]
breed [ genes gene ]
breed [ codeturtles codeturtle ]

globals [
  gp_weighted_gene_list
  gp_syntaxlist
  gp_generation
  avgfitness
  bestfitness
  worstfitness
  gp_best_fitness_this_gen
  the_watched_one
]


genes-own
[
  c_type
  input_var_list
  output_type  ; void (command), reporter, boolean
  odds
]

codeturtles-own
[
  my_code
  my_tree
  gp_raw_fitness
  birthtime
  result
]

to setup
  clear-all
  reset-ticks
  gp-setup
end 




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                   START OF GP LIBRARY CODE                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;      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-episode"
;;
;; Notes
;;
;;  Structure of a tree node:
;;    ["NODE_VALUE"  RTYPE_*  TYPE_*  CHILD1  CHILD2  ... ]
;;

to-report gp-target-answer
  report ticks * 3
end 

to gp-setup
  gp-setup-genes
  gp-setup-codeturtles
end 

to gp-setup-genes
  ;set gp_syntaxlist csv:from-file "genes.csv"
  set gp_syntaxlist init-gp-syntaxlist
  foreach gp_syntaxlist [ [?]->
    if not any? turtles with [label = first ?][
      create-genes 1 [
        ;["gp_if" "TYPE_COMMAND" "RTYPE_BOOLEAN" "RTYPE_COMMAND" 10]
        set label first ?
        set input_var_list sublist ? 2 (length ? - 1)
        set output_type item 1 ?
        set odds last ?
        move-to one-of patches with [pycor = min-pycor]
      ]
    ]
  ]
  set gp_weighted_gene_list (reduce [[?1 ?2]-> (sentence ?1 ?2)] (map [[?]-> n-values ([odds] of ?) [[label] of ?] ] sort genes))
end 

to gp-setup-codeturtles
  create-codeturtles population-size [ gp-initialize-codeturtle [0]]
end 


;; whenever codeturtles are created (at the beginning of each generation) this procedure is run
;; gen_config: (list [my_code] of winner [my_code] of partner )

to gp-initialize-codeturtle [gene_lists]
  ifelse gene_lists = [0]
  [
    set my_code (gp-weighted-random-genes initial-chromosome-length)
  ]
  [
    set my_code (gp-cross-chromosomes gene_lists)
  ]
  carefully [
    set my_tree gp-compile-tree (sublist my_code (1 + position "Q" my_code) length my_code)
  ][set my_tree "0"]
  set birthtime ticks
  set size 2
  set shape "circle"
  set gp_raw_fitness 100  ; large number (very unfit)
  set xcor random-xcor ; find the start patch
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

to-report gp-weighted-random-genes [ length_gene ]
  report fput "Q" n-of length_gene gp_weighted_gene_list
end 

to-report gp-cross-chromosomes [DNA_lists]
  let DNA0 first DNA_lists
  let DNA1 last  DNA_lists
  ifelse length DNA0 < length DNA1
  [ set DNA1 sublist DNA1 0 (1 + length DNA0) ]
  [ if length DNA0 > length DNA1 [
    set DNA1 (sentence DNA1 n-values (length DNA0 - length DNA1) ["0"]) ]
  ]
  let dna []
  (foreach DNA0 DNA1 [ [d1 d2]->
    ifelse (random 100 < crossover-chance)
    [ set dna lput d2 dna ]
    [
      ifelse (random 100 < mutate-chance)
      [ set dna lput (one-of gp_weighted_gene_list) dna ]
      [ set dna lput d1 dna ]]
  ])
  report dna
end 


;;

to-report gp-compile-tree [this_code]
  ; this_code : [ "gp_+" "3" "8" "32" "0" ]

  let thegene one-of turtles with [label = first this_code]
  set this_code but-first this_code
  let tree reduce [[?1 ?2]-> (word ?1 " " ?2)] [(sentence label input_var_list)] of thegene

  while [not empty? this_code and member? "R" tree][
    set thegene one-of turtles with [label = first this_code]
    set this_code but-first this_code
    let index position "R" tree
    set tree replace-item index tree (insert-node-string thegene)
  ]
  report tree
end 

to-report insert-node-string [thegene]
  report reduce [[?1 ?2]-> (word " " ?1 " " ?2 " ")] [(sentence label map [[?]-> (word "(" ? ")")] input_var_list)] of thegene
end 







;; This is the main "go" procedure for the gp-library.

to gp-episode
  gp-create-next-generation ; breed_option = "wta" "equal"
  gp-run-codeturtles
  gp-update-fitness
  if move? [ask codeturtles [set ycor min-pycor + gp-fitness * world-height - 1]]
  gp-plot
  tick
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 gp-run-codeturtles
  ask codeturtles [carefully [set result (runresult my_tree)][die]]
end 

to gp-update-fitness
  ask codeturtles [
    set gp_raw_fitness gp-calculate-fitness
  ]
end 

; user-defined fitness function ( cost function )

to-report gp-calculate-fitness
  report abs (gp-target-answer - result)
end 

to-report gp-fitness
  report 1 / (1 + gp_raw_fitness)
end 

to gp-create-next-generation

  if breed_option = "wta" ; winner takes all
  [
    let winner min-one-of codeturtles [gp_raw_fitness]
    repeat population-size - count turtles [
      let partner one-of codeturtles
      gp-breed-new-codeturtle (list gp_generation [my_code] of winner [my_code] of partner ) ]
  ]
  if breed_option = "equal"
  [
    repeat population-size - count turtles [
      let couple n-of 2 codeturtles with [gp-fitness >= avgfitness]
      if couple = nobody [set couple n-of 2 codeturtles]
      gp-breed-new-codeturtle (list [my_code] of first sort couple [my_code] of last sort couple) ]
  ]

if count codeturtles > n-die-out-each-tick [ ask n-of n-die-out-each-tick codeturtles [ die ] ]
end 


; gen_config: (list [my_code] of turtle1 [my_code] of turtle2 )

to gp-breed-new-codeturtle [gene_lists]
  create-codeturtles 1 [ gp-initialize-codeturtle gene_lists ]
end 







;; plot the fitnesses of the current generation, and update the gp-best-fitness-this-gen variable

to gp-plot
  if any? codeturtles [
    set bestfitness max [ gp-fitness ] of codeturtles
    set avgfitness mean [ gp-fitness ] of codeturtles
    set worstfitness min [ gp-fitness ] of codeturtles
    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 



;; 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 " tree: " my_tree " result: " result )]
end 

to gp-show-all
  ;clear-output
  foreach sort-by [[?1 ?2]-> [gp_raw_fitness] of ?1 < [gp_raw_fitness] of ?2] codeturtles
  [
    [?]-> ask ? [
      show (word self " code: " my_code " tree: " my_tree " result: " result )
    ]
  ]
end 

to select-one
  if mouse-down? [
    set the_watched_one closest-codeturtle mouse-xcor mouse-ycor turtles with [breed != links]
    ask links [die]
    ask turtles with [shape = "square"][die]
    ask codeturtles [set label ""]
    watch the_watched_one
    ask the_watched_one [
      set label my_tree
      setxy mouse-xcor mouse-ycor
    ]
    display
  ]
end 

to-report closest-codeturtle [x y agent-set]  ; Return closest agent to x, y
 report min-one-of codeturtles [distancexy x y]
end 

to reset-codeturtles
end 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                    END OF GP LIBRARY CODE                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; These are atom genes of procedures and reporters, that help form the DNA of the codeturtles.

to-report init-gp-syntaxlist
report [
  ["gp_+"      "TYPE_OPERATOR" "R" "R" 10]
  ["gp_-"      "TYPE_OPERATOR" "R" "R" 10]
  ["gp_*"      "TYPE_OPERATOR" "R" "R" 5]
  ["gp_safediv" "TYPE_REPORTER" "R" "R" 5]
  ["gp_random"  "TYPE_REPORTER" "R" 10]
  ["gp_ticks"   "TYPE_REPORTER" 5]
  ["0" "TYPE_REPORTER" 20]
  ["1" "TYPE_REPORTER" 20]
  ["2" "TYPE_REPORTER" 20]
  ["3" "TYPE_REPORTER" 20]
  ["4" "TYPE_REPORTER" 20]
  ["5" "TYPE_REPORTER" 20]
  ["8" "TYPE_REPORTER" 20]
  ["16" "TYPE_REPORTER" 20]
  ["32" "TYPE_REPORTER" 20]
]
end 

to-report gp_ticks
  report ticks
end 

to-report gp_ifelse-value [bool tree1 tree2]
  report ifelse-value bool [ runresult tree1 ][ runresult tree2 ]
end 

to-report gp_+ [input1 input2]
  report input1 + input2
end 

to-report gp_- [input1 input2]
  report input1 - input2
end 

to-report gp_* [input1 input2]
  report input1 * input2
end 

to-report gp_safediv [input1 input2]
  report ifelse-value (input2 != 0) [input1 / input2][999999]
end 

to-report gp_random [input]
  report random input
end 

to-report gp_>= [input1 input2]
  report input1 >= input2
end 

to-report gp_<= [input1 input2]
  report input1 <= input2
end 

to-report gp_> [input1 input2]
  report input1 >= input2
end 

to-report gp_< [input1 input2]
  report input1 >= input2
end 

There are 4 versions of this model.

Uploaded by When Description Download
Jihe Gao almost 7 years ago unmove by default Download this version
Jihe Gao almost 7 years ago remove read-from-string Download this version
Jihe Gao almost 7 years ago remove distancexy-nowrap Download this version
Jihe Gao almost 7 years ago Initial upload Download this version

Attached files

File Type Description Last updated
GEP-in-netlogo.png preview Preview for 'GEP-in-netlogo' almost 7 years ago, by Jihe Gao Download

This model does not have any ancestors.

This model does not have any descendants.