readd single-point and some mutation operators

This commit is contained in:
2026-02-08 22:45:40 +01:00
parent e9c4cb46e6
commit a7c70462b2
2 changed files with 65 additions and 3 deletions

View File

@@ -13,10 +13,10 @@ TOURNAMENT_SIZE :: 5
CROSSOVER_RATE :: 0.7
MUTATION_RATE :: 0.01
SURVIVOR_SELECTION_POLICY :: probabilistic_crowding
PARENT_SELECTION_POLICY :: roulette_selection
CROSSOVER_POLICY :: uniform_crossover
PARENT_SELECTION_POLICY :: random_selection
CROSSOVER_POLICY :: single_point_crossover
MUTATION_POLICY :: bit_flip_mutation
SURVIVOR_SELECTION_POLICY :: generational_replacement
RANDOM_SEED :: u64(42)
OUTPUT_FILE :: "output/data.csv"

View File

@@ -206,6 +206,29 @@ roulette_selection :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -
return pop[len(pop) - 1]
}
single_point_crossover :: proc(parent1, parent2: Chromosome) -> (Chromosome, Chromosome) {
if rand.float64() > CROSSOVER_RATE {
return clone_chromosome(parent1), clone_chromosome(parent2)
}
size := bit_array.len(parent1)
point := rand.int_max(size)
child1 := bit_array.create(size)
child2 := bit_array.create(size)
for i in 0 ..< point {
bit_array.set(child1, i, bit_array.get(parent1, i))
bit_array.set(child2, i, bit_array.get(parent2, i))
}
for i in point ..< size {
bit_array.set(child1, i, bit_array.get(parent2, i))
bit_array.set(child2, i, bit_array.get(parent1, i))
}
return child1, child2
}
two_point_crossover :: proc(parent1, parent2: Chromosome) -> (Chromosome, Chromosome) {
size := bit_array.len(parent1)
@@ -258,6 +281,45 @@ bit_flip_mutation :: proc(chrom: Chromosome) {
}
}
swap_mutation :: proc(chromosome: Chromosome) {
size := bit_array.len(chromosome)
if rand.float64() < MUTATION_RATE {
i := rand.int_max(size)
j := rand.int_max(size)
bit_i := bit_array.get(chromosome, i)
bit_j := bit_array.get(chromosome, j)
bit_array.set(chromosome, i, bit_j)
bit_array.set(chromosome, j, bit_i)
}
}
inversion_mutation :: proc(chromosome: Chromosome) {
size := bit_array.len(chromosome)
if rand.float64() < MUTATION_RATE {
point1 := rand.int_max(size)
point2 := rand.int_max(size)
if point1 > point2 {
point1, point2 = point2, point1
}
// Reverse segment
for i := 0; i < (point2 - point1 + 1) / 2; i += 1 {
left := point1 + i
right := point2 - i
bit_left := bit_array.get(chromosome, left)
bit_right := bit_array.get(chromosome, right)
bit_array.set(chromosome, left, bit_right)
bit_array.set(chromosome, right, bit_left)
}
}
}
clone_chromosome :: proc(chrom: Chromosome) -> Chromosome {
size := bit_array.len(chrom)
clone := bit_array.create(size)