feat: add loading of optimal cost from solutions.txt
feat: add edge recombination crossover
feat: add into_iter for population
chore: add instances to run the algorithm on
feat(tsp): add data loading
chore: add constructor for TSPRandomInitializer
fix: iterate city positions by rows
refactor: use swap_rows in SwapPerturbaiton instead of swapping by indices
feat: add plotting of TSP
feat: add utilities to perturbation to iterate through wrappers easily Make PerturbationOperator implement Any, allowing it to be downcasted. Make WrapperPerturbation for perturbations that wrap other perturbations, such as the mutation perturbation and bounded perturbation. Make ListWrapperPerturbation for pertrubations that wrap multiple pertrubations, such as the combined perturbation. This should allow for easily looking through perturbations, finding all perturbations of a specific type and modifying them. One use case can be for changing the probability of a mutation perturbation during evolution.
chore: do not pass pairing as mut
tests: tweak one_max parameters
refactor: abstract pairing to n-ary
tests: adjust evolution one_max algorithm to always find optimum
feat(binary_string): add single bit perturbation, flip perturbation
refactor: pass rng as argument Instead of having the Rng stored inside the structs, pass it through the functions. This means it's no longer necessary to pass perturbations etc. as mutable.
tests: add simple test for evolution on one_max
refactor: do perturbation in place instead of cloning
fix: tournament selection in case last wins returned wrong index
fix: tournament replacement strategy could be using wrong indices