forked from jibsen/galib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathex21.C
222 lines (178 loc) · 7.25 KB
/
ex21.C
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/* ----------------------------------------------------------------------------
ex21.C
mbwall 1jan96
Copyright (c) 1995-1996 Massachusetts Institute of Technology
DESCRIPTION:
This example illustrates various uses of the AlleleSet in concert with the
ArrayAlleleGenome. In particular, we use the RealGenome to show how you can
use the enumerated and bounded types of allele sets.
You can define one allele set for an entire array, or you can define one
allele set for each element in the array. The constructor that you use to
create the array determines which behaviour you'll get.
---------------------------------------------------------------------------- */
#include <stdio.h>
#include <ga/ga.h>
#include <ga/std_stream.h>
#define cout STD_COUT
#define endl STD_ENDL
#define INSTANTIATE_REAL_GENOME
#include <ga/GARealGenome.h>
float Objective1(GAGenome &);
float Objective2(GAGenome &);
float Objective3(GAGenome &);
float Objective4(GAGenome &);
int
main(int argc, char** argv)
{
cout << "Example 21\n\n";
cout << "This example shows various uses of the allele set object\n";
cout << "in combination with the real number genome.\n\n"; cout.flush();
// See if we've been given a seed to use (for testing purposes). When you
// specify a random seed, the evolution will be exactly the same each time
// you use that seed number.
unsigned int seed = 0;
for(int ii=1; ii<argc; ii++) {
if(strcmp(argv[ii++],"seed") == 0) {
seed = atoi(argv[ii]);
}
}
// First make a bunch of genomes. We'll use each one in turn for a genetic
// algorithm later on. Each one illustrates a different method of using the
// allele set object. Each has its own objective function.
int length = 8;
// This genome uses an enumerated list of alleles. We explictly add each
// allele to the allele set. Any element of the genome may assume the value
// of any member of the allele set.
GARealAlleleSet alleles1;
alleles1.add(-10);
alleles1.add(0.1);
alleles1.add(1.0);
alleles1.add(10);
alleles1.add(100);
GARealGenome genome1(length, alleles1, Objective1);
// This genome uses a bounded set of continous numbers. The default arguments
// are INCLUSIVE for both the lower and upper bounds, so in this case the
// allele set is [0,1] and any element of the genome may assume a value [0,1].
GARealAlleleSet alleles2(0, 1);
GARealGenome genome2(length, alleles2, Objective2);
// Similar to the previous set, but this one has EXCLUSIVE bounds and we create
// the allele set explicitly (even though in this case
GARealAlleleSetArray alleles2a;
for(int i=0; i<length; i++)
alleles2a.add(0, 1, GAAllele::EXCLUSIVE, GAAllele::EXCLUSIVE);
GARealGenome genome2a(alleles2a, Objective2);
// Here we create a genome whose elements may assume any value in the interval
// [0.0, 10.0) discretized on the interval 0.5, i.e. the values 0.0, 0.5, 1.0,
// and so on up to but not including 10.0.
// Note that the default operators for the real genome are uniform initializer,
// gaussian mutator, and uniform crossover. Since gaussian is not the behavior
// we want for mutation, we assign the flip mutator instead.
GARealAlleleSet alleles3(0,10,0.5,GAAllele::INCLUSIVE,GAAllele::EXCLUSIVE);
GARealGenome genome3(length, alleles3, Objective3);
genome3.crossover(GARealUniformCrossover);
genome3.mutator(GARealSwapMutator);
// This genome is created using an array of allele sets. This means that each
// element of the genome will assume a value in its corresponding allele set.
// For example, since the first allele set is [0,10], the first element of the
// genome will be in [0,10]. Notice that you can add allele sets in many other
// ways than those shown.
GARealAlleleSetArray alleles4;
alleles4.add(0,10);
alleles4.add(50,100);
alleles4.add(-10,-5);
alleles4.add(-0.01,-0.0001);
alleles4.add(10000,11000);
GARealGenome genome4(alleles4, Objective4);
// Now that we have the genomes, create a parameter list that will be used for
// all of the genetic algorithms and all of the genomes.
GAParameterList params;
GASteadyStateGA::registerDefaultParameters(params);
params.set(gaNnGenerations, 500);
params.set(gaNpopulationSize, 110);
params.set(gaNscoreFrequency, 10);
params.set(gaNflushFrequency, 50);
params.set(gaNselectScores, (int)GAStatistics::AllScores);
params.parse(argc, argv, gaFalse);
// Now do a genetic algorithm for each one of the genomes that we created.
GASteadyStateGA ga1(genome1);
ga1.parameters(params);
ga1.set(gaNscoreFilename, "bog1.dat");
cout << "\nrunning ga number 1 (alternate allele(0) and allele(3))..."<<endl;
ga1.evolve(seed);
cout << "the ga generated:\n" << ga1.statistics().bestIndividual() << endl;
GASteadyStateGA ga2(genome2);
ga2.parameters(params);
ga2.set(gaNscoreFilename, "bog2.dat");
cout << "\nrunning ga number 2 (continuous descending order)..." << endl;
ga2.evolve();
cout << "the ga generated:\n" << ga2.statistics().bestIndividual() << endl;
GASteadyStateGA ga2a(genome2a);
ga2a.parameters(params);
ga2a.set(gaNscoreFilename, "bog2a.dat");
cout << "\nrunning ga number 2a (descending order, EXCLUSIVE)..." << endl;
ga2a.evolve();
cout << "the ga generated:\n" << ga2a.statistics().bestIndividual() << endl;
GASteadyStateGA ga3(genome3);
ga3.parameters(params);
ga3.set(gaNscoreFilename, "bog3.dat");
cout << "\nrunning ga number 3 (discretized ascending order)..." << endl;
ga3.evolve();
cout << "the ga generated:\n" << ga3.statistics().bestIndividual() << endl;
GASteadyStateGA ga4(genome4);
ga4.parameters(params);
ga4.set(gaNscoreFilename, "bog4.dat");
cout << "\nrunning ga number 4 (maximize each gene)..." << endl;
ga4.evolve();
cout << "the ga generated:\n" << ga4.statistics().bestIndividual() << endl;
return 0;
}
// This objective function tries to maximize the occurance of the first and
// fourth alleles. It tries to put the first allele in the even elements and
// the fourth allele in the odd elements.
float
Objective1(GAGenome& g)
{
GARealGenome& genome = (GARealGenome&)g;
float value=0.0;
for(int i=0; i<genome.length(); i++){
if(i%2 == 0 && genome.gene(i) == genome.alleleset().allele(0))
value += 1.0;
if(i%2 != 0 && genome.gene(i) == genome.alleleset().allele(3))
value += 1.0;
}
return value;
}
// This objective function tries to generate a straight - it gives higher score
// to a genome whose elements descend in value. If two genomes both have
// elements in strictly descending order, they get the same score regardless
// of their values.
float
Objective2(GAGenome& g)
{
GARealGenome& genome = (GARealGenome&)g;
float value=0.0;
for(int i=1; i<genome.length(); i++)
if(genome.gene(i) < genome.gene(i-1)) value += 1.0;
return value;
}
// This objective function generates a straight by giving higher score to a
// genome whose elements ascend in value.
float
Objective3(GAGenome& g)
{
GARealGenome& genome = (GARealGenome&)g;
float value=0.0;
for(int i=1; i<genome.length(); i++)
if(genome.gene(i) > genome.gene(i-1)) value += 1.0;
return value;
}
// This objective tries to maximize each element in the genome.
float
Objective4(GAGenome& g)
{
GARealGenome& genome = (GARealGenome&)g;
float value=0.0;
for(int i=0; i<genome.length(); i++)
value += genome.gene(i);
return value;
}