summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2012-07-09 08:39:37 -0600
committerMike Buland <mike@xagasoft.com>2012-07-09 08:39:37 -0600
commit40ee7ad5aeadeb9823e1cd6e1218a1999c608a65 (patch)
tree6e819d8406d818eaa63cb6f04e2a129b8561c213 /src
downloadlibgenetic-40ee7ad5aeadeb9823e1cd6e1218a1999c608a65.tar.gz
libgenetic-40ee7ad5aeadeb9823e1cd6e1218a1999c608a65.tar.bz2
libgenetic-40ee7ad5aeadeb9823e1cd6e1218a1999c608a65.tar.xz
libgenetic-40ee7ad5aeadeb9823e1cd6e1218a1999c608a65.zip
New libgenetic. Genetic algorithms, only good.
Diffstat (limited to 'src')
-rw-r--r--src/operator.cpp10
-rw-r--r--src/operator.h25
-rw-r--r--src/operatorbasic.cpp48
-rw-r--r--src/operatorbasic.h32
-rw-r--r--src/phenotype.cpp10
-rw-r--r--src/phenotype.h36
-rw-r--r--src/phenotypebinary.cpp101
-rw-r--r--src/phenotypebinary.h29
-rw-r--r--src/population.cpp10
-rw-r--r--src/population.h14
-rw-r--r--src/tests/binary.cpp37
11 files changed, 352 insertions, 0 deletions
diff --git a/src/operator.cpp b/src/operator.cpp
new file mode 100644
index 0000000..7324856
--- /dev/null
+++ b/src/operator.cpp
@@ -0,0 +1,10 @@
1#include "genetic/operator.h"
2
3Genetic::Operator::Operator()
4{
5}
6
7Genetic::Operator::~Operator()
8{
9}
10
diff --git a/src/operator.h b/src/operator.h
new file mode 100644
index 0000000..8688667
--- /dev/null
+++ b/src/operator.h
@@ -0,0 +1,25 @@
1#ifndef GENETIC_OPERATOR_H
2#define GENETIC_OPERATOR_H
3
4#include <bu/list.h>
5
6namespace Genetic
7{
8 class Phenotype;
9 typedef Bu::List<Phenotype *> PhenotypeList;
10
11 class Operator
12 {
13 public:
14 Operator();
15 virtual ~Operator();
16
17 virtual Phenotype *random()=0;
18 virtual int parentCount()=0;
19 virtual Phenotype *mate( const PhenotypeList &lParents )=0;
20
21 private:
22 };
23};
24
25#endif
diff --git a/src/operatorbasic.cpp b/src/operatorbasic.cpp
new file mode 100644
index 0000000..ce37f78
--- /dev/null
+++ b/src/operatorbasic.cpp
@@ -0,0 +1,48 @@
1#include "genetic/operatorbasic.h"
2#include "genetic/phenotype.h"
3
4#include <bu/random.h>
5#include <bu/sio.h>
6using namespace Bu;
7
8Genetic::OperatorBasic::OperatorBasic( Phenotype *pProgenitor,
9 float fMutationRate ) :
10 pProgenitor( pProgenitor ),
11 fMutationRate( fMutationRate )
12{
13}
14
15Genetic::OperatorBasic::~OperatorBasic()
16{
17 delete pProgenitor;
18}
19
20Genetic::Phenotype *Genetic::OperatorBasic::random()
21{
22 Genetic::Phenotype *pNew = pProgenitor->makeEmptyOffspring();
23 pNew->randomize();
24 return pNew;
25}
26
27Genetic::Phenotype *Genetic::OperatorBasic::mate(
28 const Genetic::PhenotypeList &lParents )
29{
30 Genetic::Phenotype *pChild = lParents.first()->makeEmptyOffspring();
31
32 // Right now, we assume both parents have the same amount of "DNA"
33 int iSplitPoint = ((uint32_t)Bu::Random::rand())%lParents.first()->getSize();
34 pChild->copyFrom( *lParents.first(), 0, iSplitPoint );
35 pChild->copyFrom( *lParents.last(), iSplitPoint,
36 lParents.last()->getSize()-iSplitPoint );
37
38 // Mutate the child some
39 for( int j = 0; j < pChild->getSize(); j++ )
40 {
41 //sio << Bu::Random::randNorm() << sio.nl;
42 if( Bu::Random::randNorm() <= fMutationRate )
43 pChild->mutate( j, 1.0 );
44 }
45
46 return pChild;
47}
48
diff --git a/src/operatorbasic.h b/src/operatorbasic.h
new file mode 100644
index 0000000..2eaf198
--- /dev/null
+++ b/src/operatorbasic.h
@@ -0,0 +1,32 @@
1#ifndef GENETIC_OPERATOR_BASIC_H
2#define GENETIC_OPERATOR_BASIC_H
3
4#include "genetic/operator.h"
5
6namespace Genetic
7{
8 /**
9 * Very simple genetic operator that covers all the basics. It will do
10 * single cut Phenotype splicing between two parents, and random mutation
11 * on the child. All work is based on a progenitor Phenotype, which is the
12 * template for creating new, random Phenotypes. OperatorBasic takes
13 * ownership of the progenitor and will delete it when OperatorBasic is
14 * destroyed.
15 */
16 class OperatorBasic : public Operator
17 {
18 public:
19 OperatorBasic( Phenotype *pProgenitor, float fMutationRate );
20 virtual ~OperatorBasic();
21
22 virtual Phenotype *random();
23 virtual int parentCount() { return 2; }
24 virtual Phenotype *mate( const PhenotypeList &lParents );
25
26 private:
27 Phenotype *pProgenitor;
28 float fMutationRate;
29 };
30};
31
32#endif
diff --git a/src/phenotype.cpp b/src/phenotype.cpp
new file mode 100644
index 0000000..1eca170
--- /dev/null
+++ b/src/phenotype.cpp
@@ -0,0 +1,10 @@
1#include "genetic/phenotype.h"
2
3Genetic::Phenotype::Phenotype()
4{
5}
6
7Genetic::Phenotype::~Phenotype()
8{
9}
10
diff --git a/src/phenotype.h b/src/phenotype.h
new file mode 100644
index 0000000..7c564d5
--- /dev/null
+++ b/src/phenotype.h
@@ -0,0 +1,36 @@
1#ifndef GENETIC_PHENOTYPE_H
2#define GENETIC_PHENOTYPE_H
3
4#include <bu/string.h>
5
6namespace Genetic
7{
8 class Phenotype
9 {
10 public:
11 Phenotype();
12 virtual ~Phenotype();
13
14 virtual int getSize()=0;
15 virtual Phenotype &randomize()=0;
16 /**
17 * Modify the given location by the given magnitude. The magnitude
18 * should be between -1.0 and 1.0 inclusive. A 0.0 indicates no
19 * change.
20 */
21 virtual void mutate( int iLocation, float fMagnitude )=0;
22 virtual Phenotype &copyFrom( const Phenotype &rSrc, int iStart,
23 int iSize, int iDest=-1 )=0;
24 /**
25 * Produces a Phenotype class that can be used to contain the data for
26 * an offspring. The produced phenotype will be compatible, but empty.
27 */
28 virtual Phenotype *makeEmptyOffspring( int iNewSize=-1 )=0;
29
30 virtual Bu::String toString()=0;
31
32 private:
33 };
34};
35
36#endif
diff --git a/src/phenotypebinary.cpp b/src/phenotypebinary.cpp
new file mode 100644
index 0000000..d16588b
--- /dev/null
+++ b/src/phenotypebinary.cpp
@@ -0,0 +1,101 @@
1#include "genetic/phenotypebinary.h"
2
3#include <bu/random.h>
4#include <bu/sio.h>
5
6using namespace Bu;
7
8// Bits per word
9#define BPW (sizeof(uint_fast32_t)*8)
10#define wordsForBits( x ) (((x)/BPW)+(((x)%BPW)?1:0))
11#define wordWithBit( x ) ((x)/BPW)
12
13Genetic::PhenotypeBinary::PhenotypeBinary( int iSize, bool bRandom ) :
14 iSize( iSize ),
15 iWords( wordsForBits(iSize) ),
16 aGenes( NULL )
17{
18 aGenes = new uint_fast32_t[iWords];
19 if( bRandom )
20 randomize();
21}
22
23Genetic::PhenotypeBinary::~PhenotypeBinary()
24{
25 delete[] aGenes;
26}
27
28Genetic::Phenotype &Genetic::PhenotypeBinary::randomize()
29{
30 for( int j = 0; j < iWords*sizeof(uint_fast32_t); j++ )
31 {
32 ((uint8_t *)aGenes)[j] = (uint8_t)Bu::Random::rand();
33 }
34
35 return *this;
36}
37
38void Genetic::PhenotypeBinary::mutate( int iLocation, float fMagnitude )
39{
40 if( fMagnitude > -0.5 && fMagnitude < 0.5 )
41 return;
42
43 aGenes[wordWithBit(iLocation)] =
44 (aGenes[wordWithBit(iLocation)]&(~(1<<((iLocation)%BPW)))) |
45 ((~aGenes[wordWithBit(iLocation)])&((1<<((iLocation)%BPW))));
46}
47
48Genetic::Phenotype *Genetic::PhenotypeBinary::makeEmptyOffspring(
49 int iNewSize )
50{
51 if( iNewSize < 0 )
52 iNewSize = iSize;
53
54 return new PhenotypeBinary( iSize );
55}
56
57Genetic::Phenotype &Genetic::PhenotypeBinary::copyFrom( const Phenotype &rSrc,
58 int iStart, int iCount, int iDest )
59{
60 const PhenotypeBinary &rbSrc =
61 dynamic_cast<const Genetic::PhenotypeBinary &>(rSrc);
62 if( iDest < 0 )
63 iDest = iStart;
64
65 // Fist draft, very sloppy: bit by bit copy, this is stupid, but easy
66 for( int j = 0; j < iCount; j++ )
67 {
68 int wd = wordWithBit(j+iDest);
69 int ws = wordWithBit(j+iStart);
70 if( (rbSrc.aGenes[ws]&(1<<((j+iStart)%BPW))) == 0)
71 {
72 aGenes[wd] &= ~(1<<((j+iDest)%BPW));
73 }
74 else
75 {
76 aGenes[wd] |= (1<<((j+iDest)%BPW));
77 }
78 }
79
80 /*
81 iStart%BPW
82 int iWords = wordsForBits(iCount);
83 for( int j = wordWithBit(iStart); j < iWords; j++ )
84 {
85 }
86 */
87
88 return *this;
89}
90
91Bu::String Genetic::PhenotypeBinary::toString()
92{
93 Bu::String sRet;
94 for( int j = 0; j < iSize; j++ )
95 {
96 sRet += (aGenes[j/BPW]&(1<<(j%BPW)))?'1':'0';
97 }
98
99 return sRet;
100}
101
diff --git a/src/phenotypebinary.h b/src/phenotypebinary.h
new file mode 100644
index 0000000..72435ed
--- /dev/null
+++ b/src/phenotypebinary.h
@@ -0,0 +1,29 @@
1#ifndef GENETIC_PHENOTYPE_BINARY_H
2#define GENETIC_PHENOTYPE_BINARY_H
3
4#include "genetic/phenotype.h"
5
6namespace Genetic
7{
8 class PhenotypeBinary : public Phenotype
9 {
10 public:
11 PhenotypeBinary( int iSize, bool bRandom=false );
12 virtual ~PhenotypeBinary();
13
14 virtual int getSize() { return iSize; }
15 virtual Phenotype &randomize();
16 virtual void mutate( int iLocation, float fMagnitude );
17 virtual Phenotype *makeEmptyOffspring( int iNewSize=-1 );
18 virtual Phenotype &copyFrom( const Phenotype &rSrc, int iStart,
19 int iCount, int iDest=-1 );
20 virtual Bu::String toString();
21
22 private:
23 int iSize;
24 int iWords;
25 uint_fast32_t *aGenes;
26 };
27};
28
29#endif
diff --git a/src/population.cpp b/src/population.cpp
new file mode 100644
index 0000000..85b859e
--- /dev/null
+++ b/src/population.cpp
@@ -0,0 +1,10 @@
1#include "genetic/population.h"
2
3Genetic::Population::Population()
4{
5}
6
7Genetic::Population::~Population()
8{
9}
10
diff --git a/src/population.h b/src/population.h
new file mode 100644
index 0000000..0fdad32
--- /dev/null
+++ b/src/population.h
@@ -0,0 +1,14 @@
1#ifndef GENETIC_POPULATION_H
2#define GENETIC_POPULATION_H
3
4namespace Genetic
5{
6 class Population
7 {
8 public:
9 Population();
10 virtual ~Population();
11 };
12};
13
14#endif
diff --git a/src/tests/binary.cpp b/src/tests/binary.cpp
new file mode 100644
index 0000000..717c171
--- /dev/null
+++ b/src/tests/binary.cpp
@@ -0,0 +1,37 @@
1#include "genetic/phenotypebinary.h"
2#include "genetic/operatorbasic.h"
3
4#include <bu/sio.h>
5#include <bu/random.h>
6#include <bu/randomcmwc.h>
7#include <time.h>
8
9using namespace Bu;
10
11int main( int argc, char *argv[] )
12{
13 Bu::Random::setGenerator<Bu::RandomCmwc>();
14 Bu::Random::seed( time( NULL ) );
15
16 Genetic::OperatorBasic op( new Genetic::PhenotypeBinary( 45 ), 0.1 );
17 Genetic::Phenotype *pPb1 = op.random();
18 Genetic::Phenotype *pPb2 = op.random();
19 Genetic::Phenotype *pPb3;
20
21 sio << pPb1->toString() << sio.nl;
22 sio << pPb2->toString() << sio.nl;
23
24 Genetic::PhenotypeList lParents;
25 lParents.append( pPb1 );
26 lParents.append( pPb2 );
27 pPb3 = op.mate( lParents );
28
29 sio << pPb3->toString() << sio.nl;
30
31 delete pPb1;
32 delete pPb2;
33 delete pPb3;
34
35 return 0;
36}
37