it works!

This commit is contained in:
2026-01-31 15:30:47 +01:00
parent 320c75b2d5
commit dcdf9ebd2a

View File

@@ -43,7 +43,7 @@ distance :: proc(x, y: int) -> int {
}
penalize :: proc(d: int) -> int {
return math.min(-3 * d, 0)
return math.min(d, 0)
}
// side-effect: reads global `items`
@@ -71,6 +71,7 @@ generate_population :: proc() -> (res: Population) {
destroy_population :: proc(pop: ^Population) {
for &chrom in pop {
if chrom.free_pointer {continue}
bit_array.destroy(&chrom)
}
}
@@ -233,28 +234,42 @@ elitism_survivor_selection :: proc(
offspring: ^Population,
parent_fitnesses: []int,
offspring_fitnesses: []int,
) -> (
res: Population,
) {
) -> Population {
Index_Fitness :: struct {
idx: int,
fitness: int,
is_parent: bool,
}
combined_size := POPULATION_SIZE * 2
combined_fitnesses := make([]int, combined_size)
defer delete(combined_fitnesses)
combined := make([]Index_Fitness, combined_size)
defer delete(combined)
copy(combined_fitnesses[:POPULATION_SIZE], parent_fitnesses)
copy(combined_fitnesses[POPULATION_SIZE:], offspring_fitnesses)
for i in 0 ..< POPULATION_SIZE {
combined[i] = {i, parent_fitnesses[i], true}
combined[POPULATION_SIZE + i] = {i, offspring_fitnesses[i], false}
}
slice.sort(combined_fitnesses)
slice.sort_by(combined[:], proc(a, b: Index_Fitness) -> bool {
return a.fitness > b.fitness
})
for &s, i in res {
if i < POPULATION_SIZE {
s = parents[i]
} else {
s = offspring[i - POPULATION_SIZE]
survivors: Population
for i in 0 ..< POPULATION_SIZE {
entry := combined[i]
source := entry.is_parent ? &parents[entry.idx] : &offspring[entry.idx]
// Create NEW bit array and copy bits
survivors[i] = bit_array.create(NUMBER_OF_ITEMS)^
for j in 0 ..< NUMBER_OF_ITEMS {
bit_array.set(&survivors[i], j, bit_array.get(source, j))
}
}
return
return survivors
}
run_ga :: proc() {
population := generate_population()
defer destroy_population(&population)
@@ -279,7 +294,7 @@ run_ga :: proc() {
tot_weight += items[idx].weight
}
fmt.printfln(
"gen %d: best fitness=%d, profit=%d (capacity=%d)",
"gen %d: best fitness=%d, profit=%d, weight=%d (capacity=%d)",
gen,
f,
tot_profit,
@@ -336,11 +351,12 @@ run_ga :: proc() {
}
main :: proc() {
items, ok := read_data(DATA_FILE)
data, ok := read_data(DATA_FILE)
if !ok {
fmt.eprintln("failed to read data from", DATA_FILE)
return
}
items = data
fmt.println("running genetic algorithm for binary knapsack problem.")
fmt.printfln(