In [1]:
%logstart
%matplotlib inline

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tspsolver.tsp_generator import TSPGenerator
from tspsolver.ga.simulator import Simulator
from tspsolver.tuning import GeneticAlgorithmParameterEstimation

OUTPUT_TABLE_DIR = "../report/tables/"
OUTPUT_FIG_DIR = "../report/figures/"


Activating auto-logging. Current session state plus future input saved.
Filename       : ipython_log.py
Mode           : rotate
Output logging : False
Raw input log  : False
Timestamping   : False
State          : active

In [2]:
NUM_DATASETS = 5 # number of datasets to take the mean fitness over 
NUM_POINTS = 50  # number of points to use in each dataset
tuner = GeneticAlgorithmParameterEstimation(NUM_DATASETS, NUM_POINTS)

In [14]:
params = {
    "num_epochs": [1000],
    "num_elites": [0, 1, 2],
    "generator": ["SimplePopulationGenerator"],
    "generator_population_size": [40],
    "selector": ["TournamentSelection"],
    "selector_tournament_size": [10],
    "crossover": ["OrderCrossover"],
    "crossover_pcross": [0.9],
    "mutator": ["InversionMutation"],
    "mutator_pmutate": [0.2]
}

In [15]:
elite_results = tuner.perform_grid_search(params)

In [16]:
elite_results


Out[16]:
crossover crossover_pcross generator generator_population_size mutator mutator_pmutate num_elites num_epochs selector selector_tournament_size fitness
0 OrderCrossover 0.9 SimplePopulationGenerator 40 InversionMutation 0.2 0 1000 TournamentSelection 10 74.018956
1 OrderCrossover 0.9 SimplePopulationGenerator 40 InversionMutation 0.2 1 1000 TournamentSelection 10 73.651241
2 OrderCrossover 0.9 SimplePopulationGenerator 40 InversionMutation 0.2 2 1000 TournamentSelection 10 74.376653

In [17]:
elite_results[['num_elites', 'fitness']].to_latex(OUTPUT_TABLE_DIR + "elite_fitness.tex")

In [7]:
gen = TSPGenerator(NUM_POINTS)
data = gen.generate()

all_fitness = []
for i, row in elite_results.iterrows():
    params = row.to_dict()
    sim = Simulator(**params)
    sim.evolve(data)
    all_fitness.append(sim.get_min_fitness()[::10])
    
df = pd.DataFrame(np.array(all_fitness))

In [11]:
ax = df.T.plot()
ax.set_xlabel("Epoch")
ax.set_ylabel("Fitness")
plt.savefig(OUTPUT_FIG_DIR + 'elite_convergence.png', bbox_inches='tight')


KNN Population Generation


In [55]:
params = {
    "num_epochs": [1000],
    "num_elites": [1],
    "generator": ["SimplePopulationGenerator", "KNNPopulationGenerator"],
    "generator_random_proportion": [0.3, 0.5, 0.6],
    "generator_population_size": [40],
    "selector": ["TournamentSelection"],
    "selector_tournament_size": [10],
    "crossover": ["OrderCrossover"],
    "crossover_pcross": [0.9],
    "mutator": ["InversionMutation"],
    "mutator_pmutate": [0.2]
}

In [56]:
NUM_DATASETS = 5 # number of datasets to take the mean fitness over 
NUM_POINTS = 100  # number of points to use in each dataset
tuner = GeneticAlgorithmParameterEstimation(NUM_DATASETS, NUM_POINTS)
knn_results = tuner.perform_grid_search(params)

In [57]:
t = knn_results.iloc[[0,3,4,5]]
t['generator_random_proportion'][0] = np.NaN
t.index = np.arange(4)
t[['generator', 'generator_random_proportion', 'fitness']]


Out[57]:
generator generator_random_proportion fitness
0 SimplePopulationGenerator NaN 134.464263
1 KNNPopulationGenerator 0.3 128.815815
2 KNNPopulationGenerator 0.5 126.743674
3 KNNPopulationGenerator 0.6 120.437607

In [58]:
t[['generator', 'generator_random_proportion', 'fitness']].to_latex(OUTPUT_TABLE_DIR + "knn_fitness.tex")

In [59]:
gen = TSPGenerator(NUM_POINTS)
data = gen.generate()
p = knn_results.iloc[[0,3,4,5]]
all_fitness = []
for i, row in p.iterrows():
    params = row.to_dict()
    sim = Simulator(**params)
    sim.evolve(data)
    all_fitness.append(sim.get_min_fitness()[::10])
    
df = pd.DataFrame(np.array(all_fitness))

In [72]:
t['generator-name'] = t[['generator', 'generator_random_proportion']].apply(lambda x: '-'.join([x[0], str(x[1])]), axis=1)
t['generator-name'][0] = t['generator'][0]
t


Out[72]:
crossover crossover_pcross generator generator_population_size generator_random_proportion mutator mutator_pmutate num_elites num_epochs selector selector_tournament_size fitness generator-name
0 OrderCrossover 0.9 SimplePopulationGenerator 40 NaN InversionMutation 0.2 1 1000 TournamentSelection 10 134.464263 SimplePopulationGenerator
1 OrderCrossover 0.9 KNNPopulationGenerator 40 0.3 InversionMutation 0.2 1 1000 TournamentSelection 10 128.815815 KNNPopulationGenerator-0.3
2 OrderCrossover 0.9 KNNPopulationGenerator 40 0.5 InversionMutation 0.2 1 1000 TournamentSelection 10 126.743674 KNNPopulationGenerator-0.5
3 OrderCrossover 0.9 KNNPopulationGenerator 40 0.6 InversionMutation 0.2 1 1000 TournamentSelection 10 120.437607 KNNPopulationGenerator-0.6

In [73]:
df.index = t['generator-name']
ax = df.T.plot()
ax.set_xlabel("Epoch")
ax.set_ylabel("Fitness")
plt.savefig(OUTPUT_FIG_DIR + 'knn_convergence.png', bbox_inches='tight')