-
Notifications
You must be signed in to change notification settings - Fork 1
/
Individual.java
209 lines (187 loc) · 5.88 KB
/
Individual.java
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
package chapter5;
public class Individual {
/**
* In this case, the chromosome is an array of integers rather than a string.
*/
private int[] chromosome;
private double fitness = -1;
/**
* Initializes random individual based on a timetable
*
* The Timetable class is a bit overloaded. It knows both fixed information
* (the courses that MUST be scheduled, the professors that MUST be given
* jobs, the classrooms that DO exist) -- but it also understands how to
* parse and unpack chromosomes which contain variable information (which
* professor teaches which class and when?)
*
* In this case, we use the Timetable for the fixed information only, and
* generate a random chromosome, making guesses at the variable information.
*
* Given the fixed information in a Timetable, we create a chromosome that
* randomly assigns timeslots, rooms, and professors to the chromosome for
* each student group and module.
*
* @param timetable
* The timetable information
*/
public Individual(Timetable timetable) {
int numClasses = timetable.getNumClasses();
// 1 gene for room, 1 for time, 1 for professor
int chromosomeLength = numClasses * 3;
// Create random individual
int newChromosome[] = new int[chromosomeLength];
int chromosomeIndex = 0;
// Loop through groups
for (Group group : timetable.getGroupsAsArray()) {
// Loop through modules
for (int moduleId : group.getModuleIds()) {
// Add random time
int timeslotId = timetable.getRandomTimeslot().getTimeslotId();
newChromosome[chromosomeIndex] = timeslotId;
chromosomeIndex++;
// Add random room
int roomId = timetable.getRandomRoom().getRoomId();
newChromosome[chromosomeIndex] = roomId;
chromosomeIndex++;
// Add random professor
Module module = timetable.getModule(moduleId);
newChromosome[chromosomeIndex] = module.getRandomProfessorId();
chromosomeIndex++;
}
}
this.chromosome = newChromosome;
}
/**
* Initializes random individual
*
* The book instructs you to copy this constructor over from Chapter 4. This
* case is a little tricky -- used in Chapter 4, this constructor will
* create a valid chromosome for a list of cities for the TSP, by using each
* city once and only once.
*
* If used in Chapter 5, however, this will create an utterly INVALID
* chromosome for the class scheduler. So you should not use this
* constructor if you hope to create a valid random individual. For that
* purpose, use the Individual(Timetable) constructor, which will create a
* valid Individual from the fixed information in the Timetable object.
*
* However, Chapter 5 still needs an Individual(int) constructor that
* creates an Individual with a chromosome of a given size. It's used in the
* crossoverPopulation method in order to initialize the offspring. The fact
* that this creates an invalid Individual doesn't matter in this case,
* because the crossover algorithm immediately rewrites the whole
* chromosome.
*
*
* @param chromosomeLength
* The length of the individuals chromosome
*/
public Individual(int chromosomeLength) {
// Create random individual
int[] individual;
individual = new int[chromosomeLength];
/**
* This comment and the for loop doesn't make sense for this chapter.
* But I'm leaving it in here because you were instructed to copy this
* class from Chapter 4 -- and NOT having this comment here might be
* more confusing than keeping it in.
*
* Comment from Chapter 4:
*
* "In this case, we can no longer simply pick 0s and 1s -- we need to
* use every city index available. We also don't need to randomize or
* shuffle this chromosome, as crossover and mutation will ultimately
* take care of that for us."
*/
for (int gene = 0; gene < chromosomeLength; gene++) {
individual[gene] = gene;
}
this.chromosome = individual;
}
/**
* Initializes individual with specific chromosome
*
* @param chromosome
* The chromosome to give individual
*/
public Individual(int[] chromosome) {
// Create individual chromosome
this.chromosome = chromosome;
}
/**
* Gets individual's chromosome
*
* @return The individual's chromosome
*/
public int[] getChromosome() {
return this.chromosome;
}
/**
* Gets individual's chromosome length
*
* @return The individual's chromosome length
*/
public int getChromosomeLength() {
return this.chromosome.length;
}
/**
* Set gene at offset
*
* @param gene
* @param offset
*/
public void setGene(int offset, int gene) {
this.chromosome[offset] = gene;
}
/**
* Get gene at offset
*
* @param offset
* @return gene
*/
public int getGene(int offset) {
return this.chromosome[offset];
}
/**
* Store individual's fitness
*
* @param fitness
* The individuals fitness
*/
public void setFitness(double fitness) {
this.fitness = fitness;
}
/**
* Gets individual's fitness
*
* @return The individual's fitness
*/
public double getFitness() {
return this.fitness;
}
public String toString() {
String output = "";
for (int gene = 0; gene < this.chromosome.length; gene++) {
output += this.chromosome[gene] + ",";
}
return output;
}
/**
* Search for a specific integer gene in this individual.
*
* For instance, in a Traveling Salesman Problem where cities are encoded as
* integers with the range, say, 0-99, this method will check to see if the
* city "42" exists.
*
* @param gene
* @return
*/
public boolean containsGene(int gene) {
for (int i = 0; i < this.chromosome.length; i++) {
if (this.chromosome[i] == gene) {
return true;
}
}
return false;
}
}