This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
AICup/Lectures/Student_lecture 1.ipynb

576 lines
210 KiB
Text
Raw Normal View History

2020-10-01 16:03:04 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
2020-10-19 15:25:30 +00:00
"## First Lab\n",
2020-10-12 09:45:37 +00:00
"\n",
"What we are going to do today:\n",
"- read TSP data\n",
"- define euclidean distance function\n",
"- define a ProblemInstance python class \n",
"- store nodes in an instance of the class defined before\n",
"- plot raw data\n",
"- generate naive solution \n",
"- check if the solution is valid\n",
"- evaluate solution!#\n",
"\n",
"NOTE: I've marked all the code that you will have to fill with a `# TODO` comment\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This cell below is simply importing some usefull 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"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Read TSP data\n",
"In this Cup you will have to deal with predefined set of problems. These problems are located in the `problems` folder.\n",
"\n",
"First lets get list them out"
]
},
{
"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",
"# example_problem = [\"./problems/eil76.tsp\"]\n",
"for prob in problems:\n",
" print(prob[12:])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Checking by hand if all of the 10 problems are in the folder would be a waste of time so we can write a line of code just to check if they are all there"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"print(np.all([n[12:] in ['fl1577.tsp','pr439.tsp','ch130.tsp','rat783.tsp','d198.tsp', 'kroA100.tsp','u1060.tsp','lin318.tsp','eil76.tsp','pcb442.tsp'] for n in problems]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### File format\n",
"All the problems are stored in a `.tsp` (this file is actually a renamed `.txt` file, so you could open them with your favorite text editor)\n",
"\n",
"As we will see in a bit all the problems files are composed of different sections:\n",
"* `NAME`: the shortned name of the problem\n",
"* `COMMENT`: a comment area that can contain the full name of the problem\n",
"* `TYPE`: this defines the type of problem at hand, in our case is always TSP\n",
"* `DIMENSION`: this states the problem dimension\n",
"* `EDGE_WEIGHT_TYPE`: this section states the types of weights applied to edges, in our case it is always EUC_2D or the weights are giveng using the euclidean distance in 2 dimension\n",
"* `BEST_KNOWN`: this states the best known result obtained, note that as the Prof said, it is unlikely to get a better performance than this\n",
"* `NODE_COORD_SECTION`: finally we have the section that states the triplets that defines the problems points. These triplets are (point_number, x,y).\n",
"\n",
"Now that we know all of that, lets print the content of a single problem"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['NAME : eil76', 'COMMENT : 76-city problem (Christofides/Eilon)', 'TYPE : TSP', 'DIMENSION : 76', 'EDGE_WEIGHT_TYPE : EUC_2D', 'BEST_KNOWN : 538', 'NODE_COORD_SECTION', '1 22 22', '2 36 26', '3 21 45', '4 45 35', '5 55 20', '6 33 34', '7 50 50', '8 55 45', '9 26 59', '10 40 66', '11 55 65', '12 35 51', '13 62 35', '14 62 57', '15 62 24', '16 21 36', '17 33 44', '18 9 56', '19 62 48', '20 66 14', '21 44 13', '22 26 13', '23 11 28', '24 7 43', '25 17 64', '26 41 46', '27 55 34', '28 35 16', '29 52 26', '30 43 26', '31 31 76', '32 22 53', '33 26 29', '34 50 40', '35 55 50', '36 54 10', '37 60 15', '38 47 66', '39 30 60', '40 30 50', '41 12 17', '42 15 14', '43 16 19', '44 21 48', '45 50 30', '46 51 42', '47 50 15', '48 48 21', '49 12 38', '50 15 56', '51 29 39', '52 54 38', '53 55 57', '54 67 41', '55 10 70', '56 6 25', '57 65 27', '58 40 60', '59 70 64', '60 64 4', '61 36 6', '62 30 20', '63 20 30', '64 15 5', '65 50 70', '66 57 72', '67 45 42', '68 38 33', '69 50 4', '70 66 8', '71 59 5', '72 35 60', '73 27 24', '74 40 20', '75 40 37', '76 40 40', 'EOF']\n"
]
}
],
"source": [
"example_problem = \"../problems/eil76.tsp\"\n",
"with open(example_problem,\"r\") as exprob:\n",
" print(exprob.read().splitlines())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Euclidean Distance\n",
"Since all of our problems are using the euclidean distance between points for the edges weights.\n",
"We will now define a function that computes the euclidean distance. This distance will also be used to build the distance matrix"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def distance_euc(point_i, point_j): # TODO\n",
" rounding = 0\n",
" # [...]\n",
" return round(distance, rounding)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's test it"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4.0"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"point_1 = (2, 2)\n",
"point_2 = (5, 5)\n",
"distance_euc(point_1, point_2)\n",
"# Expected output is 4.0 with rounding to 0 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Reading and storing the data\n",
"We will now define a Class called `ProblemInstance`\n",
"\n",
"in the Constructor of the class (`__init__()`method of a class in Python) you will have to implement the code for:\n",
"* reading the raw data\n",
"* store the metadata\n",
"* read all the point and store them\n",
"* code the method that creates the distance matrix between points\n",
"* \\[optional\\] check if the problem loaded has an optimal and in that case store the optimal solution\n",
"* \\[optional\\] code the plotting method\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"from src.utils import distance_euc\n",
"\n",
"class ProblemInstance:\n",
"\n",
" def __init__(self, name_tsp):\n",
" self.exist_opt = False\n",
" self.optimal_tour = None\n",
" self.dist_matrix = None\n",
" \n",
" # read raw data \n",
" # TODO\n",
" # [...]\n",
" self.lines = # here we expect a list of lines of the tsp file\n",
"\n",
" # store metadata set information \n",
" # TODO\n",
" self.name = # here we expect the name of the problem\n",
" self.nPoints = # here the number of pts\n",
" self.best_sol = # here the lenght of the best solution\n",
" \n",
" # read all data points and store them \n",
" # TODO\n",
" self.points = np.zeros((self.nPoints, 3)) # this is the structure where we will store the pts data \n",
" # [...] here you need to fill self.points \n",
" \n",
" self.create_dist_matrix()\n",
" \n",
" # TODO [optional]\n",
" # if the problem is one with a optimal solution, that solution is loaded\n",
" if name_tsp in [\"../problems/eil76.tsp\", \"../problems/kroA100.tsp\"]:\n",
" self.exist_opt = True\n",
" # [...]\n",
"\n",
" # read all data points and store them\n",
" self.optimal_tour = np.zeros(self.nPoints, dtype=np.int)\n",
" # [...]\n",
"\n",
" def print_info(self):\n",
" print(\"\\n#############################\\n\")\n",
" print('name: ' + self.name)\n",
" print('nPoints: ' + str(self.nPoints))\n",
" print('best_sol: ' + str(self.best_sol))\n",
" print('exist optimal: ' + str(self.exist_opt))\n",
"\n",
" def plot_data(self,show_numbers=False): # todo [optional]\n",
" plt.figure(figsize=(8, 8))\n",
" plt.title(self.name)\n",
" plt.scatter(self.points[:, 1], self.points[:, 2])\n",
" if show_numbers:\n",
" for i, txt in enumerate(np.arange(self.nPoints)): # tour_found[:-1]\n",
" plt.annotate(txt, (self.points[i, 1], self.points[i, 2]))\n",
" plt.show()\n",
"\n",
" def create_dist_matrix(self): # TODO\n",
" self.dist_matrix = # [...] define the size of the dist matrix\n",
" \n",
" # now fill it\n",
" # [...]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"------------------------\n",
"Now we can test our Class with an example problem"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"example_problem = \"../problems/eil76.tsp\"\n",
"p_inst=ProblemInstance(example_problem)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"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"
}
],
"source": [
"p_inst.print_info()\n",
"p_inst.plot_data()\n",
"#Expected output\n",
"\"\"\"\n",
"#############################\n",
"\n",
"name: eil76\n",
"nPoints: 76\n",
"best_sol: 538.0\n",
"exist optimal: True\n",
"\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"p_inst.plot_data(show_numbers=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"-------------\n",
"### Random solver \n",
"Now we will code the random solver and test it with a class called `SolverTSP` that takes the solvers and the problem instance and act as a framework to compute the solution and gives us some additional information.\n",
"We will also need to code the `evaluate_solution` method of the the `SolverTSP` class"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"def random_method(instance_): # TODO\n",
" return solution\n",
"available_methods = {\"random\": random_method} # this is here because the SolverTSP will check for the available methods"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"from time import time as t\n",
"\n",
"class SolverTSP:\n",
" def __init__(self, algorithm_name, problem_instance):\n",
" self.duration = np.inf\n",
" self.found_length = np.inf\n",
" self.algorithm_name = algorithm_name\n",
" self.name_method = \"initialized with \" + algorithm_name\n",
" self.solved = False\n",
" self.problem_instance = problem_instance\n",
" self.solution = None\n",
"\n",
" def compute_solution(self, verbose=True, return_value=True):\n",
" self.solved = False\n",
" if verbose:\n",
" print(f\"### solving with {self.algorithm_name} ####\")\n",
" start_time = t()\n",
" self.solution = available_methods[self.algorithm_name](self.problem_instance)\n",
" assert self.check_if_solution_is_valid(self.solution), \"Error the solution is not valid\"\n",
" end_time = t()\n",
" self.duration = np.around(end_time - start_time, 3)\n",
" if verbose:\n",
" print(f\"### solved ####\")\n",
" self.solved = True\n",
" self.evaluate_solution()\n",
" self._gap()\n",
" if return_value:\n",
" return self.solution\n",
"\n",
" def plot_solution(self):\n",
" assert self.solved, \"You can't plot the solution, you need to compute it first!\"\n",
" plt.figure(figsize=(8, 8))\n",
" self._gap()\n",
" plt.title(f\"{self.problem_instance.name} solved with {self.name_method} solver, gap {self.gap}\")\n",
" ordered_points = self.problem_instance.points[self.solution]\n",
" plt.plot(ordered_points[:, 1], ordered_points[:, 2], 'b-')\n",
" plt.show()\n",
"\n",
" def check_if_solution_is_valid(self, solution):\n",
" rights_values = np.sum([self.check_validation(i, solution) for i in np.arange(self.problem_instance.nPoints)])\n",
" if rights_values == self.problem_instance.nPoints:\n",
" return True\n",
" else:\n",
" return False \n",
" def check_validation(self, node , solution):\n",
" if np.sum(solution == node) == 1:\n",
" return 1\n",
" else:\n",
" return 0\n",
"\n",
" def evaluate_solution(self, return_value=False):\n",
" total_length = 0\n",
" from_node = self.solution[0] # starting_node\n",
" # TODO\n",
" # [...] compute total_lenght of the solution \n",
" self.found_length = total_length\n",
" if return_value:\n",
" return total_length\n",
"\n",
" def _gap(self):\n",
" self.evaluate_solution(return_value=False)\n",
" self.gap = np.round(\n",
" ((self.found_length - self.problem_instance.best_sol) / self.problem_instance.best_sol) * 100, 2)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"----------------------------\n",
"Now we will test our code"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"### solving with random ####\n",
"### solved ####\n",
"the total length for the solution found is 2424.0\n",
"while the optimal length is 538.0\n",
"the gap is 350.56%\n",
"the solution is found in 0.0 seconds\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"solver_name=\"random\"\n",
"# here I'm repeating this two lines just to remind you which problem we are using\n",
"example_problem = \"../problems/eil76.tsp\"\n",
"p_inst = ProblemInstance(example_problem)\n",
"\n",
"# TODO\n",
"# create an instance of SolverTSP\n",
"# compute a solution\n",
"# print the information as for the output\n",
"# plot the solution\n",
"\n",
"# this is the output expected and after that the solution's plot\n",
"\"\"\"\n",
"### solving with random ####\n",
"### solved ####\n",
"the total length for the solution found is 2424.0\n",
"while the optimal length is 538.0\n",
"the gap is 350.56%\n",
"the solution is found in 0.0 seconds\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"--------------------\n",
"Finally since our example problem has an optimal solution we can plot it"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"solver = SolverTSP(\"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()"
2020-10-01 16:03:04 +00:00
]
}
],
"metadata": {
"kernelspec": {
2020-10-12 09:45:37 +00:00
"display_name": "PyCharm (AI2020BsC)",
2020-10-01 16:03:04 +00:00
"language": "python",
2020-10-12 09:45:37 +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-10-12 09:45:37 +00:00
}