This is tool models and tackles the Knapsack problem, an NP complexity problem. It's well documented so you can easily read the code and understand how it works under the hood.
I got inspired by this great video by Kia Codes. This repository started as a rewrite of the code used in that video series (found here), moving it from Python to Typescript. After the initial port was done I decided to add my touch to adapt it to my own coding style.
# Simplest configuration, with all default options.
# Uses:
# - Single gene mutation with 50% chance of mutating the gene
# - Single point crossover function
npm run example-1
# Run the tests in watch mode
npm run test
You have a bag with a maximum weight of things it can carry. You also have a list of items with a given value and weight, your task is to come up with a list of items whose weight combined does not exceed the maximum weight and has the maximum value.
tl;dr of how this genetic algorithm works
- Create a
population
, an array ofgenomes
, which itself it's just a bitmap, an array of 1 or 0, used to identify if the given item it's included or not
const population = [
[ 0, 0, 1 ], // Genome 1 = Item index 2 included
[ 1, 0, 1 ] // Genome 2 = Items indexes 0 & 2 included
[ 1, 1, 0 ] // Genome 3 = Items indexes 0 & 1 included
];
-
Begin iterating until you hit the
generation_limit
or, if provided, until you hit themax_fitness
. You need one of these criteria otherwise the simulation would run forever -
Sort the population by
fitness
, it's a measurement of how well thegenome
performs at the given task, in this case, the more total value you can carry without exceeding the weight limit the morefitness
you will have. -
Take the fittest N
genomes
and put them into the next generation. -
Take two
genomes
in a weighted random choice* -
Apply a crossover (See One-point crossover for the simples example) function to those
genomes
-
Apply a mutation (see the
gene_mutation
function as an example) to both thegenomes
and push them to the next generation -
Repeat this process (jumping to step 5) until you have the desired number of
genomes
in thenext_population
-
Once the stop criteria, defined in step 2, is reached, sort the population one last time by fitness and return the fittest
genome
, that's your solution
* A weighed choice means that you randomly choose elements in a list assigning them different probabilities of being selected, for example:
Element 1 = weight 70 = 70%
Element 2 = weight 20 = 20%
Element 3 = weigth 10 = 10%