add elitism
This commit is contained in:
@@ -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,
|
||||
|
||||
41
src/ga.odin
41
src/ga.odin
@@ -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}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user