diff --git a/src/common.odin b/src/common.odin index bf1450b..71a2c37 100644 --- a/src/common.odin +++ b/src/common.odin @@ -14,6 +14,7 @@ CROSSOVER_RATE :: 0.7 MUTATION_RATE :: 0.015 RANDOM_SEED :: u64(42) OUTPUT_FILE :: "output/data.csv" +SURVIVOR_SELECTION_POLICY :: probabilistic_crowding Problem :: struct { name: string, diff --git a/src/ga.odin b/src/ga.odin index dd3078c..3aa9f5a 100644 --- a/src/ga.odin +++ b/src/ga.odin @@ -407,3 +407,53 @@ write_results :: proc(filename: string, stats: []Stats) -> bool { csv.writer_flush(&w) return true } + +// Standard generational replacement (no crowding) +generational_replacement :: proc( + pop: ^Population, + offspring: ^Population, + pop_fitnesses: []f64, + offspring_fitnesses: []f64, + maximize: bool, +) -> Population { + next_gen: Population + + // Apply elitism + elite_idx := get_best_indices(pop_fitnesses[:], ELITISM_COUNT, maximize) + defer delete(elite_idx) + + for i in 0 ..< ELITISM_COUNT { + next_gen[i] = clone_chromosome(pop[elite_idx[i]]) + } + + // Rest are offspring (standard replacement) + for i := ELITISM_COUNT; i < POPULATION_SIZE; i += 1 { + next_gen[i] = clone_chromosome(offspring[i]) + } + + return next_gen +} + +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 +} diff --git a/src/main.odin b/src/main.odin index f77a42f..fcd859c 100644 --- a/src/main.odin +++ b/src/main.odin @@ -33,5 +33,5 @@ main :: proc() { fmt.printfln("RMSE: %.4f\n", baseline) } - run_ga(problem, deterministic_crowding) + run_ga(problem, SURVIVOR_SELECTION_POLICY) }