diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..436f0ff --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.analysis.extraPaths": [ + "./tests" + ] +} \ No newline at end of file diff --git a/Projet_algo.ipynb b/Projet_algo.ipynb index 594083d..585b4a9 100644 --- a/Projet_algo.ipynb +++ b/Projet_algo.ipynb @@ -1657,6 +1657,125 @@ "plt.ylabel(\"Optimal Cost\")\n", "plt.show()" ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "4fcf097c", + "metadata": {}, + "source": [ + "## La méthode du coude " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "14189433", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ca2ef6d8", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n", + "c:\\Python310\\lib\\site-packages\\sklearn\\cluster\\_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning\n", + " warnings.warn(\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from sklearn.cluster import KMeans\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import random, time, math\n", + "\n", + "# Function to generate random coordinates for cities\n", + "def generate_cities(nb, max_coords=1000):\n", + " return [random.sample(range(max_coords), 2) for _ in range(nb)]\n", + "\n", + "nb_ville = 100 # number of cities\n", + "max_coords = 1000 # maximum value for coordinates\n", + "\n", + "max_clusters = 20 # maximum number of clusters\n", + "\n", + "start_time_generate = time.time()\n", + "cities = generate_cities(nb_ville, max_coords) # generate cities\n", + "stop_time_generate = time.time()\n", + "\n", + "# Function to apply the elbow method for determining optimal number of clusters\n", + "def elbow_method(cities, max_clusters):\n", + " inertias = [] # list to store the inertia for each number of clusters\n", + " for i in range(1, max_clusters+1):\n", + " # Apply KMeans clustering\n", + " kmeans = KMeans(n_clusters=i, random_state=0).fit(cities)\n", + " # Append the inertia (sum of squared distances to closest centroid) to the list\n", + " inertias.append(kmeans.inertia_)\n", + " return inertias\n", + "\n", + "cities = generate_cities(nb_ville, max_coords) # generate cities \n", + "inertias = elbow_method(cities, max_clusters) # apply elbow method\n", + "\n", + "plt.figure()\n", + "plt.plot(range(1, len(inertias)+1), inertias, marker='o') # plot the inertia for each number of clusters\n", + "plt.title('Elbow Method') # set title of the plot\n", + "plt.xlabel('Number of clusters') # set x-axis label\n", + "plt.ylabel('Inertia') # set y-axis label\n", + "plt.show() # display the plot" + ] } ], "metadata": { @@ -1675,7 +1794,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.10.2" } }, "nbformat": 4, diff --git a/tests/04_cluster_ant_colony_no_animation_elbow_algo.py b/tests/04_cluster_ant_colony_no_animation_elbow_algo.py index d6581a4..3c57c87 100644 --- a/tests/04_cluster_ant_colony_no_animation_elbow_algo.py +++ b/tests/04_cluster_ant_colony_no_animation_elbow_algo.py @@ -42,70 +42,3 @@ 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()