Merge branch 'Test'
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 52 KiB |
BIN
.assets/images/berlin52/stats_52berlin_aco_0.1_to_10_secs.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 101 KiB |
BIN
.assets/images/ch150/stats_ch150_aco_0.1_to_300_secs.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
.assets/images/eil76/stats_eil76_aco_0.1_to_10_secs.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
.assets/images/eil76/stats_eil76_aco_0.1_to_10_secs_beta_2.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
.assets/images/stats_aco_alpha1-2_beta2-5.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
1293
Projet_algo.ipynb
411
Projet_algo_french.ipynb
Normal 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
|
After Width: | Height: | Size: 13 KiB |
BIN
cluster_0.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
cluster_1.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
evolution_cluster_0.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
evolution_cluster_1.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
@ -3,67 +3,22 @@ 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
|
||||
|
||||
@ -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()
|
||||
111
tests/04_cluster_ant_colony_no_animation_elbow_algo.py
Normal 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()
|
||||
@ -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)]
|
||||
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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()
|
||||
@ -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()
|
||||
@ -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()
|
||||
@ -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')
|
||||
|
||||
@ -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()
|
||||
76
tests/103_analyse_aco_alpha_beta.py
Normal 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()
|
||||
82
tests/104_analyse_aco_compare_citites.py
Normal 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()
|
||||
@ -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]]
|
||||
@ -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]]
|
||||
@ -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']]
|
||||
@ -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']]
|
||||
55
tests/data_sample/ALL_tsp/att48.opt.tour
Normal 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
|
||||
55
tests/data_sample/ALL_tsp/att48.tsp
Normal 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
|
||||
157
tests/data_sample/ALL_tsp/ch150.opt.tour
Normal 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
|
||||
1662
tests/data_sample/ALL_tsp/d1655.tsp
Normal file
83
tests/data_sample/ALL_tsp/eil76.opt.tour
Normal 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
|
||||
2
tests/data_sample/a280_cities_minimum_2579.txt
Normal 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]]
|
||||
1
tests/data_sample/att48_cities_minimum_33523.txt
Normal 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]]
|
||||
3
tests/data_sample/berlin52_cities_minimum_7542.txt
Normal 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]]
|
||||
23
tests/data_sample/d1655_cities_minimum_62128.txt
Normal 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]]
|
||||
3
tests/data_sample/eil76_cities_minimum_538.txt
Normal 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]]
|
||||
33
tests/data_sample/generate_cities_with_matplotlib.py
Normal 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()
|
||||
@ -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
46
tests/libs/simulated_annealing_stats.py
Normal 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
|
||||