add elitism

This commit is contained in:
2026-02-06 09:22:52 +01:00
parent 0a1192ca40
commit 321e4353d8
3 changed files with 44 additions and 4 deletions

View File

@@ -9,9 +9,10 @@ POPULATION_SIZE :: 100
GENERATIONS :: 100
TOURNAMENT_SIZE :: 3
CROSSOVER_RATE :: 0.8
MUTATION_RATE :: 0.01
MUTATION_RATE :: 0.05
RANDOM_SEED :: u64(42)
OUTPUT_FILE :: "output/data.csv"
ELITISM_COUNT :: 2
Problem :: struct {
name: string,

View File

@@ -135,10 +135,25 @@ bit_flip_mutation :: proc(chrom: Chromosome) {
}
}
clone_chromosome :: proc(chrom: Chromosome) -> Chromosome {
size := bit_array.len(chrom)
clone := bit_array.create(size)
for i in 0 ..< size {
bit_array.set(clone, i, bit_array.get(chrom, i))
}
return clone
}
create_offspring :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -> Population {
offspring: Population
for i := 0; i < POPULATION_SIZE; i += 2 {
elite_idx := get_best_indices(fitnesses[:], ELITISM_COUNT, maximize)
defer delete(elite_idx)
for i in 0 ..< ELITISM_COUNT {
offspring[i] = clone_chromosome(pop[elite_idx[i]])
}
for i := ELITISM_COUNT; i < POPULATION_SIZE; i += 2 {
parent1 := tournament_selection(pop, fitnesses, maximize)
parent2 := tournament_selection(pop, fitnesses, maximize)
@@ -158,6 +173,30 @@ create_offspring :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) ->
return offspring
}
get_best_indices :: proc(fitnesses: []f64, count: int, maximize: bool) -> []int {
indices := make([]int, len(fitnesses))
for i in 0 ..< len(indices) {
indices[i] = i
}
// Partial sort for top N
for i in 0 ..< count {
best := i
for j in i + 1 ..< len(indices) {
is_better := maximize ? fitnesses[indices[j]] > fitnesses[indices[best]] : fitnesses[indices[j]] < fitnesses[indices[best]]
if is_better {
best = j
}
}
indices[i], indices[best] = indices[best], indices[i]
}
result := make([]int, count)
copy(result, indices[:count])
delete(indices)
return result
}
write_results :: proc(filename: string, stats: []Stats) -> bool {
handle, err := os.open(filename, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, 0o644)
if err != os.ERROR_NONE {return false}

View File

@@ -8,8 +8,8 @@ main :: proc() {
// Choose problem
problem_type := "feature_selection" // or "knapsack"
state := rand.create(RANDOM_SEED)
context.random_generator = runtime.default_random_generator(&state)
// state := rand.create(RANDOM_SEED)
// context.random_generator = runtime.default_random_generator(&state)
problem: Problem
switch problem_type {