Merge branch 'Test'

This commit is contained in:
Rom168 2023-06-20 15:27:55 +02:00
commit ebc5684c9d
59 changed files with 3919 additions and 798 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because one or more lines are too long

411
Projet_algo_french.ipynb Normal file
View File

@ -0,0 +1,411 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"id": "83c2b1e7-b401-4a15-adf0-d43cebf9ad81",
"metadata": {},
"source": [
"# **Algorithm project** # \n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "0b4f92e5-ac40-4491-983d-890c4f0f6694",
"metadata": {},
"source": [
"## <u> Contexte du projet </u>\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "5f483b31-1246-4f00-ae39-718ef92ce9eb",
"metadata": {},
"source": [
"L'ADEME a lancé un appel pour promouvoir de nouvelles solutions de mobilité. CesiCDP, avec son équipe de 4 personnes, répond à cet appel en se concentrant sur la gestion de tournées de livraison. L'objectif est de minimiser la durée totale de la tournée en tenant compte du trafic et d'autres contraintes. Des financements attractifs sont en jeu pour développer l'activité de CesiCDP. L'ajout de contraintes supplémentaires au problème rendra l'étude plus réaliste et plus difficile à résoudre, mais cela démontrera l'expertise de l'équipe."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "fc23daaf-9f25-4c5a-bf6c-300a7ed8d623",
"metadata": {},
"source": [
"Notre objectif est de développer un algorithme qui nous permettra de passer par tous les points de livraison dans un temps optimisé."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "d633beb7-8f26-46d4-9cd9-1d0093e5b5c3",
"metadata": {},
"source": [
"## <u>Contraintes choisies </u>\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "35fc1c3c-d7a9-4423-a948-aa00ab51dbf4",
"metadata": {},
"source": [
"La contrainte que nous avons choisie est la suivante :\n",
"\n",
"- Avoir plusieurs camions disponibles simultanément pour effectuer les livraisons."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "ba356166-604a-4627-ac0f-93b76eb7a22d",
"metadata": {},
"source": [
"## <u>Formulation du problème </u>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "c4d6888b-14e6-4745-880f-0a063ebf7476",
"metadata": {},
"source": [
"Considérons un graphe G=(V,E), où V est l'ensemble des villes (ou points de livraison) et E est l'ensemble des routes entre les villes. Il y a k camions disponibles pour effectuer les livraisons.\n",
"\n",
"Le problème consiste à trouver un itinéraire pour chaque camion, de sorte que toutes les livraisons soient effectuées dans le temps le plus court possible, à la fois vers et depuis l'entrepôt.\n",
"\n",
"Le problème que nous avons avec les contraintes mentionnées ci-dessus est le VRP (Problème de Routage des Véhicules)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "6d392f68",
"metadata": {},
"source": [
"## <u> Contraintes du problème </u>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "f95dba22",
"metadata": {},
"source": [
"Liste des contraintes du problème :\n",
"\n",
"- Tous les clients doivent être servis.\n",
"- Un client ne peut être servi que par un seul véhicule.\n",
"- Lorsqu'un véhicule quitte un client, il ne peut se rendre que chez un autre client.\n",
"\n",
"Nous allons donc attribuer à chaque client une route desservie par un seul véhicule."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "c1ca5507",
"metadata": {},
"source": [
"## <u>Demonstration de la complexité du VRP </u>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "37632b4b",
"metadata": {},
"source": [
"#### **Introduction**\n",
"\n",
"Le Problème de Routage des Véhicules (VRP) est une extension du Problème du Voyageur de Commerce (TSP) et est connu pour être un problème NP-difficile. Nous allons démontrer la complexité du VRP en nous basant sur le problème de la chaîne Hamiltonienne, qui est connu pour être NP-complet."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "6a63522a",
"metadata": {},
"source": [
"#### **Définitions préliminaires**\n",
"\n",
"- Problème de la chaîne Hamiltonienne : le problème consiste à déterminer si un graphe non orienté donné possède une chaîne Hamiltonienne, c'est-à-dire un chemin qui visite chaque sommet exactement une fois.\n",
"\n",
"- Problème du voyageur de commerce (TSP) : le problème consiste à trouver le circuit le plus court possible qui visite chaque ville d'un ensemble donné de villes et revient à la ville d'origine.\n",
"\n",
"- Problème de routage des véhicules (VRP) : le problème consiste à livrer une série de clients avec plusieurs véhicules tout en minimisant le coût total, tel que le temps de livraison ou la distance parcourue."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "589a1874",
"metadata": {},
"source": [
"#### **Preuve de complexité du TSP**.\n",
"\n",
"Le TSP (Traveling Salesman Problem) est une extension du problème de chaîne Hamiltonienne. En fait, un cas particulier du TSP est le problème de chaîne Hamiltonienne, dans lequel toutes les arêtes ont le même poids (ou coût). Dans ce cas, trouver le circuit le plus court dans le TSP revient à trouver une chaîne Hamiltonienne dans le graphe. Puisque le problème de chaîne Hamiltonienne est NP-complet, le TSP doit être au moins aussi difficile, donc le TSP est NP-complet."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "92658e81",
"metadata": {},
"source": [
"#### **Preuve de complexité du VRP**.\n",
"\n",
"Le VRP (Vehicle Routing Problem) est une extension du TSP (Traveling Salesman Problem). En fait, un cas particulier du VRP est le TSP où il n'y a qu'un seul véhicule disponible pour effectuer les livraisons. Dans ce cas, trouver la solution au VRP revient à trouver la solution au TSP.\n",
"\n",
"Puisque le TSP est NP-complet, le VRP doit être au moins aussi difficile, donc le VRP est NP-difficile. De plus, le VRP introduit des contraintes supplémentaires, telles que la présence de plusieurs véhicules et éventuellement des capacités de véhicule et des fenêtres de temps, ce qui le rend encore plus complexe."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "a4106346",
"metadata": {},
"source": [
"#### **Conclusion**\n",
"\n",
"En conclusion, nous avons démontré que le problème de VRP (Vehicle Routing Problem) est un problème NP-difficile en le réduisant au problème TSP (Traveling Salesman Problem) NP-complet, qui à son tour peut être réduit au problème de chaîne Hamiltonienne NP-complet. Cette démonstration met en évidence la difficulté de résoudre le VRP, en particulier pour de grandes instances. En pratique, des méthodes (méta)heuristiques et approximatives sont souvent utilisées pour résoudre le VRP, comme nous le verrons plus tard."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "16b3b8a7-4658-4509-a511-7a395654e6f1",
"metadata": {},
"source": [
"## <u> Modélisation mathématique </u>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "b54bfa8c",
"metadata": {},
"source": [
"#### **Paramètres :**"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "8e80a196",
"metadata": {},
"source": [
"\n",
"$V=\\{0,1,2,...,n_v\\}$ : l'ensemble des villes, où 0 est la base (ou dépôt), $1,2,...,n_v$ sont les villes de livraison. $n_v+1$ sera le dépôt pour le retour. <br>\n",
"$K=\\{1,2,...,k\\}$ : tous les camions. <br>\n",
"$E$ représente les arcs entre deux clients $i,j \\in V$ <br>\n",
"$G=(V,E)$ : le graphe avec V comme sommets (villes) et E comme arêtes <br>\n",
"$d_{ij}$ : distance (ou temps de voyage) de la ville i à la ville $j$ (coût de voyage) <br>\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "1219e4f2",
"metadata": {},
"source": [
"#### **Variables de décisions**"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "a6d398fa",
"metadata": {},
"source": [
"$x_{ijk}$ : variable binaire qui vaut 1 si le camion $k$ va d'une ville $i$ à une ville $j$, sinon elle vaut 0."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "e635cf14",
"metadata": {},
"source": [
"#### **Fonction objectif**"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "56652859",
"metadata": {},
"source": [
"$$\\min \\sum_{k∈K} \\sum_{i∈V} \\sum_{j∈V} d_{ij} x_{ijk} $$"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "a1465000",
"metadata": {},
"source": [
"#### **Contraintes du VRP**\n",
"\n",
"- Chaque ville est visitée qu'une et une seule fois :\n",
"$$\\sum_{k \\in K} \\sum_{j \\in V} x_{ijk} = 1, \\forall i \\in V, i \\ne 0$$\n",
"\n",
"- Si un camion arrive à une ville il doit en partir :\n",
"$$\\sum_{i \\in V} x_{ijk} = \\sum_{j \\in V} x_{ijk}, \\forall k \\in K, \\forall i \\in V, \\forall j \\in V $$\n",
"<br> \n",
"\n",
"- Contrainte d'élimination des sous-tours (pour s'assurer que chaque camion effectue un tour complet)\n",
"$$\\sum_{i \\in S, j \\notin S} x_{ijk} \\geq 1, \\forall k \\in K, \\forall \\; sous-ensemble \\; S \\; de \\; V, 0 \\in S, S \\ne V $$"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "4abc2a0f",
"metadata": {},
"source": [
"# Pour le VRP avec les contraintes de TW"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "e3f015b9",
"metadata": {},
"source": [
"## Variable de décision : \n",
"\n",
"$[a_i, b_i]$ la fenêtre de temps pour le client $i$ <br>\n",
"$T_{ik}$ le moment auquel le véhicule $k$ arrive au client $i$\n",
"\n",
"\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "2adf2be7",
"metadata": {},
"source": [
"# Contrainte de TW \n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "549b1ea9",
"metadata": {},
"source": [
"$T_{ik}$ est le moment auquel le véhicule $k$ arrive au client $i$. <br>\n",
"$d_{ij}$ est le temps nécessaire pour se rendre du client $i$ au client $j$. <br>\n",
"$T_{jk}$ est le moment auquel le véhicule $k$ arrive au client $j$. <br>\n",
"$M$ est une grande constante <br>\n",
"\n",
"\n",
"- Les fenêtres de temps doivent être respectées :\n",
"\n",
"$ a_j \\leq T_{jk} \\leq b_j,∀k∈ K ,∀j∈V$ <br>\n",
"\n",
"- Les temps d'arrivé aux différentes villes pour chaque camion doivent être cohérent :\n",
"\n",
"$ T_{ik} + d_{ij} \\leq T_{jk} + M(1-x_{ijk}), ∀i, j ∈ V, ∀k∈ K $"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "559a2325",
"metadata": {},
"source": [
"Dans notre cas, lorsque $x_{ijk}$ est égal à 1, la partie de droite de l'inégalité devient simplement $T_{jk}$, ce qui rend la contrainte effective.\n",
"Cependant, lorsque $x_{ijk}$ est égal à 0 (ce qui signifie que le véhicule $k$ ne se rend pas directement du client $i$ au client $j$), la partie de droite de l'inégalité devient $T_{jk} + M$. Ici, \"M\" est choisi assez grand pour que cette contrainte soit toujours satisfaite quelles que soient les valeurs de $T_{ik}$ et $T_{jk}$. En d'autres termes, lorsque $x_{ijk}$ est égal à 0, cette contrainte n'a pas d'impact sur le modèle."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "f1fc2f34",
"metadata": {},
"source": [
"# Implémentation ACO "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a2821a73",
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": []
},
{
"attachments": {},
"cell_type": "markdown",
"id": "b069576f",
"metadata": {},
"source": [
"# Implémentation du Recuit simulé "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da14539e",
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": []
},
{
"attachments": {},
"cell_type": "markdown",
"id": "e033c9cf",
"metadata": {},
"source": [
"# Implémentation du PSO \n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00402ada",
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

BIN
all_clusters.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
cluster_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
cluster_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
evolution_cluster_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
evolution_cluster_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -58,7 +58,7 @@ def plot_clusters(cities, clusters):
nb_ville = 1000
max_coords = 1000
nb_truck = 2
nb_truck = 20
# Define the coordinates of the cities
# And set depot at the first city in the middle of the map

View File

@ -9,6 +9,7 @@ def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]
previous_route = None
random.seed(42)
def draw_cities(cities, previous_route, color='b', title=' '):
plt.title(title)
@ -59,9 +60,9 @@ def simulated_annealing(cities, color='b', temperature=100000, cooling_rate=0.99
plt.ioff()
return best_solution
nb_ville = 50
nb_ville = 150
max_coords = 1000
nb_truck = 4
nb_truck = 3
temperature = 10000
cooling_rate = 0.999
temperature_ok = 0.000001

View File

@ -3,14 +3,16 @@ import random, time
from libs.clustering import split_tour_across_clusters
from libs.simulated_annealing import SimulatedAnnealing, total_distance
random.seed(42)
def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]
nb_ville = 100
nb_ville = 150
max_coords = 1000
nb_truck = 4
nb_truck = 3
temperature = 10000
cooling_rate = 0.999
cooling_rate = 0.9999
temperature_ok = 0.001
start_time_generate = time.time()

View File

@ -0,0 +1,87 @@
import matplotlib.pyplot as plt
import random, time
from libs.clustering import split_tour_across_clusters
from libs.simulated_annealing_stats import SimulatedAnnealing, total_distance
def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]
nb_ville = 100
max_coords = 1000
nb_truck = 1
temperature = 10000
cooling_rates = [ 0.999 , 0.99, 0.9 , 0.8]
temperature_ok = 0.001
start_time_generate = time.time()
cities = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
cities[0] = [max_coords/2, max_coords/2]
stop_time_generate = time.time()
optimal = 33523
start_time_split = time.time()
clusters = split_tour_across_clusters(cities, nb_truck)
stop_time_split = time.time()
for cluster in clusters.values():
print(len(cluster))
print("\n---- TIME ----")
print("generate cities time: ", stop_time_generate - start_time_generate)
print("split cities time: ", stop_time_split - start_time_split)
# create new figure for annealing paths
plt.figure()
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#9467bd', # Violet
'#d62728', # Rouge
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
results = []
for cooling_rate in cooling_rates:
print(f"\n---- Running with cooling rate: {cooling_rate} ----")
distances_over_time = []
for i, cluster_indices in enumerate(clusters.values()):
cluster_cities = [cities[index] for index in cluster_indices]
simulated_annealing = SimulatedAnnealing(cluster_cities, temperature=10000, cooling_rate=cooling_rate, temperature_ok=0.01)
best_route, distances = simulated_annealing.run()
distances_over_time.extend(distances)
# Record results for this cooling rate
results.append({
'cooling_rate': cooling_rate,
'distances': distances_over_time,
})
# Plotting total distances for each cooling rate over time
plt.figure()
for result in results:
plt.plot(result['distances'], label=f'Cooling rate: {result["cooling_rate"]}')
plt.xlabel('Iteration')
plt.ylabel('Total distance')
plt.legend(loc='upper right')
plt.title('Total distance over iterations for different cooling rates')
plt.axhline(y=optimal, color='black', linestyle='--')
plt.show()

View File

@ -3,72 +3,27 @@ import matplotlib.pyplot as plt
import numpy as np
import random, time, math
from libs.clustering import split_tour_across_clusters
from libs.aco import AntColony, total_distance
random.seed(3)
random.seed(42)
def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]
def distance(city1, city2):
return math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2) + 1e-10
def total_distance(cities):
return sum([distance(cities[i - 1], cities[i]) for i in range(len(cities))])
class AntColony:
def __init__(self, cities, n_ants, alpha=1, beta=2, evaporation=0.5, intensification=2, max_time=0.1):
self.cities = cities
self.n = len(cities)
self.n_ants = n_ants
self.alpha = alpha
self.beta = beta
self.evaporation = evaporation
self.intensification = intensification
self.max_time = max_time
self.pheromones = [[1 / self.n for _ in range(self.n)] for __ in range(self.n)]
def choose_next_city(self, ant):
unvisited_cities = [i for i in range(self.n) if i not in ant]
probabilities = [self.pheromones[ant[-1]][i] ** self.alpha * ((1 / distance(self.cities[ant[-1]], self.cities[i])) ** self.beta) for i in unvisited_cities]
total = sum(probabilities)
if total == 0:
probabilities = [1 / len(unvisited_cities) for _ in unvisited_cities]
else:
probabilities = [p / total for p in probabilities]
return np.random.choice(unvisited_cities, p=probabilities)
def update_pheromones(self, ant):
pheromones_delta = self.intensification / total_distance([self.cities[i] for i in ant])
for i in range(len(ant) - 1):
self.pheromones[ant[i]][ant[i+1]] += pheromones_delta
def run(self):
best_ant = []
best_distance = float('inf')
start_time = time.time()
while time.time() - start_time < self.max_time:
ants = [[random.randint(0, self.n - 1)] for _ in range(self.n_ants)]
for ant in ants:
for _ in range(self.n - 1):
ant.append(self.choose_next_city(ant))
ant_distance = total_distance([self.cities[i] for i in ant])
if ant_distance < best_distance:
best_distance = ant_distance
best_ant = ant.copy()
self.update_pheromones(ant)
self.pheromones = [[(1 - self.evaporation) * p for p in row] for row in self.pheromones]
return [self.cities[i] for i in best_ant]
nb_ville = 50
nb_ville = 150
max_coords = 1000
nb_truck = 2
max_time = 3
nb_truck = 3
max_time = 6
nb_ants = 10
alpha = 1
beta = 6
evaporation = 0.5
intensification = 2
max_time_per_cluster = max_time / nb_truck
start_time_generate = time.time()
cities = generate_cities(nb_ville, max_coords)
cities = generate_cities(nb_ville, max_coords)
cities[0] = [max_coords/2, max_coords/2]
stop_time_generate = time.time()
@ -117,7 +72,7 @@ for i, cluster_indices in enumerate(clusters.values()):
cluster_cities = [cities[index] for index in cluster_indices]
# Appel de la fonction AntColony.run
ant_colony = AntColony(cluster_cities, n_ants=nb_ants, max_time=max_time_per_cluster)
ant_colony = AntColony(cluster_cities, n_ants=nb_ants, max_time=max_time_per_cluster, alpha=alpha, beta=beta, evaporation=evaporation, intensification=intensification)
best_route = ant_colony.run()
best_routes.append((best_route, color))
@ -135,8 +90,8 @@ for i, (route, color) in enumerate(best_routes):
y = [city[1] for city in route]
x.append(x[0])
y.append(y[0])
plt.plot(x, y, color=color, marker='x', linestyle='-', label=f"Cluster {i}")
plt.plot(x, y, color=color, marker='o', linestyle='-', label=f"Cluster {i}")
# add title with nb_ville, nb_truck and max_time
plt.title(f"nb_ville = {nb_ville}, nb_truck = {nb_truck}, max_time = {max_time}")
plt.title(f"nb_ville = {len(cities)}, nb_truck = {nb_truck}, max_time = {max_time}")
plt.show()
plt.show()

View File

@ -0,0 +1,111 @@
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import random, time, math
from libs.clustering import split_tour_across_clusters
from libs.aco import AntColony, total_distance
def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]
nb_ville = 1500
max_coords = 1000
nb_truck = 2
max_time = 10
nb_ants = 10
max_time_per_cluster = max_time / nb_truck
start_time_generate = time.time()
cities = generate_cities(nb_ville, max_coords)
stop_time_generate = time.time()
start_time_split = time.time()
clusters = split_tour_across_clusters(cities, nb_truck)
stop_time_split = time.time()
def elbow_method(cities, max_clusters):
inertias = []
for i in range(1, max_clusters+1):
kmeans = KMeans(n_clusters=i, random_state=0).fit(cities)
inertias.append(kmeans.inertia_)
return inertias
cities = generate_cities(nb_ville, max_coords) # Assurez-vous que les villes sont générées avant de les passer à la méthode du coude
inertias = elbow_method(cities, max_clusters=50)
plt.figure()
plt.plot(range(1, len(inertias)+1), inertias, marker='o')
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('Inertia')
plt.show()
for cluster in clusters.values():
print(len(cluster))
print("\n---- TIME ----")
print("generate cities time: ", stop_time_generate - start_time_generate)
print("split cities time: ", stop_time_split - start_time_split)
# create new figure for annealing paths
plt.figure()
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
best_routes = []
for i, cluster_indices in enumerate(clusters.values()):
# Sélection d'une couleur pour le cluster
color = colors[i % len(colors)]
# Récupération des coordonnées de la ville
cluster_cities = [cities[index] for index in cluster_indices]
# Appel de la fonction AntColony.run
ant_colony = AntColony(cluster_cities, n_ants=nb_ants, max_time=max_time_per_cluster, alpha=1, beta=5)
best_route = ant_colony.run()
best_routes.append((best_route, color))
print("Total distance for cluster", i, ": ", total_distance(best_route))
# calculate total distance for all clusters
full_total_distance = 0
for route, color in best_routes:
full_total_distance += total_distance(route)
print("Total distance for all clusters: ", full_total_distance)
for i, (route, color) in enumerate(best_routes):
x = [city[0] for city in route]
y = [city[1] for city in route]
x.append(x[0])
y.append(y[0])
plt.plot(x, y, color="blue", marker='o', linestyle='-', label=f"Cluster {i}")
# add title with nb_ville, nb_truck and max_time
plt.title(f"nb_ville = {len(cities)}, nb_truck = {nb_truck}, max_time = {max_time}")
plt.show()

View File

@ -4,8 +4,6 @@ import numpy as np
import random, time, math
from libs.clustering import split_tour_across_clusters
random.seed(3)
def generate_cities(nb, max_coords=1000):
return [random.sample(range(max_coords), 2) for _ in range(nb)]

View File

@ -1,18 +1,19 @@
from matplotlib import pyplot as plt
from libs.aco import AntColony, total_distance
cities = [[37.4393516691, 541.2090699418], [612.1759508571, 494.3166877396], [38.1312338227, 353.1484581781], [53.4418081065, 131.484901365], [143.0606355347, 631.7200953923], [689.9451267256, 468.5354998742], [112.7478815786, 529.417757826], [141.4875865042, 504.818485571], [661.0513901702, 445.9375182115], [98.7899036592, 384.5926031158], [697.3881696597, 180.3962284275], [536.4894189738, 287.2279085051], [192.4067320507, 20.439405931], [282.7865258765, 229.8001556189], [240.8251726391, 281.51414372], [246.9281323057, 322.461332116], [649.7313216456, 62.3331575282], [352.96585626, 666.7873101942], [633.392367658, 534.9398453712], [488.311799404, 437.4869439948], [141.4039286509, 228.4325551488], [17.3632612602, 240.2407068508], [397.5586451389, 231.3591208928], [565.7853781464, 282.3858748974], [475.8975387047, 468.5392706317], [322.4224566559, 550.3165478233], [397.5586634023, 74.7588387765], [672.8618339396, 432.882640963], [571.2189680147, 530.261699153], [104.6531165914, 482.8224768783], [356.7098388794, 67.6477131712], [400.4070255527, 253.6794479997], [282.3036243109, 426.8380500923], [58.7766988363, 507.1712386832], [189.75062244, 460.3815233617], [659.9124120147, 226.6284156239], [639.0307636033, 467.2302300719], [415.0258357432, 233.3045376118], [547.2662016307, 161.6589278401], [616.6547902644, 339.3409309407], [494.8592427417, 148.1217856389], [629.9980812186, 433.4548164038], [471.101431241, 314.2219307579], [138.2440514421, 137.1679919735], [91.5847556724, 110.0203007516], [390.6972811808, 423.9774318385], [565.1617825137, 429.1598152874], [54.5248980387, 438.5515408431], [334.350832971, 153.796923804], [531.0291024509, 612.3874827889], [475.7345905802, 385.7844618897], [228.8325218994, 410.4461939615], [578.3805347586, 321.3303494537], [358.9170574485, 404.4670352898], [486.4648554867, 593.0429937016], [343.169370767, 509.3123571315], [530.3626972076, 137.6881275684], [498.8065475299, 576.2102674608], [224.31827155, 312.4677490415], [595.836073259, 81.8130051356], [661.5588724308, 217.0456944477], [43.6892045516, 305.4722789165], [79.465345253, 445.9641737689], [210.4163247004, 130.7151137038], [432.2642292251, 629.4092661116], [623.2487161301, 69.189285084], [436.5194739944, 282.935645607], [59.4163265482, 40.1280234442], [630.9230074073, 230.342988813], [579.3265539688, 601.0359410602], [117.862450748, 112.9796833705], [297.7912565664, 166.3131886803], [22.7642703744, 455.5340094037], [259.7095810385, 10.6199925885], [342.3579873647, 599.3880182608], [10.0260950143,
488.9310558282], [315.2926064118, 273.2275475579], [220.7044919297, 270.0819745721], [192.1186059948, 314.1839922798], [271.5042718992, 225.2921989972], [530.7320005441, 504.0670155337], [42.5331441666, 656.3645162886], [396.1274792588, 539.4648066027], [118.6631474021, 508.7129103929], [395.6913876595, 699.5376048429], [559.0157105844, 560.8866941411], [22.6471035906, 526.2470392816], [135.6377085256, 325.8409901555], [141.4507014379, 485.2477927763], [396.7741299332, 460.7557115283], [87.7494562765, 19.6170129082], [350.4245639661, 420.6531186835], [216.7010817133, 466.4816410995], [130.9237737024, 351.1491733079], [72.6329856671, 645.7852219213], [144.6002949996, 457.4224283926], [212.3725077442, 594.9216893413], [49.9186786455, 541.4350825349], [656.6943525585, 558.1109593509], [176.5941623792, 648.5239953299], [500.3825200226, 198.7428378322], [634.317867842, 612.8291643194], [59.7537372726, 551.6321886765], [15.2145765106, 143.0441928532], [283.0054378872, 376.4439530184], [146.5389000907, 39.4231794338], [101.8685605377, 635.098685018], [588.1968537448, 580.5946976921], [457.2628632528, 350.0164047376], [537.4663680494, 472.5842276692], [269.3669098585, 367.4763636538], [239.9045383695, 102.629765339], [88.4677500396, 384.0507209275], [658.9133693395, 583.9575181023], [97.7359146347, 157.4558657632], [506.6191384007, 233.0022156094], [500.2566898239, 64.9136393489], [594.4048565021, 275.874186899], [66.230814661, 24.1317387604], [598.4162993909, 414.5557574275], [172.308833083, 344.3963466366], [299.48128518, 251.829512132], [303.8379894831, 21.052606379], [197.896926984, 512.388896098], [56.0199567669, 243.0663818382], [255.5566183121, 448.8651882442], [608.4256112402, 222.5421309272], [70.2722703273, 77.9227026433], [398.2298999899, 119.557657386], [635.4970237093, 133.3225902609], [378.3484559418, 272.2907677147], [484.8029663388, 677.0730379436], [278.8710882619, 299.9308770828], [381.6537300653, 360.3337602785], [557.6070707573, 595.3185092281], [249.0589749342, 76.6595112599], [562.9048787838, 670.0382113114], [398.550436558, 392.6493259144], [590.893972056, 370.7414913742], [558.2008003726, 0.4198814512], [461.4114714423, 530.5254969413], [354.7242881504, 685.40453619], [193.6611295657,
669.7432521028], [352.3140807211, 140.3273323662], [308.434570974, 115.2054269847], [299.588137008, 530.588961902], [334.2748764383, 152.1494569394], [690.9658585947, 134.5793307203], [48.0798124069, 270.968067372], [91.6467647724, 166.3541158474]]
optimal = 6528
name = "berlin52"
cities = [[565, 575], [25, 185], [345, 750], [945, 685], [845, 655], [880, 660], [25, 230], [525, 1000], [580, 1175], [650, 1130], [1605, 620], [1220, 580], [1465, 200], [1530, 5], [845, 680], [725, 370], [145, 665], [415, 635], [510, 875], [560, 365], [300, 465], [520, 585], [480, 415],
[835, 625], [975, 580], [1215, 245], [1320, 315], [1250, 400], [660, 180], [410, 250], [420, 555], [575, 665], [1150, 1160], [700, 580], [685, 595], [685, 610], [770, 610], [795, 645], [720, 635], [760, 650], [475, 960], [95, 260], [875, 920], [700, 500], [555, 815], [830, 485],
[1170, 65], [830, 610], [605, 625], [595, 360], [1340, 725], [1740, 245]]
optimal = 7542
n_ants = 10
alpha = 1
beta = 2
evaporation = 0.5
intensification = 2
max_times = [1, 2, 5]
iterations = 2
max_times = [0.1, 0.5, 1, 2, 5]
iterations = 1
best_distances = []
times = []
@ -48,13 +49,13 @@ for max_time in max_times:
times.append(max_time)
title = ""
title += "Best distance per iterations\n"
title += "Ants: " + str(n_ants) + " "
title += "Alpja: " + str(alpha) + " "
title += "Beta: " + str(beta) + " "
title += "Evaporation: " + str(evaporation) + " "
title += "Intensification: " + str(intensification) + " "
title += "Max time: " + str(max_time)
title += "Best distance per iterations ({})\n".format(name)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Ants: " + str(n_ants) + " / "
title += "Alpha: " + str(alpha) + " / "
title += "Beta: " + str(beta) + " / "
title += "Evaporation: " + str(evaporation) + " / "
title += "Intensification: " + str(intensification)
plt.title(title)
plt.xlabel('Iteration')
plt.ylabel('Distance')

View File

@ -0,0 +1,80 @@
import matplotlib.pyplot as plt
import numpy as np
from libs.clustering import split_tour_across_clusters
from libs.aco import AntColony, total_distance
cities = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
optimal = 33523
max_times = [0.1, 0.2, 0.5, 1, 2]
n_ants = 10
alphas = [1, 2, 4, 6]
beta = 4
evaporation = 0.5
intensification = 2
n_runs = 2 # Nombre de fois où chaque configuration sera exécutée pour obtenir une moyenne
average_best_route_per_max_time_per_alpha = []
for alpha in alphas:
average_best_route_per_max_time = []
for max_time in max_times:
total_best_route_length = 0
for _ in range(n_runs):
print("Run number: ", _, "for max_time: ", max_time, " and alpha: ", alpha)
clusters = split_tour_across_clusters(cities, 1)
total_distance_for_run = 0
for i, cluster_indices in enumerate(clusters.values()):
cluster_cities = [cities[index] for index in cluster_indices]
ant_colony = AntColony(cluster_cities, n_ants=n_ants, max_time=max_time, alpha=alpha, beta=beta, evaporation=evaporation, intensification=intensification)
best_route = ant_colony.run()
total_distance_for_run += total_distance(best_route)
total_best_route_length += total_distance_for_run
average_best_route_length = total_best_route_length / n_runs
average_best_route_per_max_time.append(average_best_route_length)
average_best_route_per_max_time_per_alpha.append(average_best_route_per_max_time)
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
total_bars_per_group = len(alphas)
total_groups = len(max_times)
unit_space_per_group = 1
bars_space_per_group = total_bars_per_group / (total_bars_per_group + 1)
bar_width = bars_space_per_group / total_bars_per_group
bar_positions = np.arange(total_groups)
plt.figure(figsize=(10, 7))
for i, average_best_route_per_max_time in enumerate(average_best_route_per_max_time_per_alpha):
plt.bar(bar_positions + i * bar_width, average_best_route_per_max_time, width=bar_width, color=colors[i], label=f'Alpha={alphas[i]}')
for j, v in enumerate(average_best_route_per_max_time):
plt.text(j + i * bar_width, v + 0.01 + (i*0.2), int(v), va='bottom', ha='center')
plt.axhline(y=optimal, color='r')
plt.xticks(bar_positions + bar_width / 2, max_times) # Set the x-axis labels to be the max_time values
plt.xlabel('Max time')
plt.ylabel('Average best route length')
plt.legend()
title = ""
title += "Average best route length ({} iterations) for different max times\n".format(n_runs)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Ants: " + str(n_ants) + " / "
title += "Alpha: " + str(alphas) + " / "
title += "Beta: " + str(beta) + " / "
title += "Evaporation: " + str(evaporation) + " / "
title += "Intensification: " + str(intensification)
plt.title(title)
plt.show()

View File

@ -0,0 +1,86 @@
import matplotlib.pyplot as plt
from libs.clustering import split_tour_across_clusters
from libs.aco import AntColony, total_distance
import numpy as np
cities = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
optimal = 33523
max_times = [0.1, 0.2, 0.5, 1, 2]
n_ants = 10
alpha = 1
betas = [2, 4, 6, 8] # Pour contenir deux valeurs de beta
evaporation = 0.5
intensification = 2
n_runs = 2 # Nombre de fois où chaque configuration sera exécutée pour obtenir une moyenne
average_best_route_per_max_time_per_beta = []
for beta in betas:
average_best_route_per_max_time = []
for max_time in max_times:
total_best_route_length = 0
for _ in range(n_runs):
print("Run number: ", _, "for max_time: ", max_time, " and beta: ", beta)
clusters = split_tour_across_clusters(cities, 1)
total_distance_for_run = 0
for i, cluster_indices in enumerate(clusters.values()):
cluster_cities = [cities[index] for index in cluster_indices]
ant_colony = AntColony(cluster_cities, n_ants=n_ants, max_time=max_time, alpha=alpha, beta=beta, evaporation=evaporation, intensification=intensification)
best_route = ant_colony.run()
total_distance_for_run += total_distance(best_route)
total_best_route_length += total_distance_for_run
average_best_route_length = total_best_route_length / n_runs
average_best_route_per_max_time.append(average_best_route_length)
average_best_route_per_max_time_per_beta.append(average_best_route_per_max_time)
# Maintenant, nous avons toutes les valeurs moyennes, créons un histogramme
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
total_bars_per_group = len(betas)
total_groups = len(max_times)
# Unité d'espace pour chaque groupe de barres (incluant l'espace entre les groupes)
unit_space_per_group = 1
# Espace qui serait occupé par les barres dans chaque groupe
bars_space_per_group = total_bars_per_group / (total_bars_per_group + 1)
# La largeur de chaque barre serait
bar_width = bars_space_per_group / total_bars_per_group
index = np.arange(len(max_times))
plt.figure()
for i, average_best_route_per_max_time in enumerate(average_best_route_per_max_time_per_beta):
plt.bar(index + i * bar_width, average_best_route_per_max_time, bar_width, color=colors[i], label='Beta = '+str(betas[i]))
for j, v in enumerate(average_best_route_per_max_time):
plt.text(j + i * bar_width, v + 0.01 + (i*0.2), int(v), va='bottom', ha='center')
plt.axhline(y=optimal, color='r')
plt.xlabel('Max time')
plt.ylabel('Average best route length')
title = ""
title += "Comparaison of betas with average best route length ({} iterations) for different max times and each betas\n".format(n_runs)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Ants: " + str(n_ants) + " / "
title += "Alpha: " + str(alpha) + " / "
title += "Evaporation: " + str(evaporation) + " / "
title += "Intensification: " + str(intensification)
plt.title(title)
plt.xticks(index + bar_width / 2, max_times)
plt.legend()
plt.tight_layout()
plt.show()

View File

@ -0,0 +1,91 @@
import matplotlib.pyplot as plt
from libs.clustering import split_tour_across_clusters
from libs.aco import AntColony, total_distance
cities = [[37.4393516691, 541.2090699418], [612.1759508571, 494.3166877396], [38.1312338227, 353.1484581781], [53.4418081065, 131.484901365], [143.0606355347, 631.7200953923], [689.9451267256, 468.5354998742], [112.7478815786, 529.417757826], [141.4875865042, 504.818485571], [661.0513901702, 445.9375182115], [98.7899036592, 384.5926031158], [697.3881696597, 180.3962284275], [536.4894189738, 287.2279085051], [192.4067320507, 20.439405931], [282.7865258765, 229.8001556189], [240.8251726391, 281.51414372], [246.9281323057, 322.461332116], [649.7313216456, 62.3331575282], [352.96585626, 666.7873101942], [633.392367658, 534.9398453712], [488.311799404, 437.4869439948], [141.4039286509, 228.4325551488], [17.3632612602, 240.2407068508], [397.5586451389, 231.3591208928], [565.7853781464, 282.3858748974], [475.8975387047, 468.5392706317], [322.4224566559, 550.3165478233], [397.5586634023, 74.7588387765], [672.8618339396, 432.882640963], [571.2189680147, 530.261699153], [104.6531165914, 482.8224768783], [356.7098388794, 67.6477131712], [400.4070255527, 253.6794479997], [282.3036243109, 426.8380500923], [58.7766988363, 507.1712386832], [189.75062244, 460.3815233617], [659.9124120147, 226.6284156239], [639.0307636033, 467.2302300719], [415.0258357432, 233.3045376118], [547.2662016307, 161.6589278401], [616.6547902644, 339.3409309407], [494.8592427417, 148.1217856389], [629.9980812186, 433.4548164038], [471.101431241, 314.2219307579], [138.2440514421, 137.1679919735], [91.5847556724, 110.0203007516], [390.6972811808, 423.9774318385], [565.1617825137, 429.1598152874], [54.5248980387, 438.5515408431], [334.350832971, 153.796923804], [531.0291024509, 612.3874827889], [475.7345905802, 385.7844618897], [228.8325218994, 410.4461939615], [578.3805347586, 321.3303494537], [358.9170574485, 404.4670352898], [486.4648554867, 593.0429937016], [343.169370767, 509.3123571315], [530.3626972076, 137.6881275684], [498.8065475299, 576.2102674608], [224.31827155, 312.4677490415], [595.836073259, 81.8130051356], [661.5588724308, 217.0456944477], [43.6892045516, 305.4722789165], [79.465345253, 445.9641737689], [210.4163247004, 130.7151137038], [432.2642292251, 629.4092661116], [623.2487161301, 69.189285084], [436.5194739944, 282.935645607], [59.4163265482, 40.1280234442], [630.9230074073, 230.342988813], [579.3265539688, 601.0359410602], [117.862450748, 112.9796833705], [297.7912565664, 166.3131886803], [22.7642703744, 455.5340094037], [259.7095810385, 10.6199925885], [342.3579873647, 599.3880182608], [10.0260950143,
488.9310558282], [315.2926064118, 273.2275475579], [220.7044919297, 270.0819745721], [192.1186059948, 314.1839922798], [271.5042718992, 225.2921989972], [530.7320005441, 504.0670155337], [42.5331441666, 656.3645162886], [396.1274792588, 539.4648066027], [118.6631474021, 508.7129103929], [395.6913876595, 699.5376048429], [559.0157105844, 560.8866941411], [22.6471035906, 526.2470392816], [135.6377085256, 325.8409901555], [141.4507014379, 485.2477927763], [396.7741299332, 460.7557115283], [87.7494562765, 19.6170129082], [350.4245639661, 420.6531186835], [216.7010817133, 466.4816410995], [130.9237737024, 351.1491733079], [72.6329856671, 645.7852219213], [144.6002949996, 457.4224283926], [212.3725077442, 594.9216893413], [49.9186786455, 541.4350825349], [656.6943525585, 558.1109593509], [176.5941623792, 648.5239953299], [500.3825200226, 198.7428378322], [634.317867842, 612.8291643194], [59.7537372726, 551.6321886765], [15.2145765106, 143.0441928532], [283.0054378872, 376.4439530184], [146.5389000907, 39.4231794338], [101.8685605377, 635.098685018], [588.1968537448, 580.5946976921], [457.2628632528, 350.0164047376], [537.4663680494, 472.5842276692], [269.3669098585, 367.4763636538], [239.9045383695, 102.629765339], [88.4677500396, 384.0507209275], [658.9133693395, 583.9575181023], [97.7359146347, 157.4558657632], [506.6191384007, 233.0022156094], [500.2566898239, 64.9136393489], [594.4048565021, 275.874186899], [66.230814661, 24.1317387604], [598.4162993909, 414.5557574275], [172.308833083, 344.3963466366], [299.48128518, 251.829512132], [303.8379894831, 21.052606379], [197.896926984, 512.388896098], [56.0199567669, 243.0663818382], [255.5566183121, 448.8651882442], [608.4256112402, 222.5421309272], [70.2722703273, 77.9227026433], [398.2298999899, 119.557657386], [635.4970237093, 133.3225902609], [378.3484559418, 272.2907677147], [484.8029663388, 677.0730379436], [278.8710882619, 299.9308770828], [381.6537300653, 360.3337602785], [557.6070707573, 595.3185092281], [249.0589749342, 76.6595112599], [562.9048787838, 670.0382113114], [398.550436558, 392.6493259144], [590.893972056, 370.7414913742], [558.2008003726, 0.4198814512], [461.4114714423, 530.5254969413], [354.7242881504, 685.40453619], [193.6611295657,
669.7432521028], [352.3140807211, 140.3273323662], [308.434570974, 115.2054269847], [299.588137008, 530.588961902], [334.2748764383, 152.1494569394], [690.9658585947, 134.5793307203], [48.0798124069, 270.968067372], [91.6467647724, 166.3541158474]]
optimal = 6528
max_times = [0.01, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20]
n_ants = 10
alpha = 1
beta = 6
evaporation = 0.5
intensification = 2
n_runs = 3 # Nombre de fois où chaque configuration sera exécutée pour obtenir une moyenne
average_best_route_per_max_time = []
for max_time in max_times:
total_best_route_length = 0
for _ in range(n_runs):
print("Run number: ", _, "for max_time: ", max_time)
clusters = split_tour_across_clusters(cities, 1)
total_distance_for_run = 0
for i, cluster_indices in enumerate(clusters.values()):
cluster_cities = [cities[index] for index in cluster_indices]
ant_colony = AntColony(cluster_cities, n_ants=n_ants, max_time=max_time, alpha=alpha, beta=beta, evaporation=evaporation, intensification=intensification)
best_route = ant_colony.run()
total_distance_for_run += total_distance(best_route)
total_best_route_length += total_distance_for_run
average_best_route_length = total_best_route_length / n_runs
average_best_route_per_max_time.append(average_best_route_length)
# Maintenant, nous avons toutes les valeurs moyennes, créons un histogramme
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
plt.figure()
bar_width = 0.8
bar_positions = range(len(max_times)) # Crée une liste d'indices pour chaque barre
plt.bar(bar_positions, average_best_route_per_max_time, width=bar_width, color=colors[:len(max_times)])
plt.axhline(y=optimal, color='r')
# Ajouter des valeurs au-dessus des barres
for i, v in enumerate(average_best_route_per_max_time):
plt.text(i - 0.15, v + 0.01, round(v, 2))
plt.xticks(bar_positions, max_times) # Fixe les labels sur l'axe des x aux valeurs de max_time
plt.xlabel('Max time')
plt.ylabel('Average best route length')
title = ""
title += "Average best route length ({} iterations) for different max times\n".format(n_runs)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Ants: " + str(n_ants) + " / "
title += "Alpha: " + str(alpha) + " / "
title += "Beta: " + str(beta) + " / "
title += "Evaporation: " + str(evaporation) + " / "
title += "Intensification: " + str(intensification)
plt.title(title)
plt.show()

View File

@ -1,13 +1,14 @@
from matplotlib import pyplot as plt
from libs.simulated_annealing import SimulatedAnnealing, total_distance
name = "att48"
cities = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
optimal = 33523
temperatures = [100000, 1000000, 10000000, 100000000]
cooling_rate = 0.99999
temperature_ok = 0.000001
iterations = 2
temperatures = [100.0, 1000.0, 10000.0, 100000.0]
cooling_rate = 0.9995
temperature_ok = 0.1
iterations = 5
best_distances = []
temps = []
@ -36,17 +37,18 @@ colors = [
for temperature in temperatures:
for iteration in range(iterations):
simulated_annealing = SimulatedAnnealing(cities, temperature=temperature, cooling_rate=0.999, temperature_ok=0.01)
simulated_annealing = SimulatedAnnealing(cities, temperature=temperature, cooling_rate=cooling_rate, temperature_ok=0.0000001)
print("Running iteration number {}/{} ({} temperature)".format(iteration + 1, iterations, temperature))
best_route = simulated_annealing.run()
best_distances.append([total_distance(best_route), colors[temperatures.index(temperature) % len(colors)]])
temps.append(temperature)
title = ""
title += "Best distance per iterations\n"
title += "Temperature: " + str(temperature) + " "
title += "Cooling rate: " + str(cooling_rate) + " "
title += "Temperature ok: " + str(temperature_ok) + " "
title += "Best distance per iterations ({})\n".format(name)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Temperature: " + str(temperature) + " / "
title += "Cooling rate: " + str(cooling_rate) + " / "
title += "Temperature ok: " + str(temperature_ok) + " / "
plt.title(title)
plt.xlabel('Iteration')
plt.ylabel('Distance')

View File

@ -0,0 +1,128 @@
import matplotlib.pyplot as plt
from libs.clustering import split_tour_across_clusters
from libs.simulated_annealing import SimulatedAnnealing, total_distance
import numpy as np
name = "att48"
cities = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
optimal = 33523
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
nb_ville = 100
max_coords = 1000
nb_truck = 1
temperatures = [100 ,1000, 10000, 100000]
cooling_rate = 0.9999
temperature_ok = 0.001
iterations = 3
clusters = split_tour_across_clusters(cities, nb_truck)
for cluster in clusters.values():
print(len(cluster))
# create new figure for annealing paths
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
best_routes = []
average_distances = []
# Pour chaque température
for temperature in temperatures:
# Créez une liste pour stocker les distances pour chaque itération
distances = []
# Effectuez un certain nombre d'itérations
for _ in range(iterations):
best_routes = []
for i, cluster_indices in enumerate(clusters.values()):
# Récupération des coordonnées de la ville
cluster_cities = [cities[index] for index in cluster_indices]
# Appel de la fonction simulated_annealing
simulated_annealing = SimulatedAnnealing(cluster_cities, temperature=temperature, cooling_rate=cooling_rate, temperature_ok=temperature_ok)
best_route = simulated_annealing.run()
best_routes.append((best_route, colors[i % len(colors)]))
# Calculez la distance totale pour toutes les routes obtenues lors de cette itération
total_distance_for_iteration = sum([total_distance(route) for route, color in best_routes])
# Ajoutez cette distance à la liste des distances
distances.append(total_distance_for_iteration)
# Calculez la moyenne des distances et ajoutez-la à la liste des moyennes des distances
average_distances.append(np.mean(distances))
# Créez un nouvel histogramme pour afficher les moyennes des distances
plt.figure()
# Affichez un bar pour chaque température, avec la couleur correspondante et la moyenne des distances comme hauteur
for i in range(len(temperatures)):
plt.bar(str(temperatures[i]), average_distances[i], color=colors[i % len(colors)])
# Ajoutez des étiquettes à chaque barre avec la moyenne des distances
for i in range(len(temperatures)):
plt.text(i, average_distances[i], round(average_distances[i], 2), ha = 'center')
# Définir un titre
title = ""
title += "Average distance per temperature ({})\n".format(name)
title += "Nb cities: " + str(len(cities)) + " / "
title += "Cooling rate: " + str(cooling_rate) + " / "
title += "Temperature ok: " + str(temperature_ok)
plt.title(title)
plt.axhline(y=optimal, color='r')
# Définir les étiquettes des axes
plt.xlabel('Initial temperature')
plt.ylabel('Average distance over {} iterations'.format(iterations))
# Afficher l'histogramme
plt.show()

View File

@ -0,0 +1,76 @@
import numpy as np
from matplotlib import pyplot as plt
from libs.aco import AntColony, total_distance
name = "berlin52"
cities = [[565, 575], [25, 185], [345, 750], [945, 685], [845, 655], [880, 660], [25, 230], [525, 1000], [580, 1175], [650, 1130], [1605, 620], [1220, 580], [1465, 200], [1530, 5], [845, 680], [725, 370], [145, 665], [415, 635], [510, 875], [560, 365], [300, 465], [520, 585], [480, 415],
[835, 625], [975, 580], [1215, 245], [1320, 315], [1250, 400], [660, 180], [410, 250], [420, 555], [575, 665], [1150, 1160], [700, 580], [685, 595], [685, 610], [770, 610], [795, 645], [720, 635], [760, 650], [475, 960], [95, 260], [875, 920], [700, 500], [555, 815], [830, 485],
[1170, 65], [830, 610], [605, 625], [595, 360], [1340, 725], [1740, 245]]
optimal = 7542
n_ants = 10
alpha = [1, 2]
beta = [2, 3, 4, 5]
evaporation = 0.5
intensification = 2
max_times = [1]
iterations = 1
bar_width = 0.15
opacity = 0.8
x = np.arange(len(max_times))
fig, ax = plt.subplots()
# Preparing the colormap
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
color_dict = {}
for i in range(len(alpha)):
for j in range(len(beta)):
best_distances = []
for max_time in max_times:
for iteration in range(iterations):
ant_colony = AntColony(cities, n_ants, alpha[i], beta[j], evaporation, intensification, max_time)
print("Running iteration number {}/{} ({} sec)".format(iteration + 1, iterations, max_time))
best_route = ant_colony.run()
best_distances.append(total_distance(best_route))
# Defining a unique key for each alpha-beta pair
key = f"alpha={alpha[i]}_beta={beta[j]}"
if key not in color_dict:
color_dict[key] = colors[i * len(beta) + j]
ax.bar(x + (i * len(beta) + j) * bar_width, best_distances, bar_width, alpha=opacity, color=color_dict[key], label='alpha={} beta={}'.format(alpha[i], beta[j]))
ax.set_xlabel('Max Time')
ax.set_ylabel('Best Distance')
ax.set_title('Best distances per max time for each alpha and beta')
ax.set_xticks(x + bar_width / 3)
ax.set_xticklabels(max_times)
ax.legend()
plt.axhline(y=optimal, color='r')
plt.show()

View File

@ -0,0 +1,82 @@
import numpy as np
from matplotlib import pyplot as plt
from libs.aco import AntColony, total_distance
name_1 = "att48"
cities_1 = [[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]
optimal_1 = 33523
name_2 = "berlin52"
cities_2 = [[565, 575], [25, 185], [345, 750], [945, 685], [845, 655], [880, 660], [25, 230], [525, 1000], [580, 1175], [650, 1130], [1605, 620], [1220, 580], [1465, 200], [1530, 5], [845, 680], [725, 370], [145, 665], [415, 635], [510, 875], [560, 365], [300, 465], [520, 585], [480, 415],
[835, 625], [975, 580], [1215, 245], [1320, 315], [1250, 400], [660, 180], [410, 250], [420, 555], [575, 665], [1150, 1160], [700, 580], [685, 595], [685, 610], [770, 610], [795, 645], [720, 635], [760, 650], [475, 960], [95, 260], [875, 920], [700, 500], [555, 815], [830, 485],
[1170, 65], [830, 610], [605, 625], [595, 360], [1340, 725], [1740, 245]]
optimal_2 = 7542
name_3 = "eil76"
cities_3 = [[22, 22], [36, 26], [21, 45], [45, 35], [55, 20], [33, 34], [50, 50], [55, 45], [26, 59], [40, 66], [55, 65], [35, 51], [62, 35], [62, 57], [62, 24], [21, 36], [33, 44], [9, 56], [62, 48], [66, 14],
[44, 13], [26, 13], [11, 28], [7, 43], [17, 64], [41, 46], [55, 34], [35, 16], [52, 26], [43, 26], [31, 76], [22, 53], [26, 29], [50, 40], [55, 50], [54, 10], [60, 15], [47, 66], [30, 60], [30, 50], [12, 17], [15, 14], [16, 19], [21, 48], [50, 30], [51, 42], [50, 15], [48, 21], [12, 38], [15, 56], [29, 39], [54, 38], [55, 57], [67, 41], [10, 70], [6, 25], [65, 27], [40, 60], [70, 64], [64, 4], [36, 6], [30, 20], [20, 30], [15, 5], [50, 70], [57, 72], [45, 42], [38, 33], [50, 4], [66, 8], [59,
5], [35, 60], [27, 24], [40, 20], [40, 37], [40, 40]]
optimal_3 = 538
all_names = [name_1, name_2, name_3]
all_cities = [cities_1, cities_2, cities_3]
all_optimals = [optimal_1, optimal_2, optimal_3]
n_ants = 10
alpha = 1
beta = 4
evaporation = 0.5
intensification = 2
max_times = [1, 2, 3]
iterations = 1
bar_width = 0.15
opacity = 0.8
x = np.arange(len(max_times))
fig, ax = plt.subplots()
# Preparing the colormap
colors = [
'#1f77b4', # Bleu moyen
'#ff7f0e', # Orange
'#2ca02c', # Vert
'#d62728', # Rouge
'#9467bd', # Violet
'#8c564b', # Marron
'#e377c2', # Rose
'#7f7f7f', # Gris
'#bcbd22', # Vert olive
'#17becf', # Turquoise
'#1b9e77', # Vert Teal
'#d95f02', # Orange foncé
'#7570b3', # Violet moyen
'#e7298a', # Fuchsia
'#66a61e', # Vert pomme
'#e6ab02', # Jaune or
'#a6761d', # Bronze
'#666666', # Gris foncé
'#f781bf', # Rose clair
'#999999', # Gris moyen
]
best_distances = []
for cities in all_cities:
for max_time in max_times:
for iteration in range(iterations):
ant_colony = AntColony(cities, n_ants, alpha, beta, evaporation, intensification, max_time)
print("Running iteration number {}/{} ({} sec)".format(iteration + 1, iterations, max_time))
best_route = ant_colony.run()
best_distances.append([total_distance(best_route), colors[max_times.index(max_time) % len(colors)]])
ax.set_xlabel('Max Time')
ax.set_ylabel('Best Distance')
ax.set_title('Best distances per max time for each alpha and beta')
ax.set_xticks(x + bar_width / 3)
ax.set_xticklabels(max_times)
ax.legend()
plt.axhline(y=100, color='r')
plt.show()

View File

@ -0,0 +1 @@
[[111, 952], [74, 934], [161, 942], [113, 892], [37, 858], [182, 835], [214, 910], [161, 887], [91, 807], [30, 797], [858, 941], [909, 939], [944, 895], [950, 836], [950, 778], [939, 734], [889, 734], [861, 783], [845, 854], [885, 875], [940, 227], [872, 210], [832, 120], [879, 65], [934, 75], [952, 151], [917, 195], [885, 144], [895, 102], [922, 137], [108, 214], [59, 185], [94, 117], [154, 116]]

View File

@ -0,0 +1 @@
[[904, 878], [767, 923], [878, 779], [815, 853], [778, 744], [694, 794], [874, 129], [783, 161], [809, 53], [870, 52], [818, 101], [749, 69], [165, 115], [106, 172], [91, 80], [208, 35], [191, 155], [126, 105], [104, 709], [176, 831], [95, 906], [203, 753], [254, 825], [125, 829], [841, 794], [244, 817], [143, 96], [860, 50], [752, 844], [210, 808], [117, 48], [862, 124], [183, 59], [143, 177], [876, 219], [928, 97], [726, 822], [791, 894], [110, 861], [120, 767]]

View File

@ -1 +0,0 @@
[['6734', '1453'], ['2233', '10'], ['5530', '1424'], ['401', '841'], ['3082', '1644'], ['7608', '4458'], ['7573', '3716'], ['7265', '1268'], ['6898', '1885'], ['1112', '2049'], ['5468', '2606'], ['5989', '2873'], ['4706', '2674'], ['4612', '2035'], ['6347', '2683'], ['6107', '669'], ['7611', '5184'], ['7462', '3590'], ['7732', '4723'], ['5900', '3561'], ['4483', '3369'], ['6101', '1110'], ['5199', '2182'], ['1633', '2809'], ['4307', '2322'], ['675', '1006'], ['7555', '4819'], ['7541', '3981'], ['3177', '756'], ['7352', '4506'], ['7545', '2801'], ['3245', '3305'], ['6426', '3173'], ['4608', '1198'], ['23', '2216'], ['7248', '3779'], ['7762', '4595'], ['7392', '2244'], ['3484', '2829'], ['6271', '2135'], ['4985', '140'], ['1916', '1569'], ['7280', '4899'], ['7509', '3239'], ['10', '2676'], ['6807', '2993'], ['5185', '3258'], ['3023', '1942']]

View File

@ -1,3 +0,0 @@
[['22', '22'], ['36', '26'], ['21', '45'], ['45', '35'], ['55', '20'], ['33', '34'], ['50', '50'], ['55', '45'], ['26', '59'], ['40', '66'], ['55', '65'], ['35', '51'], ['62', '35'], ['62', '57'], ['62', '24'], ['21', '36'], ['33', '44'], ['9', '56'], ['62', '48'], ['66', '14'],
['44', '13'], ['26', '13'], ['11', '28'], ['7', '43'], ['17', '64'], ['41', '46'], ['55', '34'], ['35', '16'], ['52', '26'], ['43', '26'], ['31', '76'], ['22', '53'], ['26', '29'], ['50', '40'], ['55', '50'], ['54', '10'], ['60', '15'], ['47', '66'], ['30', '60'], ['30', '50'], ['12', '17'], ['15', '14'], ['16', '19'], ['21', '48'], ['50', '30'], ['51', '42'], ['50', '15'], ['48', '21'], ['12', '38'], ['15', '56'], ['29', '39'], ['54', '38'], ['55', '57'], ['67', '41'], ['10', '70'], ['6', '25'], ['65', '27'], ['40', '60'], ['70', '64'], ['64', '4'], ['36', '6'], ['30', '20'], ['20', '30'], ['15', '5'], ['50', '70'], ['57', '72'], ['45', '42'], ['38', '33'], ['50', '4'], ['66', '8'], ['59',
'5'], ['35', '60'], ['27', '24'], ['40', '20'], ['40', '37'], ['40', '40']]

View File

@ -0,0 +1,55 @@
NAME : att48.opt.tour
COMMENT : Optimum solution for att48
TYPE : TOUR
DIMENSION : 48
TOUR_SECTION
1
8
38
31
44
18
7
28
6
37
19
27
17
43
30
36
46
33
20
47
21
32
39
48
5
42
24
10
45
35
4
26
2
29
34
41
16
22
3
23
14
25
13
11
12
15
40
9
-1
EOF

View File

@ -0,0 +1,55 @@
NAME : att48
COMMENT : 48 capitals of the US (Padberg/Rinaldi)
TYPE : TSP
DIMENSION : 48
EDGE_WEIGHT_TYPE : ATT
NODE_COORD_SECTION
1 6734 1453
2 2233 10
3 5530 1424
4 401 841
5 3082 1644
6 7608 4458
7 7573 3716
8 7265 1268
9 6898 1885
10 1112 2049
11 5468 2606
12 5989 2873
13 4706 2674
14 4612 2035
15 6347 2683
16 6107 669
17 7611 5184
18 7462 3590
19 7732 4723
20 5900 3561
21 4483 3369
22 6101 1110
23 5199 2182
24 1633 2809
25 4307 2322
26 675 1006
27 7555 4819
28 7541 3981
29 3177 756
30 7352 4506
31 7545 2801
32 3245 3305
33 6426 3173
34 4608 1198
35 23 2216
36 7248 3779
37 7762 4595
38 7392 2244
39 3484 2829
40 6271 2135
41 4985 140
42 1916 1569
43 7280 4899
44 7509 3239
45 10 2676
46 6807 2993
47 5185 3258
48 3023 1942
EOF

View File

@ -0,0 +1,157 @@
NAME : ch150.opt.tour
COMMENT : Length 6528
TYPE : TOUR
DIMENSION : 150
TOUR_SECTION
1
98
103
82
95
107
5
100
143
97
146
26
75
18
142
85
65
132
137
50
55
58
141
83
56
90
46
92
54
138
134
131
32
23
38
67
43
109
51
20
25
110
81
29
86
135
70
108
102
114
99
19
2
37
6
28
9
42
120
47
139
40
53
118
24
12
116
101
41
57
39
127
69
36
61
11
148
130
17
66
60
140
117
129
27
31
123
74
13
106
91
119
68
128
45
71
44
64
112
136
145
144
49
147
72
80
14
122
77
133
15
78
21
150
115
4
104
22
125
149
62
3
113
10
94
88
121
79
59
16
111
105
33
126
52
93
124
35
96
89
8
7
84
30
63
48
73
76
34
87
-1
EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
NAME : eil76.opt.tour
COMMENT : Optimum tour for eil76.tsp (538)
TYPE : TOUR
DIMENSION : 76
TOUR_SECTION
1
33
63
16
3
44
32
9
39
72
58
10
31
55
25
50
18
24
49
23
56
41
43
42
64
22
61
21
47
36
69
71
60
70
20
37
5
15
57
13
54
19
14
59
66
65
38
11
53
7
35
8
46
34
52
27
45
29
48
30
4
75
76
67
26
12
40
17
51
6
68
2
74
28
62
73
-1
EOF

View File

@ -0,0 +1,2 @@
[[288, 149], [288, 129], [270, 133], [256, 141], [256, 157], [246, 157], [236, 169], [228, 169], [228, 161], [220, 169], [212, 169], [204, 169], [196, 169], [188, 169], [196, 161], [188, 145], [172, 145], [164, 145], [156, 145], [148, 145], [140, 145], [148, 169], [164, 169], [172, 169], [156, 169], [140, 169], [132, 169], [124, 169], [116, 161], [104, 153], [104, 161], [104, 169], [90, 165], [80, 157], [64, 157], [64, 165], [56, 169], [56, 161], [56, 153], [56, 145], [56, 137], [56, 129], [56, 121], [40, 121], [40, 129], [40, 137], [40, 145], [40, 153], [40, 161], [40, 169], [32, 169], [32, 161], [32, 153], [32, 145], [32, 137], [32, 129], [32, 121], [32, 113], [40, 113], [56, 113], [56, 105], [48, 99], [40, 99], [32, 97], [32, 89], [24, 89], [16, 97], [16, 109], [8, 109], [8, 97], [8, 89], [8, 81], [8, 73], [8, 65], [8, 57], [16, 57], [8, 49], [8, 41], [24, 45], [32, 41], [32, 49], [32, 57], [32, 65], [32, 73], [32, 81], [40, 83], [40, 73], [40, 63], [40, 51], [44, 43], [44, 35], [44, 27], [32, 25], [24, 25], [16, 25], [16, 17], [24, 17], [32, 17], [44, 11], [56, 9], [56, 17], [56, 25], [56, 33], [56, 41], [64, 41], [72, 41], [72, 49], [56, 49], [48, 51], [56, 57], [56, 65], [48, 63], [48, 73], [56, 73], [56, 81], [48, 83], [56, 89], [56, 97], [104, 97], [104, 105], [104, 113], [104, 121], [104, 129], [104, 137], [104, 145], [116, 145], [124, 145], [132, 145], [132, 137], [140, 137], [148, 137], [156, 137], [164, 137], [172, 125], [172, 117], [172, 109], [172, 101], [172, 93], [172, 85], [180, 85], [180, 77], [180, 69], [180, 61], [180, 53], [172, 53], [172, 61], [172, 69], [172, 77], [164, 81], [148, 85], [124, 85], [124, 93], [124, 109], [124, 125], [124, 117], [124, 101], [104, 89], [104, 81], [104, 73], [104, 65], [104, 49], [104, 41], [104, 33], [104, 25], [104, 17], [92, 9], [80, 9], [72, 9], [64, 21], [72, 25], [80, 25], [80, 25], [80, 41], [88, 49], [104, 57], [124, 69], [124, 77], [132, 81], [140, 65], [132, 61], [124, 61], [124, 53], [124, 45], [124, 37], [124, 29], [132, 21], [124, 21], [120, 9], [128, 9], [136, 9], [148, 9], [162, 9], [156, 25], [172, 21], [180, 21], [180, 29], [172, 29], [172, 37], [172, 45], [180, 45], [180, 37], [188, 41], [196, 49], [204, 57], [212, 65], [220, 73], [228, 69], [228, 77], [236, 77], [236, 69], [236, 61], [228, 61], [228, 53], [236, 53], [236, 45], [228, 45], [228, 37], [236, 37], [236, 29], [228, 29], [228, 21], [236, 21], [252, 21], [260, 29], [260, 37], [260, 45], [260, 53], [260, 61], [260, 69], [260, 77], [276, 77], [276,
69], [276, 61], [276, 53], [284, 53], [284, 61], [284, 69], [284, 77], [284, 85], [284, 93], [284, 101], [288, 109], [280, 109], [276, 101], [276, 93], [276, 85], [268, 97], [260, 109], [252, 101], [260, 93], [260, 85], [236, 85], [228, 85], [228, 93], [236, 93], [236, 101], [228, 101], [228, 109], [228, 117], [228, 125], [220, 125], [212, 117], [204, 109], [196, 101], [188, 93], [180, 93], [180, 101], [180, 109], [180, 117], [180, 125], [196, 145], [204, 145], [212, 145], [220, 145], [228, 145], [236, 145], [246, 141], [252, 125], [260, 129], [280, 133]]

View File

@ -0,0 +1 @@
[[6734, 1453], [2233, 10], [5530, 1424], [401, 841], [3082, 1644], [7608, 4458], [7573, 3716], [7265, 1268], [6898, 1885], [1112, 2049], [5468, 2606], [5989, 2873], [4706, 2674], [4612, 2035], [6347, 2683], [6107, 669], [7611, 5184], [7462, 3590], [7732, 4723], [5900, 3561], [4483, 3369], [6101, 1110], [5199, 2182], [1633, 2809], [4307, 2322], [675, 1006], [7555, 4819], [7541, 3981], [3177, 756], [7352, 4506], [7545, 2801], [3245, 3305], [6426, 3173], [4608, 1198], [23, 2216], [7248, 3779], [7762, 4595], [7392, 2244], [3484, 2829], [6271, 2135], [4985, 140], [1916, 1569], [7280, 4899], [7509, 3239], [10, 2676], [6807, 2993], [5185, 3258], [3023, 1942]]

View File

@ -0,0 +1,3 @@
[[565, 575], [25, 185], [345, 750], [945, 685], [845, 655], [880, 660], [25, 230], [525, 1000], [580, 1175], [650, 1130], [1605, 620], [1220, 580], [1465, 200], [1530, 5], [845, 680], [725, 370], [145, 665], [415, 635], [510, 875], [560, 365], [300, 465], [520, 585], [480, 415],
[835, 625], [975, 580], [1215, 245], [1320, 315], [1250, 400], [660, 180], [410, 250], [420, 555], [575, 665], [1150, 1160], [700, 580], [685, 595], [685, 610], [770, 610], [795, 645], [720, 635], [760, 650], [475, 960], [95, 260], [875, 920], [700, 500], [555, 815], [830, 485],
[1170, 65], [830, 610], [605, 625], [595, 360], [1340, 725], [1740, 245]]

View File

@ -0,0 +1,23 @@
[[0.0, 0.0], [1224.3, 945.6], [1325.9, 945.6], [1325.9, 971.0], [1224.3, 971.0], [1224.3, 996.4], [1325.9, 996.4], [1325.9, 1021.8], [1224.3, 1021.8], [1186.2, 1034.5], [1084.6, 1034.5], [1052.8, 1034.5], [1027.4, 1034.5], [1224.3, 1047.2], [1325.9, 1047.2], [1186.2, 1059.9], [1084.6, 1059.9], [1052.8, 1059.9], [1027.4, 1059.9], [1224.3, 1072.6], [1325.9, 1072.6], [1186.2, 1085.3], [1084.6, 1085.3], [1052.8, 1085.3], [1027.4, 1085.3], [1224.3, 1098.0], [1325.9, 1098.0], [1186.2, 1110.7], [1084.6, 1110.7], [1052.8, 1110.7], [1027.4, 1110.7], [1224.3, 1123.4], [1325.9, 1123.4], [1186.2, 1136.1], [1084.6, 1136.1], [1052.8, 1136.1], [1027.4, 1136.1], [1224.3, 1148.8], [1325.9, 1148.8], [1186.2,
1161.5], [1084.6, 1161.5], [1052.8, 1161.5], [1027.4, 1161.5], [1224.3, 1174.2], [1325.9, 1174.2], [1186.2, 1186.9], [1084.6, 1186.9], [1052.8, 1186.9], [1027.4, 1186.9], [1224.3, 1199.6], [1325.9, 1199.6], [1186.2, 1212.3], [1084.6, 1212.3], [1052.8, 1212.3], [1027.4, 1212.3], [1224.3, 1225.0], [1325.9, 1225.0], [1186.2, 1237.7], [1084.6, 1237.7], [1052.8, 1237.7], [1027.4, 1237.7], [1224.3, 1250.4], [1325.9, 1250.4], [1186.2, 1263.1], [1084.6, 1263.1], [1052.8, 1263.1], [1027.4, 1263.1], [1224.3, 1275.8], [1325.9, 1275.8], [1186.2, 1288.5], [1084.6, 1288.5], [1052.8, 1288.5], [1027.4, 1288.5], [1027.4, 1313.9], [1052.8, 1313.9], [1084.6, 1313.9], [1186.2, 1313.9], [1287.8, 1339.3], [1262.4, 1339.3], [1186.2, 1339.3], [1084.6, 1339.3], [1052.8, 1339.3], [1027.4, 1339.3], [1027.4, 1364.7], [1052.8, 1364.7], [1084.6, 1364.7], [1186.2, 1364.7], [1186.2, 1390.1], [1084.6, 1390.1], [1052.8, 1390.1], [1027.4, 1390.1], [1224.3, 1402.8], [1325.9, 1402.8], [1186.2, 1415.5], [1084.6, 1415.5], [1052.8, 1415.5], [1027.4, 1415.5], [1224.3, 1428.2], [1325.9, 1428.2], [1325.9, 1453.6], [1224.3, 1453.6], [1224.3, 1479.0], [1325.9, 1479.0], [1186.2, 1491.7], [1084.6, 1491.7], [1052.8, 1491.7], [1027.4, 1504.4], [1224.3, 1504.4], [1325.9, 1504.4], [1052.8,
1517.1], [1224.3, 1529.8], [1325.9, 1529.8], [1325.9, 1555.2], [1224.3, 1555.2], [1224.3, 1580.6], [1325.9, 1580.6], [1325.9, 1606.0], [1224.3, 1606.0], [1224.3, 1631.4], [1325.9, 1631.4], [1325.9, 1656.8], [1224.3, 1656.8], [1224.3, 1682.2], [1325.9, 1682.2], [1325.9, 1707.6], [1224.3, 1707.6], [1224.3, 1733.0], [1325.9, 1733.0], [1097.3, 1948.9], [1071.9, 1948.9], [1224.3, 2152.1], [1325.9, 2152.1], [1325.9, 2177.5], [1224.3, 2177.5], [1224.3, 2202.9], [1325.9, 2202.9], [1325.9, 2228.3], [1224.3, 2228.3], [1224.3, 2253.7], [1325.9, 2253.7], [1325.9, 2279.1], [1224.3, 2279.1], [1224.3, 2304.5], [1325.9, 2304.5], [1325.9, 2329.9], [1224.3, 2329.9], [1224.3, 2355.3], [1325.9, 2355.3], [1325.9, 2380.7], [1224.3, 2380.7], [1224.3, 2406.1], [1325.9, 2406.1], [1325.9, 2431.5], [1224.3, 2431.5], [1224.3, 2456.9], [1325.9, 2456.9], [1325.9, 2482.3], [1224.3, 2482.3], [1262.4, 2545.8], [1287.8, 2545.8], [1325.9, 2609.3], [1224.3, 2609.3], [1224.3, 2634.7], [1325.9, 2634.7], [1186.2, 2647.4], [1084.6, 2647.4], [1052.8, 2647.4], [1027.4, 2660.1], [1224.3, 2660.1], [1325.9, 2660.1], [1052.8, 2672.8], [1224.3, 2685.5], [1325.9, 2685.5], [1325.9, 2710.9], [1224.3, 2710.9], [1224.3, 2736.3], [1325.9, 2736.3], [1325.9, 2761.7], [1224.3, 2761.7], [1224.3,
2787.1], [1325.9, 2787.1], [1325.9, 2812.5], [1224.3, 2812.5], [1325.9, 2837.9], [1224.3, 2837.9], [1186.2, 2837.9], [1084.6, 2837.9], [1224.3, 2863.3], [1325.9, 2863.3], [1325.9, 2888.7], [1224.3, 2888.7], [1224.3, 2914.1], [1325.9, 2914.1], [1325.9, 2939.5], [1224.3, 2939.5], [1579.9, 3028.4], [1605.3, 3028.4], [1630.7, 3028.4], [1656.1, 3028.4], [1681.5, 3028.4], [1706.9, 3028.4], [1732.3, 3028.4], [1757.7, 3028.4], [1783.1, 3028.4], [1808.5, 3028.4], [1833.9, 3028.4], [1859.3, 3028.4], [1884.7, 3028.4], [1910.1, 3028.4], [1935.5, 3028.4], [1973.6, 3015.7], [1999.0, 3015.7], [2024.4, 3015.7], [1922.8, 2984.0], [1821.2, 2984.0], [1618.0, 2971.3], [1681.5, 2964.9], [1783.1, 2964.9], [1821.2, 2958.6], [1922.8, 2958.6], [1643.4, 2945.9], [1681.5, 2939.5], [1783.1, 2939.5], [1973.6, 2939.5], [1999.0, 2939.5], [2024.4, 2939.5], [2075.2, 2939.5], [2176.8, 2939.5], [1948.2, 2920.5], [1872.0, 2920.5], [1618.0, 2920.5], [1681.5, 2914.1], [1783.1, 2914.1], [1973.6, 2914.1], [1999.0, 2914.1], [2024.4, 2914.1], [2075.2, 2914.1], [2176.8, 2914.1], [2176.8, 2888.7], [2075.2, 2888.7], [1783.1, 2888.7], [1681.5, 2888.7], [1618.0, 2869.7], [1872.0, 2869.7], [1948.2, 2869.7], [2176.8, 2863.3], [2075.2, 2863.3], [1783.1, 2863.3], [1681.5, 2863.3], [1643.4,
2844.3], [1681.5, 2837.9], [1783.1, 2837.9], [1878.3, 2837.9], [1903.7, 2837.9], [1929.1, 2837.9], [1973.6, 2837.9], [1999.0, 2837.9], [2024.4, 2837.9], [2075.2, 2837.9], [2176.8, 2837.9], [1618.0, 2818.9], [1681.5, 2812.5], [1783.1, 2812.5], [2075.2, 2812.5], [2176.8, 2812.5], [2176.8, 2787.1], [2075.2, 2787.1], [2024.4, 2787.1], [1999.0, 2787.1], [1973.6, 2787.1], [1783.1, 2787.1], [1681.5, 2787.1], [1618.0, 2768.1], [1681.5, 2761.7], [1783.1, 2761.7], [2075.2, 2761.7], [2176.8, 2761.7], [1643.4, 2742.7], [1681.5, 2736.3], [1783.1, 2736.3], [1878.3, 2736.3], [1903.7, 2736.3], [1929.1, 2736.3], [2075.2, 2736.3], [2176.8, 2736.3], [1618.0, 2717.3], [1681.5, 2710.9], [1783.1, 2710.9], [1821.2, 2710.9], [1922.8, 2710.9], [1973.6, 2710.9], [1999.0, 2710.9], [2024.4, 2710.9], [2075.2, 2710.9], [2176.8, 2710.9], [2176.8, 2685.5], [2075.2, 2685.5], [2024.4, 2685.5], [1999.0, 2685.5], [1973.6, 2685.5], [1922.8, 2685.5], [1821.2, 2685.5], [1783.1, 2685.5], [1757.7, 2685.5], [1732.3, 2685.5], [1706.9, 2685.5], [1681.5, 2685.5], [1656.1, 2685.5], [1618.0, 2666.5], [1821.2, 2660.1], [1922.8, 2660.1], [2075.2, 2660.1], [2176.8, 2660.1], [1643.4, 2641.1], [1681.5, 2634.7], [1783.1, 2634.7], [1821.2, 2634.7], [1922.8, 2634.7], [2075.2, 2634.7], [2176.8,
2634.7], [1618.0, 2615.7], [1681.5, 2609.3], [1783.1, 2609.3], [1821.2, 2609.3], [1922.8, 2609.3], [1973.6, 2609.3], [1999.0, 2609.3], [2024.4, 2609.3], [2075.2, 2609.3], [2176.8, 2609.3], [1935.5, 2571.2], [1910.1, 2571.2], [1884.7, 2571.2], [1859.3, 2571.2], [1833.9, 2571.2], [1808.5, 2571.2], [1783.1, 2571.2], [1757.7, 2571.2], [1732.3, 2571.2], [1706.9, 2571.2], [1681.5, 2571.2], [1656.1, 2571.2], [1630.7, 2571.2], [1605.3, 2571.2], [1579.9, 2571.2], [1973.6, 2558.5], [1999.0, 2558.5], [2024.4, 2558.5], [2113.3, 2545.8], [2138.7, 2545.8], [1922.8, 2526.8], [1821.2, 2526.8], [1618.0, 2514.1], [1681.5, 2507.7], [1783.1, 2507.7], [1821.2, 2501.4], [1922.8, 2501.4], [1643.4, 2488.7], [1681.5, 2482.3], [1783.1, 2482.3], [1973.6, 2482.3], [1999.0, 2482.3], [2024.4, 2482.3], [2075.2, 2482.3], [2176.8, 2482.3], [1948.2, 2463.3], [1872.0, 2463.3], [1618.0, 2463.3], [1681.5, 2456.9], [1783.1, 2456.9], [1973.6, 2456.9], [1999.0, 2456.9], [2024.4, 2456.9], [2075.2, 2456.9], [2176.8, 2456.9], [2176.8, 2431.5], [2075.2, 2431.5], [1783.1, 2431.5], [1681.5, 2431.5], [1618.0, 2412.5], [1872.0, 2412.5], [1948.2, 2412.5], [2176.8, 2406.1], [2075.2, 2406.1], [1783.1, 2406.1], [1681.5, 2406.1], [1643.4, 2387.1], [1681.5, 2380.7], [1783.1, 2380.7], [1878.3,
2380.7], [1903.7, 2380.7], [1929.1, 2380.7], [1973.6, 2380.7], [1999.0, 2380.7], [2024.4, 2380.7], [2075.2, 2380.7], [2176.8, 2380.7], [1618.0, 2361.7], [1681.5, 2355.3], [1783.1, 2355.3], [2075.2, 2355.3], [2176.8, 2355.3], [2176.8, 2329.9], [2075.2, 2329.9], [2024.4, 2329.9], [1999.0, 2329.9], [1973.6, 2329.9], [1783.1, 2329.9], [1681.5, 2329.9], [1618.0, 2310.9], [1681.5, 2304.5], [1783.1, 2304.5], [2075.2, 2304.5], [2176.8, 2304.5], [1643.4, 2285.5], [1681.5, 2279.1], [1783.1, 2279.1], [1878.3, 2279.1], [1903.7, 2279.1], [1929.1, 2279.1], [2075.2, 2279.1], [2176.8, 2279.1], [1618.0, 2260.1], [1681.5, 2253.7], [1783.1, 2253.7], [1821.2, 2253.7], [1922.8, 2253.7], [1973.6, 2253.7], [1999.0, 2253.7], [2024.4, 2253.7], [2075.2, 2253.7], [2176.8, 2253.7], [2176.8, 2228.3], [2075.2, 2228.3], [2024.4, 2228.3], [1999.0, 2228.3], [1973.6, 2228.3], [1922.8, 2228.3], [1821.2, 2228.3], [1783.1, 2228.3], [1757.7, 2228.3], [1732.3, 2228.3], [1706.9, 2228.3], [1681.5, 2228.3], [1656.1, 2228.3], [1618.0, 2209.3], [1821.2, 2202.9], [1922.8, 2202.9], [2075.2, 2202.9], [2176.8, 2202.9], [1643.4, 2183.9], [1681.5, 2177.5], [1783.1, 2177.5], [1821.2, 2177.5], [1922.8, 2177.5], [2075.2, 2177.5], [2176.8, 2177.5], [1618.0, 2158.5], [1681.5, 2152.1], [1783.1,
2152.1], [1821.2, 2152.1], [1922.8, 2152.1], [1973.6, 2152.1], [1999.0, 2152.1], [2024.4, 2152.1], [2075.2, 2152.1], [2176.8, 2152.1], [2113.3, 1948.9], [2138.7, 1948.9], [1935.5, 1745.7], [1910.1, 1745.7], [1884.7, 1745.7], [1859.3, 1745.7], [1833.9, 1745.7], [1808.5, 1745.7], [1783.1, 1745.7], [1757.7, 1745.7], [1732.3, 1745.7], [1706.9, 1745.7], [1681.5, 1745.7], [1656.1, 1745.7], [1630.7, 1745.7], [1605.3, 1745.7], [1579.9, 1745.7], [1973.6, 1733.0], [1999.0, 1733.0], [2024.4, 1733.0], [2075.2, 1733.0], [2176.8, 1733.0], [2176.8, 1707.6], [2075.2, 1707.6], [1922.8, 1701.3], [1821.2, 1701.3], [1618.0, 1688.6], [1681.5, 1682.2], [1783.1, 1682.2], [2075.2, 1682.2], [2176.8, 1682.2], [1922.8, 1675.9], [1821.2, 1675.9], [1643.4, 1663.2], [1681.5, 1656.8], [1783.1, 1656.8], [1973.6, 1656.8], [1999.0, 1656.8], [2024.4, 1656.8], [2075.2, 1656.8], [2176.8, 1656.8], [1948.2, 1637.8], [1872.0, 1637.8], [1618.0, 1637.8], [1681.5, 1631.4], [1783.1, 1631.4], [1973.6, 1631.4], [1999.0, 1631.4], [2024.4, 1631.4], [2075.2, 1631.4], [2176.8, 1631.4], [2176.8, 1606.0], [2075.2, 1606.0], [1783.1, 1606.0], [1681.5, 1606.0], [1618.0, 1587.0], [1872.0, 1587.0], [1948.2, 1587.0], [2176.8, 1580.6], [2075.2, 1580.6], [1783.1, 1580.6], [1681.5, 1580.6], [1643.4,
1561.6], [1681.5, 1555.2], [1783.1, 1555.2], [1872.0, 1555.2], [1903.7, 1555.2], [1929.1, 1555.2], [1973.6, 1555.2], [1999.0, 1555.2], [2024.4, 1555.2], [2075.2, 1555.2], [2176.8, 1555.2], [1618.0, 1536.2], [1681.5, 1529.8], [1783.1, 1529.8], [2075.2, 1529.8], [2176.8, 1529.8], [2176.8, 1504.4], [2075.2, 1504.4], [2024.4, 1504.4], [1999.0, 1504.4], [1973.6, 1504.4], [1783.1, 1504.4], [1681.5, 1504.4], [1618.0, 1485.4], [1681.5, 1479.0], [1783.1, 1479.0], [2075.2, 1479.0], [2176.8, 1479.0], [1643.4, 1460.0], [1681.5, 1453.6], [1783.1, 1453.6], [1872.0, 1453.6], [1903.7, 1453.6], [1929.1, 1453.6], [2075.2, 1453.6], [2176.8, 1453.6], [1618.0, 1434.6], [1681.5, 1428.2], [1783.1, 1428.2], [1821.2, 1428.2], [1922.8, 1428.2], [1973.6, 1428.2], [1999.0, 1428.2], [2024.4, 1428.2], [2075.2, 1428.2], [2176.8, 1428.2], [2176.8, 1402.8], [2075.2, 1402.8], [2024.4, 1402.8], [1999.0, 1402.8], [1973.6, 1402.8], [1922.8, 1402.8], [1821.2, 1402.8], [1783.1, 1402.8], [1757.7, 1402.8], [1732.3, 1402.8], [1706.9, 1402.8], [1681.5, 1402.8], [1656.1, 1402.8], [1618.0, 1383.8], [1821.2, 1377.4], [1922.8, 1377.4], [1643.4, 1358.4], [1681.5, 1352.0], [1783.1, 1352.0], [1821.2, 1352.0], [1922.8, 1352.0], [2113.3, 1352.0], [2138.7, 1352.0], [1618.0, 1333.0], [1681.5,
1326.6], [1783.1, 1326.6], [1821.2, 1326.6], [1922.8, 1326.6], [1973.6, 1326.6], [1999.0, 1326.6], [2024.4, 1326.6], [1935.5, 1288.5], [1910.1, 1288.5], [1884.7, 1288.5], [1859.3, 1288.5], [1833.9, 1288.5], [1808.5, 1288.5], [1783.1, 1288.5], [1757.7, 1288.5], [1732.3, 1288.5], [1706.9, 1288.5], [1681.5, 1288.5], [1656.1, 1288.5], [1630.7, 1288.5], [1605.3, 1288.5], [1579.9, 1288.5], [1973.6, 1275.8], [1999.0, 1275.8], [2024.4, 1275.8], [2075.2, 1275.8], [2176.8, 1275.8], [2176.8, 1250.4], [2075.2, 1250.4], [1922.8, 1244.1], [1821.2, 1244.1], [1618.0, 1231.4], [1681.5, 1225.0], [1783.1, 1225.0], [2075.2, 1225.0], [2176.8, 1225.0], [1922.8, 1218.7], [1821.2, 1218.7], [1643.4, 1206.0], [1681.5, 1199.6], [1783.1, 1199.6], [1973.6, 1199.6], [1999.0, 1199.6], [2024.4, 1199.6], [2075.2, 1199.6], [2176.8, 1199.6], [1948.2, 1180.6], [1872.0, 1180.6], [1618.0, 1180.6], [1681.5, 1174.2], [1783.1, 1174.2], [1973.6, 1174.2], [1999.0, 1174.2], [2024.4, 1174.2], [2075.2, 1174.2], [2176.8, 1174.2], [2176.8, 1148.8], [2075.2, 1148.8], [1783.1, 1148.8], [1681.5, 1148.8], [1618.0, 1129.8], [1872.0, 1129.8], [1948.2, 1129.8], [2176.8, 1123.4], [2075.2, 1123.4], [1783.1, 1123.4], [1681.5, 1123.4], [1643.4, 1104.4], [1681.5, 1098.0], [1783.1, 1098.0], [1878.3,
1098.0], [1903.7, 1098.0], [1929.1, 1098.0], [1973.6, 1098.0], [1999.0, 1098.0], [2024.4, 1098.0], [2075.2, 1098.0], [2176.8, 1098.0], [1618.0, 1079.0], [1681.5, 1072.6], [1783.1, 1072.6], [2075.2, 1072.6], [2176.8, 1072.6], [2176.8, 1047.2], [2075.2, 1047.2], [2024.4, 1047.2], [1999.0, 1047.2], [1973.6, 1047.2], [1783.1, 1047.2], [1681.5, 1047.2], [1618.0, 1028.2], [1681.5, 1021.8], [1783.1, 1021.8], [2075.2, 1021.8], [2176.8, 1021.8], [1643.4, 1002.8], [1681.5, 996.4], [1783.1, 996.4], [1878.3, 996.4], [1903.7, 996.4], [1929.1, 996.4], [2075.2, 996.4], [2176.8, 996.4], [1618.0, 977.4], [1681.5, 971.0], [1783.1, 971.0], [1821.2, 971.0], [1922.8, 971.0], [1973.6, 971.0], [1999.0, 971.0], [2024.4, 971.0], [2075.2, 971.0], [2176.8, 971.0], [2176.8, 945.6], [2075.2, 945.6], [2024.4, 945.6], [1999.0, 945.6], [1973.6, 945.6], [1922.8, 945.6], [1821.2, 945.6], [1783.1, 945.6], [1757.7, 945.6], [1732.3, 945.6], [1706.9, 945.6], [1681.5, 945.6], [1656.1, 945.6], [1618.0, 926.6], [1821.2, 920.2], [1922.8, 920.2], [1643.4, 901.2], [1681.5, 894.8], [1783.1, 894.8], [1821.2, 894.8], [1922.8, 894.8], [1618.0, 875.8], [1681.5, 869.4], [1783.1, 869.4], [1821.2, 869.4], [1922.8, 869.4], [1973.6, 869.4], [1999.0, 869.4], [2024.4, 869.4], [2449.8, 2037.8], [2475.2, 2037.8], [2500.6, 2037.8], [2526.0, 2037.8], [2551.4, 2037.8], [2576.8, 2037.8], [2602.2, 2037.8], [2627.6, 2037.8], [2672.1, 2037.8], [2697.5, 2037.8], [2722.9, 2037.8], [2748.3, 2037.8], [2773.7, 2037.8], [2799.1, 2037.8], [2824.5, 2037.8], [2849.9, 2037.8], [2926.1, 2075.9], [3002.3, 2075.9], [3053.1, 2075.9], [3103.9, 2075.9], [3167.4, 2075.9], [3243.6, 2075.9], [3294.4, 2075.9], [3345.2, 2075.9], [3383.3, 2088.6], [3459.5, 2088.6], [3497.6, 2088.6], [3599.2, 2088.6], [3650.0, 2088.6], [3675.4, 2088.6], [3700.8, 2088.6], [2849.9, 2114.0], [2824.5, 2114.0], [2799.1, 2114.0], [2773.7, 2114.0], [2748.3, 2114.0], [2722.9, 2114.0], [2697.5, 2114.0], [2672.1, 2114.0], [2627.6, 2114.0], [2602.2, 2114.0], [2576.8, 2114.0], [2551.4, 2114.0], [2526.0, 2114.0], [2500.6, 2114.0], [2475.2, 2114.0], [2449.8, 2114.0], [3497.6, 2126.7], [3599.2, 2126.7], [3459.5, 2139.4], [3383.3, 2139.4], [3345.2, 2152.1], [3294.4, 2152.1], [3243.6, 2152.1], [3167.4, 2152.1], [3103.9,
2152.1], [3053.1, 2152.1], [3002.3, 2152.1], [2926.1, 2152.1], [2875.3, 2152.1], [2849.9, 2152.1], [2824.5, 2152.1], [2773.7, 2152.1], [2672.1, 2152.1], [2634.0, 2152.1], [2532.4, 2152.1], [2468.9, 2158.5], [2532.4, 2177.5], [2634.0, 2177.5], [2672.1, 2177.5], [2773.7, 2177.5], [2494.3, 2183.9], [2672.1, 2202.9], [2773.7, 2202.9], [2926.1, 2202.9], [3002.3, 2202.9], [3053.1, 2202.9], [3103.9, 2202.9], [3167.4, 2202.9], [3243.6, 2202.9], [3294.4, 2202.9], [3345.2, 2202.9], [2468.9, 2209.3], [3383.3, 2215.6], [3459.5, 2215.6], [3497.6, 2215.6], [3599.2, 2215.6], [3675.4, 2215.6], [3726.2, 2215.6], [2875.3, 2228.3], [2849.9, 2228.3], [2824.5, 2228.3], [2773.7, 2228.3], [2672.1, 2228.3], [2634.0, 2228.3], [2608.6, 2228.3], [2583.2, 2228.3], [2557.8, 2228.3], [2532.4, 2228.3], [2507.0, 2228.3], [3675.4, 2241.0], [3726.2, 2241.0], [3599.2, 2253.7], [3497.6, 2253.7], [2875.3, 2253.7], [2849.9, 2253.7], [2824.5, 2253.7], [2773.7, 2253.7], [2672.1, 2253.7], [2634.0, 2253.7], [2532.4, 2253.7], [2468.9, 2260.1], [3383.3, 2266.4], [3459.5, 2266.4], [3675.4, 2266.4], [3726.2, 2266.4], [3345.2, 2279.1], [3294.4, 2279.1], [3243.6, 2279.1], [3167.4, 2279.1], [3103.9, 2279.1], [3053.1, 2279.1], [3002.3, 2279.1], [2926.1, 2279.1], [2780.0, 2279.1], [2754.6,
2279.1], [2729.2, 2279.1], [2634.0, 2279.1], [2532.4, 2279.1], [2494.3, 2285.5], [3675.4, 2291.8], [3726.2, 2291.8], [2634.0, 2304.5], [2532.4, 2304.5], [2468.9, 2310.9], [3675.4, 2317.2], [3726.2, 2317.2], [3345.2, 2329.9], [3294.4, 2329.9], [3243.6, 2329.9], [3167.4, 2329.9], [3103.9, 2329.9], [3053.1, 2329.9], [3002.3, 2329.9], [2926.1, 2329.9], [2875.3, 2329.9], [2849.9, 2329.9], [2824.5, 2329.9], [2634.0, 2329.9], [2532.4, 2329.9], [3383.3, 2342.6], [3459.5, 2342.6], [3497.6, 2342.6], [3599.2, 2342.6], [3675.4, 2342.6], [3726.2, 2342.6], [2634.0, 2355.3], [2532.4, 2355.3], [2468.9, 2361.7], [3675.4, 2368.0], [3726.2, 2368.0], [3599.2, 2380.7], [3497.6, 2380.7], [2875.3, 2380.7], [2849.9, 2380.7], [2824.5, 2380.7], [2780.0, 2380.7], [2754.6, 2380.7], [2729.2, 2380.7], [2634.0, 2380.7], [2532.4, 2380.7], [2494.3, 2387.1], [3383.3, 2393.4], [3459.5, 2393.4], [3675.4, 2393.4], [3726.2, 2393.4], [3345.2, 2406.1], [3294.4, 2406.1], [3243.6, 2406.1], [3167.4, 2406.1], [3103.9, 2406.1], [3053.1, 2406.1], [3002.3, 2406.1], [2926.1, 2406.1], [2634.0, 2406.1], [2532.4, 2406.1], [2468.9, 2412.5], [2722.9, 2412.5], [2799.1, 2412.5], [3675.4, 2418.8], [3726.2, 2418.8], [2634.0, 2431.5], [2532.4, 2431.5], [3675.4, 2444.2], [3726.2, 2444.2], [3345.2,
2456.9], [3294.4, 2456.9], [3243.6, 2456.9], [3167.4, 2456.9], [3103.9, 2456.9], [3053.1, 2456.9], [3002.3, 2456.9], [2926.1, 2456.9], [2875.3, 2456.9], [2849.9, 2456.9], [2824.5, 2456.9], [2634.0, 2456.9], [2532.4, 2456.9], [2468.9, 2463.3], [2722.9, 2463.3], [2799.1, 2463.3], [3383.3, 2469.6], [3459.5, 2469.6], [3497.6, 2469.6], [3599.2, 2469.6], [3675.4, 2469.6], [3726.2, 2469.6], [2875.3, 2482.3], [2849.9, 2482.3], [2824.5, 2482.3], [2634.0, 2482.3], [2532.4, 2482.3], [2494.3, 2488.7], [3675.4, 2495.0], [3726.2, 2495.0], [2773.7, 2501.4], [2672.1, 2501.4], [2532.4, 2507.7], [2634.0, 2507.7], [3497.6, 2507.7], [3599.2, 2507.7], [2468.9, 2514.1], [3383.3, 2520.4], [3459.5, 2520.4], [3675.4, 2520.4], [3726.2, 2520.4], [2773.7, 2526.8], [2672.1, 2526.8], [2926.1, 2533.1], [3002.3, 2533.1], [3053.1, 2533.1], [3103.9, 2533.1], [3167.4, 2533.1], [3243.6, 2533.1], [3294.4, 2533.1], [3345.2, 2533.1], [3675.4, 2545.8], [3726.2, 2545.8], [2875.3, 2558.5], [2849.9, 2558.5], [2824.5, 2558.5], [2430.8, 2571.2], [2456.2, 2571.2], [2481.6, 2571.2], [2507.0, 2571.2], [2532.4, 2571.2], [2557.8, 2571.2], [2583.2, 2571.2], [2608.6, 2571.2], [2634.0, 2571.2], [2659.4, 2571.2], [2684.8, 2571.2], [2710.2, 2571.2], [2735.6, 2571.2], [2761.0, 2571.2], [2786.4,
2571.2], [3675.4, 2571.2], [3726.2, 2571.2], [3345.2, 2583.9], [3294.4, 2583.9], [3243.6, 2583.9], [3167.4, 2583.9], [3103.9, 2583.9], [3053.1, 2583.9], [3002.3, 2583.9], [2926.1, 2583.9], [3383.3, 2596.6], [3459.5, 2596.6], [3497.6, 2596.6], [3599.2, 2596.6], [3675.4, 2596.6], [3726.2, 2596.6], [2875.3, 2609.3], [2849.9, 2609.3], [2824.5, 2609.3], [2773.7, 2609.3], [2672.1, 2609.3], [2634.0, 2609.3], [2532.4, 2609.3], [2468.9, 2615.7], [3675.4, 2622.0], [3726.2, 2622.0], [3599.2, 2634.7], [3497.6, 2634.7], [2773.7, 2634.7], [2672.1, 2634.7], [2634.0, 2634.7], [2532.4, 2634.7], [2494.3, 2641.1], [3383.3, 2647.4], [3459.5, 2647.4], [3675.4, 2647.4], [3726.2, 2647.4], [3345.2, 2660.1], [3294.4, 2660.1], [3243.6, 2660.1], [3167.4, 2660.1], [3103.9, 2660.1], [3053.1, 2660.1], [3002.3, 2660.1], [2926.1, 2660.1], [2773.7, 2660.1], [2672.1, 2660.1], [2468.9, 2666.5], [3675.4, 2672.8], [3726.2, 2672.8], [2634.0, 2679.2], [2608.6, 2679.2], [2583.2, 2679.2], [2507.0, 2685.5], [2532.4, 2685.5], [2557.8, 2685.5], [2672.1, 2685.5], [2773.7, 2685.5], [2824.5, 2685.5], [2849.9, 2685.5], [2875.3, 2685.5], [3675.4, 2698.2], [3726.2, 2698.2], [3345.2, 2710.9], [3294.4, 2710.9], [3243.6, 2710.9], [3167.4, 2710.9], [3103.9, 2710.9], [3053.1, 2710.9], [3002.3,
2710.9], [2926.1, 2710.9], [2875.3, 2710.9], [2849.9, 2710.9], [2824.5, 2710.9], [2773.7, 2710.9], [2672.1, 2710.9], [2634.0, 2710.9], [2532.4, 2710.9], [2468.9, 2717.3], [3383.3, 2723.6], [3459.5, 2723.6], [3497.6, 2723.6], [3599.2, 2723.6], [3675.4, 2723.6], [3726.2, 2723.6], [2780.0, 2736.3], [2754.6, 2736.3], [2729.2, 2736.3], [2634.0, 2736.3], [2532.4, 2736.3], [2494.3, 2742.7], [3675.4, 2749.0], [3726.2, 2749.0], [3599.2, 2761.7], [3497.6, 2761.7], [2634.0, 2761.7], [2532.4, 2761.7], [2468.9, 2768.1], [3383.3, 2774.4], [3459.5, 2774.4], [3675.4, 2774.4], [3726.2, 2774.4], [3345.2, 2787.1], [3294.4, 2787.1], [3243.6, 2787.1], [3167.4, 2787.1], [3103.9, 2787.1], [3053.1, 2787.1], [3002.3, 2787.1], [2926.1, 2787.1], [2875.3, 2787.1], [2849.9, 2787.1], [2824.5, 2787.1], [2634.0, 2787.1], [2532.4, 2787.1], [3675.4, 2799.8], [3726.2, 2799.8], [2634.0, 2812.5], [2532.4, 2812.5], [2468.9, 2818.9], [3675.4, 2825.2], [3726.2, 2825.2], [3345.2, 2837.9], [3294.4, 2837.9], [3243.6, 2837.9], [3167.4, 2837.9], [3103.9, 2837.9], [3053.1, 2837.9], [3002.3, 2837.9], [2926.1, 2837.9], [2875.3, 2837.9], [2849.9, 2837.9], [2824.5, 2837.9], [2780.0, 2837.9], [2754.6, 2837.9], [2729.2, 2837.9], [2634.0, 2837.9], [2532.4, 2837.9], [2494.3, 2844.3], [3383.3,
2850.6], [3459.5, 2850.6], [3497.6, 2850.6], [3599.2, 2850.6], [3675.4, 2850.6], [3726.2, 2850.6], [2634.0, 2863.3], [2532.4, 2863.3], [2468.9, 2869.7], [2722.9, 2869.7], [2799.1, 2869.7], [3675.4, 2876.0], [3726.2, 2876.0], [3599.2, 2888.7], [3497.6, 2888.7], [2634.0, 2888.7], [2532.4, 2888.7], [3383.3, 2901.4], [3459.5, 2901.4], [3675.4, 2901.4], [3726.2, 2901.4], [3345.2, 2914.1], [3294.4, 2914.1], [3243.6, 2914.1], [3167.4, 2914.1], [3103.9, 2914.1], [3053.1, 2914.1], [3002.3, 2914.1], [2926.1, 2914.1], [2875.3, 2914.1], [2849.9, 2914.1], [2824.5, 2914.1], [2634.0, 2914.1], [2532.4, 2914.1], [2468.9, 2920.5], [2722.9, 2920.5], [2799.1, 2920.5], [3675.4, 2926.8], [3726.2, 2926.8], [2875.3, 2939.5], [2849.9, 2939.5], [2824.5, 2939.5], [2634.0, 2939.5], [2532.4, 2939.5], [2494.3, 2945.9], [3675.4, 2952.2], [3726.2, 2952.2], [2773.7, 2958.6], [2672.1, 2958.6], [2532.4, 2964.9], [2634.0, 2964.9], [2926.1, 2964.9], [3002.3, 2964.9], [3053.1, 2964.9], [3103.9, 2964.9], [3167.4, 2964.9], [3243.6, 2964.9], [3294.4, 2964.9], [3345.2, 2964.9], [2468.9, 2971.3], [3383.3, 2977.6], [3459.5, 2977.6], [3497.6, 2977.6], [3599.2, 2977.6], [3675.4, 2977.6], [3726.2, 2977.6], [2773.7, 2984.0], [2672.1, 2984.0], [3675.4, 3003.0], [3726.2, 3003.0], [3599.2,
3015.7], [3497.6, 3015.7], [2875.3, 3015.7], [2849.9, 3015.7], [2824.5, 3015.7], [2430.8, 3028.4], [2456.2, 3028.4], [2481.6, 3028.4], [2507.0, 3028.4], [2532.4, 3028.4], [2557.8, 3028.4], [2583.2, 3028.4], [2608.6, 3028.4], [2634.0, 3028.4], [2659.4, 3028.4], [2684.8, 3028.4], [2710.2, 3028.4], [2735.6, 3028.4], [2761.0, 3028.4], [2786.4, 3028.4], [3383.3, 3028.4], [3459.5, 3028.4], [3345.2, 3041.1], [3294.4, 3041.1], [3243.6, 3041.1], [3167.4, 3041.1], [3103.9, 3041.1], [3053.1, 3041.1], [3002.3, 3041.1], [2926.1, 3041.1], [3535.7, 3066.5], [3561.1, 3066.5], [3586.5, 3066.5], [3586.5, 2012.4], [3535.7, 2012.4], [3484.9, 2012.4], [3408.7, 2012.4], [3345.2, 2012.4], [3294.4, 2012.4], [3243.6, 2012.4], [3167.4, 2012.4], [3103.9, 2012.4], [3053.1, 2012.4], [3002.3, 2012.4], [2926.1, 2012.4], [2926.1, 1936.2], [3002.3, 1936.2], [3053.1, 1936.2], [3103.9, 1936.2], [3167.4, 1936.2], [3243.6, 1936.2], [3294.4, 1936.2], [3345.2, 1936.2], [3408.7, 1936.2], [3484.9, 1936.2], [3535.7, 1936.2], [3586.5, 1936.2], [3446.8, 1796.5], [3421.4, 1796.5], [3396.0, 1796.5], [2786.4, 1745.7], [2761.0, 1745.7], [2735.6, 1745.7], [2710.2, 1745.7], [2684.8, 1745.7], [2659.4, 1745.7], [2634.0, 1745.7], [2608.6, 1745.7], [2583.2, 1745.7], [2557.8, 1745.7], [2532.4,
1745.7], [2507.0, 1745.7], [2481.6, 1745.7], [2456.2, 1745.7], [2430.8, 1745.7], [2824.5, 1733.0], [2849.9, 1733.0], [2875.3, 1733.0], [2773.7, 1701.3], [2672.1, 1701.3], [2468.9, 1688.6], [2532.4, 1682.2], [2634.0, 1682.2], [3249.9, 1682.2], [3351.5, 1682.2], [2773.7, 1675.9], [2672.1, 1675.9], [2494.3, 1663.2], [2532.4, 1656.8], [2634.0, 1656.8], [2824.5, 1656.8], [2849.9, 1656.8], [2875.3, 1656.8], [3249.9, 1656.8], [3351.5, 1656.8], [2799.1, 1637.8], [2722.9, 1637.8], [2468.9, 1637.8], [2532.4, 1631.4], [2634.0, 1631.4], [2824.5, 1631.4], [2849.9, 1631.4], [2875.3, 1631.4], [3249.9, 1631.4], [3351.5, 1631.4], [3351.5, 1606.0], [3249.9, 1606.0], [2634.0, 1606.0], [2532.4, 1606.0], [2468.9, 1587.0], [2722.9, 1587.0], [2799.1, 1587.0], [2532.4, 1580.6], [2634.0, 1580.6], [3249.9, 1580.6], [3351.5, 1580.6], [2494.3, 1561.6], [2532.4, 1555.2], [2634.0, 1555.2], [2729.2, 1555.2], [2754.6, 1555.2], [2780.0, 1555.2], [2824.5, 1555.2], [2849.9, 1555.2], [2875.3, 1555.2], [2468.9, 1536.2], [2532.4, 1529.8], [2634.0, 1529.8], [2532.4, 1504.4], [2634.0, 1504.4], [2824.5, 1504.4], [2849.9, 1504.4], [2875.3, 1504.4], [2468.9, 1485.4], [2532.4, 1479.0], [2634.0, 1479.0], [2964.2, 1479.0], [2494.3, 1460.0], [2532.4, 1453.6], [2634.0, 1453.6], [2729.2,
1453.6], [2754.6, 1453.6], [2780.0, 1453.6], [2468.9, 1434.6], [2532.4, 1428.2], [2634.0, 1428.2], [2672.1, 1428.2], [2773.7, 1428.2], [2824.5, 1428.2], [2849.9, 1428.2], [2875.3, 1428.2], [2875.3, 1402.8], [2849.9, 1402.8], [2824.5, 1402.8], [2773.7, 1402.8], [2672.1, 1402.8], [2634.0, 1402.8], [2608.6, 1402.8], [2583.2, 1402.8], [2557.8, 1402.8], [2532.4, 1402.8], [2507.0, 1402.8], [2468.9, 1383.8], [2672.1, 1377.4], [2773.7, 1377.4], [2964.2, 1377.4], [2494.3, 1358.4], [2532.4, 1352.0], [2634.0, 1352.0], [2672.1, 1352.0], [2773.7, 1352.0], [2468.9, 1333.0], [2532.4, 1326.6], [2634.0, 1326.6], [2672.1, 1326.6], [2773.7, 1326.6], [2824.5, 1326.6], [2849.9, 1326.6], [2875.3, 1326.6], [2786.4, 1288.5], [2761.0, 1288.5], [2735.6, 1288.5], [2710.2, 1288.5], [2684.8, 1288.5], [2659.4, 1288.5], [2634.0, 1288.5], [2608.6, 1288.5], [2583.2, 1288.5], [2557.8, 1288.5], [2532.4, 1288.5], [2507.0, 1288.5], [2481.6, 1288.5], [2456.2, 1288.5], [2430.8, 1288.5], [2824.5, 1275.8], [2849.9, 1275.8], [2875.3, 1275.8], [2773.7, 1244.1], [2672.1, 1244.1], [2468.9, 1231.4], [2532.4, 1225.0], [2634.0, 1225.0], [2672.1, 1218.7], [2773.7, 1218.7], [2494.3, 1206.0], [2532.4, 1199.6], [2634.0, 1199.6], [2824.5, 1199.6], [2849.9, 1199.6], [2875.3, 1199.6], [2799.1,
1180.6], [2722.9, 1180.6], [2468.9, 1180.6], [2532.4, 1174.2], [2634.0, 1174.2], [2824.5, 1174.2], [2849.9, 1174.2], [2875.3, 1174.2], [2634.0, 1148.8], [2532.4, 1148.8], [2468.9, 1129.8], [2722.9, 1129.8], [2799.1, 1129.8], [2634.0, 1123.4], [2532.4, 1123.4], [2494.3, 1104.4], [2532.4, 1098.0], [2634.0, 1098.0], [2729.2, 1098.0], [2754.6, 1098.0], [2780.0, 1098.0], [2824.5, 1098.0], [2849.9, 1098.0], [2875.3, 1098.0], [2468.9, 1079.0], [2532.4, 1072.6], [2634.0, 1072.6], [2919.7, 1066.3], [3021.3, 1066.3], [3091.2, 1066.3], [3192.8, 1066.3], [3243.6, 1066.3], [3345.2, 1066.3], [2875.3, 1047.2], [2849.9, 1047.2], [2824.5, 1047.2], [2634.0, 1047.2], [2532.4, 1047.2], [2919.7, 1040.9], [3021.3, 1040.9], [3091.2, 1040.9], [3192.8, 1040.9], [3243.6, 1040.9], [3345.2, 1040.9], [2468.9, 1028.2], [2532.4, 1021.8], [2634.0, 1021.8], [2919.7, 1015.5], [3021.3, 1015.5], [3091.2, 1015.5], [3192.8, 1015.5], [3243.6, 1015.5], [3345.2, 1015.5], [2494.3, 1002.8], [2532.4, 996.4],
[2634.0, 996.4], [2729.2, 996.4], [2754.6, 996.4], [2780.0, 996.4], [2919.7, 990.1], [3021.3, 990.1], [2468.9, 977.4], [2532.4, 971.0], [2634.0, 971.0], [2672.1, 971.0], [2773.7, 971.0], [2824.5, 971.0], [2849.9, 971.0], [2875.3, 971.0], [2875.3, 945.6], [2849.9, 945.6], [2824.5, 945.6], [2773.7, 945.6], [2672.1, 945.6], [2634.0, 945.6], [2608.6, 945.6], [2583.2, 945.6], [2557.8, 945.6], [2532.4, 945.6], [2507.0, 945.6], [2468.9, 926.6], [2672.1, 920.2], [2773.7, 920.2], [2494.3, 901.2], [2532.4, 894.8], [2634.0, 894.8], [2672.1, 894.8], [2773.7, 894.8], [2468.9, 875.8], [2532.4, 869.4], [2634.0, 869.4], [2672.1, 869.4], [2773.7, 869.4], [2824.5, 869.4], [2849.9, 869.4], [2875.3, 869.4], [3091.2, 958.3], [3116.6, 958.3], [3142.0, 958.3], [3167.4, 958.3], [3192.8, 958.3], [3218.2, 958.3], [3243.6, 958.3], [3269.0, 958.3], [3294.4, 958.3], [3319.8, 958.3], [3319.8, 882.1], [3294.4, 882.1], [3269.0, 882.1], [3243.6, 882.1], [3218.2, 882.1], [3192.8, 882.1], [3167.4, 882.1], [3142.0, 882.1], [3116.6, 882.1], [3091.2, 882.1], [3116.6, 844.0], [3218.2, 844.0], [3535.7, 831.3], [3561.1, 831.3], [3586.5, 831.3], [3650.0, 882.1], [3675.4, 882.1], [3726.2, 882.1], [3726.2, 907.5], [3675.4, 907.5], [3650.0, 907.5], [3650.0, 932.9], [3675.4, 932.9], [3726.2, 932.9], [3726.2, 958.3], [3675.4, 958.3], [3650.0, 958.3], [3650.0, 983.7], [3675.4, 983.7], [3726.2, 983.7], [3726.2, 1009.1], [3675.4, 1009.1], [3650.0, 1009.1], [3650.0, 1034.5], [3675.4, 1034.5], [3726.2, 1034.5], [3726.2, 1059.9], [3675.4, 1059.9], [3650.0, 1059.9], [3650.0, 1085.3], [3675.4, 1085.3], [3726.2, 1085.3], [3726.2, 1110.7], [3675.4, 1110.7], [3650.0, 1110.7], [3650.0, 1136.1], [3675.4, 1136.1], [3726.2, 1136.1], [3726.2, 1161.5], [3675.4, 1161.5], [3650.0, 1161.5], [3650.0, 1186.9], [3675.4, 1186.9], [3726.2, 1186.9], [3586.5, 1199.6], [3561.1, 1199.6], [3650.0, 1212.3], [3675.4, 1212.3], [3726.2, 1212.3], [3726.2, 1237.7], [3675.4, 1237.7], [3650.0, 1237.7], [3650.0, 1263.1], [3675.4, 1263.1], [3726.2, 1263.1], [3726.2, 1288.5], [3675.4, 1288.5], [3650.0, 1288.5], [3586.5, 1301.2], [3561.1, 1301.2], [3650.0, 1313.9], [3675.4, 1313.9], [3726.2, 1313.9], [3726.2, 1339.3], [3675.4, 1339.3], [3650.0, 1339.3], [3650.0, 1364.7], [3675.4, 1364.7], [3726.2, 1364.7], [3726.2, 1390.1], [3675.4, 1390.1], [3650.0, 1390.1], [3650.0, 1415.5], [3675.4, 1415.5], [3726.2, 1415.5], [3726.2, 1440.9], [3675.4, 1440.9], [3650.0, 1440.9], [3650.0, 1466.3], [3675.4, 1466.3], [3726.2, 1466.3], [3726.2, 1491.7], [3675.4, 1491.7], [3650.0,
1491.7], [3650.0, 1517.1], [3675.4, 1517.1], [3726.2, 1517.1], [3726.2, 1542.5], [3675.4, 1542.5], [3650.0, 1542.5], [3573.8, 1548.9], [3548.4, 1548.9], [3650.0, 1567.9], [3675.4, 1567.9], [3726.2, 1567.9], [3726.2, 1593.3], [3675.4, 1593.3], [3650.0, 1593.3], [3650.0, 1618.7], [3675.4, 1618.7], [3726.2, 1618.7], [3726.2, 1644.1], [3675.4, 1644.1], [3650.0, 1644.1], [3726.2, 1669.5], [3675.4, 1669.5], [3650.0, 1669.5], [3599.2, 1669.5], [3497.6, 1669.5], [3497.6, 1694.9], [3599.2, 1694.9], [3599.2, 1720.3], [3497.6, 1720.3]]

View File

@ -0,0 +1,3 @@
[[22, 22], [36, 26], [21, 45], [45, 35], [55, 20], [33, 34], [50, 50], [55, 45], [26, 59], [40, 66], [55, 65], [35, 51], [62, 35], [62, 57], [62, 24], [21, 36], [33, 44], [9, 56], [62, 48], [66, 14],
[44, 13], [26, 13], [11, 28], [7, 43], [17, 64], [41, 46], [55, 34], [35, 16], [52, 26], [43, 26], [31, 76], [22, 53], [26, 29], [50, 40], [55, 50], [54, 10], [60, 15], [47, 66], [30, 60], [30, 50], [12, 17], [15, 14], [16, 19], [21, 48], [50, 30], [51, 42], [50, 15], [48, 21], [12, 38], [15, 56], [29, 39], [54, 38], [55, 57], [67, 41], [10, 70], [6, 25], [65, 27], [40, 60], [70, 64], [64, 4], [36, 6], [30, 20], [20, 30], [15, 5], [50, 70], [57, 72], [45, 42], [38, 33], [50, 4], [66, 8], [59,
5], [35, 60], [27, 24], [40, 20], [40, 37], [40, 40]]

View File

@ -0,0 +1,33 @@
import matplotlib.pyplot as plt
# Liste pour stocker les coordonnées des points cliqués
points = []
def onclick(event):
global points
# Ajouter le point cliqué à la liste
points.append([int(event.xdata), int(event.ydata)])
# Afficher le point sur le graphique
plt.plot(event.xdata, event.ydata, 'ro')
plt.draw() # Redessiner le graphique
# Créer un graphique vierge de 1000 par 1000
fig, ax = plt.subplots(figsize=(10,10))
plt.xlim(0, 1000)
plt.ylim(0, 1000)
# Connecter le gestionnaire d'événements au graphique
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
# Afficher les points cliqués
for point in points:
print(f"Ville à la position {point}")
# Si vous voulez avoir les positions dans une liste, vous pouvez le faire comme suit
print(points)
input()

View File

@ -20,7 +20,7 @@ class AntColony:
def choose_next_city(self, ant):
unvisited_cities = [i for i in range(self.n) if i not in ant]
probabilities = [self.pheromones[ant[-1]][i] ** self.alpha * ((1 / self.distance(self.cities[ant[-1]], self.cities[i])) ** self.beta) for i in unvisited_cities]
probabilities = [self.pheromones[ant[-1]][i] ** self.alpha * ((1 / distance(self.cities[ant[-1]], self.cities[i])) ** self.beta) for i in unvisited_cities]
total = sum(probabilities)
if total == 0:
probabilities = [1 / len(unvisited_cities) for _ in unvisited_cities]
@ -29,7 +29,7 @@ class AntColony:
return np.random.choice(unvisited_cities, p=probabilities)
def update_pheromones(self, ant):
pheromones_delta = self.intensification / self.total_distance([self.cities[i] for i in ant])
pheromones_delta = self.intensification / total_distance([self.cities[i] for i in ant])
for i in range(len(ant) - 1):
self.pheromones[ant[i]][ant[i+1]] += pheromones_delta
@ -42,7 +42,7 @@ class AntColony:
for ant in ants:
for _ in range(self.n - 1):
ant.append(self.choose_next_city(ant))
ant_distance = self.total_distance([self.cities[i] for i in ant])
ant_distance = total_distance([self.cities[i] for i in ant])
if ant_distance < best_distance:
best_distance = ant_distance
best_ant = ant.copy()

0
tests/libs/elbow.py Normal file
View File

View File

@ -0,0 +1,46 @@
import math, random
def distance(city1, city2):
return math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2)
def total_distance(cities):
return sum([distance(cities[i - 1], cities[i]) for i in range(len(cities))])
class SimulatedAnnealing:
def __init__(self, cities, temperature=10000, cooling_rate=0.9999, temperature_ok=0.001):
self.cities = cities
self.temperature = temperature
self.cooling_rate = cooling_rate
self.temperature_ok = temperature_ok
self.distances = []
self.temperatures = []
def run(self):
interration = 0
current_solution = self.cities.copy()
best_solution = self.cities.copy()
while self.temperature > self.temperature_ok:
new_solution = current_solution.copy()
# Swap two cities in the route
i = random.randint(0, len(new_solution) - 1)
j = random.randint(0, len(new_solution) - 1)
new_solution[i], new_solution[j] = new_solution[j], new_solution[i]
# Calculate the acceptance probability
current_energy = total_distance(current_solution)
new_energy = total_distance(new_solution)
delta = new_energy - current_energy
if delta < 0 or random.random() < math.exp(-delta / self.temperature):
current_solution = new_solution
if total_distance(current_solution) < total_distance(best_solution):
best_solution = current_solution
if interration % 10 == 0:
self.distances.append(total_distance(current_solution))
# Cool down
self.temperature *= self.cooling_rate
interration += 1
# Print every 1000 iterations
if interration % 10 == 0:
print("Iteration", interration, "with distance", total_distance(current_solution))
return best_solution, self.distances