-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGabilInd.cpp
More file actions
191 lines (159 loc) · 6.14 KB
/
GabilInd.cpp
File metadata and controls
191 lines (159 loc) · 6.14 KB
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
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstdlib>
#include <vector>
#include <time.h> //Used for random operator power
using namespace std;
/*
// Class Individual
// this class represents each of the individuals that will be used on a GABIL
// genetic algorithm. The class will consist of the following variables:
// a) A set of rules. This will be a vector<int> of size n*k, where n is the number
// of rules and k is the size of each rule. Each int will be 0 or 1, accordingly.
// b) The size of the rule set.
// c) A fitness value, defined by the fitness function.
//
// Additionally, it will have the following functions:
// a) mutation operator, which will "flip" a "bit" of a rule chain.
// b) selection operator, which will be a 2 point crossover variant.
// c) fitness function, that compares the obtained values against expected values.
*/
const int MAX_RS = 3; //Upper bound to the number of initial rules
float randomF(); //returns a random value between 0 and 1
class Individual {
public:
vector<int> ruleSet;
int setSize;
float fitness; //How good is it
float fitWeight;
float unFitness;//How bad is it
float unFitWeight;
//****************** CONSTRUCTORS ********************//
Individual() {}
//creates an individual with a random ruleSet, given a rule size
Individual(int size) {
float a = randomF();
int rules = static_cast <int> (floor(randomF()*MAX_RS))+1; //Defines the ruleSet size
vector<int> rs(size*MAX_RS);
for (int i = 0; i < size*rules; i++) {
rs.at(i) = randomF() > 0.5 ? 1 : 0; //Initial randomization
}
ruleSet = rs;
setSize = size;
fitness = -1;
}
//Creates an individual with pre established values
Individual(vector<int> rs, int size) {
ruleSet = rs;
setSize = size;
fitness = -1;
}
//*************** OVERRIDE OPERATORS ******************//
bool operator < (const Individual& i) const {
return (fitness > i.fitness);
}
//******************* FUNCTIONS ***********************//
void mutate() {
for (int i = 0; i < ruleSet.size(); i++) {
if (randomF() < 0.01) {
ruleSet.at(i) = (ruleSet.at(i)+1)%2; //shifts the bit
break;
}
}
}
//Returns the evaluation of a set
int evaluate(vector<int> set, vector<int> rs) {
int i = 0; //iterate over the ruleSet
int k = 0; //iterate over the to-compare-set
int t = 0; //final evaluation
int ruleSS = ruleSet.size();
int j = 0; //iterate over the size of each rule attribute
while (i < ruleSS) {
int j1 = rs.at(j);
if (j1 == -1) { //Reached the end of the instructions
return (set.at(k) == ruleSet.at(i) ? 1 : 0); //Compare and return the value
}
t = 1;
while (j1 > 0) {
if (ruleSet.at(i) == 1 && set.at(k) == 1){
j++;
k += j1;
i += j1;
t = 0;
break; //Found a matching pattern, move on to the next segment
}
j1--;
i++;
k++;
}
if (t == 1) { //This rule doesnt have a matching pattern, move on to the next one
k = 0;
j = 0;
i += setSize - i%setSize;
}
}
return 0; //error bias because it couldnt find a matching pattern
}
void getFitness(vector<vector<int> > rules, vector<int> attrSize) {
float k = 0;
float i = 0;
for (vector<vector<int> >::iterator it = rules.begin(); it < rules.end(); it++) {
k += (float) evaluate(*it, attrSize);
i++;
}
fitness = k/i;
unFitness = 1-fitness;
return;
}
//Defines a lower bound for an individual's rule set
//This value goes between 0 and the ruleSet size - 1,
//so that we can ensure a 2 point partition.
//Possible Range: [0, size-1]
int lowerBound() {
return (int) floor(randomF()*ruleSet.size());
}
//Same deal, but with an upper bound
//This one needs the lower bound to ensure that it will create it after
//and not before it.
//Possible Range: [lowerbound+1, size]
int upperBound(int lb) {
return (int) floor(randomF()*(ruleSet.size()-lb))+lb+1; //it works, trust me
}
//******This is where it gets Tricky*********//
//Defines a lower bound for an individual's ruleset
//unlike the other case, this is restricted to values that would
//only fit the first lower bound, so it can ensure a crossover
//they must also ensure that the upper bound doesnt go outside
//the array.. so there's that as well
//Possible Range: [0+lowk, idonteven]. Discrete values with "size" jumps
int lowerBoundT(int lowk, int highk) {
int kk = lowk % setSize; //How offset is the lowerBound in relation to a rule's start
int range = highk - lowk; //The size of the (soon to be crossovered) segment
int rules = ruleSet.size()/setSize;
return (int) ( ((floor(randomF()*(rules-floor((range+kk-1)/setSize)))+1)*setSize)
+kk-setSize ); //C stands for Complex.
return 0;
}
//Same deal, but trickier.
//Possible Range: [0+highk, idonteven]
int upperBoundT(int lowk, int highk, int lb) {
int rules = ruleSet.size()/setSize;
int range = highk - lowk;
int hb = lb;
int poss = rules-floor(lb/setSize);
return (int) (floor(randomF()*(rules-floor(lb/setSize)-floor((range)/setSize)-1))
* setSize + lb+range); //Bruh
//return (int) (floor(randomF()*(rules-floor(lb/setSize) - floor(range)))
// * setSize + lb+range); //Bruh
}
};
float randomF() {
return static_cast <float> (rand()) / static_cast <float> (RAND_MAX+1);
}
/*int main() {
srand(time(NULL));
int s = 4;
int a = 3;
Individual i(s);
}*/