2020-10-01 16:03:04 +00:00
|
|
|
{
|
|
|
|
"cells": [
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {
|
|
|
|
"collapsed": true,
|
|
|
|
"pycharm": {
|
|
|
|
"name": "#%% md\n"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"source": [
|
2020-11-01 18:24:26 +00:00
|
|
|
"## Second Lab\n",
|
|
|
|
"\n",
|
|
|
|
"What we are going to do today:\n",
|
|
|
|
"- Recap of the previous Lab\n",
|
|
|
|
"- Define the nearest neighbor method and use it\n",
|
|
|
|
"- Define the Best Nearest Neighbors and use it \n",
|
|
|
|
"- Define the Multi Fragment and use it\n",
|
|
|
|
"- Finally compare these Constructive Methods"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"This cell below is simply importing some useful stuff for later"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 1,
|
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"import glob\n",
|
|
|
|
"import numpy as np\n",
|
|
|
|
"from matplotlib import pyplot as plt\n",
|
2020-11-22 19:12:54 +00:00
|
|
|
"\n",
|
2020-11-01 18:24:26 +00:00
|
|
|
"from time import time as t"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"## Recap\n",
|
|
|
|
"### The problems\n",
|
|
|
|
"As we saw last time, we have 12 problems and two have an optimal solution"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 2,
|
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"- ch130.tsp\n",
|
|
|
|
"- d198.tsp\n",
|
|
|
|
"- eil76.tsp\n",
|
|
|
|
"- fl1577.tsp\n",
|
|
|
|
"- kroA100.tsp\n",
|
|
|
|
"- lin318.tsp\n",
|
|
|
|
"- pcb442.tsp\n",
|
|
|
|
"- pr439.tsp\n",
|
|
|
|
"- rat783.tsp\n",
|
|
|
|
"- u1060.tsp\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"problems = glob.glob('../problems/*.tsp')\n",
|
|
|
|
"for prob in problems:\n",
|
|
|
|
" if prob in [\"../problems/eil76.tsp\", \"../problems/kroA100.tsp\"]:\n",
|
|
|
|
" print(f\"- {prob[12:]} with opt\", sep='\\t')\n",
|
|
|
|
" else:\n",
|
|
|
|
" print(f\"- {prob[12:]}\", sep='\\t')"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"#### ProblemInstance Class\n",
|
|
|
|
"Last time we implemented an ProblemInstance class that we can use to load a problem. "
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 3,
|
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"from src.io_tsp import ProblemInstance"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 6,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
"#############################\n",
|
|
|
|
"name: eil76\n",
|
|
|
|
"nPoints: 76\n",
|
|
|
|
"best_sol: 538.0\n",
|
|
|
|
"exist optimal: True\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"image/png": "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
|
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 576x576 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {
|
|
|
|
"needs_background": "light"
|
|
|
|
},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"[[ 0. 15. 23. ... 18. 23. 25.]\n",
|
|
|
|
" [15. 0. 24. ... 7. 12. 15.]\n",
|
|
|
|
" [23. 24. 0. ... 31. 21. 20.]\n",
|
|
|
|
" ...\n",
|
|
|
|
" [18. 7. 31. ... 0. 17. 20.]\n",
|
|
|
|
" [23. 12. 21. ... 17. 0. 3.]\n",
|
|
|
|
" [25. 15. 20. ... 20. 3. 0.]]\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"example_problem = \"../problems/eil76.tsp\"\n",
|
|
|
|
"p_inst = ProblemInstance(example_problem)\n",
|
|
|
|
"p_inst.print_info()\n",
|
|
|
|
"p_inst.plot_data()\n",
|
|
|
|
"print(p_inst.dist_matrix)"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"### TSPSolver Class\n",
|
|
|
|
"Even here, instead of reimplementing the class everytime, we can import the one I prepared before.\n",
|
|
|
|
"This implementation is ready to receive a lot of different types of problems"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 4,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"from src.TSP_solver import TSPSolver\n",
|
|
|
|
"from src.constructive_algorithms import random_method"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"The class implements the following methods:\n",
|
|
|
|
"..."
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 7,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"### solving with ['random'] ####\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
2020-11-22 19:12:54 +00:00
|
|
|
"image/png": "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
|
2020-11-01 18:24:26 +00:00
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 576x576 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {
|
|
|
|
"needs_background": "light"
|
|
|
|
},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2020-11-22 19:12:54 +00:00
|
|
|
"best solution with len 2665.0 \n",
|
2020-11-01 18:24:26 +00:00
|
|
|
"with a total time of 0.0 seconds\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"available_solvers = {\"random\": random_method}\n",
|
|
|
|
"\n",
|
|
|
|
"solver = TSPSolver(\"random\", p_inst, available_solvers)\n",
|
|
|
|
"start = t()\n",
|
|
|
|
"solver.compute_solution(return_value=False, verbose=True)\n",
|
|
|
|
"end = t()\n",
|
|
|
|
"\n",
|
|
|
|
"solver.plot_solution()\n",
|
|
|
|
"print(f\"best solution with len {solver.found_length} \\nwith a total time of {np.round(end - start, 5)} seconds\")"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"### Let's analyse the performances of the random Method\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 8,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {
|
2020-11-22 19:12:54 +00:00
|
|
|
"scrolled": false
|
2020-11-01 18:24:26 +00:00
|
|
|
},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
2020-11-22 19:12:54 +00:00
|
|
|
"image/png": "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
|
2020-11-01 18:24:26 +00:00
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 800x600 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2020-11-22 19:12:54 +00:00
|
|
|
"best solution 2160.0 on 1000 trials,\n",
|
|
|
|
"with a total time of 0.59 seconds\n"
|
2020-11-01 18:24:26 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"number_of_trials = 1000\n",
|
|
|
|
"found_lens = []\n",
|
|
|
|
"start = t()\n",
|
|
|
|
"for _ in range(number_of_trials):\n",
|
|
|
|
" solver.compute_solution(return_value=False, verbose=False)\n",
|
|
|
|
" found_lens.append(solver.found_length)\n",
|
|
|
|
"end = t()\n",
|
|
|
|
"fig=plt.figure(figsize=(8,6), dpi= 100, facecolor='w', edgecolor='k')\n",
|
|
|
|
"plt.ylabel(\"Solution Length\")\n",
|
|
|
|
"plt.xlabel(\"Tries\")\n",
|
|
|
|
"plt.plot(found_lens, \"*\",label=\"Random\")\n",
|
|
|
|
"plt.plot(np.ones(number_of_trials)*p_inst.best_sol, \"r-\",label=\"Optimal\")\n",
|
|
|
|
"plt.legend(loc=\"center right\")\n",
|
|
|
|
"plt.show()\n",
|
|
|
|
"\n",
|
|
|
|
"print(f\"best solution {min(found_lens)} on {number_of_trials} trials,\\nwith a total time of {np.round(end - start, 2)} seconds\")"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"-------------\n",
|
|
|
|
"## Constructive Algorithm\n",
|
|
|
|
"### Nearest Neighbor Method"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 9,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
2020-11-22 19:12:54 +00:00
|
|
|
"def alessio_marco_nn(instance_, starting_node=0): \n",
|
|
|
|
" # TODO\n",
|
|
|
|
" tour=[starting_node]\n",
|
|
|
|
" for i in range(instance_.nPoints):\n",
|
|
|
|
" next_node = np.argsort(instance_.dist_matrix[i])[0]\n",
|
|
|
|
" index=0\n",
|
|
|
|
" while next_node in tour:\n",
|
|
|
|
" index+=1\n",
|
|
|
|
" if index<instance_.nPoints:\n",
|
|
|
|
" next_node = np.argsort(instance_.dist_matrix[i])[index]\n",
|
|
|
|
" else:\n",
|
|
|
|
" break\n",
|
|
|
|
" tour.append(next_node)\n",
|
|
|
|
" # [...]\n",
|
|
|
|
" tour.append(starting_node)\n",
|
|
|
|
" return np.array(tour) \n",
|
|
|
|
"\n",
|
2020-11-01 18:24:26 +00:00
|
|
|
"def nn( instance_, starting_node=0): \n",
|
|
|
|
" # TODO\n",
|
2020-11-22 19:12:54 +00:00
|
|
|
" dist_matrix = np.copy(instance_.dist_matrix)\n",
|
|
|
|
" n = int(instance_.nPoints)\n",
|
|
|
|
" node = starting_node\n",
|
|
|
|
" tour = [node]\n",
|
|
|
|
" # Suggestion ^^^^\n",
|
|
|
|
" for _ in range(n - 1):\n",
|
|
|
|
" for new_node in np.argsort(dist_matrix[node]):\n",
|
|
|
|
" if new_node not in tour:\n",
|
|
|
|
" tour.append(new_node)\n",
|
|
|
|
" node = new_node\n",
|
|
|
|
" break\n",
|
2020-11-01 18:24:26 +00:00
|
|
|
" # [...]\n",
|
|
|
|
" tour.append(starting_node)\n",
|
|
|
|
" return np.array(tour)"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2020-11-22 19:12:54 +00:00
|
|
|
"execution_count": 10,
|
2020-11-01 18:24:26 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"### solving with ['nn'] ####\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"image/png": "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
|
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 576x576 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {
|
|
|
|
"needs_background": "light"
|
|
|
|
},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"best solution with len 680.0 \n",
|
2020-11-22 19:12:54 +00:00
|
|
|
"with a total time of 0.0378 seconds\n"
|
2020-11-01 18:24:26 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"available_solvers = {\"random\": random_method,\n",
|
2020-11-22 19:12:54 +00:00
|
|
|
" \"amnn\":alessio_marco_nn,\n",
|
|
|
|
" \"nn\":nn}\n",
|
2020-11-01 18:24:26 +00:00
|
|
|
"\n",
|
|
|
|
"solver = TSPSolver(\"nn\", p_inst, available_solvers)\n",
|
|
|
|
"start = t()\n",
|
|
|
|
"solver.compute_solution(return_value=False, verbose=True)\n",
|
|
|
|
"end = t()\n",
|
|
|
|
"\n",
|
|
|
|
"solver.plot_solution()\n",
|
|
|
|
"print(f\"best solution with len {solver.found_length} \\nwith a total time of {np.round(end - start, 5)} seconds\")"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {
|
|
|
|
"id": "A25UdIeTJOp8"
|
|
|
|
},
|
|
|
|
"source": [
|
|
|
|
"### Best Nearest Neighbors"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 10,
|
|
|
|
"metadata": {
|
|
|
|
"id": "i_cC5eA-XT0B"
|
|
|
|
},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"def best_nn(instance):\n",
|
|
|
|
" # TODO\n",
|
|
|
|
" \n",
|
|
|
|
" # [...]\n",
|
|
|
|
" return solution\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 11,
|
|
|
|
"metadata": {
|
|
|
|
"colab": {
|
|
|
|
"base_uri": "https://localhost:8080/",
|
|
|
|
"height": 534
|
|
|
|
},
|
|
|
|
"id": "lRAGk5zEXW0U",
|
|
|
|
"outputId": "493f692e-ef0c-4a94-dfc9-6726e9a5ac43"
|
|
|
|
},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"### solving with ['best_nn'] ####\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"image/png": "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
|
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 576x576 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {
|
|
|
|
"needs_background": "light"
|
|
|
|
},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"best solution with len 601.0 \n",
|
|
|
|
"with a total time of 0.05389 seconds\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"available_solvers = {\"random\": random_method,\n",
|
|
|
|
" \"nn\": nn,\n",
|
|
|
|
" \"best_nn\": best_nn}\n",
|
|
|
|
"\n",
|
|
|
|
"solver = TSPSolver(\"best_nn\", p_inst, available_solvers)\n",
|
|
|
|
"start = t()\n",
|
|
|
|
"solver.compute_solution(return_value=False, verbose=True)\n",
|
|
|
|
"end = t()\n",
|
|
|
|
"\n",
|
|
|
|
"solver.plot_solution()\n",
|
|
|
|
"print(f\"best solution with len {solver.found_length} \\nwith a total time of {np.round(end - start, 5)} seconds\")"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {
|
|
|
|
"id": "uXtOOk25XXpR"
|
|
|
|
},
|
|
|
|
"source": [
|
|
|
|
"### Multi Fragment"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 12,
|
|
|
|
"metadata": {
|
|
|
|
"id": "1oo-Zv7vXdTq"
|
|
|
|
},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"def check_if_edge_available(n1, n2, sol):\n",
|
|
|
|
" return (len(sol[str(n1)]) < 2) and (len(sol[str(n2)]) < 2)\n",
|
|
|
|
"\n",
|
|
|
|
"def check_if_not_close(edge_to_append, sol):\n",
|
|
|
|
" n1, n2 = edge_to_append\n",
|
|
|
|
" from_city = n2\n",
|
|
|
|
" if len(sol[str(from_city)]) == 0:\n",
|
|
|
|
" return True\n",
|
|
|
|
" partial_tour = [from_city]\n",
|
|
|
|
" iter_num = 0\n",
|
|
|
|
" while True:\n",
|
|
|
|
" if len(sol[str(from_city)]) == 1:\n",
|
|
|
|
" if from_city == n1:\n",
|
|
|
|
" return_value = False\n",
|
|
|
|
" break\n",
|
|
|
|
" elif iter_num > 1:\n",
|
|
|
|
" return_value = True\n",
|
|
|
|
" break\n",
|
|
|
|
" else:\n",
|
|
|
|
" from_city = sol[str(from_city)][0]\n",
|
|
|
|
" partial_tour.append(from_city)\n",
|
|
|
|
" iter_num += 1\n",
|
|
|
|
" else:\n",
|
|
|
|
" for node_connected in sol[str(from_city)]:\n",
|
|
|
|
" if node_connected not in partial_tour:\n",
|
|
|
|
" from_city = node_connected\n",
|
|
|
|
" partial_tour.append(node_connected)\n",
|
|
|
|
" iter_num +=1\n",
|
|
|
|
" return return_value\n",
|
|
|
|
"\n",
|
|
|
|
"def create_solution(start_sol, sol):\n",
|
|
|
|
" assert len(start_sol)==2, \"too many cities with just one link\"\n",
|
|
|
|
" n1, n2 = start_sol\n",
|
|
|
|
" from_city = n2\n",
|
|
|
|
" sol_list = [n1, n2]\n",
|
|
|
|
" iter_num = 0\n",
|
|
|
|
" while iter_num <300:\n",
|
|
|
|
" for node_connected in sol[str(from_city)]:\n",
|
|
|
|
" iter_num += 1\n",
|
|
|
|
" if node_connected not in sol_list:\n",
|
|
|
|
" from_city = node_connected\n",
|
|
|
|
" sol_list.append(node_connected)\n",
|
|
|
|
" sol_list.append(n1)\n",
|
|
|
|
" return sol_list\n",
|
|
|
|
"\n",
|
|
|
|
"def mf(instance):\n",
|
|
|
|
" mat = np.copy(instance.dist_matrix)\n",
|
|
|
|
" mat = np.triu(mat)\n",
|
|
|
|
" mat[mat == 0] = 100000\n",
|
|
|
|
" # TODO\n",
|
|
|
|
" \n",
|
|
|
|
" #[...]\n",
|
|
|
|
" return create_solution(start_list, solution)\n",
|
|
|
|
"\n",
|
|
|
|
"\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 13,
|
|
|
|
"metadata": {
|
|
|
|
"colab": {
|
|
|
|
"base_uri": "https://localhost:8080/",
|
|
|
|
"height": 516
|
|
|
|
},
|
|
|
|
"id": "-iTyocncXg0d",
|
|
|
|
"outputId": "9a48f544-d4ef-4f57-f786-789006ca5432"
|
|
|
|
},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"### solving with ['multi_fragment'] ####\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"image/png": "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
|
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 576x576 with 1 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {
|
|
|
|
"needs_background": "light"
|
|
|
|
},
|
|
|
|
"output_type": "display_data"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"best solution with len 600.0 \n",
|
|
|
|
"with a total time of 0.00597 seconds\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"available_solvers = {\"random\": random_method,\n",
|
|
|
|
" \"nn\":nn,\n",
|
|
|
|
" \"best_nn\":best_nn,\n",
|
|
|
|
" \"multi_fragment\": mf\n",
|
|
|
|
" }\n",
|
|
|
|
"\n",
|
|
|
|
"solver = TSPSolver(\"multi_fragment\", p_inst, available_solvers)\n",
|
|
|
|
"start = t()\n",
|
|
|
|
"solver.compute_solution(return_value=False, verbose=True)\n",
|
|
|
|
"end = t()\n",
|
|
|
|
"\n",
|
|
|
|
"solver.plot_solution()\n",
|
|
|
|
"print(f\"best solution with len {solver.found_length} \\nwith a total time of {np.round(end - start, 5)} seconds\")"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {
|
|
|
|
"id": "lp9RXLX9Ye1M"
|
|
|
|
},
|
|
|
|
"source": [
|
|
|
|
"### Comparison Constructive methods"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 23,
|
|
|
|
"metadata": {
|
|
|
|
"colab": {
|
|
|
|
"base_uri": "https://localhost:8080/",
|
|
|
|
"height": 239
|
|
|
|
},
|
|
|
|
"id": "jZ4R8UZgYed7",
|
|
|
|
"outputId": "28475799-f823-42e9-91ad-b9c3ed029bdd",
|
|
|
|
"scrolled": true
|
|
|
|
},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stderr",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"100%|██████████| 4/4 [00:01<00:00, 2.94it/s, using multi_fragment for d198] \n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"from time import time as t\n",
|
|
|
|
"import pandas as pd\n",
|
|
|
|
"from tqdm import tqdm\n",
|
|
|
|
"\n",
|
|
|
|
"available_solvers = {\"random\": random_method,\n",
|
|
|
|
" \"nn\":nn,\n",
|
|
|
|
" \"best_nn\":best_nn,\n",
|
|
|
|
" \"multi_fragment\": mf\n",
|
|
|
|
" }\n",
|
|
|
|
"\n",
|
|
|
|
"show_plots = False\n",
|
|
|
|
"verbose = False\n",
|
|
|
|
"problems = [\"../problems/eil76.tsp\", \"../problems/kroA100.tsp\", \"../problems/ch130.tsp\", \"../problems/d198.tsp\"]\n",
|
|
|
|
"methods = available_solvers.keys()\n",
|
|
|
|
"results = []\n",
|
|
|
|
"index = []\n",
|
|
|
|
"with tqdm(problems) as tq:\n",
|
|
|
|
" for filename in tq:\n",
|
|
|
|
" p_inst = ProblemInstance(filename)\n",
|
|
|
|
" if verbose:\n",
|
|
|
|
" print(\"\\n\\n#############################\")\n",
|
|
|
|
" p_inst.print_info()\n",
|
|
|
|
" if show_plots:\n",
|
|
|
|
" p_inst.plot_data()\n",
|
|
|
|
"\n",
|
|
|
|
" for method in methods:\n",
|
|
|
|
" tq.set_postfix_str(f\"using {method} for {p_inst.name}\")\n",
|
|
|
|
" solver = TSPSolver(method, p_inst, available_solvers)\n",
|
|
|
|
" start = t()\n",
|
|
|
|
" solver.compute_solution(return_value=False, verbose=verbose)\n",
|
|
|
|
" end = t()\n",
|
|
|
|
" if verbose: \n",
|
|
|
|
" print(f\"the total length for the solution found is {solver.found_length}\",\n",
|
|
|
|
" f\"while the optimal length is {p_inst.best_sol}\",\n",
|
|
|
|
" f\"the gap is {solver.gap} %\",\n",
|
|
|
|
" f\"the solution is found in {np.round(end - start, 5)} seconds\",sep=\"\\n\")\n",
|
|
|
|
" index.append((filename[12:], method))\n",
|
|
|
|
" results.append([solver.found_length, p_inst.best_sol, solver.gap, end - start])\n",
|
|
|
|
"\n",
|
|
|
|
" if show_plots:\n",
|
|
|
|
" solver.plot_solution()\n",
|
|
|
|
"\n",
|
|
|
|
" if p_inst.exist_opt and show_plots:\n",
|
|
|
|
" solver = TSPSolver(\"optimal\", p_inst)\n",
|
|
|
|
" solver.solved = True\n",
|
|
|
|
" solver.solution = np.concatenate([p_inst.optimal_tour, [p_inst.optimal_tour[0]]])\n",
|
|
|
|
" solver.plot_solution()\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
|
|
|
"execution_count": 24,
|
|
|
|
"metadata": {
|
|
|
|
"id": "v8iJZ1QtY6WM"
|
|
|
|
},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/html": [
|
|
|
|
"<div>\n",
|
|
|
|
"<style scoped>\n",
|
|
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
|
|
" vertical-align: middle;\n",
|
|
|
|
" }\n",
|
|
|
|
"\n",
|
|
|
|
" .dataframe tbody tr th {\n",
|
|
|
|
" vertical-align: top;\n",
|
|
|
|
" }\n",
|
|
|
|
"\n",
|
|
|
|
" .dataframe thead th {\n",
|
|
|
|
" text-align: right;\n",
|
|
|
|
" }\n",
|
|
|
|
"</style>\n",
|
|
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
|
|
" <thead>\n",
|
|
|
|
" <tr style=\"text-align: right;\">\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" <th>tour length</th>\n",
|
|
|
|
" <th>optimal solution</th>\n",
|
|
|
|
" <th>gap</th>\n",
|
|
|
|
" <th>time to solve</th>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>problem</th>\n",
|
|
|
|
" <th>method</th>\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" <th></th>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" </thead>\n",
|
|
|
|
" <tbody>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th rowspan=\"4\" valign=\"top\">eil76.tsp</th>\n",
|
|
|
|
" <th>random</th>\n",
|
|
|
|
" <td>2616.0</td>\n",
|
|
|
|
" <td>538.0</td>\n",
|
|
|
|
" <td>386.25</td>\n",
|
|
|
|
" <td>0.000970</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>nn</th>\n",
|
|
|
|
" <td>680.0</td>\n",
|
|
|
|
" <td>538.0</td>\n",
|
|
|
|
" <td>26.39</td>\n",
|
|
|
|
" <td>0.000997</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>best_nn</th>\n",
|
|
|
|
" <td>601.0</td>\n",
|
|
|
|
" <td>538.0</td>\n",
|
|
|
|
" <td>11.71</td>\n",
|
|
|
|
" <td>0.049906</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>multi_fragment</th>\n",
|
|
|
|
" <td>600.0</td>\n",
|
|
|
|
" <td>538.0</td>\n",
|
|
|
|
" <td>11.52</td>\n",
|
|
|
|
" <td>0.005983</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th rowspan=\"4\" valign=\"top\">kroA100.tsp</th>\n",
|
|
|
|
" <th>random</th>\n",
|
|
|
|
" <td>163891.0</td>\n",
|
|
|
|
" <td>21282.0</td>\n",
|
|
|
|
" <td>670.09</td>\n",
|
|
|
|
" <td>0.001030</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>nn</th>\n",
|
|
|
|
" <td>27807.0</td>\n",
|
|
|
|
" <td>21282.0</td>\n",
|
|
|
|
" <td>30.66</td>\n",
|
|
|
|
" <td>0.001961</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>best_nn</th>\n",
|
|
|
|
" <td>24815.0</td>\n",
|
|
|
|
" <td>21282.0</td>\n",
|
|
|
|
" <td>16.60</td>\n",
|
|
|
|
" <td>0.101760</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>multi_fragment</th>\n",
|
|
|
|
" <td>24287.0</td>\n",
|
|
|
|
" <td>21282.0</td>\n",
|
|
|
|
" <td>14.12</td>\n",
|
|
|
|
" <td>0.007005</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th rowspan=\"4\" valign=\"top\">ch130.tsp</th>\n",
|
|
|
|
" <th>random</th>\n",
|
|
|
|
" <td>44209.0</td>\n",
|
|
|
|
" <td>6110.0</td>\n",
|
|
|
|
" <td>623.55</td>\n",
|
|
|
|
" <td>0.001029</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>nn</th>\n",
|
|
|
|
" <td>7578.0</td>\n",
|
|
|
|
" <td>6110.0</td>\n",
|
|
|
|
" <td>24.03</td>\n",
|
|
|
|
" <td>0.002980</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>best_nn</th>\n",
|
|
|
|
" <td>6880.0</td>\n",
|
|
|
|
" <td>6110.0</td>\n",
|
|
|
|
" <td>12.60</td>\n",
|
|
|
|
" <td>0.206479</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>multi_fragment</th>\n",
|
|
|
|
" <td>7849.0</td>\n",
|
|
|
|
" <td>6110.0</td>\n",
|
|
|
|
" <td>28.46</td>\n",
|
|
|
|
" <td>0.017952</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th rowspan=\"4\" valign=\"top\">d198.tsp</th>\n",
|
|
|
|
" <th>random</th>\n",
|
|
|
|
" <td>188837.0</td>\n",
|
|
|
|
" <td>15780.0</td>\n",
|
|
|
|
" <td>1096.69</td>\n",
|
|
|
|
" <td>0.001047</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>nn</th>\n",
|
|
|
|
" <td>18975.0</td>\n",
|
|
|
|
" <td>15780.0</td>\n",
|
|
|
|
" <td>20.25</td>\n",
|
|
|
|
" <td>0.005039</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>best_nn</th>\n",
|
|
|
|
" <td>17565.0</td>\n",
|
|
|
|
" <td>15780.0</td>\n",
|
|
|
|
" <td>11.31</td>\n",
|
|
|
|
" <td>0.694035</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" <tr>\n",
|
|
|
|
" <th>multi_fragment</th>\n",
|
|
|
|
" <td>17111.0</td>\n",
|
|
|
|
" <td>15780.0</td>\n",
|
|
|
|
" <td>8.43</td>\n",
|
|
|
|
" <td>0.065004</td>\n",
|
|
|
|
" </tr>\n",
|
|
|
|
" </tbody>\n",
|
|
|
|
"</table>\n",
|
|
|
|
"</div>"
|
|
|
|
],
|
|
|
|
"text/plain": [
|
|
|
|
" tour length optimal solution gap \\\n",
|
|
|
|
"problem method \n",
|
|
|
|
"eil76.tsp random 2616.0 538.0 386.25 \n",
|
|
|
|
" nn 680.0 538.0 26.39 \n",
|
|
|
|
" best_nn 601.0 538.0 11.71 \n",
|
|
|
|
" multi_fragment 600.0 538.0 11.52 \n",
|
|
|
|
"kroA100.tsp random 163891.0 21282.0 670.09 \n",
|
|
|
|
" nn 27807.0 21282.0 30.66 \n",
|
|
|
|
" best_nn 24815.0 21282.0 16.60 \n",
|
|
|
|
" multi_fragment 24287.0 21282.0 14.12 \n",
|
|
|
|
"ch130.tsp random 44209.0 6110.0 623.55 \n",
|
|
|
|
" nn 7578.0 6110.0 24.03 \n",
|
|
|
|
" best_nn 6880.0 6110.0 12.60 \n",
|
|
|
|
" multi_fragment 7849.0 6110.0 28.46 \n",
|
|
|
|
"d198.tsp random 188837.0 15780.0 1096.69 \n",
|
|
|
|
" nn 18975.0 15780.0 20.25 \n",
|
|
|
|
" best_nn 17565.0 15780.0 11.31 \n",
|
|
|
|
" multi_fragment 17111.0 15780.0 8.43 \n",
|
|
|
|
"\n",
|
|
|
|
" time to solve \n",
|
|
|
|
"problem method \n",
|
|
|
|
"eil76.tsp random 0.000970 \n",
|
|
|
|
" nn 0.000997 \n",
|
|
|
|
" best_nn 0.049906 \n",
|
|
|
|
" multi_fragment 0.005983 \n",
|
|
|
|
"kroA100.tsp random 0.001030 \n",
|
|
|
|
" nn 0.001961 \n",
|
|
|
|
" best_nn 0.101760 \n",
|
|
|
|
" multi_fragment 0.007005 \n",
|
|
|
|
"ch130.tsp random 0.001029 \n",
|
|
|
|
" nn 0.002980 \n",
|
|
|
|
" best_nn 0.206479 \n",
|
|
|
|
" multi_fragment 0.017952 \n",
|
|
|
|
"d198.tsp random 0.001047 \n",
|
|
|
|
" nn 0.005039 \n",
|
|
|
|
" best_nn 0.694035 \n",
|
|
|
|
" multi_fragment 0.065004 "
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"execution_count": 24,
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "execute_result"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"index = pd.MultiIndex.from_tuples(index, names=['problem', 'method'])\n",
|
|
|
|
"\n",
|
|
|
|
"df = pd.DataFrame(results, index=index, columns=[\"tour length\", \"optimal solution\", \"gap\", \"time to solve\"])\n",
|
|
|
|
"df"
|
2020-10-01 16:03:04 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"metadata": {
|
|
|
|
"kernelspec": {
|
2020-11-01 18:24:26 +00:00
|
|
|
"display_name": "PyCharm (AI2020BsC)",
|
2020-10-01 16:03:04 +00:00
|
|
|
"language": "python",
|
2020-11-01 18:24:26 +00:00
|
|
|
"name": "pycharm-61970693"
|
2020-10-01 16:03:04 +00:00
|
|
|
},
|
|
|
|
"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.8.3"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"nbformat": 4,
|
|
|
|
"nbformat_minor": 1
|
2020-11-01 18:24:26 +00:00
|
|
|
}
|