HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Traveling Salesman Problem genetic algorithm

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
salesmanproblemtravelinggeneticalgorithm

Problem

This is my take on this problem. I don't pre determine the distances, it's not suitable for the application I'll use it for. I'll use it in shool to determine some a mean total distance and how to setup a the poles of a power grid.

```
from random import sample
from random import random
from random import uniform
from random import shuffle
from math import sqrt
from time import time
from itertools import permutations
import matplotlib.pyplot as plt
import cProfile
import pstats
import io

class NodesLeastDistanceGA:
""" Traveling salesman problem genetic algorithm """

def __init__(self, parent, side, verbose=False):
""" Constructor """
self._parent = parent
self._side = side

self._mutate_rate = 0.07
self._population_size = 60 if len(parent) > 10 else 10
self._new_generation_size = self._population_size*2
self._rounds = 200
self._genlen = len(parent)
self._verbose = verbose
self._cached_distances = {}
self._cached_fitness = {}

def algorithm(self):
"""
Initialize population of lists and sets fittest.

Yields a new population and mutate a small amount of the individuals to avoid getting stuck.

Thorough elitism the most fitest individual is carried through the rounds.
"""

population = self.generate_population()
fitest = min(population, key=self.fitness)

total_time = time()
for r in range(self._rounds):
new_pop = []
while len(new_pop) self.fitness(new_fittest):
fitest = new_fittest
if r % 50 == 0:
print(r, self.fitness(min(population, key=self.fitness)))

population = self.selection(new_pop)
if fitest not in population:
population += [fitest]

self.result(population, fitest, total_time)

def result(self, population, fitest, total_time):
if self._verbose:
f

Solution

This is a very superficial review, but you have your generic algorithm code mixed in with the problem you're applying it to. In a general sense, this should be avoided whenever possible. Having only loosely related code immediately beside each other is just asking for something bad to happen during a future change.

Whenever I start on a learn a new language, I usually create a GA implementation for practice, and in case I ever actually need it.

It's a fairly easy concept to abstract out:

-
The class contains information about the set of possible genes (if a closed set), the max population size, maybe percentage chances of gene crossovers and other chance events (provided you want this to be constant across generations).

-
I keep mine simple and only expose a handful of methods. The main method is just a function that automates the processing of an entire generation. It takes the population, runs each genetic sequence through a fitness function (that the caller provides), then chops and repopulates.

By separating the GA code from the use code, you can safely make changes to either without risking breaking some almost unrelated, but coupled code. You also then have the benefit of using your independent GA implementation in any other projects you may need it for without needing to copy and paste select bits from your TSP code.

Context

StackExchange Code Review Q#143643, answer score: 4

Revisions (0)

No revisions yet.