it works!
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user