;TODO calcular a ocupacao otima em cada via a cada passo - feito
;TODO armazenar ocupacao media (atual e otima) - feito
;TODO plotar capacidade das vias - feito
;TODO distribuicao proporcional nao deve considerar motoristas finalizados - feito
;BUGFIX distribuicao proporcional de motoristas (esta zerando quando motoristas ja passaram pela intersecao) - feito
;BUGFIX distribuicao proporcional tem que ser incrementada a cada passo, e nao setada - feito
;BUGFIX historico e' zerado quando os 2 valores sao iguais - feito
;TODO atualizar historico - feito
;HEISENBUGFIX algumas vezes o agente fica com melhor via = -1 - feito
;TODO truncar historico entre 60:140? - feito
;TODO atualizar pontuacao - aparentemente feito
;TODO colorir arestas de acordo com ocupacao media - feito
;TODO historico / ocupacao percentual ou fracionario? - noneed
;TODO plotar tempos de viagem por par OD - feito
;BUGFIX historico limitado em 60 - FEITO
;TODO forcar motoristas a so 1 par OD - feito
;TODO forcar motoristas teimosos
;TODO implementar um enroute? para retirar escolha gulosa -feito
;TODO ver questao da ponderacao da previsao - feito
;BUGFIX nao esta plotando ocupacao media - corrigido

globals [
  num-intersections 
  num-roads 
  ideal-segment-length
]

breed [ intersections intersection ]
breed [ drivers driver ]

directed-link-breed [ roads road ]

intersections-own [ 
   x y
   id
]

roads-own [
  road-id  ;identificador da via
  capacity ;capacidade [130:250]
  num-drv  ;numero de motoristas
  opt-num-drv ;numero proporcional de motoristas
  
  avg-num-drv ;ocupacao real media
  avg-opt-drv ;ocupacao proporcional media
  
  fftt  ;free-flow travel time
  travel-time ;tempo de viagem
  
  history ;historico de ocupacao
]

drivers-own [
  current-route ;lista de road-id descrevendo a rota atual
  route-weight  ;peso da rota a ser calculado na chegada
  actual-tt     ;tempo de viagem real do motorista
  
  optimal-route ;rota otima (menor #nos ate o destino)
  expected-tt   ;tempo de viagem esperado (considera os motoristas no mesmo par OD
  
  roads-weight  ;lista com o peso das rotas TODO: sera' necessario?
  
  origin        ;ID do no' de origem
  destination   ;ID do no' de destino
  current-node  ;ID do no' atual
  
  current-road  ;via atual (a via mesmo, nao o ID)
  
  predictors       ;lista com 'num-roads' conjuntos de 'num-predictors' preditores
  predictors-score ;lista com 'num-roads' conjuntos de 'num-predictors' pontos p. preditores
  best-predictors  ;lista com o indice do melhor preditor por via (?)
]

to setup 
    clear-all
    build-network
    setup-drivers
    
    ask intersections [ set label id ]
end

to go
  reset-road-network
  
  while [drivers-not-arrived] [
    step
  ]
  
  experience-travel-times
  update-predictors-score
  update-history
  
  update-roads-visual
  
  do-plots
  
  tick
end

to step 
  distribute-drivers-proportionally
  choose-next-road
  advance
end

to setup-drivers
  create-drivers num-drivers [
      set origin 1 + random 3  ;origem em nos 1, 2 ou 3
      set destination 8 + random 3 ;destino em 8, 9 ou 10
      
      set current-node origin
      set current-route []
      set optimal-route calculate-opt-route origin destination
      
      set predictors n-values num-roads [random-predictors]
      set predictors-score n-values num-roads [initial-scores]
      set best-predictors n-values num-roads [random num-predictors]
      
      set roads-weight n-values num-roads [1]
      
      let myorig origin
      let mydest destination
      move-to one-of intersections with [id = myorig]
      face-nowrap one-of intersections with [id = mydest]
    ]
  
  calculate-ett
end

to distribute-drivers-proportionally
  ask intersections [
    let drv-at-intersection count drivers-here with [current-node != destination];desconta os motoristas que ja chegaram
   
    let total-capacity sum [capacity] of my-out-links
    
    ask my-out-links [
      let proportion capacity / total-capacity
      set opt-num-drv opt-num-drv + (proportion * drv-at-intersection)
    ]

    
  ]
end
;    atualiza o historico de ocupacao das vias, inserindo a ocupacao da rodada atual
to update-history 
  ask roads [
    ;show history
    let occupation (num-drv / capacity) * 100
    
    if occupation < 60 [set occupation 60]
    if occupation > 140 [set occupation 140]
    
    set history remove-item (length history - 1) history
    set history fput occupation history
    if length history = 1 [show (word "error " history)]
  ]
end

;calcula o tempo de viagem esperado para cada motorista
to calculate-ett
  
  ask drivers [
    let drv-same-od 0
    let exp-drv 0
    let ett 0
  
    let myorig origin
    let mydest destination
    
    set drv-same-od count drivers with [origin = myorig and destination = mydest]
    
    set exp-drv drv-same-od ; - 50  + random 101 ;adiciona ruido +-50
    
    foreach optimal-route [
      ask ? [set ett ett + fftt * (1 + exp-drv / capacity) ^ 2]
    ]
    set expected-tt ett
  ]
end

; reinicia a rede de trafego: coloca os motoristas na origem, reseta as rotas
; reseta os tempos de viagem das vias e a ocupacao 
to reset-road-network 
  reset-drivers
  reset-roads
end

;reinicia o estado dos motoristas, posicionando-os na origem e resetando as rotas
to reset-drivers
    ask drivers [
     
      set current-node origin
      set current-route []
      
      ;TODO atualizar os pesos das rotas
      ;set roads-weight n-values num-roads [1]
      let myorig origin
      let mydest destination
      move-to one-of intersections with [id = myorig]
      face-nowrap one-of intersections with [id = mydest]
    ]
end

;reinicia o estado das vias (num-motoristas; num-proporcional; tempo-de-viagem)
to reset-roads
  ask roads [ 
    set num-drv  0
    set opt-num-drv 0
    set travel-time 0
  ]
end

;faz cada motorista escolher a proxima via a ser usada
to choose-next-road
    
  ask drivers[
    
    if current-node = destination [stop] ;nao faz escolhas se ja tiver chegado
    
    ;configura variaveis para serem usadas dentro dos asks
    let node-id current-node
    let the-predictors predictors
    let the-scores predictors-score
    let the-roads-weight roads-weight
    let myorig origin
    let mydest destination
    
    ;inicializa melhor via e menor ocupacao encontrada
    let best-road-id -1
    let lowest-prediction 100000 ;inicializa menor ocupacao com valor grande
    
    ;a partir da intersecao atual...
    ask intersections with [id = node-id] [
      
      let will-reach-dest false
      
      ;...analisa todos os links de saida para achar o melhor
      ask my-out-links [
        
;        ifelse [id] of end2 = mydest 
;        [
;          set best-road-id road-id
;          set will-reach-dest true
;        ]
        ;[
          ;se ja encontrou aresta que leva ao destino, nao procura mais
          if will-reach-dest [stop] 
          if (not in-route myorig mydest) [stop]
          
          let scores sublist the-scores (road-id - 1) road-id
          
          let hiscore max (item 0 scores)
          let best-pred-index position hiscore (item 0 scores)
          
          let curr-predictors sublist the-predictors (road-id - 1) road-id  ;OK - obtem os preditores desta via
          ;set best-pred-index 0
          
          let best-predictor (item best-pred-index (item 0 curr-predictors)) 
          
          let predicted-occ predict-occupation best-predictor history
          let weighted-prev predicted-occ * item (road-id - 1) the-roads-weight
          
          ;COMPARAR COM MELHOR PREDICAO E AJUSTAR MELHOR VIA
          if weighted-prev < lowest-prediction [
            set lowest-prediction predicted-occ
            set best-road-id road-id
          ]
        ;];ifelse
      ] ;ask my-out-links
    ] ;ask intersections
    
    
    set current-road one-of roads with [road-id = best-road-id]
    ;face-nowrap [end1] of current-road
    ;fd 1
    
    ask current-road [set num-drv num-drv + 1]
  ]
end

to-report in-route [orig dest]
  
  let forbidden []
  
  if dest = 8  [ set forbidden [18 20 21 22 23 24] ]
  if dest = 9  [ set forbidden [21 23 24] ]
  
  report not member? road-id forbidden

;  int rid = r.getId();
;        int[] forbidden = null;
;        
;        if(destination.getId() == 8) {
;             int[] fbd = {18, 20, 21, 22, 23, 24};
;             forbidden = fbd;
;        }
;        if(destination.getId() == 9){
;            int[] fbd = {21,23, 24};
;            forbidden = fbd;
;        }
;        if(forbidden == null) return true;
;        
;        for(int badlink : forbidden) if(rid == badlink) return false;
;        
;        return true;
end

;faz o motorista chegar ao destino da via escolhida e experimentar o tempo de viagem
to advance
  ask drivers [
    if current-node = destination [stop]
    
    ;adiciona a via atual 'a rota
    set current-route lput current-road current-route
    
    ;avanca para a proxima intersecao
    set current-node [id] of [end2] of current-road
    let nid current-node
    move-to one-of intersections with [id = nid]
    
  ]
  show "advanced"
end

;calcula o tempo de viagem gasto pelos motoristas
to experience-travel-times
  ask roads [
    
    set travel-time fftt * (1 + alpha * (num-drv / capacity) ^ beta)
    
    ;show num-drv
    ;show opt-num-drv
    
    if num-drv > 0 [
      set avg-num-drv ((num-drv - avg-num-drv) / (ticks + 1)) + avg-num-drv
      set avg-opt-drv ((opt-num-drv - avg-opt-drv) / (ticks + 1)) + avg-opt-drv
    ]
    ;show avg-opt-drv
;    avgNumDrivers = ((getNumDrivers() - getAvgNumDrivers()) / (Experiment.getInstance().getTimestep() + 1)) + getAvgNumDrivers();
  ]
  
  ask drivers [
    let attR 0 ;inicializa o tempo de viagem do motorista
    
    ;calcula o custo da rota
    foreach current-route [
      ask ? [set attR attR + travel-time]
    ]
    
    set actual-tt attR
    
    set route-weight actual-tt / expected-tt
    
    ;atualiza o vetor de pesos de rota por aresta
    foreach current-route [
      let rw roads-weight
      let att actual-tt
      let w route-weight
      
      ask ? [
        let rid road-id
        set rw replace-item (rid - 1) rw w
      ;replace-item 0 [1 3 3] 3
      ]
      set roads-weight rw
    ]
  ]
end

;atualiza a pontuacao dos preditores de cada motorista
;somente sao atualizados os preditores que foram usados na ultima viagem
;SC = (1-u)SC + u[(Ca / Xa) -1]*ATTR
to update-predictors-score 

  ;para cada via...
  ask roads [
    if num-drv = 0 [stop]
    
    let rid road-id
    let rhist history
    let rocc capacity / num-drv
    
    ;para cada motorista
    ask drivers [
      let curr-predictors sublist predictors (rid - 1) rid  ;OK - obtem os preditores desta via
      let scores sublist predictors-score (rid - 1) rid
      
      let bpindex item (rid - 1) best-predictors ;obtem o indice do melhor preditor desta via    
      
      ;obtem o score e o recalcula
      let score item bpindex (item 0 scores)
      set score (1 - learning-factor) * score + learning-factor * (rocc - 1) * actual-tt
      
      ;coloca o novo score na sub-lista das pontuacoes dos preditores daquela via
      let new-scores replace-item bpindex (item 0 scores) score
      
      ;atualiza em qual indice esta o melhor preditor
      let bpidx position (max new-scores) new-scores ;OK
      set best-predictors replace-item (rid - 1) best-predictors bpidx
      
      
      ;show (word new-scores " " bpidx)
      
      ;coloca a sub-lista na lista de pontuacoes geral
       set predictors-score replace-item (rid - 1) predictors-score new-scores 
      ;show predictors-score
      
      ;atualiza os indices dos melhores preditores
;      foreach predictors-score [
;        set bpidx position max 
;      ]
      
;      let curr-predictors sublist predictors (rid - 1) rid  ;OK - obtem os preditores desta via
      ;set best-pred-index 0
      
      ;let best-predictor (item best-pred-index (item 0 curr-predictors)) 
      ;let predicted-occ predict-occupation best-predictor rhist
      
      
    ]
  ]
  
  

end

;retorna a rota otima entre nos origem-destino
to-report calculate-opt-route [org dest]
  
  let rid-list []
  
  if org = 1 and dest = 8 [ set rid-list [1 6 15] ]
  if org = 1 and dest = 9 [ set rid-list [3 12 20] ]
  if org = 1 and dest = 10 [ set rid-list [3 12 21] ]
  
  if org = 2 and dest = 8 [ set rid-list [6 15] ]
  if org = 2 and dest = 9 [ set rid-list [6 13 18] ]
  if org = 2 and dest = 10 [ set rid-list [6 15 23] ]

  if org = 3 and dest = 8 [ set rid-list [9 17] ]
  if org = 3 and dest = 9 [ set rid-list [9 18] ]
  if org = 3 and dest = 10 [ set rid-list [9 18 24] ]
  
  
  let opt-route []
  
  foreach rid-list [
    set opt-route lput one-of roads with [road-id = ?] opt-route
  ]
  
  report opt-route
end

; Prediz a ocupacao na via dado uma estrategia (o preditor) e o historico.
; A previsao e' dada pela formula:
; p(t) = x(t - 1) * a(t - 1) + x(t - 2) * a(t -2) +..
;      ... + x(t - MEMORY-SIZE) * a(t - MEMORY-SIZE)
; onde p(t) e' a previsao no tempo t, x(t) e a ocupacao da via no tempo t,
; a(t) e' o peso para o tempo t e MEMORY-SIZE e' o tamanho do historico
to-report predict-occupation [predictor occ-history]
  let prediction sum (map [?1 * ?2] predictor occ-history)
  if prediction < 60 [set prediction  60]
  if prediction > 140 [set prediction  140]

  report prediction
end
  

;diz se todos os motoristas ja chegaram nos seus destinos
to-report drivers-not-arrived
  let all-arrived true
  ask drivers [
    if current-node != destination [ set all-arrived false ]
  ]
  report not all-arrived
end

;gera uma lista de zeros como score inicial dos preditores
to-report initial-scores
  report n-values num-predictors [0] ;score inicial dos preditores e' zero
end

;gera uma lista com 'num-predictors' preditores aleatorios
to-report random-predictors
  report n-values num-predictors [random-predictor]
end

;gera um vetor de pesos entre [-1:1] do tamanho do historico
to-report random-predictor
  report n-values (history-size) [1.0 - random-float 2.0]
end

to build-network
  clear-turtles
    
  file-open "mgta2" ;user-file
  set num-intersections file-read
  set num-roads file-read
  set ideal-segment-length file-read

  repeat num-intersections  [ 
    create-intersections 1 [
      set id file-read ;id-counter

      set xcor file-read / 1.1
      set ycor file-read / 1.1
      
      update-node-visual
    ]
  ]
  repeat num-roads  [
    let r-id file-read
    let id1 file-read
    let id2 file-read
    let primary? file-read
    ask intersections with [ id = id1 ]  [
      create-roads-to intersections with [id = id2] [
        set road-id r-id
        
        set num-drv 0
        set opt-num-drv 0
        set avg-num-drv 0
        set avg-opt-drv 0
        
        set fftt 5
        set capacity 130 + random 121
        ;set capacity num-drivers / 7.5 ;TODO REMOVER ISSO APOS TESTAR
        set label road-id
        set label-color red
        
        set history n-values history-size [60 + random 81] ;historico de valores entre 60 e 140
      ]
    ]
  ]
  file-close  
  
   ask roads [
      set shape "default"
      set thickness .2
    ]
end

to update-node-visual
    set shape "circle 2"
    set size ideal-segment-length / 3
    set color 5
end

to do-plots
  plot-travel-times
  plot-roads-occupation
  plot-tt-per-od
end

to plot-travel-times
  let total-att 0
  let total-ett 0
  
  ask drivers [
    set total-att total-att + actual-tt
    set total-ett total-ett + expected-tt
  ]
  
  let avg-att total-att / num-drivers
  let avg-ett total-ett / num-drivers
  
  set-current-plot "avg-travel-time"
  
  set-current-plot-pen "actual"
  plot avg-att
  
  set-current-plot-pen "expected"
  plot avg-ett
end

to plot-tt-per-od 
  let counter 1
  let origins [1 2 3]
  let dests [8 9 10]

  set-current-plot "travel-time-per-od"
  
  clear-plot

  foreach origins [
    let orig ?
    foreach dests [
      let dest ?
      
      set-current-plot-pen "actual"
      plotxy counter (att-per-od orig dest)
      
      set-current-plot-pen "expected"
      plotxy (counter) (ett-per-od orig dest)
      
      set counter counter + 1
    ]
  ]

end

to-report att-per-od [orig dest]
  let total-tt 0
  
  ask drivers with [origin = orig and destination = dest] [
    set total-tt total-tt + actual-tt
  ]
  if total-tt = 0 [report 0]
  report total-tt / count drivers with [origin = orig and destination = dest]
end

to-report ett-per-od [orig dest]
  let total-tt 0
  
  ask drivers with [origin = orig and destination = dest] [
    set total-tt total-tt + expected-tt
  ]
  if total-tt = 0 [report 0]
  report total-tt / count drivers with [origin = orig and destination = dest]
end

to plot-roads-occupation
  set-current-plot "drivers-per-road"
  clear-plot
  set-current-plot-pen "actual"
  
  ask roads [
    plotxy road-id avg-num-drv
  ]
  
  
  set-current-plot-pen "proportional"
    ask roads [
    plotxy road-id avg-opt-drv
 ;   if road-id = 24 [show (word "error " road-id " " avg-opt-drv)]
  ]
  if plot-capacity? [  
    set-current-plot-pen "capacity"
    ask roads [
      plotxy (road-id + .5) capacity
    ]
  ]
  
  set-current-plot "inst-drv-per-road"
  clear-plot
  set-current-plot-pen "actual"
  
  ask roads [
    plotxy road-id num-drv
  ]
  
  set-current-plot-pen "proportional"
  
  ask roads [
    plotxy road-id opt-num-drv
  ]
end

to update-roads-visual
  ask roads [
    
    let occ avg-num-drv / capacity
    
    if inst-road-view?
    [set occ num-drv / capacity]
    
    set color green
    if occ > 0.80 [set color yellow]
    if occ > 1.00 [set color orange]
    if occ > 1.20 [set color red]
    
   ; show occ
  ]
end
@#$#@#$#@
GRAPHICS-WINDOW
210
10
649
470
16
16
13.0
1
10
1
1
1
0
1
1
1
-16
16
-16
16
0
0
1
ticks

BUTTON
17
94
90
127
NIL
setup
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL

SLIDER
6
138
178
171
num-drivers
num-drivers
1
2002
1002
1
1
NIL
HORIZONTAL

SLIDER
6
193
178
226
history-size
history-size
1
5
3
1
1
NIL
HORIZONTAL

SLIDER
6
237
178
270
num-predictors
num-predictors
1
5
2
1
1
NIL
HORIZONTAL

BUTTON
99
94
162
127
NIL
go
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL

SLIDER
14
339
186
372
alpha
alpha
.1
2
1
.1
1
NIL
HORIZONTAL

SLIDER
14
301
186
334
beta
beta
.1
3
2
.1
1
NIL
HORIZONTAL

BUTTON
101
54
164
87
NIL
go
T
1
T
OBSERVER
NIL
NIL
NIL
NIL

SLIDER
14
383
186
416
learning-factor
learning-factor
0
1
0.1
.1
1
NIL
HORIZONTAL

PLOT
651
142
930
292
avg-travel-time
iteration
travel-time
0.0
10.0
0.0
10.0
true
true
PENS
"actual" 1.0 0 -16777216 true
"expected" 1.0 0 -2674135 true

PLOT
653
312
926
466
drivers-per-road
id-road
#drivers
1.0
25.0
0.0
10.0
true
true
PENS
"proportional" 1.0 1 -2674135 true
"actual" 1.0 1 -16777216 true
"capacity" 1.0 2 -10899396 true

SWITCH
846
384
1002
417
plot-capacity?
plot-capacity?
0
1
-1000

BUTTON
18
52
82
85
NIL
step
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL

PLOT
690
10
872
130
inst-drv-per-road
road-id
#drivers
1.0
25.0
0.0
10.0
true
false
PENS
"actual" 1.0 1 -16777216 true
"proportional" 1.0 1 -2674135 true

SWITCH
468
49
631
82
inst-road-view?
inst-road-view?
1
1
-1000

PLOT
664
10
883
139
travel-time-per-OD
od-pair
travel-time
1.0
10.0
0.0
10.0
true
false
PENS
"actual" 1.0 1 -16777216 true
"expected" 1.0 1 -2674135 true

TEXTBOX
246
391
396
409
Up to 80%
13
55.0
1

TEXTBOX
245
406
395
424
Up to 100%
13
45.0
1

TEXTBOX
245
421
395
439
Up to 120%
13
25.0
1

TEXTBOX
245
436
395
454
Up to 140%
13
15.0
1

TEXTBOX
221
374
371
392
Occupation:
13
9.9
1

BUTTON
102
10
165
43
go 50
repeat 50 [\ngo\n]
NIL
1
T
OBSERVER
NIL
NIL
NIL
NIL

@#$#@#$#@
WHAT IS IT?
-----------
This model is an implementation of the modified Minority Game algorithm for traffic assignment proposed in the paper: Road Traffic Optimisation Using an Evolutionary Game written by Syed Md. Galib and Irene Moser.


HOW IT WORKS
------------
Agents predict occupancy on the roads they can use on their trip. They have a set of predictors for each link and "believe" the prediction made by the best scored predictor. Then they choose the next link of their trip as the one with the least predicted occupancy. This is repeated until they reach their destinations. Then travel times are calculated and the predictors' score are updated.


HOW TO USE IT
-------------
Click 'setup' to load the road network and place the drivers on their origins (uniformely distributed on the nodes 1, 2 and 3). Click 'go' to simulate one iteration. The 'go 50' button simulates 50 iterations, and the looped 'go' repeats iterations forever.

If one of the parameters is changed, the setup button must be pressed again to create the simulation environment with the updated values. Parameters are:

- num-drivers: the number of drivers on the network
- history-size: drivers store road occupation from 'history-size' iterations from the past
- alpha and beta: these are parameters of the travel time calculation formula: 
fftt * (1 + alpha * (num-drv / capacity) ^ beta)
- learning-factor: it weights the score to be updated on the predictors (lower makes previous scores more important than the current)


THINGS TO NOTICE
----------------
The networks tends to self-organise. Drivers distribute themselves almost proportionally to the capacity of the roads. On average, actual travel times are lower than the expected.


THINGS TO TRY
-------------
It is interesting to see how the parameters affect the simulation.


EXTENDING THE MODEL
-------------------
It is possible to force drivers to have only one origin-destination pair by changing the code. 



CREDITS AND REFERENCES
----------------------
This implementation was built to the Advanced Artificial Intelligence course at UFRGS.
Author: Anderson Rocha Tavares
Advisor: Ana L. C. Bazzan

Paper: Road Traffic Optimisation Using an Evolutionary Game
Authors: Syed Md. Galib and Irene Moser
@#$#@#$#@
default
true
0
Polygon -7500403 true true 150 5 40 250 150 205 260 250

airplane
true
0
Polygon -7500403 true true 150 0 135 15 120 60 120 105 15 165 15 195 120 180 135 240 105 270 120 285 150 270 180 285 210 270 165 240 180 180 285 195 285 165 180 105 180 60 165 15

arrow
true
0
Polygon -7500403 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150

box
false
0
Polygon -7500403 true true 150 285 285 225 285 75 150 135
Polygon -7500403 true true 150 135 15 75 150 15 285 75
Polygon -7500403 true true 15 75 15 225 150 285 150 135
Line -16777216 false 150 285 150 135
Line -16777216 false 150 135 15 75
Line -16777216 false 150 135 285 75

bug
true
0
Circle -7500403 true true 96 182 108
Circle -7500403 true true 110 127 80
Circle -7500403 true true 110 75 80
Line -7500403 true 150 100 80 30
Line -7500403 true 150 100 220 30

butterfly
true
0
Polygon -7500403 true true 150 165 209 199 225 225 225 255 195 270 165 255 150 240
Polygon -7500403 true true 150 165 89 198 75 225 75 255 105 270 135 255 150 240
Polygon -7500403 true true 139 148 100 105 55 90 25 90 10 105 10 135 25 180 40 195 85 194 139 163
Polygon -7500403 true true 162 150 200 105 245 90 275 90 290 105 290 135 275 180 260 195 215 195 162 165
Polygon -16777216 true false 150 255 135 225 120 150 135 120 150 105 165 120 180 150 165 225
Circle -16777216 true false 135 90 30
Line -16777216 false 150 105 195 60
Line -16777216 false 150 105 105 60

car
false
0
Polygon -7500403 true true 300 180 279 164 261 144 240 135 226 132 213 106 203 84 185 63 159 50 135 50 75 60 0 150 0 165 0 225 300 225 300 180
Circle -16777216 true false 180 180 90
Circle -16777216 true false 30 180 90
Polygon -16777216 true false 162 80 132 78 134 135 209 135 194 105 189 96 180 89
Circle -7500403 true true 47 195 58
Circle -7500403 true true 195 195 58

circle
false
0
Circle -7500403 true true 0 0 300

circle 2
false
0
Circle -7500403 true true 0 0 300
Circle -16777216 true false 30 30 240

cow
false
0
Polygon -7500403 true true 200 193 197 249 179 249 177 196 166 187 140 189 93 191 78 179 72 211 49 209 48 181 37 149 25 120 25 89 45 72 103 84 179 75 198 76 252 64 272 81 293 103 285 121 255 121 242 118 224 167
Polygon -7500403 true true 73 210 86 251 62 249 48 208
Polygon -7500403 true true 25 114 16 195 9 204 23 213 25 200 39 123

cylinder
false
0
Circle -7500403 true true 0 0 300

dot
false
0
Circle -7500403 true true 90 90 120

face happy
false
0
Circle -7500403 true true 8 8 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Polygon -16777216 true false 150 255 90 239 62 213 47 191 67 179 90 203 109 218 150 225 192 218 210 203 227 181 251 194 236 217 212 240

face neutral
false
0
Circle -7500403 true true 8 7 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Rectangle -16777216 true false 60 195 240 225

face sad
false
0
Circle -7500403 true true 8 8 285
Circle -16777216 true false 60 75 60
Circle -16777216 true false 180 75 60
Polygon -16777216 true false 150 168 90 184 62 210 47 232 67 244 90 220 109 205 150 198 192 205 210 220 227 242 251 229 236 206 212 183

fish
false
0
Polygon -1 true false 44 131 21 87 15 86 0 120 15 150 0 180 13 214 20 212 45 166
Polygon -1 true false 135 195 119 235 95 218 76 210 46 204 60 165
Polygon -1 true false 75 45 83 77 71 103 86 114 166 78 135 60
Polygon -7500403 true true 30 136 151 77 226 81 280 119 292 146 292 160 287 170 270 195 195 210 151 212 30 166
Circle -16777216 true false 215 106 30

flag
false
0
Rectangle -7500403 true true 60 15 75 300
Polygon -7500403 true true 90 150 270 90 90 30
Line -7500403 true 75 135 90 135
Line -7500403 true 75 45 90 45

flower
false
0
Polygon -10899396 true false 135 120 165 165 180 210 180 240 150 300 165 300 195 240 195 195 165 135
Circle -7500403 true true 85 132 38
Circle -7500403 true true 130 147 38
Circle -7500403 true true 192 85 38
Circle -7500403 true true 85 40 38
Circle -7500403 true true 177 40 38
Circle -7500403 true true 177 132 38
Circle -7500403 true true 70 85 38
Circle -7500403 true true 130 25 38
Circle -7500403 true true 96 51 108
Circle -16777216 true false 113 68 74
Polygon -10899396 true false 189 233 219 188 249 173 279 188 234 218
Polygon -10899396 true false 180 255 150 210 105 210 75 240 135 240

house
false
0
Rectangle -7500403 true true 45 120 255 285
Rectangle -16777216 true false 120 210 180 285
Polygon -7500403 true true 15 120 150 15 285 120
Line -16777216 false 30 120 270 120

leaf
false
0
Polygon -7500403 true true 150 210 135 195 120 210 60 210 30 195 60 180 60 165 15 135 30 120 15 105 40 104 45 90 60 90 90 105 105 120 120 120 105 60 120 60 135 30 150 15 165 30 180 60 195 60 180 120 195 120 210 105 240 90 255 90 263 104 285 105 270 120 285 135 240 165 240 180 270 195 240 210 180 210 165 195
Polygon -7500403 true true 135 195 135 240 120 255 105 255 105 285 135 285 165 240 165 195

line
true
0
Line -7500403 true 150 0 150 300

line half
true
0
Line -7500403 true 150 0 150 150

pentagon
false
0
Polygon -7500403 true true 150 15 15 120 60 285 240 285 285 120

person
false
0
Circle -7500403 true true 110 5 80
Polygon -7500403 true true 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90
Rectangle -7500403 true true 127 79 172 94
Polygon -7500403 true true 195 90 240 150 225 180 165 105
Polygon -7500403 true true 105 90 60 150 75 180 135 105

plant
false
0
Rectangle -7500403 true true 135 90 165 300
Polygon -7500403 true true 135 255 90 210 45 195 75 255 135 285
Polygon -7500403 true true 165 255 210 210 255 195 225 255 165 285
Polygon -7500403 true true 135 180 90 135 45 120 75 180 135 210
Polygon -7500403 true true 165 180 165 210 225 180 255 120 210 135
Polygon -7500403 true true 135 105 90 60 45 45 75 105 135 135
Polygon -7500403 true true 165 105 165 135 225 105 255 45 210 60
Polygon -7500403 true true 135 90 120 45 150 15 180 45 165 90

sheep
false
0
Rectangle -7500403 true true 151 225 180 285
Rectangle -7500403 true true 47 225 75 285
Rectangle -7500403 true true 15 75 210 225
Circle -7500403 true true 135 75 150
Circle -16777216 true false 165 76 116

square
false
0
Rectangle -7500403 true true 30 30 270 270

square 2
false
0
Rectangle -7500403 true true 30 30 270 270
Rectangle -16777216 true false 60 60 240 240

star
false
0
Polygon -7500403 true true 151 1 185 108 298 108 207 175 242 282 151 216 59 282 94 175 3 108 116 108

target
false
0
Circle -7500403 true true 0 0 300
Circle -16777216 true false 30 30 240
Circle -7500403 true true 60 60 180
Circle -16777216 true false 90 90 120
Circle -7500403 true true 120 120 60

tree
false
0
Circle -7500403 true true 118 3 94
Rectangle -6459832 true false 120 195 180 300
Circle -7500403 true true 65 21 108
Circle -7500403 true true 116 41 127
Circle -7500403 true true 45 90 120
Circle -7500403 true true 104 74 152

triangle
false
0
Polygon -7500403 true true 150 30 15 255 285 255

triangle 2
false
0
Polygon -7500403 true true 150 30 15 255 285 255
Polygon -16777216 true false 151 99 225 223 75 224

truck
false
0
Rectangle -7500403 true true 4 45 195 187
Polygon -7500403 true true 296 193 296 150 259 134 244 104 208 104 207 194
Rectangle -1 true false 195 60 195 105
Polygon -16777216 true false 238 112 252 141 219 141 218 112
Circle -16777216 true false 234 174 42
Rectangle -7500403 true true 181 185 214 194
Circle -16777216 true false 144 174 42
Circle -16777216 true false 24 174 42
Circle -7500403 false true 24 174 42
Circle -7500403 false true 144 174 42
Circle -7500403 false true 234 174 42

turtle
true
0
Polygon -10899396 true false 215 204 240 233 246 254 228 266 215 252 193 210
Polygon -10899396 true false 195 90 225 75 245 75 260 89 269 108 261 124 240 105 225 105 210 105
Polygon -10899396 true false 105 90 75 75 55 75 40 89 31 108 39 124 60 105 75 105 90 105
Polygon -10899396 true false 132 85 134 64 107 51 108 17 150 2 192 18 192 52 169 65 172 87
Polygon -10899396 true false 85 204 60 233 54 254 72 266 85 252 107 210
Polygon -7500403 true true 119 75 179 75 209 101 224 135 220 225 175 261 128 261 81 224 74 135 88 99

wheel
false
0
Circle -7500403 true true 3 3 294
Circle -16777216 true false 30 30 240
Line -7500403 true 150 285 150 15
Line -7500403 true 15 150 285 150
Circle -7500403 true true 120 120 60
Line -7500403 true 216 40 79 269
Line -7500403 true 40 84 269 221
Line -7500403 true 40 216 269 79
Line -7500403 true 84 40 221 269

x
false
0
Polygon -7500403 true true 270 75 225 30 30 225 75 270
Polygon -7500403 true true 30 75 75 30 270 225 225 270

@#$#@#$#@
NetLogo 4.1.3
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
@#$#@#$#@
default
0.0
-0.2 0 1.0 0.0
0.0 1 1.0 0.0
0.2 0 1.0 0.0
link direction
true
0
Line -7500403 true 150 150 90 180
Line -7500403 true 150 150 210 180

@#$#@#$#@
0
@#$#@#$#@
