#include <src/SporeCloud.h>
Inheritance diagram for SporeCloud:
We globally have these 2 options for th G.A.:
The idea is that agents don't have yet a mating AI which alows them to reproduce by choosing their partners on self-organized criteria (like for example a pretty blue plume on the head).
Thus we're left with agents meeting each other on an explicit criterion, or chance. The first poses the problem of defining this criterion, and the second is not possible on collision only : A GA relying on collisions to reproduce would possibly end up favoring AI that collide... which we don't want.
So, a way to maximize agents interactions without relying on collision or other explicit rendez-vous points is to do like plants, fish, mushrooms... This leads to the concept of a spore cloud (thanks goes to Nawwaf Kharma for pointing this idea out).
I simulate here the spore cloud by a volumic concentration leading to probabilities of fecundation. As for the locality database, the world is divided into elementary volumes. Then when an agent wishes to get fecunded it simply gets spores from the environment:
The volumic concentrations are updated by diffusion equations, using the simulator once more. Note that the integration update frequency of the cloud spore diffusion may be different than the frequency of the agents physics.
I also add a decay time after which the spores are non-functional and thus eliminated. A future extension may be to gradually reduce the spores efficiency by playing on probabilities, instead of this clear cut. Think for example of radioactive half-life time.
Public Types | |
typedef SporeVolume *(* | SporeVolumeFactory )(void *) |
Public Member Functions | |
SporeCloud (double originx, double originy, double originz, double sizex, double sizey, double sizez, int divx, int divy, int divz, double baseDiffusionCoef, double lowestConcentration, SporeVolumeFactory factory=&sporeVolumeFactory, void *user=0) | |
double | getDiffusionCoefficient () |
for info purpose | |
virtual void | step () |
numerical integration step. Warning... condition stability applies... please use the schedule method and check the return value! | |
virtual bool | schedule (double integrationTimeStep) |
Check that the integrationTimeStep respects the stability condition and in this case, schedule the various parts of the computations by spreading them over the time step to reduce CPU peaks return true if the stability condition is OK, false otherwise. | |
virtual void | addSpore (double x, double y, double z, Genome *genome, double concentration) |
Adds an individual agent spore cloud to the global cloud for diffusion The genome will be ref'd in case the agent dies An half-life in simulator time units should be provided for the spore vitality! | |
virtual ConcentrationList * | getConcentrationList (double x, double y, double z) |
Returns a concentration list at the given location Used by agents during reproduction the concentration list for the given location. May be null. | |
Static Public Member Functions | |
static SporeVolume * | sporeVolumeFactory (void *user) |
Default factory creates volume objects for this class. Subclass may thus choose to create volumes of its own type. Too bad C++ doesn't allow virtual functions from constructor (I know, big debate...). | |
Protected Member Functions | |
SporeVolume * | cyclicVolume (int x, int y, int z) |
consider world is cyclic in XY => no boundary condition!!! Boundary condition in Z is closed world = altitude limit Please use pre-computed traversal pointers in volumes instead of this This is a utility for the constructor because I'm lazy to split all the special boundary cases! May return null pointer if this cell is unused | |
void | intermediateStepDecay () |
computations are distributed in time | |
void | intermediateStepXn () |
void | intermediateStepXp () |
void | intermediateStepYn () |
void | intermediateStepYp () |
void | intermediateStepZn () |
void | intermediateStepZp () |
void | intermediateStepPostProcess () |
Protected Attributes | |
SporeVolume ** | volume |
data structure for xyz bricks, actually a big array of spore volume list. Array is still necessary for direct access, from (x,y,z) => correct volume | |
SporeVolume ** | volumeEnd |
int | vsize |
SporeVolume * | firstVolume |
But for list traversal, it's more efficient not to visit unused cells. | |
SporeVolume * | firstProcess |
And for each step, it's even more efficient to visit only those with non-empty neighbors. | |
double | originx |
Re-used from locality DB: the origin is the super-brick corner minimum coordinates. | |
double | originy |
Re-used from locality DB: the origin is the super-brick corner minimum coordinates. | |
double | originz |
Re-used from locality DB: the origin is the super-brick corner minimum coordinates. | |
double | sizex |
Re-used from locality DB: length of the edges of the super-brick. | |
double | sizey |
Re-used from locality DB: length of the edges of the super-brick. | |
double | sizez |
Re-used from locality DB: length of the edges of the super-brick. | |
int | divx |
Re-used from locality DB: number of sub-brick divisions in each direction. | |
int | divy |
Re-used from locality DB: number of sub-brick divisions in each direction. | |
int | divz |
Re-used from locality DB: number of sub-brick divisions in each direction. | |
double | timeStep |
Used as dt for integration. | |
double | lowestConcentration |
Min concentration for a volume. Below this, consider there is no cloud. | |
double | diffuseXN |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffuseXP |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffuseYN |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffuseYP |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffuseZN |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffuseZP |
Diffusion coefficients constants, precomputed with grid size & time step Plan for anisotropic diffusion if gravity taken into account & maybe global wind? | |
double | diffusionCoefficient |
for info purpose | |
Classes | |
struct | ConcentrationList |
Was initially a map, but inefficient iterators => Try a sorted list Still inefficient in accessing elements & iterators (thanks oprofile) => make own structure! More... | |
struct | Genome |
struct | SporeVolume |
all the lists present in one volume More... |
|
Check that the integrationTimeStep respects the stability condition and in this case, schedule the various parts of the computations by spreading them over the time step to reduce CPU peaks return true if the stability condition is OK, false otherwise. Now schedule intermediate steps to distribute computations in time In fact: final step + post process + next decay still no match for an intermediate step according to oprofile => schedule all these in only one delta compared to intermediate steps. Now computations are distributed in time, let the fun begins! |
|
numerical integration step. Warning... condition stability applies... please use the schedule method and check the return value! Original all-in-one code below. Now split into several parts to distribute the computations in time thanks to the simulator Step does the final update TODO: restore all-in-one mode for batch mode, where peaks don't matter => could this improve perfs by de-allocating lists only once per update? Reimplemented in DrawableSporeCloud. |