Biological evolution simulator

Overview

biosim4

What is this?

This pile of code was used to simulate biological creatures that evolve through natural selection. The results of the experiments are summarized in this YouTube video:

      "I programmed some creatures. They evolved."

      https://www.youtube.com/watch?v=N3tRFayqVtk

This code lacks a friendly interface, so compiling and executing the program may require attention to details. If you ask questions in the Issues, I'll try to help if I can.

Document Contents

Code walkthrough

Main data structures

The code in the src directory compiles to a single console program named biosim4. When it is invoked, it will read parameters from a config file named biosim4.ini by default. A different config file can be specified on the command line.

The simulator will then configure a 2D arena where the creatures live. Class Grid (see grid.h and grid.cpp) contains a 2D array of 16-bit indexes, where each nonzero index refers to a specific individual in class Peeps (see below). Zero values in Grid indicate empty locations. Class Grid does not know anything else about the world; it only stores indexes to represent who lives where.

The population of creatures is stored in class Peeps (see peeps.h and peeps.cpp). Class Peeps contains all the individuals in the simulation, stored as instances of struct Indiv in a std::vector container. The indexes in class Grid are indexes into the vector of individuals in class Peeps. Class Peeps keeps a container of struct Indiv, but otherwise does not know anything about the internal workings of individuals.

Each individual is represented by an instance of struct Indiv (see indiv.h and indiv.cpp). Struct Indiv contains an individual's genome, its corresponding neural net brain, and a redundant copy of the individual's X,Y location in the 2D grid. It also contains a few other parameters for the individual, such as its "responsiveness" level, oscillator period, age, and other personal parameters. Struct Indiv knows how to convert an individual's genome into its neural net brain at the beginning of the simulation. It also knows how to print the genome and neural net brain in text format to stdout during a simulation. It also has a function Indiv::getSensor() that is called to compute the individual's input neurons for each simulator step.

All the simulator code lives in the BS namespace (short for "biosim".)

Config file

The config file, named biosim4.ini by default, contains all the tunable parameters for a simulation run. The biosim4 executable reads the config file at startup, then monitors it for changes during the simulation. Although it's not foolproof, many parameters can be modified during the simulation run. Class ParamManager (see params.h and params.cpp) manages the configuration parameters and makes them available to the simulator through a read-only pointer provided by ParamManager::getParamRef().

See the provided biosim4.ini for documentation for each parameter. Most of the parameters in the config file correspond to members in struct Params (see params.h). A few additional parameters may be stored in struct Params. See the documentation in params.h for how to support new parameters.

Program output

Depending on the parameters in the config file, the following data can be produced:

  • The simulator will append one line to logs/epoch.txt after the completion of each generation. Each line records the generation number, number of individuals who survived the selection criterion, an estimate of the population's genetic diversity, average genome length, and number of deaths due to the "kill" gene. This file can be fed to tools/graphlog.gp to produce a graphic plot.

  • The simulator will display a small number of sample genomes at regular intervals to stdout. Parameters in the config file specify the number and interval. The genomes are displayed in hex format and also in a mnemonic format that can be fed to tools/graph-nnet.py to produce a graphic network diagram.

  • Movies of selected generations will be created in the images/ directory. Parameters in the config file specify the interval at which to make movies. Each movie records a single generation.

  • At intervals, a summary is printed to stdout showing the total number of neural connections throughout the population from each possible sensory input neuron and to each possible action output neuron.

Main program loop

The simulator starts with a call to simulator() in simulator.cpp. After initializing the world, the simulator executes three nested loops: the outer loop for each generation, an inner loop for each simulator step within the generation, and an innermost loop for each individual in the population. The innermost loop is thread-safe so that it can be parallelized by OpenMP.

At the end of each simulator step, a call is made to endOfSimStep() in single-thread mode (see endOfSimStep.cpp) to create a video frame representing the locations of all the individuals at the end of the simulator step. The video frame is pushed on to a stack to be converted to a movie later. Also some housekeeping may be done for certain selection scenarios. See the comments in endOfSimStep.cpp for more information.

At the end of each generation, a call is made to endOfGeneration() in single-thread mode (see endOfGeneration.cpp) to create a video from the saved video frames. Also a new graph might be generated showing the progress of the simulation. See endOfGeneraton.cpp for more information.

Sensory inputs and action outputs

See the YouTube video (link above) for a description of the sensory inputs and action outputs. Each sensory input and each action output is a neuron in the individual's neural net brain.

The header file sensors-actions.h contains enum Sensor which enumerates all the possible sensory inputs and enum Action which enumerates all the possible action outputs. In enum Sensor, all the sensory inputs before the enumerant NUM_SENSES will be compiled into the executable, and all action outputs before NUM_ACTIONS will be compiled. By rearranging the enumerants in those enums, you can select a subset of all possible sensory and action neurons to be compiled into the simulator.

Basic value types

There are a few basic value types:

  • enum Compass represents eight-way directions with enumerants N=0, NE, E, SW, S, SW, W, NW, CENTER.

  • struct Dir is an abstract representation of the values of enum Compass.

  • struct Coord is a signed 16-bit integer X,Y coordinate pair. It is used to represent a location in the 2D world, or can represent the difference between two locations.

  • struct Polar holds a signed 32-bit integer magnitude and a direction of type Dir.

Various conversions and math are possible between these basic types. See unitTestBasicTypes.cpp for examples. Also see basicTypes.h for more information.

Pheromones

A simple system is used to simulate pheromones emitted by the individuals. Pheromones are called "signals" in simulator-speak (see signals.h and signals.cpp). Struct Signals holds a single layer that overlays the 2D world in class Grid. Each location can contain a level of pheromone (there's only a single kind of pheromone supported at present). The pheromone level at any grid location is stored as an unsigned 8-bit integer, where zero means no pheromone, and 255 is the maximum. Each time an individual emits a pheromone, it increases the pheromone values in a small neighborhood around the individual up to the maximum value of 255. Pheromone levels decay over time if they are not replenished by the individuals in the area.

Useful utility functions

The utility function visitNeighborhood() in grid.cpp can be used to execute a user-defined lambda or function over each location within a circular neighborhood defined by a center point and floating point radius. The function calls the user-defined function once for each location, passing it a Coord value. Only locations within the bounds of the grid are visited. The center location is included among the visited locations. For example, a radius of 1.0 includes only the center location plus four neighboring locations. A radius of 1.5 includes the center plus all the eight-way neighbors. The radius can be arbitrarily large but large radii require lots of CPU cycles.

Installing the code


Copy the directory structure to a location of your choice.

Building the executable


System requirements

This code is known to run in the following environment:

  • Ubuntu 21.04
  • cimg-dev 2.8.4 or later
  • libopencv-dev 4.2 or later
  • gcc 9.3 or 10.3
  • python-igraph 0.8.3 (used only by tools/graph-nnet.py)
  • gnuplot 5.2.8 (used only by tools/graphlog.gp)

The code also runs in distributions based on Ubuntu 20.04, but only if the default version of cimg-dev is replaced with version 2.8.4 or later.

Compiling

Two ways to compile:

  • The file named "biosim4.cbp" is a configuration file for the Code::Blocks IDE version 20.03.

  • A Makefile is provided which was created from biosim4.cbp with cbp2make, but is not tested. A default "make" will generate a debug and a release version.

Bugs


If you try to compile the simulator under a distribution based on Ubuntu 20.04, you will encounter this bug in the version of CImg.h (package cimg-dev) provided by the package maintainer:

      https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=951965

In biosim4, CImg.h is used only as a convenient interface to OpenCV to generate movies of the simulated creatures in their 2D world. You have several choices if you want to proceed with Ubuntu 20.04:

  • You can strip out the code that generates the movies and just run the simulator without the movies. Most of that graphics code is in imageWriter.cpp and imageWriter.h.

  • You can upgrade your CImg.h to version 2.8.4 or later by getting it from the appropriate Debian repository. Sorry I don't have the instructions at hand to do this.

  • You could convert the CImg.h function calls to use OpenCV directly. Sorry I don't have a guide for how to do that.

Execution


Edit the config file (default "biosim4.ini") for the parameters you want for the simulation run, then execute the Debug or Release executable in the bin directory. Optionally specify the name of the config file as the first command line argument, e.g.:

./bin/Release/biosim4 [biosim4.ini]

Tools directory


tools/graphlog.gp takes the generated log file logs/epoch-log.txt and generates a graphic plot of the simulation run in images/log.png. You may need to adjust the directory paths in graphlog.gp for your environment. graphlog.gp can be invoked manually, or if the option "updateGraphLog" is set to true in the simulation config file, the simulator will try to invoke tools/graphlog.gp automatically during the simulation run. Also see the parameter named updateGraphLogStride in the config file.

tools/graph-nnet.py takes a text file (hardcoded name "net.txt") and generates a neural net connection diagram using igraph. The file net.txt contains an encoded form of one genome, and must be the same format as the files generated by displaySampleGenomes() in src/analysis.cpp which is called by simulator() in src/simulator.cpp. The genome output is printed to stdout automatically if the parameter named "displaySampleGenomes" is set to nonzero in the config file. An individual genome can be copied from that output stream and renamed "net.txt" in order to run graph-nnet.py.

Build log


In case it helps for debugging the build process, here is a build log from Code::Blocks running under Ubuntu 21.04:

-------------- Clean: Release in biosim4 (compiler: GNU GCC Compiler)---------------

Cleaned "biosim4 - Release"

-------------- Build: Release in biosim4 (compiler: GNU GCC Compiler)---------------

g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/analysis.cpp -o obj/Release/src/analysis.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/basicTypes.cpp -o obj/Release/src/basicTypes.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/createBarrier.cpp -o obj/Release/src/createBarrier.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/endOfGeneration.cpp -o obj/Release/src/endOfGeneration.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/endOfSimStep.cpp -o obj/Release/src/endOfSimStep.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/executeActions.cpp -o obj/Release/src/executeActions.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/feedForward.cpp -o obj/Release/src/feedForward.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/genome-compare.cpp -o obj/Release/src/genome-compare.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/genome.cpp -o obj/Release/src/genome.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/getSensor.cpp -o obj/Release/src/getSensor.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/grid.cpp -o obj/Release/src/grid.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/imageWriter.cpp -o obj/Release/src/imageWriter.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/indiv.cpp -o obj/Release/src/indiv.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/main.cpp -o obj/Release/src/main.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/params.cpp -o obj/Release/src/params.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/peeps.cpp -o obj/Release/src/peeps.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/random.cpp -o obj/Release/src/random.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/signals.cpp -o obj/Release/src/signals.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/simulator.cpp -o obj/Release/src/simulator.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/spawnNewGeneration.cpp -o obj/Release/src/spawnNewGeneration.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/survival-criteria.cpp -o obj/Release/src/survival-criteria.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/unitTestBasicTypes.cpp -o obj/Release/src/unitTestBasicTypes.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/unitTestConnectNeuralNetWiringFromGenome.cpp -o obj/Release/src/unitTestConnectNeuralNetWiringFromGenome.o
g++ -Wall -fexceptions -fopenmp -O3 -I/usr/include/opencv4 -c /home/dm/sw/biosim4-git/src/unitTestGridVisitNeighborhood.cpp -o obj/Release/src/unitTestGridVisitNeighborhood.o
g++  -o bin/Release/biosim4 obj/Release/src/analysis.o obj/Release/src/basicTypes.o obj/Release/src/createBarrier.o obj/Release/src/endOfGeneration.o obj/Release/src/endOfSimStep.o obj/Release/src/executeActions.o obj/Release/src/feedForward.o obj/Release/src/genome-compare.o obj/Release/src/genome.o obj/Release/src/getSensor.o obj/Release/src/grid.o obj/Release/src/imageWriter.o obj/Release/src/indiv.o obj/Release/src/main.o obj/Release/src/params.o obj/Release/src/peeps.o obj/Release/src/random.o obj/Release/src/signals.o obj/Release/src/simulator.o obj/Release/src/spawnNewGeneration.o obj/Release/src/survival-criteria.o obj/Release/src/unitTestBasicTypes.o obj/Release/src/unitTestConnectNeuralNetWiringFromGenome.o obj/Release/src/unitTestGridVisitNeighborhood.o  -lX11 -lgomp -pthread -O3 -s  /usr/lib/x86_64-linux-gnu/libopencv_core.so /usr/lib/x86_64-linux-gnu/libopencv_video.so /usr/lib/x86_64-linux-gnu/libopencv_videoio.so
Output file is bin/Release/biosim4 with size 778.42 KB
Process terminated with status 0 (0 minute(s), 11 second(s))
0 error(s), 0 warning(s) (0 minute(s), 11 second(s))
Issues
  • make: *** No targets specified and no makefile found.  Stop.

    make: *** No targets specified and no makefile found. Stop.

    I am excited to take your code for a spin.

    I am following your docker instructions.

    1. I cloned the repo
    2. I ran docker build -t biosim4 . it build successfully
    3. I tried to run docker run --rm -ti -vpwd:/app --name biosim biosim4 make but get the error: make: *** No targets specified and no makefile found. Stop.

    Is there something im missing here?

    Im on windows 10 if that helps.

    opened by mikecann 10
  • Remove redundant square roots

    Remove redundant square roots

    These two functions both calculate cos(t)/r, where t is the angle between offset and dir and r is the length of offset. This method achieves that by calculating a unit vector in the direction of dir, which is then accessed by f without recalculating each call. The dot product of this vector with offset is then just cos(t)*r, since the other vector is of unit length. Finding cos(t)/r then just requires dividing by r^2.

    On my machine, this reduces the time spend in these functions by around 40%, and this speeds up the entire program by around 25% (with video encoding disabled and other settings default), but obviously this is dependent on how often these signals are being used.

    The output of this function is within 10^(-8) of the output of the original, with the difference coming largely from the fact that raySameness only works to float precision, whereas it seems intended for this function to work to double precision.

    The comments mention that this function uses the "positive absolute cosine", which seems to imply that |cos(t)| should be being used instead. Doing that fails to reproduce the behaviour of the code being replaced so I've left it as is.

    opened by Asa-Hopkins 9
  • Rewrote Makefile to a simpler and hand made edition

    Rewrote Makefile to a simpler and hand made edition

    Build binary using all source files src/.cpp, and let them depend on all src/.h, and only build either release or debug builds, not both.

    This include the fixes from pull requests #67 and #68, and provide a fix for issue #65.

    opened by petterreinholdtsen 8
  • testapp.py and associated files/libs

    testapp.py and associated files/libs

    A Python script for testing a biosim4 simulation. It also includes some utility functions to manipulate .ini files and simulation parameters.

    Files and libs in Tests directory.

    opened by venzen 8
  • fix bug in github action

    fix bug in github action

    now that it's actually working, i can test it and fix it =)

    this checks that any changes made to the code base do not ruin the compilation of the program by ensuring that make still completes.

    the problem was that github action runs in an environment where the -ti flag makes no sense, it was sloppy on my part to forget omitting them (just a copy/paste thing). It's the difference between what you want to run on your machine to make it useful to work with VS what you want in CI to perform checks.

    opened by mathematicalmichael 8
  • Confusion about signals

    Confusion about signals

    I watched the video on YouTube and it was great. I watched it a few times and I'm trying to re-implement the simulator myself.

    I had a question about how signals travel in the neural network. My understanding goes like this:

    1. Signals come from input neurons, when it is activated (whatever the reason). The strength of a signal can be 0, 1, or anything in between.
    2. Signals travel through connections and the strength is multiplied by the connection's strength.
    3. The strength of the signal leaving a neuron is tanh(sum(inputs)).
    4. When a signal gets to an output neuron, then this action represented by the neuron has some chance to be executed. The greater the strength, the more likely that action will be chosen.

    I currently have the following questions:

    1. How does it work when an internal neuron is connected to itself? In tanh(sum(inputs)), we can't include the self connection's input, because it does not exist yet. But once the output is activated, then a new input is activated. I don't know how to deal with this recursivity.
    2. What does it mean when an output neuron receives a negative signal? Does everything below 0 mean no activation at all?
    3. At around the 15-minute mark in the video, an example neural network is shown. (see the image below) It says that the MvE neuron is more likely to be activated when the path forward is free to go (LPf input). But when it isn't then the other output neuron (Mrn) becomes more likely to be chosen. How can it be active? I don't see anything connected to it. The only input I see goes to MvE, and MvE has no output. The video says that the signal comes from the internal neuron, but where does the signal come from?

    (image for question 3) image

    Thank you!

    (I'm still reading the code, so if I find an answer I'll post it here. I'm not comfortable with C++ unfortunately.)

    opened by mfcochauxlaberge 5
  • Peeps::queueForDeath() queues already dead Indiv-s in RadioactiveChallenge

    Peeps::queueForDeath() queues already dead Indiv-s in RadioactiveChallenge

    Symptom: Some individuals are queued for death even after they marked as dead already when RadioActiveWalls mode is on. This results indirectly allowing for individuals to be added to move queue even if they have no movement scheduled. As a result getPopulationDensityAlongAxis will assert with assert(dir != Compass::CENTER);

    Expected: No assert and dead individuals never should be queued twice.

    This is my first ever github community contribution, so I am not familiar with the procedure. I am happy to create a PR with the fix, if you think it needs to be fixed. Please leave a comment and I get the work done.

    opened by artofimagination 5
  • suse error

    suse error

    First let me start by saying i have very little experience in linux atempted to get running from suse cimg-devel version 2.9.7 libopencv-devel version 4.5.2 gcc10 10.3.1

    attempted make failed with the following.

    [email protected]:~/Downloads/biosim4-main> make test -d bin/Debug || mkdir -p bin/Debug test -d obj/Debug/src || mkdir -p obj/Debug/src g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/signals.cpp -o obj/Debug/src/signals.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/main.cpp -o obj/Debug/src/main.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/params.cpp -o obj/Debug/src/params.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/peeps.cpp -o obj/Debug/src/peeps.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/random.cpp -o obj/Debug/src/random.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/simulator.cpp -o obj/Debug/src/simulator.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/spawnNewGeneration.cpp -o obj/Debug/src/spawnNewGeneration.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/survival-criteria.cpp -o obj/Debug/src/survival-criteria.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/unitTestBasicTypes.cpp -o obj/Debug/src/unitTestBasicTypes.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/unitTestConnectNeuralNetWiringFromGenome.cpp -o obj/Debug/src/unitTestConnectNeuralNetWiringFromGenome.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/unitTestGridVisitNeighborhood.cpp -o obj/Debug/src/unitTestGridVisitNeighborhood.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/genome-compare.cpp -o obj/Debug/src/genome-compare.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/analysis.cpp -o obj/Debug/src/analysis.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/basicTypes.cpp -o obj/Debug/src/basicTypes.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/createBarrier.cpp -o obj/Debug/src/createBarrier.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/endOfGeneration.cpp -o obj/Debug/src/endOfGeneration.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/endOfSimStep.cpp -o obj/Debug/src/endOfSimStep.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/executeActions.cpp -o obj/Debug/src/executeActions.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/feedForward.cpp -o obj/Debug/src/feedForward.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/genome.cpp -o obj/Debug/src/genome.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/getSensor.cpp -o obj/Debug/src/getSensor.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/grid.cpp -o obj/Debug/src/grid.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/imageWriter.cpp -o obj/Debug/src/imageWriter.o g++ -Wall -fexceptions -g -fopenmp -I/usr/include/opencv4 -c src/indiv.cpp -o obj/Debug/src/indiv.o g++ -o bin/Debug/biosim4 obj/Debug/src/signals.o obj/Debug/src/main.o obj/Debug/src/params.o obj/Debug/src/peeps.o obj/Debug/src/random.o obj/Debug/src/simulator.o obj/Debug/src/spawnNewGeneration.o obj/Debug/src/survival-criteria.o obj/Debug/src/unitTestBasicTypes.o obj/Debug/src/unitTestConnectNeuralNetWiringFromGenome.o obj/Debug/src/unitTestGridVisitNeighborhood.o obj/Debug/src/genome-compare.o obj/Debug/src/analysis.o obj/Debug/src/basicTypes.o obj/Debug/src/createBarrier.o obj/Debug/src/endOfGeneration.o obj/Debug/src/endOfSimStep.o obj/Debug/src/executeActions.o obj/Debug/src/feedForward.o obj/Debug/src/genome.o obj/Debug/src/getSensor.o obj/Debug/src/grid.o obj/Debug/src/imageWriter.o obj/Debug/src/indiv.o -lX11 -lpthread -fopenmp /usr/lib/x86_64-linux-gnu/libopencv_core.so /usr/lib/x86_64-linux-gnu/libopencv_video.so /usr/lib/x86_64-linux-gnu/libopencv_videoio.so /usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/ld: cannot find /usr/lib/x86_64-linux-gnu/libopencv_core.so: No such file or directory /usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/ld: cannot find /usr/lib/x86_64-linux-gnu/libopencv_video.so: No such file or directory /usr/lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/bin/ld: cannot find /usr/lib/x86_64-linux-gnu/libopencv_videoio.so: No such file or directory collect2: error: ld returned 1 exit status make: *** [Makefile:60: out_debug] Error 1

    opened by sychris 5
  • minor tweak to Makefile so the project compiles properly

    minor tweak to Makefile so the project compiles properly

    • Added -fopenmp to CFLAGS so that openMP pragma's are recognised and used
    • Added -lgomp to LDFLAGS so openMP is linked properly

    with these two minor changes everything makes properly on debian 11 inside my WSL2

    opened by arhi 4
  • Allow the MOVE_LR action to go in the left.

    Allow the MOVE_LR action to go in the left.

    As written, when the level is less than zero, it goes left a negative amount. This is the same as going right with a positive amount. So, this action only goes to the right.

    If the range of level is from -1.0f to 1.0f, then the code for MOVE_RIGHT is correct for this case. too For when it's less than zero, it goes right a negative amount.

    But, if we limit the range of neurons between 0.0f and 1.0f, then how about setting 0.5f as moving forward, less than that is to the left, and more it to the right? The proposed fix is for this expectation.

    opened by GregEakin 4
  • Repeated  sensorVal message

    Repeated sensorVal message

    Great video and good idea to make the code open source .

    Successfully compiled from the instructions in the README file using the docker image.

    For the initial hundred or so generations of most sims I run, this message repeats verbosely:

    sensorVal=-2147483648 for genetic similarity fwd

    Do most users experience this or is it perhaps due to a wayward parameter ?

    I'm not seeing repeat messages other than this particular value and genetic similarity "fwd".

    opened by venzen 4
  • Balance out

    Balance out "kill" function

    I came here after view the video about the simulation. The section about the "kill" function has a terrifying implication. It kind of keeps me awake at night. But I think I finally found the solution.

    • The "kill" function is a social action but the sims have no social evaluation. I will refer to the Sims collective/community/collection as "the Sims", therefore using singular verbs. The "sims" without capitalization refers to multiple of sims. That means the Sims has no "motive" to evolve into a stronger community, they simply evolved to survive.
    • The "kill" function also is a purely negative function in terms of social benefit while it is the ONLY social function. And by "social" I mean the interaction between the sims themselves, not "environmental" factors. And by "negative" I mean having less sims seems worse than having more.
    • After those realizations, it would be kind of surprising to see a long-term equilibrium that does not involve mass killings.

    I think if we can introduce a mechanism for the Sims to evaluate its actions (without implicit instruction aka "divine intervention"), it will evolve differently. There is an elegant way to do it. I think the conditions to reproduce should include 1 more dimension. The sims can only reproduce if it has at least 1 sim in close proximity. It's not stated explicitly but repopulation/reproduction is also a social function, a passive/hidden one rather than an active one.

    I think that can be achieved in multiple ways. I can see there are multiple sensory inputs coded about population/pheromones gradient/density in the video which were not used. But I am not qualified to say which way represents best whatever the program wants to achieve.

    I hope someone can take the suggestion to tweak the project to see if we can find "humanity".

    I don't know how much resource is required to do that tweak so I will just put one of them up here. I of course couldn't do it myself as I barely understand the requirements to run the simulation. If anyone wants more ideas, here are a few more "natural social evaluation":

    • the more crowded the proximity, the higher chance of reproduction. That means repopulation is not an equal game for all genes, the "killing loners" are what they are.
    • We can introduce genders where reproduction requires different sexes in close proximity. That probably will also reduce the "kill" gene. I think that tweak could reveal some fascinating understanding about who we are.
    opened by nvu1991 2
  • Windows Port / Similar Sim

    Windows Port / Similar Sim

    Hi, Thank you for creating this program and the explanation video, it really helped me understand the theory behind this simulation and I decided to create my own version of the simulation using the theory and visualisations you created :D

    https://user-images.githubusercontent.com/33568643/167718427-d59df614-6cee-4036-9e8e-da55312b2032.mov

    https://github.com/oxi-dev0/NeuroSim

    It uses SFML to render and so is Windows compatible; I'm not sure about mac or linux, as I did not setup the premake file to configure for them, but it should work.

    Its not a port / a full rewrite, as the only code i used for reference was the grid header; the actual neural simulation is my own code where it back flows from the effectors down it's chain using cached values and recursion when needed, im not sure how biosim4 does it on a code level, but it does produce results similar to biosim4 so it could be considered somewhat of a rewrite :D

    It also can produce the neural map visualisations in the program and has a viewer where you can drag the view around, zoom in and hover over the connections to see their weight.

    Despite it not being a port / os specific rewrite (it doesnt have pheremones or the population receptors), I hope some people on windows who want to run biosim4 still find it beneficial :)

    opened by oxi-dev0 1
  • Defold port

    Defold port

    Hi Im working on a Defold port. It looks really great so far:

    https://user-images.githubusercontent.com/3954182/167335845-6d78e80e-bdb4-439c-a844-b53c22367085.mp4

    I wanted to make sure this is ok to do. I will be releasing the project soon as MIT for anyone to use and wanted to be sure to give correct credits etc. Would you like any specific papers or names in the credits?

    opened by dlannan 6
  • Input neuron values not negative

    Input neuron values not negative

    I was wondering why the input neuron output is 0 to 1 whereas other neurons are -1 to 1 and the output neurons seem to expect -1 to 1 as well.

    In particular, input like LAST_MOVE_DIR_X maps -1 to 0 to 1 as 0 to .5 to 1. This seem asymmetrical and seems like the math would artificially bias toward one direction or the other.

    Thanks so much for making this video! Before I watched it I had thought neural networks were way beyond my comprehension.

    opened by Wingman8 3
  • Having issue with makefile

    Having issue with makefile

    I've been trying to make it using the makefile, but I've been experiencing issues. I'm running on raspberry pi 4 4GB, which is debian-based.

    [email protected]:~/biosim4 $ make
    test -d bin/Debug || mkdir -p bin/Debug
    test -d obj/Debug/src || mkdir -p obj/Debug/src
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/signals.cpp -o obj/Debug/src/signals.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/main.cpp -o obj/Debug/src/main.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/params.cpp -o obj/Debug/src/params.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/peeps.cpp -o obj/Debug/src/peeps.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/random.cpp -o obj/Debug/src/random.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/simulator.cpp -o obj/Debug/src/simulator.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/spawnNewGeneration.cpp -o obj/Debug/src/spawnNewGeneration.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/survival-criteria.cpp -o obj/Debug/src/survival-criteria.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/unitTestBasicTypes.cpp -o obj/Debug/src/unitTestBasicTypes.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/unitTestConnectNeuralNetWiringFromGenome.cpp -o obj/Debug/src/unitTestConnectNeuralNetWiringFromGenome.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/unitTestGridVisitNeighborhood.cpp -o obj/Debug/src/unitTestGridVisitNeighborhood.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/genome-compare.cpp -o obj/Debug/src/genome-compare.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/analysis.cpp -o obj/Debug/src/analysis.o
    g++ -Wall -fexceptions -fopenmp -g -fopenmp -I/usr/include/opencv4 -c src/basicTypes.cpp -o obj/Debug/src/basicTypes.o
    src/basicTypes.cpp: In member function ‘BS::Coord BS::Polar::asCoord() const’:
    src/basicTypes.cpp:135:15: warning: left shift count >= width of type [-Wshift-count-overflow]
             1L << 32,    // S
                   ^~
    src/basicTypes.cpp:137:15: warning: left shift count >= width of type [-Wshift-count-overflow]
             1L << 32,    // W
                   ^~
    src/basicTypes.cpp:139:15: warning: left shift count >= width of type [-Wshift-count-overflow]
             1L << 32,    // E
                   ^~
    src/basicTypes.cpp:141:15: warning: left shift count >= width of type [-Wshift-count-overflow]
             1L << 32,    // N
                   ^~
    src/basicTypes.cpp:135:12: error: right operand of shift expression ‘(1 << 32)’ is >= than the precision of the left operand [-fpermissive]
             1L << 32,    // S
             ~~~^~~~~
    src/basicTypes.cpp:153:55: warning: integer overflow in expression of type ‘long int’ results in ‘2147483647’ [-Woverflow]
         int64_t temp = ((int64_t)mag >> 32) ^ ((1L << 31) - 1);
                                                ~~~~~~~~~~~^~~
    src/basicTypes.cpp:154:33: warning: left shift count >= width of type [-Wshift-count-overflow]
         len = (len + temp) / (1L << 32); // Divide to make sure we get an arithmetic shift
    
    opened by mollthecoder 15
  • Publish scientific article on Biosim?

    Publish scientific article on Biosim?

    Learning about Biosim4 reminded me of the Tierra system from thirty years ago, and made me hope you will publish your experiences with it as a scientific paper to make sure your ideas are conserved and recognized also when Youtube is long gone.

    Are you aware of the Tierray system? You can read more about it in https://en.wikipedia.org/wiki/Tierra_(computer_simulation) , https://faculty.cc.gatech.edu/~turk/bio_sim/articles/tierra_thomas_ray.pdf , https://www.nytimes.com/1991/08/27/science/lively-computer-creation-blurs-definition-of-life.html , https://www.mediamatic.net/en/page/9047/tierra and https://yewtu.be/watch?v=Wl5rRGVD0QI .

    opened by petterreinholdtsen 1
Owner
David R. Miller
David R. Miller
Simple evolution simulator with generations mechanic and customizable settings.

SimpleEvolution Simple evolution simulator with generations mechanic and customizable settings. Field is divided in three sections: safe zone, medium

Oleg 3 Dec 18, 2021
A Motorola 68K simulator based on Musashi-master 68K simulator.

cpmsim Originally referenced as http://home.earthlink.net/~schultdw/cpm68/simulator.html (now 404) This simple CP/M-68K simulator, is built around the

Neil Cherry 8 Oct 26, 2021
A comprehensive guide to 50 years of evolution of strict C programming, a tribute to Dennis Ritchie's language

42 School Cheat Sheet by agavrel ?? Intended for 42 alumni, current students and candidates Truth can only be found in one place: the code – Robert C.

Antonin GAVREL 952 Aug 4, 2022
Anti-Grain Evolution. 2D graphics engine for Speed and Quality in C++.

Anti-Grain Evolution This project is based on ideas found in Maxim (mcseem) Shemanarev's Anti-Grain Geometry library, but oriented towards maximizing

Artem G. 94 Jul 22, 2022
Mobile robot simulator

The Stage Simulator This is the Stage README file, containing an introduction, license and citation information. Stage is a 2(.5)D robotics standalone

Richard Vaughan 350 Jul 29, 2022
Real-time 2D fluid simulator with lots of visualization options.

Fluid Simulator Building Start by cloning the program and all submodules using the following command: git clone --recursive https://github.com/linusmo

Linus Mossberg 26 Jun 20, 2022
Restoration of The Linux Scheduler Simulator (LinSched)

Restoration of The Linux Scheduler Simulator (LinSched)

Jim Huang 13 Sep 3, 2021
HiFi error modeler and simulator with ploidy

A HiFi Shotgun Simulator Author: Gene Myers First: Aug 1, 2021 Current: Aug 1, 2021 Commands Himodel HIsim The Error Model Commands This module contai

Eugene W Myers Jr 9 Aug 4, 2022
GrandOrgue is a sample based pipe organ simulator.

GrandOrgue is a sample based pipe organ simulator. It currently supports Linux, Windows and OS X. Porting to other OS supported by RtMidi,

GrandOrgue 62 Jul 26, 2022
JaBS - Jaakko's Backscattering Simulator

JaBS - Jaakko's Backscattering Simulator

null 3 Mar 31, 2022
a Little Computer 3 simulator

smol3 ??️ a Little Computer 3 simulator smol3 is a tiny LC3 simulator written in C. It aims to be fast and correct. TODO read input binary files write

pry 1 Oct 22, 2021
Using Pi Pico to provide trimwheel for Flightgear Flight Simulator

Trimwheel for FGFS This uses a Rotary Encoder (RE) and a Raspberry Pi Pico (Pico) to connect the RE to FlightGear Flight Simulator as a Pitch Trimwhee

Dave Attwood 1 Dec 14, 2021
Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control

StockSimulator Stock exchange simulator made in Swing using Java with logic backend in C++ giving it faster load time and better data control Features

Dušan Todorović 0 Mar 1, 2022
An Electronic voting machine simulator using C

EVM-using-C An Electronic voting machine simulator using C The project is divided into few parts 1.The program first asks to enter the information of

BABA SHANKAR S N 1 Oct 24, 2021
Adaptive Runtime AUTOSAR Linux Simulator

Adaptive-AUTOSAR Adaptive AUTOSAR is a simulated Adaptive Platform enviroment over Linux defined by AUTOSAR. The goal of this project is to implement

Armin Kassemi Langroodi 91 Aug 5, 2022
Fastest-lap is an optimal laptime simulator, written in C++, and with a python API.

Fastest-lap ?? ?? Fastest-lap is an optimal laptime simulator, written in C++, and with a python API. What can be done Numerical G-G diagram: given a

Juan Manzanero 289 Aug 9, 2022
Plus42 : An Enhanced HP-42S Calculator Simulator

------------------------------------------------------------------------------- Plus42 is an advanced scientific programmable calculator app. It simul

Thomas Okken 12 Mar 8, 2022
Open source simulator for autonomous vehicles built on Unreal Engine / Unity, from Microsoft AI & Research

Welcome to AirSim AirSim is a simulator for drones, cars and more, built on Unreal Engine (we now also have an experimental Unity release). It is open

Microsoft 13.4k Aug 9, 2022
A 555 timer simulator running on the ATTiny85 :)

ATTiny555 A 555 timer simulator running on the ATTiny85 :) For a more detailed description (and build instructions), check me out on Hackaday! Overvie

null 60 Jul 14, 2022