In [2]:
#@title Licensed under the Apache License, Version 2.0 & Creative Common licence 4.0
# EvoFlow and its tutorials are released under the Apache 2.0 licence
# its documentaton is licensed under the Creative Common licence 4.0

Visualization callback setup

As seen above visualizing the route on the map is useful to quickly assess how good the current best route is so its a good idea to do the same while our model evolve its population.

To do this we are going to use a callback that will redraw the best route at the end of each generation. Callbacks, similarly to keras.callbacks allows you to add your own custom codes at key points of the algorithms so it is easy to customize the evolution loop.


In [ ]:
class MapCallback(Callback):
    def __init__(self, chart_data, idx2city):
        # init graph
        self.chart_data = chart_data
        self.idx2city = idx2city
        self.fig = go.Figure(go.Scattergeo(
                lat = chart_data['lat'],
                lon = chart_data['lon'],
                text = chart_data['name'],
                marker_color= chart_data['population']))
        self.fig.update_layout(title = 'Intial map', showlegend=False,
                                  geo = go.layout.Geo(scope='europe', showframe = False, 
                                                      projection_type = 'mercator', 
                                                      lonaxis_range=lon_axis, 
                                                      lataxis_range=lat_axis))
        self.fig.show()
    def on_generation_end(self, generation, metrics, fitness_scores, populations):
        
        # get the best model
        # the model only have one population hence the [0]
        route = populations[0][0]  # population is sorted by fitness score
        best_distance = fitness_scores[0][0]  # best fitness score = shortest distance
        
        frames = []
        initial_city = self.idx2city[int(route[0])]
        for idx in range(len(route) - 1):
            start_city = self.idx2city[int(route[idx])]
            stop_city = self.idx2city[int(route[idx + 1])]
            distance = distances[start_city['idx']][stop_city['idx']]
            frames.append(go.Scattergeo(
                    lon = [start_city['lon'], stop_city['lon']],
                    lat = [start_city['lat'], stop_city['lat']],
                    mode = 'lines',
                    line = dict(width = 1,color = 'red')))

        # last leg
        frames.append(go.Scattergeo(
                    lon = [stop_city['lon'], initial_city['lon']],
                    lat = [stop_city['lat'], initial_city['lat']],
                    mode = 'lines',
                    line = dict(width = 1,color = 'red')))
        
        self.fig.update_layout(title = 'Generation %d Total distance %d kms'  % (generation, best_distance))