diff --git a/DP.ipynb b/DP.ipynb new file mode 100644 index 0000000..3a4ddfa --- /dev/null +++ b/DP.ipynb @@ -0,0 +1,294 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Subset-Sum Problem (SSP)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The **Subset Sum problem (SSP)** is defined as follows:\n", + "\n", + ">Given a set $S = \\{x_1, x_2, \\ldots, x_n\\}$ of positive integers,\n", + ">and a positive integers $t$, is there a subset of $S$ whose sum is equal to $t$?\n", + "\n", + "This is the **decision version** of SSP as it only asks for a true/false answer." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Example\n", + "\n", + "$S=\\{1,2,3,10\\}$ and $t=13$.\n", + "\n", + "A solution is given by $\\{1,2,10\\}$. There is also another solution: $\\{3,10\\}$." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exhaustive search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An **exhaustive search algorithm** for this problem can written *iteratively* as follows:\n", + "\n", + "**INPUT:** A set $S = \\{x_1, x_2, \\ldots, x_n\\}$ of positive integers, and a positive integer $t$.\n", + "\n", + "**OUTPUT:** $(c_1,\\ldots,c_n)$ such that $\\sum_{i=1}^n c_i x_i = t$\n", + "\n", + "1. **for all** $(c_1,\\ldots,c_n)\\in\\{0,1\\}^n$ **do**\n", + "2. $\\quad$ **if** $\\sum_{i=1}^n c_i x_i = t$ **then**\n", + "3. $\\qquad$ **return** $(c_1,\\ldots,c_n)$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now think of the exhaustive search as a binary tree, where at each level we decide whether to include the $i^\\text{th}$ number or not. For example, if $S = \\{a, b, c, d\\}$ then we get:\n", + "\n", + "![](img/ssp-binary-tree.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Write a recursive version of the exhaustive search algorithm." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "......................................................................................\n", + "......................................................................................\n", + "......................................................................................\n", + "......................................................................................\n", + "......................................................................................\n", + "......................................................................................\n", + "......................................................................................\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dynamic Programming." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The above iterative pseudocode considers the subsets of $S$ as the search space.\n", + "Another way to search for solutions is to iteratively build the answer for smaller target values $t' = 0, 1, 2, 3, \\ldots$ until we reach $t$.\n", + "\n", + "If we have built all the possible sums from the subset $\\{x_1,\\ldots,x_k\\}$, what other sums become possible if we add $x_{k+1}$ to the set?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "............................................................................\n", + "............................................................................\n", + "............................................................................\n", + "............................................................................\n", + "............................................................................\n", + "............................................................................\n", + "............................................................................\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now explain how we can use this for a bottom-up approach to decide SSP." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementation" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from random import randint, sample" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def get_S_t(n, MAX_X = 100):\n", + " S = [randint(1,MAX_X) for i in range(n)]\n", + " t = sum(sample(S,randint(1,n)))\n", + " return S,t" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([42, 26, 59, 27, 18, 74, 92, 54, 85, 31], 96)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "get_S_t(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1) Memoization (Top-down approach)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:38:11.266563Z", + "start_time": "2022-10-25T11:38:11.256547Z" + } + }, + "outputs": [], + "source": [ + "# Implementation" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:38:11.281559Z", + "start_time": "2022-10-25T11:38:11.271567Z" + } + }, + "outputs": [], + "source": [ + "# Test examples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2) Bottom-up approach" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:38:11.295714Z", + "start_time": "2022-10-25T11:38:11.286560Z" + } + }, + "outputs": [], + "source": [ + "# Implementation" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:38:11.311861Z", + "start_time": "2022-10-25T11:38:11.295714Z" + } + }, + "outputs": [], + "source": [ + "# Test examples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conclusion\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# List of references\n" + ] + } + ], + "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.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "6d1e45cadc3597bb8b6600530fbdf8c3eefe919a24ef54d9d32b318795b772e0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/DT.ipynb b/DT.ipynb new file mode 100644 index 0000000..03c18ea --- /dev/null +++ b/DT.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Linear Congruential Random Number Generators" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ">A **linear congruential generator** (**LCG**) is an algorithm that yields a sequence of pseudo-randomized numbers calculated with a discontinuous piecewise linear function. The method represents one of the oldest and best-known pseudorandom number generator algorithms. The theory behind them is relatively easy to understand, and they are easily implemented and fast, especially on computer hardware which can provide modular arithmetic by storage-bit truncation.\n", + ">\n", + ">The generator is defined by the recurrence relation:\n", + ">$$X_{n+1} = \\left( a X_n + c \\right)\\bmod m$$\n", + ">where $X$ is the sequence of pseudo-random values, and\n", + ">- $m,\\, 0\\lt m$ is the \"modulus\",\n", + ">- $a,\\,0 \\lt a \\lt m$ is the \"multiplier\",\n", + ">- $c,\\,0 \\le c \\lt m$ is the \"increment\",\n", + ">- $X_0,\\,0 \\le X_0 \\lt m$ is the \"seed\" or \"start value\",\n", + ">These are integer constants that specify the generator.\n", + ">If $c=0$, the generator is often called a \"multiplicative congruential generator\" (MCG), or *Lehmer RNG*.\n", + ">If $cā‰ 0$, the method is called a \"mixed congruential generator\".\n", + ">\n", + ">[[Wikipedia](https://en.wikipedia.org/wiki/Linear_congruential_generator)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tasks\n", + "\n", + "- Create an LCG with your Student ID as the modulus $m$, and suitable random values for $a, c$, and the *seed*. (See starter code below.)\n", + "- Use Decision Tress (DTs) from the `scikit-learn` library to assess the quality of your chosen PRNG. (If it is easy to predict the next digits then it is less random.)\n", + " - Select 3 hyper-parameters and study their effect.\n", + "\n", + "Explain your reasoning, and justify any choices of the hyperparameters (and/or run experiments to find the optimal ones).\n", + "\n", + "Evaluate your models, and use visualisation to show the trees and any relevant plots.\n", + "\n", + "Write a conclusion that summarises your findings, and makes recommendations." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:37:52.790405Z", + "start_time": "2022-10-25T11:37:50.972952Z" + } + }, + "outputs": [], + "source": [ + "from math import log\n", + "from random import randint\n", + "from matplotlib import pyplot as plt\n", + "from sklearn import tree\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.model_selection import cross_val_score\n", + "from sklearn.metrics import r2_score\n", + "from sklearn.ensemble import RandomForestClassifier" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialisation of the LCG parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Assign suitable values to the fllowing variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#.#.#.#.#.#.# IMPORTANT #.#.#.#.#.#.#\n", + "\n", + "MODULUS = ............. # Set this to your Student ID\n", + "\n", + "#.#.#.#.#.#.# IMPORTANT #.#.#.#.#.#.#" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A = 101\n", + "C = 13\n", + "SEED = 321" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Base $b$ representation of numbers" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def base_b(n, b):\n", + " \"\"\" Get a list representing the number n written in base 'b' \"\"\"\n", + " bitlength = 1+int(log(MODULUS)/log(b))\n", + " r = []\n", + " for _ in range(bitlength):\n", + " r.insert(0, n%b)\n", + " n //= b\n", + " return r" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "base_b(11,3) # Example: 11 in base 3 is: 2+0*3+1*3^2 --> 102 --> [0,0,...,1,0,2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LCG" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def lcg(seed, modulus, a, c):\n", + " \"\"\" Linear congruential generator: š‘‹_{š‘›+1} = (š‘Žš‘‹_š‘›+š‘) mod š‘š \"\"\"\n", + " while True:\n", + " seed = (a * seed + c) % modulus\n", + " yield seed" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "generator = lcg(SEED, MODULUS, A, C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Data generation" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[32434, 65991, 121936, 93405, 51262, 115779, 88828, 82809, 92170, 49983]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stream = [next(generator) for _ in range(10_000)]\n", + "stream[:10] # Example" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def get_features(stream, base):\n", + " ''' Repalce each random number from 'stream' by a vector of its base b digits '''\n", + " return [base_b(n, base) for n in stream]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "data = get_features(stream, base=3)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(32434, [0, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stream[0], data[0] # Example" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(9999, 9999)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = data[:-1]\n", + "y = data[1:]\n", + "len(X), len(y)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([0, 1, 1, 2, 2, 1, 1, 1, 0, 2, 1], [1, 0, 1, 0, 0, 1, 1, 2, 0, 1, 0])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X[0], y[0] # Example" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(7499, 2500)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)\n", + "len(X_train), len(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ..................." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "tags": [] + }, + "source": [ + "# Conclusion\n", + "\n", + "........" + ] + } + ], + "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.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "6d1e45cadc3597bb8b6600530fbdf8c3eefe919a24ef54d9d32b318795b772e0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/Feedback and Marks.md b/Feedback and Marks.md new file mode 100644 index 0000000..c2ace40 --- /dev/null +++ b/Feedback and Marks.md @@ -0,0 +1,59 @@ +Mark: % + +# Linear Programming (LP) + +| Item | Mark | +|:------------------------ | ----:| +| Article's summary | /8 | +| Mathematical formulation | /6 | +| PuLP solution | /6 | +| | | +| **Total**: | /20 | + + +## Dynamic Programming (DP) + +| Item | Mark | +|:------------------------------- | ----:| +| Recursive formulation | /5 | +| Dynamic Programming formulation | /5 | +| Implementation - Memoization | /5 | +| Implementation - Bottom-up | /5 | +| | | +| **Total**: | /20 | + + +## Particle Swarm Optimization (PSO) + +| Item | Mark | +|:------------------ | ----:| +| Effect of `w` | /5 | +| Effect of `c1` | /5 | +| Effect of `c2` | /5 | +| Overall conclusion | /5 | +| | | +| **Total**: | /20 | + + +## Decision Trees (DT) + +| Item | Mark | +|:--------------------------- | ----:| +| Chosen parameter 1 | /5 | +| Chosen parameter 2 | /5 | +| Chosen parameter 3 | /5 | +| Conclusion & Recommendation | /5 | +| | | +| **Total**: | /20 | + + +## Reinforcement Learning (RL) + +| Item | Mark | +|:-------------------------- | ----:| +| Description of the problem | /5 | +| Rigour & technical detail | /5 | +| Critical discussion | /5 | +| Language | /5 | +| | | +| **Total**: | /20 | diff --git a/LP.ipynb b/LP.ipynb new file mode 100644 index 0000000..014b551 --- /dev/null +++ b/LP.ipynb @@ -0,0 +1,214 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "af0cba34-ce1c-4572-a2d1-e23425871b08", + "metadata": {}, + "source": [ + "# Part 1) A linear programming approach for optimizing features in ML models" + ] + }, + { + "cell_type": "markdown", + "id": "ef0baa69-7ce7-4800-afb5-9e06c8161c63", + "metadata": {}, + "source": [ + "Read the article [A linear programming approach for optimizing features in ML models](https://engineering.fb.com/2021/07/29/data-infrastructure/linear-programming/).\n", + "\n", + "Summarise it technically in about **400 words**, ensuring you capture the Mathematical formulation of how Linear Programming is used. (Do not discuss the code.)\n", + "\n", + "- Use LaTeX for the mathematical formulae, not images. You also need to expand on the formulae given in the article." + ] + }, + { + "cell_type": "markdown", + "id": "98e54944-4ae1-4246-8762-c54afd201076", + "metadata": {}, + "source": [ + "## Article's summary\n", + "\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n", + "..................................................................................................\n" + ] + }, + { + "cell_type": "markdown", + "id": "5937b132", + "metadata": {}, + "source": [ + "# Part 2) Farmer's Problem" + ] + }, + { + "cell_type": "markdown", + "id": "cbca808d", + "metadata": {}, + "source": [ + "A farmer has 500 acres of land to allocate to wheat, corn, and sugar beets.\n", + "\n", + "The following table summarises the requirements and constraints:\n", + "\n", + "| | Unit | Wheat | Corn | Sugar Beets |\n", + "|--------------------------|---------|------:|-----:|:-----------:|\n", + "| Yield | T/acre | 2.5 | 3 | 20 |\n", + "| Demand (Need for feed) | T | 200 | 240 | |\n", + "| Planting cost | Ā£/acre | 150 | 230 | 260 |\n", + "| Selling price | Ā£/T | 170 | 150 | 36 if produce ā‰¤ 6000 T |\n", + "| | Ā£/T | | | 10 if produce > 6000 T |\n", + "| Backup (Purchase price) | Ā£/T | 238 | 210 | |" + ] + }, + { + "cell_type": "markdown", + "id": "0366a3fc", + "metadata": {}, + "source": [ + "## Mathematical formulation" + ] + }, + { + "cell_type": "markdown", + "id": "06aeba09", + "metadata": {}, + "source": [ + "|Variable name| Description |\n", + "|:------------|:-----|\n", + "|$x_1$| Acres of land used for wheat |\n", + "|$x_2$| Acres of land used for corn |\n", + "|$x_3$| Acres of land used for sugar beets |\n", + "|$p_1$| Tons of crop wheat sold |\n", + "|$p_2$| Tons of crop corn sold |\n", + "|$p_3$| Tons of crop sugar beets sold at Ā£36 |\n", + "|$p_4$| Tons of crop sugar beets sold at Ā£10 |\n", + "|$y_1$| Tons of wheat purchased |\n", + "|$y_2$| Tons of corn purchased |" + ] + }, + { + "cell_type": "markdown", + "id": "56ab5cbe", + "metadata": {}, + "source": [ + "\n", + "Profit formula:\n", + "\n", + "$$\n", + ".........................\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "9b2ca564", + "metadata": {}, + "source": [ + "Constraints:\n", + "\n", + "$$\n", + "\\begin{alignat*}{4}\n", + " ......................... &\\leq ...... \\\\\n", + " ......................... &\\leq ...... \\\\\n", + " ......................... \\\\\n", + " ......................... & \\geq 0\n", + "\\end{alignat*}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "id": "94561b9d", + "metadata": {}, + "source": [ + "## Solution using PuLP" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1a5ec9b7", + "metadata": { + "ExecuteTime": { + "end_time": "2022-10-25T11:37:42.147735Z", + "start_time": "2022-10-25T11:37:42.007094Z" + } + }, + "outputs": [], + "source": [ + "from pulp import *" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6a8a4305-6710-4a39-bf0c-3f032f9b3a07", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "4418a51c-715e-4ce1-bd3b-f7d53dd06159", + "metadata": {}, + "source": [ + "### Optimal solution\n", + "\n", + "|Category |Unit|Wheat|Corn|Sugar Beets|\n", + "|---------|----|-----|----|-----------|\n", + "|Area |Acre| | | |\n", + "|Yield |T | | | |\n", + "|Sales |T | | | |\n", + "|Purchase |T | | | |\n", + "\n", + "Total cost: ..............." + ] + } + ], + "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.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "6d1e45cadc3597bb8b6600530fbdf8c3eefe919a24ef54d9d32b318795b772e0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/PSO.ipynb b/PSO.ipynb new file mode 100644 index 0000000..d5e9de9 --- /dev/null +++ b/PSO.ipynb @@ -0,0 +1,185 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# PSO for TSP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Study the effect of the parameters $w, c_1, c_2$ on:\n", + "1) the quality of solutions to Euclidean TSP instances,\n", + "2) the speed of convergence.\n", + "\n", + "Show and interpret statistical plots for increasing number of points $n=100,200,\\ldots, 1000$.\n", + "\n", + "Give an overall conclusion where you summarise the effect of these 3 parametrs, and the recommended values." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from scipy import spatial\n", + "import matplotlib.pyplot as plt\n", + "from sko.PSO import PSO_TSP" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generation of points and distances matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "n = 40\n", + "points = np.random.rand(n, 2) # generate points as coordinate (x,y) in the box [0,1] x [0,1]\n", + "distance_matrix = spatial.distance.cdist(points, points, metric='euclidean')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## PSO" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "def calc_total_distance(cycle):\n", + " '''The objective function.\n", + " Input: cycle\n", + " Return: total distance\n", + " '''\n", + " num_points, = cycle.shape\n", + " return sum([distance_matrix[cycle[i % num_points], cycle[(i + 1) % num_points]] for i in range(num_points)])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "pso_tsp = PSO_TSP(func=calc_total_distance,\n", + " n_dim=n,\n", + " size_pop=200,\n", + " max_iter=800,\n", + " w=0.8,\n", + " c1=0.1,\n", + " c2=0.1)\n", + "\n", + "best_points, best_distance = pso_tsp.run()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "best_distance [4.96612188]\n" + ] + } + ], + "source": [ + "print('best_distance', best_distance)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# %% plot\n", + "fig, ax = plt.subplots(1, 2)\n", + "best_points_ = np.concatenate([best_points, [best_points[0]]])\n", + "best_points_coordinate = points[best_points_, :]\n", + "ax[0].plot(best_points_coordinate[:, 0], best_points_coordinate[:, 1], 'o-r')\n", + "ax[1].plot(pso_tsp.gbest_y_hist)\n", + "ax[0].set_aspect('equal')\n", + "ax[1].set_aspect(80)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "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.11.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "6d1e45cadc3597bb8b6600530fbdf8c3eefe919a24ef54d9d32b318795b772e0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b51c44 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# Templates for the 7159CEM Portfolio + +The submission deadline is: 6pm on Thursday 12/12/2024. + +- Create your repository by using this template repository. (Click the green button above.) +- Work on your Jupyter notebooks to complete the 5 tasks: + + 1. Linear Programming (LP) + 2. Dynamic Programming (DP) + 3. Particle Swarm Optimization (PSO) + 4. Decision Trees (DT) + 5. Reinforcement Learning (RL) + +## Useful resources + +Mathematical formulation -- Use Markdown and [LaTeX](https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference) with [Jupyter](https://jupyter.org/). diff --git a/RL.ipynb b/RL.ipynb new file mode 100644 index 0000000..8ebf70f --- /dev/null +++ b/RL.ipynb @@ -0,0 +1,112 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reinforcement Learning" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Select one of the following research papers, read it, then write a critical summary of it in about **600 words**.\n", + "\n", + "- [A scalable approach to optimize traffic signal control with federated reinforcement learning](https://www.nature.com/articles/s41598-023-46074-3)\n", + "- [Faster sorting algorithms discovered using deep reinforcement learning](https://www.nature.com/articles/s41586-023-06004-9)\n", + "- [Discovering faster matrix multiplication algorithms with reinforcement learning](https://www.nature.com/articles/s41586-022-05172-4)\n", + "- [Educational Timetabling: Problems, Benchmarks, and State-of-the-Art Results](https://arxiv.org/abs/2201.07525)\n", + "- [Deep Reinforcement Learning in Surgical Robotics: Enhancing the Automation Level](https://arxiv.org/abs/2309.00773)\n", + "- [Reinforcement Learning for Battery Management in Dairy Farming](https://arxiv.org/abs/2308.09023)\n", + "- [Integrating Renewable Energy in Agriculture: A Deep Reinforcement Learning-based Approach](https://arxiv.org/abs/2308.08611)\n", + "\n", + "Your summary must capture the key ingredients of Reinforcement Learning mentioned in the paper, e.g. specification of the environment, agent, reward, etc.\n", + "Do not cover the background material already explained in the lectures." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**N.B.** If you use any images then put them in the `img` folder, then include using `![](img/image_filename)`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Paper summary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Title: ............................." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n", + ".................................................................\n" + ] + } + ], + "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.1" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "vscode": { + "interpreter": { + "hash": "6d1e45cadc3597bb8b6600530fbdf8c3eefe919a24ef54d9d32b318795b772e0" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/img/ssp-binary-tree.jpg b/img/ssp-binary-tree.jpg new file mode 100644 index 0000000..b202172 Binary files /dev/null and b/img/ssp-binary-tree.jpg differ