From 10b97d408b539e56a8ab5918de8a3269e54339da Mon Sep 17 00:00:00 2001 From: Pradeep Nagaraju Date: Sun, 18 Feb 2018 01:18:11 -0800 Subject: [PATCH 1/2] Recusive, dynamic programming and Graph paradigms --- algorithms/DynamicProgrammingParadigm.ipynb | 68 ++++ algorithms/GraphsParadigms.ipynb | 316 ++++++++++++++++ algorithms/RecursionParadigms.ipynb | 377 ++++++++++++++++++++ 3 files changed, 761 insertions(+) create mode 100644 algorithms/DynamicProgrammingParadigm.ipynb create mode 100644 algorithms/GraphsParadigms.ipynb create mode 100644 algorithms/RecursionParadigms.ipynb diff --git a/algorithms/DynamicProgrammingParadigm.ipynb b/algorithms/DynamicProgrammingParadigm.ipynb new file mode 100644 index 0000000..bc335b1 --- /dev/null +++ b/algorithms/DynamicProgrammingParadigm.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "380\n" + ] + } + ], + "source": [ + "'''Weighted interval schedule\n", + "Input: Number of Jobs n = 4\n", + " Job Details {Start Time, Finish Time, Profit}\n", + " Job 1: {1, 2, 50} \n", + " Job 2: {3, 5, 20}\n", + " Job 3: {6, 19, 100}\n", + " Job 4: {2, 100, 200}\n", + " This gives a the max sum of weights of the continuous jobs \n", + " '''\n", + "\n", + "jobs = [{1, 2, 50}, {3, 5, 230}, {6, 19, 100}, {2, 100, 200}]\n", + "v = [50, 230, 100, 200]\n", + "N = len(v)\n", + "p = [0] * N\n", + "p[0] = 0\n", + "p[1] = 0\n", + "p[2] = 1\n", + "p[3] = 0\n", + "M = [0] * N\n", + "\n", + "def WeightedInterval():\n", + " global p\n", + " global M\n", + " for i in range(N):\n", + " M[i] = max(v[i] + M[p[i]], M[i - 1])\n", + "WeightedInterval()\n", + "print(M[3])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cnn", + "language": "python", + "name": "cnn" + }, + "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.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/algorithms/GraphsParadigms.ipynb b/algorithms/GraphsParadigms.ipynb new file mode 100644 index 0000000..923ccad --- /dev/null +++ b/algorithms/GraphsParadigms.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "class Graph:\n", + " adj: dict = None\n", + " V: int = None\n", + " def __init__(self, V):\n", + " self.adj = {}\n", + " self.V = V\n", + " for i in range(V):\n", + " self.adj[i] = []\n", + " \n", + " def addEdge(self, v, w):\n", + " self.adj[v].append(w)\n", + " self.adj[w].append(v)\n", + " \n", + " def __str__(self):\n", + " retString = \"\"\n", + " for k, v in self.adj.items():\n", + " if [] != v:\n", + " retString += ('{}: {}\\n'.format(k, str(v)))\n", + " return retString\n", + " def __iter__(self):\n", + " for k, v in self.adj.items():\n", + " if v != []:\n", + " yield k, v\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class DirectedGraph:\n", + " adj = None\n", + " V = None\n", + " def __init__(self, V):\n", + " self.adj = {}\n", + " self.V = V\n", + " for i in range(V):\n", + " self.adj[i] = []\n", + " def addEdge(self, v, w):\n", + " self.adj[v].append(w)\n", + " def V(self):\n", + " return self.V\n", + " \n", + "def reverseGraph(g:DirectedGraph) -> DirectedGraph:\n", + " reverseGraph = DirectedGraph(g.V)\n", + " for v, w in g.adj.items():\n", + " for _v in w:\n", + " reverseGraph.addEdge(_v, v)\n", + " return reverseGraph" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "class DfsPaths():\n", + " marked: list = None\n", + " source = None\n", + " edgeTo: list = None\n", + " \n", + " def __init__(self, G: Graph, s: int):\n", + " self.marked = [False] * G.V\n", + " self.edgeTo = [0] * G.V\n", + " self.source = s\n", + " self.dfs(G, s)\n", + " \n", + " def hasPathTo(self, v: int):\n", + " return self.marked[v] \n", + " \n", + " def pathTo(self, v: int):\n", + " node = v\n", + " path = []\n", + " if self.hasPathTo(v):\n", + " while node != self.source:\n", + " path.append(node)\n", + " node = self.edgeTo[node] \n", + " path.append(self.source)\n", + " path.reverse()\n", + " return path\n", + " \n", + " def dfs(self, G, s):\n", + " self.marked[s] = True\n", + " for v in G.adj[s]:\n", + " if self.marked[v] == False:\n", + " self.dfs(G, v)\n", + " self.edgeTo[v] = s\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", + "class BfsPaths:\n", + " marked: list = None\n", + " edgeTo: list = None\n", + " bfsQueue: deque = None\n", + " distTo: list = None\n", + " def __init__(self, G: Graph, s):\n", + " self.marked = [False] * G.V\n", + " self.edgeTo = [0] * G.V\n", + " self.bfsQueue = deque([])\n", + " self.distTo = [0] * G.V\n", + " self._bfs(G, s)\n", + " \n", + " def _bfs(self, G: Graph, s):\n", + "# count = 0\n", + " if self.marked[s] == False:\n", + " self.bfsQueue.append(s)\n", + " self.marked[s] = True\n", + " self.distTo[s] = 0\n", + " \n", + " while len(self.bfsQueue) != 0:\n", + " node = self.bfsQueue.popleft()\n", + " for v in G.adj[node]:\n", + " if self.marked[v] == False:\n", + " self.marked[v] = True\n", + " self.bfsQueue.append(v)\n", + " self.edgeTo[v] = s\n", + " self.distTo[v] = self.distTo[node] + 1\n", + " \n", + " def Dist(self, v):\n", + " return self.distTo[v]\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class ConnectedComponents:\n", + " count = None\n", + " G: Graph = None\n", + " id = None\n", + " marked = None\n", + " def __init__(self, G):\n", + " self.count = 0\n", + " self.G = G\n", + " self.id = [0] * G.V\n", + " self.marked = [False] * G.V\n", + " self.CC()\n", + " def CC(self):\n", + " for v, _ in self.G.adj.items():\n", + "# print(v)\n", + " if self.marked[v] == False and self.G.adj[v] != []:\n", + " self.count += 1\n", + " self.dfs(self.G, v)\n", + " \n", + " def dfs(self, G, s):\n", + " for v in G.adj[s]:\n", + " if self.marked[v] == False:\n", + " self.marked[v] = True\n", + " self.id[v] = self.count\n", + " self.dfs(G, v)\n", + " def isConnected(self, v, w):\n", + " return self.id[v] == self.id[w]\n", + " \n", + " def count(self):\n", + " return self.count\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def createGraph(g):\n", + " g.addEdge(1,7)\n", + " g.addEdge(1,4)\n", + " g.addEdge(1,2)\n", + " g.addEdge(2,4)\n", + " g.addEdge(2,3)\n", + " g.addEdge(3,5)\n", + " g.addEdge(3,6)\n", + "# g.addEdge(8,9)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 359, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "[2, 1, 7]\n", + "1\n", + "True\n", + "[2, 3, 6]\n" + ] + } + ], + "source": [ + "g = Graph(10)\n", + "createGraph(g)\n", + "paths = DfsPaths(g, 2)\n", + "print(paths.hasPathTo(7))\n", + "print(paths.pathTo(7))\n", + "bfs = BfsPaths(g, 2)\n", + "print(bfs.Dist(1))\n", + "\n", + "##### Directed Graphs client ######\n", + "dg = DirectedGraph(10)\n", + "createGraph(dg)\n", + "dgPaths = DfsPaths(dg, 2)\n", + "print(dgPaths.hasPathTo(5))\n", + "print(dgPaths.pathTo(6))" + ] + }, + { + "cell_type": "code", + "execution_count": 404, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "### Connected components\n", + "g = Graph(10)\n", + "createGraph(g)\n", + "cc = ConnectedComponents(g)\n", + "print(cc.count)\n", + "assert cc.isConnected(8,1) == False\n", + "assert cc.isConnected(8,9) == True\n", + "assert cc.isConnected(1,4) == True\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 6, 5, 4, 7]\n" + ] + } + ], + "source": [ + "### Topological sort\n", + "g = DirectedGraph(10)\n", + "createGraph(g)\n", + "\n", + "def dfsTop(g, s):\n", + " for v in g.adj[s]:\n", + " if marked[v] == False:\n", + " dfsTop(g, v)\n", + " marked[v] = True\n", + " topology.append(s)\n", + "\n", + "def topoSort(g)\n", + " marked = [False] * g.V\n", + " topology = []\n", + " for v, _ in g.adj.items():\n", + " if g.adj[v] != [] and marked[v] == False:\n", + " # marked[v] = True\n", + " dfsTop(g, v)\n", + "\n", + " topology.reverse()\n", + "print(topology)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cnn", + "language": "python", + "name": "cnn" + }, + "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.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/algorithms/RecursionParadigms.ipynb b/algorithms/RecursionParadigms.ipynb new file mode 100644 index 0000000..56417ea --- /dev/null +++ b/algorithms/RecursionParadigms.ipynb @@ -0,0 +1,377 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['1', '1', '1', '1']\n", + "['1', '1', '1', '0']\n", + "['1', '1', '0', '1']\n", + "['1', '1', '0', '0']\n", + "['1', '0', '1', '1']\n", + "['1', '0', '1', '0']\n", + "['1', '0', '0', '1']\n", + "['1', '0', '0', '0']\n", + "['0', '1', '1', '1']\n", + "['0', '1', '1', '0']\n", + "['0', '1', '0', '1']\n", + "['0', '1', '0', '0']\n", + "['0', '0', '1', '1']\n", + "['0', '0', '1', '0']\n", + "['0', '0', '0', '1']\n", + "['0', '0', '0', '0']\n" + ] + } + ], + "source": [ + "a = list('0000')\n", + "N = 4\n", + "def enumerate(k):\n", + "# print(k)\n", + " if k == N:\n", + " #process()\n", + " print(a)\n", + " return\n", + " a[k] = '1'\n", + " enumerate(k + 1)\n", + " a[k] = '0'\n", + " enumerate(k + 1)\n", + " \n", + "enumerate(0)\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## N queens Problem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# a = [1, 2, 3, 4, 5, 6, 7]\n", + "# a = [1, 2, 3, 4, 0]\n", + "a = [1,2,3,4,5, 6, 7, 8, 9, 10, 11]\n", + "def swap(a, i, k):\n", + " c, d = a[i], a[k]\n", + " a[k] = c\n", + " a[i] = d\n", + "N = len(a)\n", + "count = 0\n", + "def enumeratePermutate(k):\n", + " global count\n", + " def canBacktrack():\n", + " for i in range(0, k):\n", + " '''Think on this like a growing pyramid and\n", + " anything that is on the diagonal (k - i) has to be eliminated'''\n", + " if (abs(a[i] - a[k]) == (k - i)):\n", + " return True\n", + " return False\n", + " if k == N:\n", + " (count) = (count) + 1\n", + " return\n", + " for i in range(k, N):\n", + " swap(a, i, k)\n", + " if (canBacktrack() is not True):\n", + " enumeratePermutate(k + 1)\n", + " swap(a, i, k)\n", + " \n", + "enumeratePermutate(0)\n", + "print(count)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "[0, 0, 0]\n", + "[0, 0, 1]\n", + "[0, 1, 0]\n", + "[0, 1, 1]\n", + "[1, 0, 0]\n", + "[1, 0, 1]\n", + "[1, 1, 0]\n", + "[1, 1, 1]\n" + ] + } + ], + "source": [ + "'''counting N-digit base-R numbers,\n", + " with currying'''\n", + "import numpy as np\n", + "# N = 2\n", + "# R = 4\n", + "# a = [0] * N\n", + "def countDigits(N):\n", + " k = 0\n", + " a = [0] * N\n", + " def enumerateDigits(k, R):\n", + " global count\n", + " if k == N:\n", + " print(a)\n", + " return\n", + " for i in range(R):\n", + " a[k] = i\n", + " enumerateDigits(k + 1, R)\n", + " countToBase = lambda R: enumerateDigits(0, R)\n", + " return countToBase\n", + " \n", + "countTwoDigitsWithBase = countDigits(2)\n", + "countThreeDigitsWithBase = countDigits(3)\n", + "# countTwoDigitsWithBase(3)\n", + "# print('')\n", + "# countTwoDigitsWithBase(4)\n", + "print('')\n", + "# countThreeDigitsWithBase(3)\n", + "countDigits(3)(2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 244, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 7. 0. 8. 0. 0. 0. 3. 0. 0.]\n", + " [ 0. 0. 0. 2. 0. 1. 0. 0. 0.]\n", + " [ 5. 0. 0. 0. 0. 0. 0. 0. 0.]\n", + " [ 0. 4. 0. 0. 0. 0. 0. 2. 6.]\n", + " [ 3. 0. 0. 0. 8. 0. 0. 0. 0.]\n", + " [ 0. 0. 0. 1. 0. 0. 0. 9. 0.]\n", + " [ 0. 9. 0. 6. 0. 0. 0. 0. 4.]\n", + " [ 0. 0. 0. 0. 7. 0. 5. 0. 0.]\n", + " [ 0. 0. 0. 0. 0. 0. 0. 0. 0.]]\n" + ] + } + ], + "source": [ + "'''sudoku solver'''\n", + "# board = np.zeros((9,9))\n", + "def resetBoard():\n", + " board = np.zeros((9,9))\n", + " board[0][0] = 7\n", + " board[0][2] = 8\n", + " board[0][6] = 3\n", + " board[1][3] = 2\n", + " board[1][5] = 1\n", + " board[2][0] = 5\n", + " board[3][1] = 4\n", + " board[3][7] = 2\n", + " board[3][8] = 6\n", + " board[4][0] = 3\n", + " board[4][4] = 8\n", + " board[5][3] = 1\n", + " board[5][7] = 9\n", + " board[6][1] = 9\n", + " board[6][3] = 6\n", + " board[6][8] = 4\n", + " board[7][4] = 7\n", + " board[7][6] = 5\n", + " return board\n", + "\n", + "print(resetBoard())" + ] + }, + { + "cell_type": "code", + "execution_count": 341, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "def boxNumber(k):\n", + " section = math.floor((k)/ 27)\n", + " boxWithinSection = math.ceil(((k + 10e-7) % 9)/ 3)\n", + " return section * 3 + boxWithinSection\n", + "StartLocationOfBox = lambda box: math.floor(box/3) * 27 + (box % 3) * 3\n", + "def canBackTrack(a, k):\n", + " if a[k] == 0:\n", + " return True\n", + " #Find if the number exists in the same row\n", + " row = math.floor(k / 9)\n", + " for i in range(9):\n", + " if k == (row * 9 + i):\n", + " continue\n", + " if a[k] == a[row * 9 + i] and a[k] != 0:\n", + " return True\n", + " #Find if the number exists in the same column\n", + " col = k % 9\n", + " for i in range(9):\n", + " if k == (i * 9 + col):\n", + " continue\n", + " if a[k] == a[i * 9 + col] and a[k] != 0:\n", + " return True\n", + " \n", + " #Find is the number exists in within the same box\n", + " box = boxNumber(k)\n", + " boxStart = StartLocationOfBox(box - 1)\n", + " for i in range(boxStart, boxStart + 3):\n", + " for j in range(3):\n", + " if k == i + j * 9:\n", + " continue\n", + " if a[k] == a[i + j * 9] and a[k] != 0:\n", + " return True\n", + " return False\n", + "\n", + "# print(boxNumber(80))\n", + "# print(StartLocationOfBox(0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = resetBoard()\n", + "a = np.reshape(board, -1)\n", + "idx = np.where(a > 0)[0]\n", + "def enumerateSudoku(k):\n", + " if k == 81:\n", + " print(np.reshape(a,(9,9)))\n", + " return\n", + " for i in range(1, 10):\n", + " if k in idx:\n", + " enumerateSudoku(k + 1)\n", + " break\n", + " else:\n", + " a[k] = i\n", + " if (canBackTrack(a, k) is False):\n", + " enumerateSudoku(k + 1)\n", + " a[k] = 0\n", + "enumerateSudoku(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 402, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 0, 0]\n", + "[0, 0, 1]\n", + "[0, 1, 1]\n", + "[0, 1, 0]\n", + "[1, 1, 0]\n", + "[1, 1, 1]\n", + "[1, 0, 1]\n", + "[1, 0, 0]\n" + ] + } + ], + "source": [ + "'''Enumerate binary digits'''\n", + "import copy\n", + "N = 3\n", + "a = [0] * N \n", + "def enumerateBinary(k):\n", + " if k == N:\n", + " print(a)\n", + " return\n", + " enumerateBinary(k + 1)\n", + " a[k] = 1 - a[k]\n", + " enumerateBinary(k + 1)\n", + "\n", + "enumerateBinary(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 420, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Best allocation: [0, 0, 0, 0, 1, 1]\n" + ] + } + ], + "source": [ + "'''load balance jobs based on finish times'''\n", + "import sys\n", + "jobs = [1.41, 1.73, 2.0, 2.23, 1.2, 6.0]\n", + "N = len(jobs)\n", + "a = [0] * N\n", + "bestAllocation = [0] * N\n", + "bestSpan = sys.maxsize\n", + "def calcSpan(a, id):\n", + " span = 0\n", + " for i in range(N):\n", + " if a[i] == id:\n", + " span += jobs[i] \n", + " return span\n", + "\n", + "makeSpan = lambda a: abs(calcSpan(a, 0) - calcSpan(a, 1))\n", + "\n", + "def canBacktrackJobs(a) -> bool:\n", + " currentSpan = makeSpan(a)\n", + " if currentSpan > bestSpan:\n", + " return True\n", + " return False\n", + " \n", + "def enumerateJobs(k):\n", + " global bestSpan\n", + " global bestAllocation\n", + " if k == N:\n", + " totalSpan = makeSpan(a)\n", + " if totalSpan < bestSpan:\n", + " bestSpan = totalSpan\n", + " bestAllocation = copy.deepcopy(a)\n", + " return\n", + " if canBacktrackJobs(a):\n", + " return\n", + " enumerateJobs(k + 1)\n", + " a[k] = 1 - a[k]\n", + " enumerateJobs(k + 1)\n", + " \n", + "enumerateJobs(0)\n", + "print('Best allocation:', bestAllocation)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cnn", + "language": "python", + "name": "cnn" + }, + "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.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From baacd5a8dc4fa78fd60fbbe9a73780899caa6a89 Mon Sep 17 00:00:00 2001 From: Pradeep Nagaraju Date: Sun, 18 Feb 2018 01:35:14 -0800 Subject: [PATCH 2/2] disable checking in ipynb checkpoints --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7994b70 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +algorithms/*checkpoint*