{ "cells": [ { "cell_type": "code", "execution_count": 3, "id": "c5f11a3e", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import math\n", "\n", "import random\n", "random.seed()\n", "\n", "class WeightedUndirectedMatrixGraph:\n", " \n", " # initialize a weighted undirected adjacency-matrix graph with n nodes\n", " #\n", " def __init__(self, n):\n", " self._num_vertices = n\n", " self._adj_matrix = np.zeros((n, n))\n", " for i in range(n-1):\n", " for j in range(i+1, n):\n", " self._adj_matrix[i][j] = math.inf\n", " self._adj_matrix[j][i] = math.inf\n", " \n", " # returns the number of nodes\n", " #\n", " def get_num_vertices(self):\n", " return self._num_vertices\n", " \n", " # returns weight of the edge between i and j\n", " #\n", " def get_weight(self, i, j):\n", " return self._adj_matrix[i][j]\n", " \n", " # the path is a list of node IDs\n", " #\n", " def get_length_of_path(self, path):\n", " length = 0\n", " for i in range(len(path) - 1):\n", " length += self.get_weight(path[i], path[i+1])\n", " return length\n", " \n", " # print the adjacency matrix\n", " #\n", " def output(self):\n", " print(self._adj_matrix)\n", " \n", " # assign weight w to the edge between i and j (both ways)\n", " # i and j must be different, and both within range(n), and w must be zero or positive\n", " #\n", " def set_weight(self, i, j, w):\n", " if i == j or i < 0 or j < 0 or i >= self._num_vertices or j >= self._num_vertices or w < 0:\n", " print(\"Warning: Invalid input to the connect method. Ignoring.\")\n", " return\n", " self._adj_matrix[i][j] = w\n", " self._adj_matrix[j][i] = w\n", " \n", " # assign random weights to all edges\n", " #\n", " def randomize(self):\n", " for i in range(self._num_vertices - 1):\n", " for j in range(i+1, self._num_vertices):\n", " random_weight = 2**random.randrange(self._num_vertices // 2)\n", " random_weight += random.randrange(2**(self._num_vertices // 2) - 1)\n", " self.set_weight(i, j, random_weight)\n", " \n", " # solve the travelling salesman problem (TSP) by brute force\n", " #\n", " # this returns the shortest cycle that visits each node exactly once\n", " # (also referred to as the shortest Hamilton cycle in the graph:\n", " # A Hamilton cycle is a cycle that visits each node exactly once.)\n", " #\n", " def solve_TSP_brute_force(self):\n", " unvisited = {i for i in range(self._num_vertices)}\n", " unvisited.remove(0) # select node 0 as the initial and final node of the cycle\n", " \n", " # helper method that actually solves the TSP\n", " #\n", " shortest_cycle, travel_distance = self._TSP_brute_force(0, 0, unvisited)\n", " print(\"Brute-force TSP solver done comparing\", \\\n", " WeightedUndirectedMatrixGraph._num_attempts, \"cycles.\")\n", " WeightedUndirectedMatrixGraph._num_attempts = 0\n", " \n", " return shortest_cycle, travel_distance\n", " \n", " # unvisited_nodes is the set of unvisited nodes\n", " # initial_node is the initial node\n", " # present_node is the node that is presently visited\n", " #\n", " # the method returns the (shortest) remaining path\n", " # and the length (i.e., total weight) of the shortest remaining path\n", " #\n", " # the remaining path is written into the list backward, to exploit faster end-of-list\n", " # operations on a Python list; since this is a cycle in an undirected graph, it does not matter\n", " #\n", " def _TSP_brute_force(self, initial_node, present_node, unvisited_nodes):\n", " \n", " # if all nodes are visited, go back to the initial node\n", " #\n", " if len(unvisited_nodes) == 0:\n", " \n", " WeightedUndirectedMatrixGraph._num_attempts += 1\n", " if WeightedUndirectedMatrixGraph._num_attempts \\\n", " % WeightedUndirectedMatrixGraph._mod_status_output == 0:\n", " print(\"\\tChecked\", WeightedUndirectedMatrixGraph._num_attempts, \"cycles.\")\n", " \n", " return [initial_node, present_node], self.get_weight(initial_node, present_node)\n", " \n", " # check which of the optional next nodes yield the shortest remaining path\n", " #\n", " else:\n", " shortest_remaining_weight = math.inf\n", " shortest_remaining_path = []\n", " \n", " unvisited_nodes_copy = {i for i in unvisited_nodes}\n", " for v in unvisited_nodes_copy:\n", " unvisited_nodes.remove(v)\n", " v_path, v_weight = self._TSP_brute_force(initial_node, v, unvisited_nodes)\n", " v_path.append(present_node)\n", " v_weight += self.get_weight(v, present_node)\n", " unvisited_nodes.add(v)\n", " \n", " if v_weight < shortest_remaining_weight:\n", " shortest_remaining_weight = v_weight\n", " shortest_remaining_path = v_path\n", " return shortest_remaining_path, shortest_remaining_weight\n", " \n", " # static variable used to count number of cycles checked by the brute-force solver\n", " #\n", " _num_attempts = 0\n", " _mod_status_output = 2000000" ] }, { "cell_type": "code", "execution_count": 4, "id": "5b59c8df", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0. 40. 32. 24. 38. 9. 52. 39. 29. 35. 88. 60.]\n", " [40. 0. 21. 39. 28. 49. 69. 61. 45. 38. 53. 5.]\n", " [32. 21. 0. 50. 24. 59. 32. 40. 55. 38. 5. 24.]\n", " [24. 39. 50. 0. 71. 63. 27. 53. 14. 29. 14. 35.]\n", " [38. 28. 24. 71. 0. 46. 30. 6. 52. 14. 10. 13.]\n", " [ 9. 49. 59. 63. 46. 0. 16. 93. 39. 36. 23. 12.]\n", " [52. 69. 32. 27. 30. 16. 0. 83. 49. 51. 49. 44.]\n", " [39. 61. 40. 53. 6. 93. 83. 0. 13. 65. 57. 47.]\n", " [29. 45. 55. 14. 52. 39. 49. 13. 0. 60. 63. 57.]\n", " [35. 38. 38. 29. 14. 36. 51. 65. 60. 0. 55. 16.]\n", " [88. 53. 5. 14. 10. 23. 49. 57. 63. 55. 0. 37.]\n", " [60. 5. 24. 35. 13. 12. 44. 47. 57. 16. 37. 0.]]\n", "\n", "Path 0 -> 1 -> 2 has the length 61.0\n" ] } ], "source": [ "n = 12\n", "\n", "g = WeightedUndirectedMatrixGraph(n)\n", "g.randomize()\n", "\n", "g.output()\n", "\n", "print(\"\\nPath 0 -> 1 -> 2 has the length\", g.get_length_of_path([0, 1, 2]))" ] }, { "cell_type": "code", "execution_count": 5, "id": "61612fa5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Random cycle: [6, 8, 2, 0, 5, 1, 9, 3, 10, 11, 4, 7, 6]\n", "Length of the random cycle: 414.0\n" ] } ], "source": [ "import random\n", "\n", "# create a random cycle and determine its distance\n", "#\n", "random_cycle = list(range(n))\n", "random.shuffle(random_cycle)\n", "random_cycle.append(random_cycle[0])\n", "\n", "print(\"Random cycle:\", random_cycle)\n", "print(\"Length of the random cycle:\", g.get_length_of_path(random_cycle))" ] }, { "cell_type": "code", "execution_count": 6, "id": "0cb8416e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\tChecked 2000000 cycles.\n", "\tChecked 4000000 cycles.\n", "\tChecked 6000000 cycles.\n", "\tChecked 8000000 cycles.\n", "\tChecked 10000000 cycles.\n", "\tChecked 12000000 cycles.\n", "\tChecked 14000000 cycles.\n", "\tChecked 16000000 cycles.\n", "\tChecked 18000000 cycles.\n", "\tChecked 20000000 cycles.\n", "\tChecked 22000000 cycles.\n", "\tChecked 24000000 cycles.\n", "\tChecked 26000000 cycles.\n", "\tChecked 28000000 cycles.\n", "\tChecked 30000000 cycles.\n", "\tChecked 32000000 cycles.\n", "\tChecked 34000000 cycles.\n", "\tChecked 36000000 cycles.\n", "\tChecked 38000000 cycles.\n", "Brute-force TSP solver done comparing 39916800 cycles.\n" ] } ], "source": [ "# call the TSP solver\n", "#\n", "salesman_path, salesman_travelling_distance = g.solve_TSP_brute_force()" ] }, { "cell_type": "code", "execution_count": 42, "id": "91c44d27", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Solution of the TSP: [0, 8, 7, 4, 9, 11, 1, 2, 10, 3, 6, 5, 0]\n", "Minimum travel distance: 175.0\n", "\n", "Validate by computing the total length of the cycle: 175.0\n" ] } ], "source": [ "print(\"\\nSolution of the TSP:\", salesman_path)\n", "print(\"Minimum travel distance:\", salesman_travelling_distance)\n", "\n", "print(\"\\nValidate by computing the total length of the cycle:\", g.get_length_of_path(salesman_path))" ] }, { "cell_type": "code", "execution_count": 46, "id": "94b547dc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sample sizes: [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88, 96, 104, 112, 120, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 18432, 20480, 22528, 24576, 26624, 28672, 30720, 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440, 65536, 73728, 81920, 90112, 98304, 106496, 114688, 122880, 131072, 147456, 163840, 180224, 196608, 212992, 229376, 245760, 262144, 294912, 327680, 360448, 393216, 425984, 458752, 491520]\n" ] } ], "source": [ "sample_sizes = []\n", "for i in range(16):\n", " for j in range(8, 16):\n", " sample_sizes.append(j * 2**i)\n", "print(\"sample sizes:\", sample_sizes)\n" ] }, { "cell_type": "code", "execution_count": 47, "id": "fcb44a13", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "i = 262144 \t\tsize = 200.0 \n", "\t\t\t [9, 1, 11, 4, 7, 8, 3, 10, 2, 6, 5, 0, 9]\n", "i = 524288 \t\tsize = 200.0 \n", "\t\t\t [9, 1, 11, 4, 7, 8, 3, 10, 2, 6, 5, 0, 9]\n", "i = 786432 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 1048576 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 1310720 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 1572864 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 1835008 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 2097152 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 2359296 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 2621440 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 2883584 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 3145728 \t\tsize = 196.0 \n", "\t\t\t [9, 0, 5, 6, 11, 1, 2, 10, 3, 8, 7, 4, 9]\n", "i = 3407872 \t\tsize = 190.0 \n", "\t\t\t [9, 6, 5, 0, 3, 8, 7, 4, 10, 2, 1, 11, 9]\n", "i = 3670016 \t\tsize = 190.0 \n", "\t\t\t [9, 6, 5, 0, 3, 8, 7, 4, 10, 2, 1, 11, 9]\n", "i = 3932160 \t\tsize = 190.0 \n", "\t\t\t [9, 6, 5, 0, 3, 8, 7, 4, 10, 2, 1, 11, 9]\n", "i = 4194304 \t\tsize = 190.0 \n", "\t\t\t [9, 6, 5, 0, 3, 8, 7, 4, 10, 2, 1, 11, 9]\n" ] } ], "source": [ "import math\n", "\n", "num_tests = 2**22\n", "\n", "overall_sampling_minimum = math.inf\n", "temporary_minimum = {i: math.inf for i in sample_sizes}\n", "sum_of_minima = {i: 0 for i in sample_sizes}\n", "count_of_minima = {i: 0 for i in sample_sizes}\n", "\n", "for i in range(1, num_tests+1):\n", " random_cycle = list(range(n))\n", " random.shuffle(random_cycle)\n", " random_cycle.append(random_cycle[0])\n", " present_cycle_length = g.get_length_of_path(random_cycle)\n", " \n", " for j in sample_sizes:\n", " if present_cycle_length < temporary_minimum[j]:\n", " temporary_minimum[j] = present_cycle_length\n", " if (i % j) == 0:\n", " sum_of_minima[j] += temporary_minimum[j]\n", " count_of_minima[j] += 1\n", " temporary_minimum[j] = math.inf\n", "\n", " if present_cycle_length < overall_sampling_minimum:\n", " overall_sampling_minimum = present_cycle_length\n", " best_found_path = random_cycle\n", " if (i % 2**18) == 0:\n", " print(\"i = \", i, \"\\t\\tsize = \", overall_sampling_minimum, \"\\n\\t\\t\\t\", best_found_path)\n" ] }, { "cell_type": "code", "execution_count": 49, "id": "5f6cdd12", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import seaborn as sbn\n", "import matplotlib.pyplot as plt\n", "\n", "vallist_random_cycles = [sum_of_minima[i] / count_of_minima[i] for i in sample_sizes]\n", "\n", "fig, ax = plt.subplots()\n", "fig.set_size_inches(15, 9)\n", "plt.xticks(fontsize=18, color=\"#322300\")\n", "plt.yticks(fontsize=18, color=\"#322300\")\n", "ax.set_xlabel(\"sample size\", fontsize=24, color=\"#322300\")\n", "ax.set_ylabel(\"average length of shortest cycle\", fontsize=24, color=\"#322300\")\n", "\n", "sbn.scatterplot(x=sample_sizes, y=vallist_random_cycles, color='#002855', s=32) # randomized outcome\n", "sbn.scatterplot(x=[math.factorial(n-1)], \\\n", " y=[salesman_travelling_distance], color='#005528', s=128) # brute force\n", "sbn.lineplot(x=[2, num_tests], y=[salesman_travelling_distance, salesman_travelling_distance], \\\n", " color='#322300', ax=ax) # black line at brute-force value for orientation\n", "ax.set_xscale('log')" ] }, { "cell_type": "code", "execution_count": null, "id": "31f7c87a", "metadata": {}, "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.9.7" } }, "nbformat": 4, "nbformat_minor": 5 }