Simple Markov Network Brain with Javascript
PLEASE NOTE:
This is not a "framework". This is a HTML5/Javascript program.
Background links: My own take on networked brains ala Chris Adami's and his teams ideas.
See:
Chris Adami's site (http://adamilab.msu.edu/markov-network-brains/)
Another good description (http://devosoft.org/a-quick-introduction-to-markov-network-brains/)
Jefferey Cave's really neat implementation (https://medium.com/@jefferey.cave/fun-with-markov-network-brains-8041c35ca883)
Arend Hintze's "Markov Brains: A Technical Introduction" is also great. (https://arxiv.org/pdf/1709.05601v1.pdf)
Evolution:
- Generate a population of "BRAINS".
- Evaluate the fitness of each of the original BRAINS
- Sort the population descending based on fitness
- For the best BRAIN (POPULATION[0] after sort)
- Crossover with a randomly chosen BRAIN from the less fit.
- Mutate gates depending on mutation rate
- Evaluate the fitness of the candidata brain
- If candidate brain is better than the worst BRAIN, replace worst Brain with candidate brain
- Go to 4 above.
The Goal:
- Have a 'rover' go around in a big circle.
- If the rover "body" touches a wall or a blue square it is dead.
- The rover accumulates fitness depending on how many times in a row it goes straight.
- The rover has a "Time_to_live".
- The rover has a 'BRAIN'.
How to Run:
- Download the repository one way or another.
- Open a Chrome browser (maybe others will work)
- Point it at "file:///your fully qualified directory name/index.html -- I use file:///Users/pneal/mnb_js/index.html
- You should see a red whirling rover in a field of white with blue boxes.
- Turn on View->Developer->Javascript Console for more info
Overview:
- The red 'rover' has 3 sensors.
- The sensors detect whether or not it senses a wall or the side of a cube.
- The data returned from the sensors is sent to the think module
- The think module contains the Markov Network Brain (MNB).
- The think module returns the best sensor choice to use.
- The rover turns in the direction of the best sensor.
Deep Copy Hassles:
-
I had to do deep copy on the "BRAIN" because mutation and crossover should not be done on the original too deep object oriented "brain" in the POPULATION array.
-
So I did the JSON trick
- BRAIN = JSON.parse(JSON.stringify(POPULATION[0]));
- POPULATION[POP_SIZE-1] = JSON.parse(JSON.stringify(BRAIN))
-
HOWEVER !!! For some reason the JSON trick wouldn't do a true "GATE" object. So I had to rewrite the "NEURONS" item as a 2 dimensional array. Sigh.
Gates:
-
I use a simple gate structure.
- 2 input indexes
- 2 output indexes
- a 2x2 matrix of 0 or 1 randomly generated for the truth table
-
I do not use probabilistic, not,neuron,or learning gates.
-
The truth table for each gate is a 2d matrix indexed by the input values
-
The values for each input index points to the binary value at INPUT_STATE[input_index]
-
The values for each output index points to the OUT_STATE[output_index] where the result of the truth table will be written.