├── demo.gif ├── README.md ├── python ├── Pipfile ├── Makefile ├── city.py ├── route.py ├── Pipfile.lock ├── population_utils.py ├── __main__.py └── cities.csv └── .gitignore /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/genetic-tsp/main/demo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thatcsharpguy/genetic-tsp/main/README.md -------------------------------------------------------------------------------- /python/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | black = "==19.3b0" 8 | isort = "*" 9 | 10 | [packages] 11 | 12 | [requires] 13 | python_version = "3.7" 14 | -------------------------------------------------------------------------------- /python/Makefile: -------------------------------------------------------------------------------- 1 | PIPENV := pipenv run 2 | 3 | BLACK_TARGETS := $(shell find . -name "*.py" -not -path "*/.venv/*" -not -path "*/.tox/*") 4 | 5 | 6 | format: 7 | $(PIPENV) isort . --apply 8 | $(PIPENV) black $(BLACK_TARGETS) 9 | .PHONY: format 10 | 11 | lint: 12 | $(PIPENV) black --check $(BLACK_TARGETS) 13 | .PHONY: lint -------------------------------------------------------------------------------- /python/city.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import math 4 | from dataclasses import dataclass 5 | 6 | 7 | @dataclass(eq=True, frozen=True) 8 | class City: # This is a gene 9 | """ 10 | La clase `City` representa uno de los parámetros que forman parte de la solución a nuestro problema. 11 | Este representa la parte del gen en el *framework* de los algoritmos genéticos. 12 | """ 13 | 14 | name: str 15 | x: int 16 | y: int 17 | 18 | def distance(self, city: City) -> float: 19 | xx = city.x - self.x 20 | yy = city.y - self.y 21 | return math.sqrt(xx ** 2 + yy ** 2) 22 | -------------------------------------------------------------------------------- /python/route.py: -------------------------------------------------------------------------------- 1 | from collections import UserList 2 | from typing import Sequence 3 | 4 | from city import City 5 | 6 | 7 | class Route(UserList): 8 | """ 9 | La clase `Route` representa una posible solución al problema presentado. 10 | Este representa la parte del cromosoma en el *framework* de los algoritmos genéticos. 11 | """ 12 | 13 | def __init__(self, cities: Sequence[City]): 14 | self.data = cities 15 | self.distance = sum( 16 | (a.distance(b) for a, b in zip(self.data[:-1], self.data[1:])) 17 | ) 18 | 19 | def __str__(self): 20 | def extract_city_info(city: City): 21 | return str(city) 22 | 23 | representation = "" 24 | # if len(self) > 6: 25 | # left = [extract_city_info(city) for city in self.data[:3]] 26 | # right = [extract_city_info(city) for city in self.data[-3:]] 27 | # cities = ", ".join(left) + ", ..., " + ", ".join(right) 28 | # else: 29 | cities = ", ".join([extract_city_info(city) for city in self.data]) 30 | 31 | return f"{self.distance:0.3f} [{cities}]" 32 | 33 | def __repr__(self): 34 | return str(self) 35 | -------------------------------------------------------------------------------- /python/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "80433ea7a59a0f3ac3c3d0b25758ed2b2dbab6e95ab4b278d7ac2fa4f30b9daf" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.7" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": {}, 19 | "develop": { 20 | "appdirs": { 21 | "hashes": [ 22 | "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", 23 | "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" 24 | ], 25 | "version": "==1.4.4" 26 | }, 27 | "attrs": { 28 | "hashes": [ 29 | "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", 30 | "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" 31 | ], 32 | "version": "==20.3.0" 33 | }, 34 | "black": { 35 | "hashes": [ 36 | "sha256:09a9dcb7c46ed496a9850b76e4e825d6049ecd38b611f1224857a79bd985a8cf", 37 | "sha256:68950ffd4d9169716bcb8719a56c07a2f4485354fec061cdd5910aa07369731c" 38 | ], 39 | "index": "pypi", 40 | "version": "==19.3b0" 41 | }, 42 | "click": { 43 | "hashes": [ 44 | "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", 45 | "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" 46 | ], 47 | "version": "==7.1.2" 48 | }, 49 | "isort": { 50 | "hashes": [ 51 | "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7", 52 | "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58" 53 | ], 54 | "index": "pypi", 55 | "version": "==5.6.4" 56 | }, 57 | "toml": { 58 | "hashes": [ 59 | "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", 60 | "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" 61 | ], 62 | "version": "==0.10.2" 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /python/population_utils.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import random 3 | from copy import deepcopy 4 | from typing import List, Sequence, Set, Tuple 5 | 6 | from city import City 7 | from route import Route 8 | 9 | CROSSOVER_POINT = 0.6 10 | MUTATION_PROBABILITY = 0.9 11 | 12 | 13 | def generate_cities( 14 | city_count: int, minx: int, miny: int, maxx: int, maxy: int 15 | ) -> Set[City]: 16 | cities = set() 17 | with open("cities.csv", encoding="utf8") as readable: 18 | reader = csv.reader(readable) 19 | for raw_city in reader: 20 | x = random.randint(minx, maxx) 21 | y = random.randint(miny, maxy) 22 | cities.add(City(name=raw_city[0], x=x, y=y)) 23 | 24 | return set(random.sample(cities, city_count)) 25 | 26 | 27 | def generate_population(cities: Set[City], population_size: int) -> List[Route]: 28 | population = [] 29 | 30 | for _ in range(population_size): 31 | population.append(Route(random.sample(cities, len(cities)))) 32 | 33 | return population 34 | 35 | 36 | def select_parents(routes: List[Route], n_parents: int) -> List[Route]: 37 | ordered_by_distance = sorted(routes, key=lambda route: route.distance) 38 | return ordered_by_distance[:n_parents] 39 | 40 | 41 | def partially_mapped_crossover(parent_s: Sequence, parent_t: Sequence): 42 | 43 | child = deepcopy(parent_s) 44 | 45 | crossover_qty = int(CROSSOVER_POINT * len(child)) 46 | crossover_point = random.randint(0, len(child) - crossover_qty - 1) 47 | for index_in_t, city_in_t in enumerate( 48 | parent_t[crossover_point : crossover_point + crossover_point], crossover_point 49 | ): 50 | position_in_s = child.index(city_in_t) 51 | child[position_in_s] = child[index_in_t] 52 | child[index_in_t] = city_in_t 53 | return child 54 | 55 | 56 | def crossover(routes: List[Route], population_size: int) -> List[Route]: 57 | missing_children = population_size - len(routes) 58 | new_children = [] 59 | 60 | for _ in range(missing_children): 61 | parent1, parent2 = random.sample(routes, 2) 62 | 63 | new_route = Route(partially_mapped_crossover(parent1, parent2).data) 64 | new_children.append(new_route) 65 | return new_children 66 | 67 | 68 | def _swap(route: Sequence, to: int, frm: int): 69 | aux = route[to] 70 | route[to] = route[frm] 71 | route[frm] = aux 72 | 73 | 74 | def mutate(routes: List[Route]) -> List[Route]: 75 | mutations = [] 76 | for route in routes: 77 | new_route = deepcopy(route.data) 78 | if MUTATION_PROBABILITY > random.random(): 79 | swap_from = random.randint(0, len(route) - 1) 80 | swap_to = random.randint(0, len(route) - 1) 81 | while swap_to == swap_from: 82 | swap_to = random.randint(0, len(route) - 1) 83 | _swap(new_route, swap_to, swap_from) 84 | mutations.append(Route(new_route)) 85 | return mutations 86 | -------------------------------------------------------------------------------- /python/__main__.py: -------------------------------------------------------------------------------- 1 | from tkinter import BOTH, CENTER, NW, SUNKEN, Canvas, Frame, Label, StringVar, Tk, W, messagebox 2 | from timeit import default_timer as timer 3 | from datetime import timedelta 4 | import threading as threading 5 | import multiprocessing as mp 6 | from route import Route 7 | from city import City 8 | from population_utils import ( 9 | _swap, 10 | crossover, 11 | generate_cities, 12 | generate_population, 13 | mutate, 14 | partially_mapped_crossover, 15 | select_parents, 16 | ) 17 | 18 | window_width = 1000 19 | window_height = 800 20 | n_cities = 20 21 | population_size = 100 22 | parents_size = 50 23 | max_generations = 500 24 | 25 | window_padding = 10 26 | current_generation = 0 27 | cities = generate_cities( 28 | n_cities, 29 | minx=window_padding, 30 | maxx=window_width - window_padding, 31 | miny=window_padding, 32 | maxy=window_height - window_padding, 33 | ) 34 | population = generate_population(cities, population_size) 35 | 36 | class CityMapper(Frame): 37 | def __init__(self): 38 | super().__init__() 39 | 40 | self.master.title("Travelling Pokemon Trainer Problem") 41 | self.pack(fill=BOTH, expand=1) 42 | self.canvas = Canvas(self) 43 | self.text = StringVar() 44 | self.statusbar = Label( 45 | self, textvariable=self.text, bd=1, relief=SUNKEN, anchor=W 46 | ) 47 | 48 | def draw_city(self, x, y, name, **kwargs): 49 | ''' 50 | Pokemon colors 51 | Yellow: #ffde00, Cerulean Blue: #3b4cca, Dark blue: #003a70 52 | ''' 53 | 54 | r = 5 55 | self.canvas.create_oval( 56 | x - r, y - r, x + r, y + r, fill="#003a70", outline="#3b4cca", width=3 57 | ) 58 | self.canvas.create_text( 59 | x, y - 10, anchor=CENTER, font=("Open Sans", 9), text=name 60 | ) 61 | 62 | def draw_best_ui(self, cities, route, generation): 63 | 64 | self.canvas.delete("all") 65 | 66 | self.canvas.create_text( 67 | 5, 68 | 0, 69 | anchor=NW, 70 | font=("Open Sans", 18), 71 | text=f"Generation {generation:03} \nDistance: {route.distance:.3f}", 72 | ) 73 | for a, b in zip(route[1:], route[:-1]): 74 | self.canvas.create_line(a.x, a.y, b.x, b.y, fill="#ffde00", width=3) 75 | for city in cities: 76 | self.draw_city(city.x, city.y, city.name) 77 | self.canvas.pack(fill=BOTH, expand=1) 78 | 79 | 80 | def genetic_algorithm(example, root): 81 | global population 82 | global current_generation 83 | 84 | start_time = timer() 85 | 86 | best_routes = sorted(population, key=lambda route: route.distance) 87 | 88 | example.draw_best_ui(cities, best_routes[0], current_generation) 89 | parents = select_parents(population, parents_size) 90 | new_children = crossover(parents, population_size) 91 | 92 | new_children_mutated = mutate(new_children) 93 | 94 | population = parents + new_children_mutated 95 | 96 | if current_generation == max_generations: 97 | end_time = timer() 98 | final_time = end_time - start_time 99 | message = "Current generation " + str(current_generation) + "\n Time {}".format(timedelta(seconds=final_time)) 100 | messagebox.showinfo("Done!", message) 101 | else: 102 | root.after(100, genetic_algorithm, example, root) 103 | current_generation = current_generation + 1 104 | 105 | 106 | def main(): 107 | 108 | root = Tk() 109 | app = CityMapper() 110 | root.geometry(f"{window_width}x{window_height}") 111 | root.after(100, genetic_algorithm, app, root) 112 | root.mainloop() 113 | 114 | 115 | if __name__ == "__main__": 116 | main() 117 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/python,pycharm+all,vscode 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm+all,vscode 4 | 5 | ### PyCharm+all ### 6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 8 | 9 | # User-specific stuff 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/**/usage.statistics.xml 13 | .idea/**/dictionaries 14 | .idea/**/shelf 15 | 16 | # Generated files 17 | .idea/**/contentModel.xml 18 | 19 | # Sensitive or high-churn files 20 | .idea/**/dataSources/ 21 | .idea/**/dataSources.ids 22 | .idea/**/dataSources.local.xml 23 | .idea/**/sqlDataSources.xml 24 | .idea/**/dynamic.xml 25 | .idea/**/uiDesigner.xml 26 | .idea/**/dbnavigator.xml 27 | 28 | # Gradle 29 | .idea/**/gradle.xml 30 | .idea/**/libraries 31 | 32 | # Gradle and Maven with auto-import 33 | # When using Gradle or Maven with auto-import, you should exclude module files, 34 | # since they will be recreated, and may cause churn. Uncomment if using 35 | # auto-import. 36 | # .idea/artifacts 37 | # .idea/compiler.xml 38 | # .idea/jarRepositories.xml 39 | # .idea/modules.xml 40 | # .idea/*.iml 41 | # .idea/modules 42 | # *.iml 43 | # *.ipr 44 | 45 | # CMake 46 | cmake-build-*/ 47 | 48 | # Mongo Explorer plugin 49 | .idea/**/mongoSettings.xml 50 | 51 | # File-based project format 52 | *.iws 53 | 54 | # IntelliJ 55 | out/ 56 | 57 | # mpeltonen/sbt-idea plugin 58 | .idea_modules/ 59 | 60 | # JIRA plugin 61 | atlassian-ide-plugin.xml 62 | 63 | # Cursive Clojure plugin 64 | .idea/replstate.xml 65 | 66 | # Crashlytics plugin (for Android Studio and IntelliJ) 67 | com_crashlytics_export_strings.xml 68 | crashlytics.properties 69 | crashlytics-build.properties 70 | fabric.properties 71 | 72 | # Editor-based Rest Client 73 | .idea/httpRequests 74 | 75 | # Android studio 3.1+ serialized cache file 76 | .idea/caches/build_file_checksums.ser 77 | 78 | ### PyCharm+all Patch ### 79 | # Ignores the whole .idea folder and all .iml files 80 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 81 | 82 | .idea/ 83 | 84 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 85 | 86 | *.iml 87 | modules.xml 88 | .idea/misc.xml 89 | *.ipr 90 | 91 | # Sonarlint plugin 92 | .idea/sonarlint 93 | 94 | ### Python ### 95 | # Byte-compiled / optimized / DLL files 96 | __pycache__/ 97 | *.py[cod] 98 | *$py.class 99 | 100 | # C extensions 101 | *.so 102 | 103 | # Distribution / packaging 104 | .Python 105 | build/ 106 | develop-eggs/ 107 | dist/ 108 | downloads/ 109 | eggs/ 110 | .eggs/ 111 | lib/ 112 | lib64/ 113 | parts/ 114 | sdist/ 115 | var/ 116 | wheels/ 117 | pip-wheel-metadata/ 118 | share/python-wheels/ 119 | *.egg-info/ 120 | .installed.cfg 121 | *.egg 122 | MANIFEST 123 | 124 | # PyInstaller 125 | # Usually these files are written by a python script from a template 126 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 127 | *.manifest 128 | *.spec 129 | 130 | # Installer logs 131 | pip-log.txt 132 | pip-delete-this-directory.txt 133 | 134 | # Unit test / coverage reports 135 | htmlcov/ 136 | .tox/ 137 | .nox/ 138 | .coverage 139 | .coverage.* 140 | .cache 141 | nosetests.xml 142 | coverage.xml 143 | *.cover 144 | *.py,cover 145 | .hypothesis/ 146 | .pytest_cache/ 147 | pytestdebug.log 148 | 149 | # Translations 150 | *.mo 151 | *.pot 152 | 153 | # Django stuff: 154 | *.log 155 | local_settings.py 156 | db.sqlite3 157 | db.sqlite3-journal 158 | 159 | # Flask stuff: 160 | instance/ 161 | .webassets-cache 162 | 163 | # Scrapy stuff: 164 | .scrapy 165 | 166 | # Sphinx documentation 167 | docs/_build/ 168 | doc/_build/ 169 | 170 | # PyBuilder 171 | target/ 172 | 173 | # Jupyter Notebook 174 | .ipynb_checkpoints 175 | 176 | # IPython 177 | profile_default/ 178 | ipython_config.py 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # pipenv 184 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 185 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 186 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 187 | # install all needed dependencies. 188 | #Pipfile.lock 189 | 190 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 191 | __pypackages__/ 192 | 193 | # Celery stuff 194 | celerybeat-schedule 195 | celerybeat.pid 196 | 197 | # SageMath parsed files 198 | *.sage.py 199 | 200 | # Environments 201 | .env 202 | .venv 203 | env/ 204 | venv/ 205 | ENV/ 206 | env.bak/ 207 | venv.bak/ 208 | pythonenv* 209 | 210 | # Spyder project settings 211 | .spyderproject 212 | .spyproject 213 | 214 | # Rope project settings 215 | .ropeproject 216 | 217 | # mkdocs documentation 218 | /site 219 | 220 | # mypy 221 | .mypy_cache/ 222 | .dmypy.json 223 | dmypy.json 224 | 225 | # Pyre type checker 226 | .pyre/ 227 | 228 | # pytype static type analyzer 229 | .pytype/ 230 | 231 | # profiling data 232 | .prof 233 | 234 | ### vscode ### 235 | .vscode/* 236 | !.vscode/settings.json 237 | !.vscode/tasks.json 238 | !.vscode/launch.json 239 | !.vscode/extensions.json 240 | *.code-workspace 241 | 242 | # End of https://www.toptal.com/developers/gitignore/api/python,pycharm+all,vscode 243 | 244 | -------------------------------------------------------------------------------- /python/cities.csv: -------------------------------------------------------------------------------- 1 | "Pueblo Paleta","Pallet Town","Masara Town","Ruta 1 y Ruta 21" 2 | "Ciudad Verde","Viridian City","Tokiwa City","Ruta 1, Ruta 2 y Ruta 22" 3 | "Ciudad Plateada","Pewter City","Nibi City","Ruta 2 , Ruta 3 y Cueva Diglett" 4 | "Ciudad Celeste","Cerulean City","Hanada City","Ruta 24, Ruta 5, Ruta 4 y Ruta 9" 5 | "Ciudad Carmín","Vermilion City","Kuchiba City","Ruta 6, Ruta 11 y Cueva Diglett" 6 | "Pueblo Lavanda","Lavender Town","Shion Town","Ruta 10, Ruta 12 y Ruta 8" 7 | "Ciudad Azulona","Celadon City","Tamamushi City","Ruta 7 y Ruta 16" 8 | "Ciudad Fucsia","Fuchsia City","Sekichiku Cuty","Ruta 19, Ruta 18 y Ruta 15" 9 | "Ciudad Azafrán","Saffron City","Yamabuki City","Ruta 5, Ruta 6, Ruta 7 y Ruta 8" 10 | "Isla Canela","Cinnabar Island","Guren Island","Ruta 21 y Ruta 20" 11 | "Pueblo Primavera","New Bark Town","Wakaba Town","Ruta 29" 12 | "Ciudad Cerezo","Cherrygrove City","Yoshino City","Ruta 29 y Ruta 30" 13 | "Ciudad Malva","Violet City","Kikyo City","Ruta 36, Ruta 32 y Ruta 31" 14 | "Pueblo Azalea","Azalea Town","Hiwada Town","Ruta 33" 15 | "Ciudad Trigal","Goldenrod City","Cogane City","Ruta 35 y Ruta 34" 16 | "Ciudad Iris","Ecruteak City","Enju City","Ruta 37, Ruta 42 y Ruta 38" 17 | "Ciudad Olivo","Olivine City","Asagi City","Ruta 39 y Ruta 40" 18 | "Ciudad Orquídea","Cianwood City","Tanba City","Ruta 41" 19 | "Pueblo Caoba","Mahogany Town","Choji Town","Ruta 42, Ruta 44 y Ruta 43" 20 | "Ciudad Endrino","Blackthorn City","Fusube City","Ruta Helada y Ruta 45" 21 | "Villa Raíz","Littleroot Town","Mishiro Town","Ruta 101" 22 | "Pueblo Escaso","Oldale Town","Kotoki Town","Ruta 101, Ruta 102 y Ruta 103" 23 | "Ciudad Petalia","Petalburg City","Touka City","Ruta 102 y Ruta 104" 24 | "Ciudad Férrica","Rustboro City","Kanazumi City","Ruta 115, Ruta 116 y Ruta 104" 25 | "Pueblo Azuliza","Dewford Town","Muro Town","Ruta 106 y Ruta 107" 26 | "Ciudad Portual","Slateport City","Kaina City","Ruta 109, Ruta 110 y Ruta 134" 27 | "Ciudad Malvalona","Mauville City","Kinsetsu City","Ruta 111, Ruta 117, Ruta 118 y Ruta 110" 28 | "Pueblo Verdegal","Verdanturf Town","Shidake Town","Ruta 117" 29 | "Pueblo Pardal","Fallarbor Town","Hajitsuge Town","Ruta 113 y Ruta 114" 30 | "Pueblo Lavacalda","Lavaridge Town","Fuen Town","Ruta 112" 31 | "Ciudad Arborada","Fortree City","Hiwamaki City","Ruta 119 y Ruta 120" 32 | "Ciudad Calagua","Lilycove City","Minamo City","Ruta 121 y Ruta 122" 33 | "Ciudad Algaria","Mossdeep City","Tokusane City","Ruta 124, Ruta 125 y Ruta 127" 34 | "Arrecípolis","Sootopolis City","Rune City","Ruta 124, Ruta 125 y Ruta 127" 35 | "Pueblo Oromar","Pacifidlog Town","Kinagi Town","Ruta 131 y Ruta 132" 36 | "Ciudad Colosalia","Ever Grande City","Saiyū City","Ruta 128" 37 | "Pueblo Hojaverde","Twinleaf Town","Futaba Town","Ruta 201" 38 | "Pueblo Arena","Sandgem Town","Masago Town","Ruta 201, Ruta 202 y Ruta 219" 39 | "Ciudad Jubileo","Jubilife City","Kotobuki City","Ruta 202, Ruta 203, Ruta 204 y Ruta 218" 40 | "Ciudad Pirita","Oreburgh City","Korugane City","Ruta 203 y Ruta 207" 41 | "Pueblo Aromaflor","Floaroma Town","Sonoo Town","Ruta 204 y Ruta 205" 42 | "Ciudad Vetusta","Eterna City","Hakutai City","Ruta 205, Ruta 206 y Ruta 211" 43 | "Pueblo Sosiego","Solaceon Town","Zui Town","Ruta 209 y Ruta 210" 44 | "Ciudad Corazón","Hearthome City","Yosuga City","Ruta 208, Ruta 209 y Ruta 212" 45 | "Ciudad Rocavelo","Veilstone City","Tobari City","Ruta 214 y Ruta 215" 46 | "Ciudad Pradera","Pastoria City","Nomose City","Ruta 212 y Ruta 213" 47 | "Pueblo Caelestis","Celestic Town","Kannagi Town","Ruta 210 y Ruta 211" 48 | "Ciudad Canal","Canalave City","Mio City","Ruta 218" 49 | "Ciudad Puntaneva","Snowpoint City","Kissaki City","Ruta 217" 50 | "Ciudad Marina","Sunyshore City","Nagisa City","Ruta 222 y Ruta 223" 51 | "Ciudad Caolín","Opelucid City","Souryuu City","Ruta 9 (Teselia), Ruta 10 (Teselia) y Ruta 11 (Teselia)" 52 | "Ciudad Esmalte","Nacrene City","Shippo City","Ruta 3 (Teselia)" 53 | "Ciudad Fayenza","Driftveil City","Hodomoe City","Ruta 6 (Teselia)" 54 | "Ciudad Gres","Striaton City","Sanyou City","Ruta 2 (Teselia) y Ruta 3 (Teselia)" 55 | "Ciudad Loza","Mistralton City","Fukiyose City","Ruta 6 (Teselia) y Ruta 7 (Teselia)" 56 | "Ciudad Mayólica","Nimbasa City","Raimon City","Ruta 4 (Teselia), Ruta 5 (Teselia) y Ruta 16 (Teselia)" 57 | "Ciudad Negra (Pokémon Negro)","Black City","Black City","Ruta 14 (Teselia) y Ruta 15 (Teselia)" 58 | "Ciudad Porcelana","Castelia City","Hiun City","Ruta 4 (Teselia), Isla Libertad (Barco), Torre Unión (Barco)" 59 | "Ciudad Teja","Icirrus City","Sekka City","Ruta 8 (Teselia)" 60 | "Pueblo Arcilla","Nuvema Town","Kanoko Town","Ruta 1 (Teselia)" 61 | "Pueblo Arenisca","Undella Town","Sazanami Town","Ruta 13 (Teselia) y Ruta 14 (Teselia)" 62 | "Pueblo Biscuit","Anville Town","Kanawa Town","Ciudad Mayólica (Tren)" 63 | "Pueblo Ladrillo","Lacunosa Town","Kagome Town","Ruta 12 (Teselia) y Ruta 13 (Teselia)" 64 | "Pueblo Terracota","Accumula Town","Karakusa Town","Ruta 1 (Teselia) y Ruta 2 (Teselia)" 65 | "Ciudad Engobe","Aspertia City","Hiougi City","Ruta 19" 66 | "Ciudad Hormigón","Virbank City","Tachiwaki City","Ruta 20, Pokéwood, Polígono Hormigón, Ciudad Porcelana (Barco)" 67 | "Pueblo Ocre","Floccesy Town","Sangi Town","Arboleda Promesa, Ruta 20, Ruta 19" 68 | "Pueblo Chamota","Lentimas Town","Yamaji Town","Ciudad Loza (Avión), Montaña Reversia" 69 | "Ciudad Marga","Humilau City","Seigaiha City","Bahía Arenisca, Ruta 21,Ruta 21" 70 | "Pueblo Boceto","Vaniville Town","Asame Town","Ruta 1" 71 | "Ciudad Novarte","Santalune City","Hakudan City","Ruta 3, Ruta 4 y Ruta 22" 72 | "Ciudad Luminalia","Lumiose City","Miare City","Ruta 4, Ruta 5, Ruta 13, Ruta 14 y Ruta 16" 73 | "Ciudad Yantra","Shalour City","Shara City","Cueva Reflejos y Ruta 12" 74 | "Pueblo Vánitas","Camphrier Town","Koboku Town","Ruta 5, Ruta 6 y Ruta 7" 75 | "Ciudad Relieve","Cyllage City","Shōyō City","Gruta Tierraunida, Ruta 8 y Ruta 10" 76 | "Ciudad Témpera","Coumarine City","Hiyoku City","Ruta 12, Bahía Azul y Ruta 13" 77 | "Ciudad Romantis","Laverre City","Kunoe City","Ruta 14, Fábrica Poké Balls y Ruta 15" 78 | "Ciudad Fluxus","Anistar City","Hyakkoku City","Ruta 17 y Ruta 18" 79 | "Ciudad Fractal","Snowbelle City","Eisetsu City","Ruta 19, Ruta 20 y Ruta 21" 80 | "Pueblo Acuarela","Aquacorde Town","Meisui Town","Ruta 1 y Ruta 2" 81 | "Pueblo Petroglifo","Ambrette Town","Kōjin Town","Ruta 8 y Ruta 9" 82 | "Pueblo Crómlech","Geosenge Town","Sekitai Town","Ruta 10 y Ruta 11" 83 | "Pueblo Fresco","Dendemille Town","Fūjo Town","Ruta 15 y Ruta 17" 84 | "Pueblo Mosaico","Couriway Town","Renri Town","Ruta 18 y Ruta 19" 85 | "Pueblo Lilii","Iki Town","Lili'i Town","Ruta 1 y Senda Mahalo" 86 | "Ciudad Hauoli","Hau'oli City","Hauoli City","Ruta 1 y Ruta 2" 87 | "Ciudad Kantai","Heahea City","Kantai City","Ruta 6, Ruta 4, Resort Hanohano y Túnel Diglett" 88 | "Pueblo Ohana","Paniola Town","Ohana Town","Rancho Ohana, Ruta 4 y Ruta 6" 89 | "Ciudad Konikoni","Konikoni City","Koniko City","Túnel Diglett y Ruta 9" 90 | "Ciudad Malíe","Malie City","Malie City","Ruta 11, Ruta 10, Cabo de las Afueras y Parque de Malíe" 91 | "Pueblo Po","Po Town","Pō Town","Ruta 17 y Mansión Misteriosa" 92 | "Aldea Marina","Seafolk Village","Seafolk Village","Prado de Poni e Isla Exeggutor" 93 | "Villa Ágata","Agate Village","Aget Village","Noroeste" 94 | "Puerto Ancla","Gateon Port","Aio Port","Puerto" 95 | "Ciudad Oasis","Phenac City","Phenace City","Oasis del Desierto" 96 | "Pueblo Pirita","Pyrite Town","Pyra Town","Suroeste" 97 | "Básix","The Under","Under","Debajo de Pueblo Pirita" 98 | "Otonia","Fall City","Fall City","Sureste, Puerto" 99 | "Villaestío","Summerland","Summerland","Sur" 100 | "Villavera","Ring Town","Ringtown","Suroeste" 101 | "Hiberna","Wintown","Wintown","Norte" --------------------------------------------------------------------------------