diff --git a/src/common.odin b/src/common.odin index b356e84..c63b56a 100644 --- a/src/common.odin +++ b/src/common.odin @@ -5,14 +5,17 @@ import "core:container/bit_array" Chromosome :: ^bit_array.Bit_Array Population :: [POPULATION_SIZE]Chromosome -POPULATION_SIZE :: 100 +POPULATION_SIZE :: 1000 GENERATIONS :: 100 -TOURNAMENT_SIZE :: 5 -CROSSOVER_RATE :: 0.8 -MUTATION_RATE :: 0.05 +POPULATION_SIZE :: 1000 +ELITISM_COUNT :: 10 +SKEW :: 0 +TOURNAMENT_SIZE :: 100 +CROSSOVER_RATE :: 0.7 +MUTATION_RATE :: 0.015 RANDOM_SEED :: u64(42) OUTPUT_FILE :: "output/data.csv" -ELITISM_COUNT :: 2 +ELITISM_COUNT :: 50 Problem :: struct { name: string, diff --git a/src/ga.odin b/src/ga.odin index 8e938ed..5f03ced 100644 --- a/src/ga.odin +++ b/src/ga.odin @@ -102,6 +102,46 @@ tournament_selection :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) return pop[best_idx] } +roulette_selection :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -> Chromosome { + adjusted_fitnesses := make([]f64, len(fitnesses), context.temp_allocator) + defer delete(adjusted_fitnesses, context.temp_allocator) + + min_fitness := fitnesses[0] + if !maximize { + for f in fitnesses { + min_fitness = min(min_fitness, f) + } + } + + total_fitness: f64 = 0 + for i in 0..= spin { + return pop[i] + } + } + + return pop[len(pop) - 1] +} + + two_point_crossover :: proc(parent1, parent2: Chromosome) -> (Chromosome, Chromosome) { size := bit_array.len(parent1) point1 := rand.int_max(size) @@ -172,8 +212,8 @@ create_offspring :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -> } for i := ELITISM_COUNT; i < POPULATION_SIZE; i += 2 { - parent1 := tournament_selection(pop, fitnesses, maximize) - parent2 := tournament_selection(pop, fitnesses, maximize) + parent1 := roulette_selection(pop, fitnesses, maximize) + parent2 := roulette_selection(pop, fitnesses, maximize) child1, child2 := uniform_crossover(parent1, parent2) diff --git a/src/main.odin b/src/main.odin index 5dc7010..9fcb772 100644 --- a/src/main.odin +++ b/src/main.odin @@ -6,7 +6,7 @@ import "base:runtime" main :: proc() { // Choose problem - problem_type := "feature_selection" // or "knapsack" + problem_type := "knapsack" // or "knapsack" // state := rand.create(RANDOM_SEED) // context.random_generator = runtime.default_random_generator(&state)