Just getting a better feel for APL. This is a basic implementation of the hello world of genetic algorithms - one max.
Starting with an initial population. Each member is a list containing ones and zeros.
Initial setup
]box on -style=max
]rows on
⎕io←0
The task basically breaks down into
- Generate initial population
⎕←p0←?10 10 ⍴ 2
┌→──────────────────┐
↓1 1 0 1 0 0 0 1 0 0│
│0 0 1 1 0 0 0 0 0 1│
│0 0 1 1 0 0 0 0 1 0│
│1 0 1 0 0 1 0 0 0 1│
│0 1 0 1 1 0 0 1 0 0│
│0 0 1 1 1 1 1 1 0 0│
│0 1 1 0 1 1 0 1 1 0│
│1 0 0 0 0 0 1 0 1 1│
│0 1 1 1 1 0 1 1 0 1│
│0 1 1 0 0 0 0 0 1 1│
└~──────────────────┘
p0 is the initial population.
- Sort the population by fitness
sort←{⍵⌷⍨⊂⍒+/[1]⍵}
sort p0
┌→──────────────────┐
↓0 1 1 1 1 0 1 1 0 1│
│0 0 1 1 1 1 1 1 0 0│
│0 1 1 0 1 1 0 1 1 0│
│1 1 0 1 0 0 0 1 0 0│
│1 0 1 0 0 1 0 0 0 1│
│0 1 0 1 1 0 0 1 0 0│
│1 0 0 0 0 0 1 0 1 1│
│0 1 1 0 0 0 0 0 1 1│
│0 0 1 1 0 0 0 0 0 1│
│0 0 1 1 0 0 0 0 1 0│
└~──────────────────┘
- Group into parents
group←{↓{⍵}⌺(⍪2 2)⊢⍵}
group sort p0
┌→────────────────────────────────────────────┐
↓ ┌→──────────────────┐ ┌→──────────────────┐ │
│ │0 1 1 1 1 0 1 1 0 1│ │0 0 1 1 1 1 1 1 0 0│ │
│ └~──────────────────┘ └~──────────────────┘ │
│ ┌→──────────────────┐ ┌→──────────────────┐ │
│ │0 1 1 0 1 1 0 1 1 0│ │1 1 0 1 0 0 0 1 0 0│ │
│ └~──────────────────┘ └~──────────────────┘ │
│ ┌→──────────────────┐ ┌→──────────────────┐ │
│ │1 0 1 0 0 1 0 0 0 1│ │0 1 0 1 1 0 0 1 0 0│ │
│ └~──────────────────┘ └~──────────────────┘ │
│ ┌→──────────────────┐ ┌→──────────────────┐ │
│ │1 0 0 0 0 0 1 0 1 1│ │0 1 1 0 0 0 0 0 1 1│ │
│ └~──────────────────┘ └~──────────────────┘ │
│ ┌→──────────────────┐ ┌→──────────────────┐ │
│ │0 0 1 1 0 0 0 0 0 1│ │0 0 1 1 0 0 0 0 1 0│ │
│ └~──────────────────┘ └~──────────────────┘ │
└∊────────────────────────────────────────────┘
- Mutate into children
split←{⍵⊆⍨1+⍺<⍳⍴⍵}
{c l←⍴⍵⋄↑⊃,/{(l-1) split ⊃,/(⊂0 3 2 1)⌷⍵}¨,/↑⊃(?(l-1)⍴⍨c÷2) ,.{⊂⍺split¨⍵} ↓group sort ⍵ } p0
┌→──────────────────┐
↓0 1 1 1 1 0 1 1 0 0│
│0 0 1 1 1 1 1 1 0 1│
│0 1 1 0 1 0 0 1 0 0│
│1 1 0 1 0 1 0 1 1 0│
│1 0 0 1 1 0 0 1 0 0│
│0 1 1 0 0 1 0 0 0 1│
│1 1 1 0 0 0 0 0 1 1│
│0 0 0 0 0 0 1 0 1 1│
│0 0 1 1 0 0 0 0 1 0│
│0 0 1 1 0 0 0 0 0 1│
└~──────────────────┘
Pondering how best to simplify this step.
- Goto 2
({c l←⍴⍵⋄sort ↑⊃,/{(l-1) split ⊃,/(⊂0 3 2 1)⌷⍵}¨,/↑⊃(?(l-1)⍴⍨c÷2) ,.{⊂⍺split¨⍵} ↓group ⍵ }⍣100)sort p0
┌→──────────────────┐
↓1 1 1 1 1 1 1 1 1 1│
│0 1 1 1 1 1 1 1 1 1│
│0 1 1 1 0 1 1 1 1 1│
│1 1 1 1 1 0 0 0 1 1│
│0 1 1 1 1 0 0 1 0 1│
│1 0 1 1 0 0 0 0 0 0│
│0 0 1 0 0 0 0 0 0 0│
│0 0 0 0 0 0 0 1 0 0│
│0 0 0 0 0 0 0 0 0 0│
│0 0 0 0 0 0 0 0 0 0│
└~──────────────────┘
Got some experiments to run. I feel like there should be a cleaner way to create the children.