From 491a6e9bd1f8b7ce610fb4971f94598455c564f1 Mon Sep 17 00:00:00 2001 From: "Kamal Bentahar (ab3735)" Date: Mon, 4 Nov 2024 15:47:06 +0000 Subject: [PATCH] Base notebooks for the coursework --- DP.ipynb | 294 +++++++++++++++++++++++++++++++ DT.ipynb | 371 ++++++++++++++++++++++++++++++++++++++++ Feedback and Marks.md | 59 +++++++ LP.ipynb | 214 +++++++++++++++++++++++ PSO.ipynb | 185 ++++++++++++++++++++ README.md | 16 ++ RL.ipynb | 112 ++++++++++++ img/ssp-binary-tree.jpg | Bin 0 -> 94889 bytes 8 files changed, 1251 insertions(+) create mode 100644 DP.ipynb create mode 100644 DT.ipynb create mode 100644 Feedback and Marks.md create mode 100644 LP.ipynb create mode 100644 PSO.ipynb create mode 100644 README.md create mode 100644 RL.ipynb create mode 100644 img/ssp-binary-tree.jpg 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 0000000000000000000000000000000000000000..b2021720a88f531130981f5c6636ea24005daeb4 GIT binary patch literal 94889 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 DnIFXY literal 0 HcmV?d00001