add generic interface for switching selection/operator policies
This commit is contained in:
+6
-1
@@ -12,9 +12,14 @@ SKEW :: 0
|
||||
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
|
||||
MUTATION_POLICY :: bit_flip_mutation
|
||||
|
||||
RANDOM_SEED :: u64(42)
|
||||
OUTPUT_FILE :: "output/data.csv"
|
||||
SURVIVOR_SELECTION_POLICY :: probabilistic_crowding
|
||||
|
||||
Problem :: struct {
|
||||
name: string,
|
||||
|
||||
+36
-9
@@ -15,7 +15,17 @@ Survivor_Selection :: proc(
|
||||
maximize: bool,
|
||||
) -> Population
|
||||
|
||||
run_ga :: proc(problem: Problem, survivor_selection: Survivor_Selection) {
|
||||
Parent_Selection :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -> Chromosome
|
||||
Crossover :: proc(parent1, parent2: Chromosome) -> (Chromosome, Chromosome)
|
||||
Mutation :: proc(chromosome: Chromosome)
|
||||
|
||||
run_ga :: proc(
|
||||
problem: Problem,
|
||||
survivor_selection: Survivor_Selection,
|
||||
parent_selection: Parent_Selection,
|
||||
crossover: Crossover,
|
||||
mutation: Mutation,
|
||||
) {
|
||||
fmt.printfln("=== Running GA: %s ===", problem.name)
|
||||
|
||||
population := generate_population(problem.chromosome_size)
|
||||
@@ -38,7 +48,14 @@ run_ga :: proc(problem: Problem, survivor_selection: Survivor_Selection) {
|
||||
stats.entropy,
|
||||
)
|
||||
|
||||
offspring := create_offspring_simple(&population)
|
||||
offspring := create_offspring(
|
||||
&population,
|
||||
pop_fitnesses[:],
|
||||
problem.maximize,
|
||||
parent_selection,
|
||||
crossover,
|
||||
mutation,
|
||||
)
|
||||
offspring_fitnesses := evaluate_population(&offspring, problem.fitness_proc)
|
||||
|
||||
next_gen := survivor_selection(
|
||||
@@ -112,7 +129,6 @@ compute_population_entropy :: proc(pop: ^Population, chromosome_size: int) -> f6
|
||||
return entropy
|
||||
}
|
||||
|
||||
// Modified compute_stats to include entropy
|
||||
compute_stats :: proc(pop: ^Population, fitnesses: []f64, chromosome_size: int, maximize: bool) -> Stats {
|
||||
best := maximize ? -math.F64_MAX : math.F64_MAX
|
||||
worst := maximize ? math.F64_MAX : -math.F64_MAX
|
||||
@@ -251,16 +267,23 @@ clone_chromosome :: proc(chrom: Chromosome) -> Chromosome {
|
||||
return clone
|
||||
}
|
||||
|
||||
create_offspring_simple :: proc(pop: ^Population) -> Population {
|
||||
create_offspring :: proc(
|
||||
pop: ^Population,
|
||||
fitnesses: []f64,
|
||||
maximize: bool,
|
||||
parent_selection: Parent_Selection,
|
||||
crossover: Crossover,
|
||||
mutation: Mutation,
|
||||
) -> Population {
|
||||
offspring: Population
|
||||
|
||||
for i := 0; i < POPULATION_SIZE; i += 2 {
|
||||
p1_idx := rand.int_max(POPULATION_SIZE)
|
||||
p2_idx := rand.int_max(POPULATION_SIZE)
|
||||
parent1 := parent_selection(pop, fitnesses, maximize)
|
||||
parent2 := parent_selection(pop, fitnesses, maximize)
|
||||
|
||||
child1, child2 := uniform_crossover(pop[p1_idx], pop[p2_idx])
|
||||
bit_flip_mutation(child1)
|
||||
bit_flip_mutation(child2)
|
||||
child1, child2 := crossover(parent1, parent2)
|
||||
mutation(child1)
|
||||
mutation(child2)
|
||||
|
||||
offspring[i] = child1
|
||||
if i + 1 < POPULATION_SIZE {
|
||||
@@ -273,6 +296,10 @@ create_offspring_simple :: proc(pop: ^Population) -> Population {
|
||||
return offspring
|
||||
}
|
||||
|
||||
random_selection :: proc(pop: ^Population, fitnesses: []f64, maximize: bool) -> Chromosome {
|
||||
return pop[rand.int_max(POPULATION_SIZE)]
|
||||
}
|
||||
|
||||
deterministic_crowding :: proc(
|
||||
pop: ^Population,
|
||||
offspring: ^Population,
|
||||
|
||||
+11
-3
@@ -7,8 +7,10 @@ import "base:runtime"
|
||||
main :: proc() {
|
||||
problem_type := "feature_selection"
|
||||
|
||||
// state := rand.create(RANDOM_SEED)
|
||||
// context.random_generator = runtime.default_random_generator(&state)
|
||||
when RANDOM_SEED != u64(0){
|
||||
state := rand.create(RANDOM_SEED)
|
||||
context.random_generator = runtime.default_random_generator(&state)
|
||||
}
|
||||
|
||||
problem: Problem
|
||||
switch problem_type {
|
||||
@@ -33,5 +35,11 @@ main :: proc() {
|
||||
fmt.printfln("RMSE: %.4f\n", baseline)
|
||||
}
|
||||
|
||||
run_ga(problem, SURVIVOR_SELECTION_POLICY)
|
||||
run_ga(
|
||||
problem,
|
||||
SURVIVOR_SELECTION_POLICY,
|
||||
PARENT_SELECTION_POLICY,
|
||||
CROSSOVER_POLICY,
|
||||
MUTATION_POLICY
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user