summaryrefslogtreecommitdiff
path: root/src/phenotypebinary.cpp
blob: d16588b2d787c552c9386366a32b958df24b0810 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "genetic/phenotypebinary.h"

#include <bu/random.h>
#include <bu/sio.h>

using namespace Bu;

// Bits per word
#define BPW     			(sizeof(uint_fast32_t)*8)
#define wordsForBits( x )	(((x)/BPW)+(((x)%BPW)?1:0))
#define wordWithBit( x )	((x)/BPW)

Genetic::PhenotypeBinary::PhenotypeBinary( int iSize, bool bRandom ) :
	iSize( iSize ),
	iWords( wordsForBits(iSize) ),
	aGenes( NULL )
{
	aGenes = new uint_fast32_t[iWords];
	if( bRandom )
		randomize();
}

Genetic::PhenotypeBinary::~PhenotypeBinary()
{
	delete[] aGenes;
}

Genetic::Phenotype &Genetic::PhenotypeBinary::randomize()
{
	for( int j = 0; j < iWords*sizeof(uint_fast32_t); j++ )
	{
		((uint8_t *)aGenes)[j] = (uint8_t)Bu::Random::rand();
	}

	return *this;
}

void Genetic::PhenotypeBinary::mutate( int iLocation, float fMagnitude )
{
	if( fMagnitude > -0.5 && fMagnitude < 0.5 )
		return;

	aGenes[wordWithBit(iLocation)] =
		(aGenes[wordWithBit(iLocation)]&(~(1<<((iLocation)%BPW)))) |
		((~aGenes[wordWithBit(iLocation)])&((1<<((iLocation)%BPW))));
}

Genetic::Phenotype *Genetic::PhenotypeBinary::makeEmptyOffspring(
	int iNewSize )
{
	if( iNewSize < 0 )
		iNewSize = iSize;

	return new PhenotypeBinary( iSize );
}

Genetic::Phenotype &Genetic::PhenotypeBinary::copyFrom( const Phenotype &rSrc,
		int iStart, int iCount, int iDest )
{
	const PhenotypeBinary &rbSrc =
		dynamic_cast<const Genetic::PhenotypeBinary &>(rSrc);
	if( iDest < 0 )
		iDest = iStart;

	// Fist draft, very sloppy: bit by bit copy, this is stupid, but easy
	for( int j = 0; j < iCount; j++ )
	{
		int wd = wordWithBit(j+iDest);
		int ws = wordWithBit(j+iStart);
		if( (rbSrc.aGenes[ws]&(1<<((j+iStart)%BPW))) == 0)
		{
			aGenes[wd] &= ~(1<<((j+iDest)%BPW));
		}
		else
		{
			aGenes[wd] |= (1<<((j+iDest)%BPW));
		}
	}

	/*
	iStart%BPW
	int iWords = wordsForBits(iCount);
	for( int j = wordWithBit(iStart); j < iWords; j++ )
	{
	}
	*/

	return *this;
}

Bu::String Genetic::PhenotypeBinary::toString()
{
	Bu::String sRet;
	for( int j = 0; j < iSize; j++ )
	{
		sRet += (aGenes[j/BPW]&(1<<(j%BPW)))?'1':'0';
	}

	return sRet;
}