├── .ipynb_checkpoints ├── NB 0.II-Objective Function Prototyping-checkpoint.ipynb ├── NB I - Datasets Generation-checkpoint.ipynb ├── NB I - Problems Book facility location-checkpoint.ipynb ├── NB I-Problem Instance 1-checkpoint.ipynb ├── NB II - Experiment 1-checkpoint.ipynb ├── NB II-Objective Function-checkpoint.ipynb ├── NB III-LR linear programming-checkpoint.ipynb ├── NB IV - Problems Book FL-checkpoint.ipynb ├── NB IV - Problems Book R-checkpoint.ipynb ├── NB V - Experiment 1-checkpoint.ipynb ├── NB V - Experiment 2-checkpoint.ipynb └── NB VI - Final Program-checkpoint.ipynb ├── NB I - Datasets Generation.ipynb ├── NB I - Problems Book R.ipynb ├── NB I - Problems Book facility location.ipynb ├── NB II - Experiment 1.ipynb ├── NB II - Experiment 2.ipynb ├── README.md ├── REFERENCES.md ├── cplex ├── Dockerfile └── installer.properties ├── helpers ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-35.pyc │ └── expand_dataset_short_syntax.cpython-35.pyc └── dataset │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-35.pyc │ ├── distance_matrices.cpython-35.pyc │ └── draw_dataset.cpython-35.pyc │ ├── distance_matrices.py │ └── draw_dataset.py ├── linear_programming_facility_location ├── .ipynb_checkpoints │ ├── 1_UFLP-checkpoint.ipynb │ ├── 2_CFLP-checkpoint.ipynb │ ├── 3_TUFLP-checkpoint.ipynb │ ├── CRAB_MB_modified-checkpoint.ipynb │ └── Objective Function-checkpoint.ipynb ├── 1_UFLP.ipynb ├── 2_CFLP.ipynb └── 3_TUFLP.ipynb ├── linear_programming_location_routing └── CRAB_MB_modified.ipynb └── linear_programming_vehicle_routing ├── .ipynb_checkpoints └── VRP_2_T-checkpoint.ipynb ├── 1_TSP.ipynb ├── 2_mTSP.ipynb └── VRP_2_T.ipynb /.ipynb_checkpoints/NB 0.II-Objective Function Prototyping-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "deletable": true, 7 | "editable": true 8 | }, 9 | "source": [ 10 | "Objective Function\n", 11 | "---" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 13, 17 | "metadata": { 18 | "code_folding": [ 19 | 0 20 | ], 21 | "collapsed": false 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "def objective_lr_1(Y,I,J,x_cus,x_icp,y_cus,y_icp):\n", 26 | " \"\"\"Calculate The cost distances Custoner/ICP\n", 27 | " \n", 28 | " Parameters:\n", 29 | " I,J sets of customers and ICP\n", 30 | " x_cus,y_cus geographique position of customers\n", 31 | " x_icp,y_icp geographique position of ICPs\n", 32 | " \n", 33 | " Decision variable:\n", 34 | " Y_ij if customer i associated with ICP j\n", 35 | " \"\"\"\n", 36 | " s = 0\n", 37 | " for i in range(I):\n", 38 | " for j in range(J):\n", 39 | " s += sqrt((x_cus[i] - x_icp[i])**2 + (y_cus[i] - y_icp[i])**2) * Y[i][j]\n", 40 | " \n", 41 | " return s" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 14, 47 | "metadata": { 48 | "code_folding": [ 49 | 0 50 | ], 51 | "collapsed": true 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "def objective_lr_2(N,J,FCT):\n", 56 | " \"\"\"Setup cost for ICPs\n", 57 | " \n", 58 | " Parameters:\n", 59 | " J sets of ICP\n", 60 | " FTC_j setup cost for ICP j\n", 61 | "\n", 62 | " Decision variable:\n", 63 | " N_j ICP j is open\n", 64 | " \"\"\"\n", 65 | " s = 0\n", 66 | " for j in range(J):\n", 67 | " s += FTC[j]*N[j]\n", 68 | " \n", 69 | " return s" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 16, 75 | "metadata": { 76 | "code_folding": [ 77 | 0 78 | ], 79 | "collapsed": true 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "def objective_lr_3(I,K,V,q,IP):\n", 84 | " \"\"\"Product acquisition cost\n", 85 | " \n", 86 | " Parameters:\n", 87 | " I,K,V sets of customers, quality level, and product varieties\n", 88 | " q_iv unit of return product custoner i quality v\n", 89 | " IP incentive cost for acquisition\n", 90 | "\n", 91 | " Decision variable:\n", 92 | "\n", 93 | " \"\"\"\n", 94 | " s = 0\n", 95 | " for i in range(I):\n", 96 | " for k in range(K):\n", 97 | " for v in range(V):\n", 98 | " s += q[i][v] * IP[i][k][v]\n", 99 | " \n", 100 | " return s" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "code_folding": [ 108 | 0 109 | ], 110 | "collapsed": true 111 | }, 112 | "outputs": [], 113 | "source": [ 114 | "def objective_lr_4(Z,C,J,B,D_crc_icp,D_crc_pc):\n", 115 | " \"\"\"Routing ICP->CRC->PC\n", 116 | " \n", 117 | " Parameters:\n", 118 | " C,J,B sets of customers, quality level, and product varieties\n", 119 | " D_crc_icp distance between CRC_c and ICP_j\n", 120 | " D_crc_pc distance between CRC_c and PC\n", 121 | "\n", 122 | " Decision variable:\n", 123 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 124 | " \"\"\"\n", 125 | " s = 0\n", 126 | " for c in range(C):\n", 127 | " for j in range(J):\n", 128 | " for b in range(B):\n", 129 | " s += (D_crc_icp[c][j] + D_crc_pc[c])* Z[c][j][b]\n", 130 | " \n", 131 | " return s" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": { 138 | "code_folding": [ 139 | 0 140 | ], 141 | "collapsed": true 142 | }, 143 | "outputs": [], 144 | "source": [ 145 | "def objective_lr_5(N,S,FCR):\n", 146 | " \"\"\"Product acquisition cost\n", 147 | " \n", 148 | " Parameters:\n", 149 | " S set of CRC\n", 150 | " FCR setup cost of CRC_c\n", 151 | "\n", 152 | " Decision variable:\n", 153 | "\n", 154 | " \"\"\"\n", 155 | " s = 0\n", 156 | " for c in range(S):\n", 157 | " s += FCR[c]*N\n", 158 | " \n", 159 | " return s" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 17, 165 | "metadata": { 166 | "code_folding": [ 167 | 0 168 | ], 169 | "collapsed": true 170 | }, 171 | "outputs": [], 172 | "source": [ 173 | "def objective_lr_6(I,K,V,q,PC):\n", 174 | " \"\"\"Processing cost\n", 175 | " \n", 176 | " Parameters:\n", 177 | " I,K,V sets of customers, quality level, and product varieties\n", 178 | " q_iv unit of return product custoner i quality v\n", 179 | " PC procesing cost\n", 180 | "\n", 181 | " Decision variable:\n", 182 | "\n", 183 | " \"\"\"\n", 184 | " s = 0\n", 185 | " for i in range(I):\n", 186 | " for k in range(K):\n", 187 | " for v in range(V):\n", 188 | " s += q[i][v] * PC[i][k][v]\n", 189 | " \n", 190 | " return s" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 18, 196 | "metadata": { 197 | "code_folding": [], 198 | "collapsed": true 199 | }, 200 | "outputs": [], 201 | "source": [ 202 | "def objective_lr_6(Z,C,J,B,FCV):\n", 203 | " \"\"\"Routing ICP->CRC->PC\n", 204 | " \n", 205 | " Parameters:\n", 206 | " C,J,B sets of customers, quality level, and product varieties\n", 207 | " FCV_b fixed cost associated to vehivle b\n", 208 | "\n", 209 | " Decision variable:\n", 210 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 211 | "\n", 212 | " \"\"\"\n", 213 | " s = 0\n", 214 | " for b in range(B):\n", 215 | " s_sub = 0\n", 216 | " for c in range(C):\n", 217 | " for j in range(J):\n", 218 | " s_sub += Z[c][j][b]\n", 219 | " s += FCV[b] * sum_7_sub\n", 220 | " \n", 221 | " return s" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 8, 227 | "metadata": { 228 | "code_folding": [], 229 | "collapsed": false, 230 | "deletable": true, 231 | "editable": true, 232 | "run_control": { 233 | "marked": false 234 | } 235 | }, 236 | "outputs": [], 237 | "source": [ 238 | "def objective_lr(decisionVariables, p):\n", 239 | " \"\"\"\n", 240 | " Parameters:\n", 241 | " Sets:\n", 242 | " I,J,C,K,V,B -> customer, ICPs, CRCs, qualities, varieties, vehicles\n", 243 | " Costs:\n", 244 | " FCT, FCR, FCV\n", 245 | " IP, PC\n", 246 | " Weight:\n", 247 | " q,\n", 248 | " D_crc_icp, D_crc_pc\n", 249 | " \n", 250 | " Decision Vqriables:\n", 251 | " Y_ij customer i associated to ICP j\n", 252 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 253 | " N_icp, N_crc -> ICP / CRC i is open\n", 254 | " \"\"\"\n", 255 | " \n", 256 | " ############################################\n", 257 | " ## Variable cost\n", 258 | " \n", 259 | " # 1. Distance betwwen customer and facilies\n", 260 | " objective_lr_distances(Y,I,J,x_cus,x_icp,y_cus,y_icp)\n", 261 | " # 4. Routing ICP->CRC->PC\n", 262 | " objective_lr_4(Z,C,J,B,D_crc_icp,D_crc_pc)\n", 263 | " \n", 264 | " ############################################\n", 265 | " ## Fixed costs\n", 266 | " \n", 267 | " # 2. Cost of establishing ICPs\n", 268 | " objective_lr_2(N_icp,J,FCT)\n", 269 | " # 5. Fixe cost for establishing CRCs\n", 270 | " objective_lr_5(N_crc,S,FCR)\n", 271 | " # 7. Fixe cost for vehicles\n", 272 | " objective_lr_6(Z,C,J,B,FCV)\n", 273 | " ############################################\n", 274 | " ## Acquisition an processing cost\n", 275 | " \n", 276 | " # 3. Acquisition cost\n", 277 | " objective_lr_3(I,K,V,q,IP)\n", 278 | " # 6. Processing cost\n", 279 | " objective_lr_6(I,K,V,q,PC)\n" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "collapsed": true 287 | }, 288 | "outputs": [], 289 | "source": [] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": null, 294 | "metadata": { 295 | "collapsed": true 296 | }, 297 | "outputs": [], 298 | "source": [] 299 | } 300 | ], 301 | "metadata": { 302 | "kernelspec": { 303 | "display_name": "Python 3.5", 304 | "language": "python", 305 | "name": "py35" 306 | }, 307 | "language_info": { 308 | "codemirror_mode": { 309 | "name": "ipython", 310 | "version": 3 311 | }, 312 | "file_extension": ".py", 313 | "mimetype": "text/x-python", 314 | "name": "python", 315 | "nbconvert_exporter": "python", 316 | "pygments_lexer": "ipython3", 317 | "version": "3.5.3" 318 | }, 319 | "toc": { 320 | "colors": { 321 | "hover_highlight": "#DAA520", 322 | "running_highlight": "#FF0000", 323 | "selected_highlight": "#FFD700" 324 | }, 325 | "moveMenuLeft": true, 326 | "nav_menu": { 327 | "height": "30px", 328 | "width": "252px" 329 | }, 330 | "navigate_menu": true, 331 | "number_sections": true, 332 | "sideBar": true, 333 | "threshold": 4, 334 | "toc_cell": false, 335 | "toc_section_display": "block", 336 | "toc_window_display": false 337 | } 338 | }, 339 | "nbformat": 4, 340 | "nbformat_minor": 2 341 | } 342 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB I - Datasets Generation-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Datasets Generation\n", 8 | "\n", 9 | "This note book aim to provide function to create, manipulate, and analyze datasets\n", 10 | "\n", 11 | "The dataset is compose a several layers or type of facility/customer mainly represented by there location" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 102, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "The autoreload extension is already loaded. To reload it, use:\n", 24 | " %reload_ext autoreload\n" 25 | ] 26 | }, 27 | { 28 | "name": "stderr", 29 | "output_type": "stream", 30 | "text": [ 31 | "C:\\ProgramData\\Anaconda3\\envs\\py35\\lib\\site-packages\\matplotlib\\__init__.py:1401: UserWarning: This call to matplotlib.use() has no effect\n", 32 | "because the backend has already been chosen;\n", 33 | "matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", 34 | "or matplotlib.backends is imported for the first time.\n", 35 | "\n", 36 | " warnings.warn(_use_error_msg)\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "import csv\n", 42 | "import os\n", 43 | "\n", 44 | "from random import uniform as unif\n", 45 | "\n", 46 | "import networkx as nx\n", 47 | "\n", 48 | "import numpy as np\n", 49 | "from numpy import linalg as LA\n", 50 | "import scipy as sp\n", 51 | "from scipy import stats\n", 52 | "\n", 53 | "import matplotlib as mpl\n", 54 | "mpl.use(\"Agg\") # Must come after importing mpl, but before importing plt\n", 55 | "import matplotlib.pyplot as plt\n", 56 | "\n", 57 | "%matplotlib inline\n", 58 | "%load_ext autoreload\n", 59 | "%autoreload 2" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 103, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [ 70 | "out_folder = \"./datasets/set1\"" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 104, 76 | "metadata": { 77 | "code_folding": [ 78 | 0 79 | ], 80 | "collapsed": true 81 | }, 82 | "outputs": [], 83 | "source": [ 84 | "if not os.path.exists(out_folder):\n", 85 | " os.makedirs(out_folder)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "## Characteristic\n", 93 | "\n", 94 | "A dataset for LRP is a set of several type of entities with a geographic position. Thus we represent it as a dictionary defining each type of entity as following:\n", 95 | "\n", 96 | "```JSON\n", 97 | "\"Entity Name\": {\n", 98 | " \"number\": integer,\n", 99 | " \"coordinate\" : string|array,\n", 100 | " \"metadata\": {\n", 101 | " \"color\": string|array,\n", 102 | " \"size\": string|array,\n", 103 | " }\n", 104 | "```\n" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 129, 110 | "metadata": { 111 | "code_folding": [], 112 | "collapsed": true 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "datasets = {\n", 117 | " \"lvl1\": {\n", 118 | " \"number\": 25,\n", 119 | " \"coordinate\" : [(i,j) for i in range(5) for j in range(5)],\n", 120 | " \"metadata\": {\n", 121 | " \"color\": [\"red\" for i in range(25)],\n", 122 | " \"size\": [10 for i in range(25)],\n", 123 | " }\n", 124 | " },\n", 125 | " \"lvl2\": {\n", 126 | " \"number\": 16,\n", 127 | " \"coordinate\" : [(i,j) for i in range(4) for j in range(4)],\n", 128 | " \"metadata\": {\n", 129 | " \"color\": [\"green\" for i in range(16)],\n", 130 | " \"size\": [20 for i in range(16)],\n", 131 | " }\n", 132 | " },\n", 133 | " \"lvl3\": {\n", 134 | " \"number\": 9,\n", 135 | " \"coordinate\" : [(i,j) for i in range(3) for j in range(3)],\n", 136 | " \"metadata\": {\n", 137 | " \"color\": [\"blue\" for i in range(9)],\n", 138 | " \"size\": [30 for i in range(9)],\n", 139 | " }\n", 140 | " }\n", 141 | "}" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "By using strings instead of arrays you signify than you want the given key to be consider has having the same expression for all element. The following example shows an example of short syntax. The function called `expand_short_syntax` define later on can be use to convert the short syntax to a full syntax." 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 130, 154 | "metadata": { 155 | "code_folding": [ 156 | 0 157 | ], 158 | "collapsed": true 159 | }, 160 | "outputs": [], 161 | "source": [ 162 | "datasets_short_syntax = {\n", 163 | " \"lvl1\": {\n", 164 | " \"number\": 1,\n", 165 | " \"coordinate\" : \"(unif(20,100),unif(20,70))\",\n", 166 | " \"metadata\": {\n", 167 | " \"color\": \"red\",\n", 168 | " \"size\": 10,\n", 169 | " }\n", 170 | " },\n", 171 | " \"lvl2\": {\n", 172 | " \"number\": 1,\n", 173 | " \"coordinate\" : [(unif(20,100),unif(20,70)) for i in range(10)],\n", 174 | " \"metadata\": {\n", 175 | " \"color\": \"green\",\n", 176 | " \"size\": 20,\n", 177 | " }\n", 178 | " },\n", 179 | " \"lvl3\": {\n", 180 | " \"number\": 10,\n", 181 | " \"coordinate\" : [(unif(20,100),unif(20,70)) for i in range(10)],\n", 182 | " \"metadata\": {\n", 183 | " \"color\": [\"blue\" for i in range(10)],\n", 184 | " \"size\": [30 for i in range(5)]+[10 for i in range(5)],\n", 185 | " }\n", 186 | " }\n", 187 | "}" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 131, 193 | "metadata": { 194 | "code_folding": [ 195 | 0 196 | ] 197 | }, 198 | "outputs": [], 199 | "source": [ 200 | "def expand_short_syntax(datasets):\n", 201 | " \"\"\"\n", 202 | " Given a dataset dictionary using the short syntax. Output the full version\n", 203 | " \"\"\"\n", 204 | " for dataset in datasets:\n", 205 | " d = datasets[dataset]\n", 206 | " \n", 207 | " if type(d[\"coordinate\"]) is str:\n", 208 | " d[\"coordinate\"] = eval(\"[\"+ str(d[\"coordinate\"]) +\" for i in range(\"+ str(d[\"number\"]) +\")]\")\n", 209 | " \n", 210 | " for metadata in d[\"metadata\"]:\n", 211 | " if type(d[\"metadata\"][metadata]) is str:\n", 212 | " d[\"metadata\"][metadata] = eval(\"[ \\\"\"+ d[\"metadata\"][metadata] +\"\\\" for i in range(\"+ str(d[\"number\"]) +\")]\")\n", 213 | " if type(d[\"metadata\"][metadata]) is int:\n", 214 | " d[\"metadata\"][metadata] = eval(\"[\"+ str(d[\"metadata\"][metadata]) +\" for i in range(\"+ str(d[\"number\"]) +\")]\")\n", 215 | " \n", 216 | " return datasets" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 132, 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/plain": [ 227 | "{'lvl1': {'coordinate': [(91.85225961702838, 31.460375252236503)],\n", 228 | " 'metadata': {'color': ['red'], 'size': [10]},\n", 229 | " 'number': 1},\n", 230 | " 'lvl2': {'coordinate': [(70.45417944700517, 53.99483668981287),\n", 231 | " (24.190019892262384, 34.35063138113162),\n", 232 | " (21.664648497818977, 64.27848633212112),\n", 233 | " (54.39917200946104, 47.54926276857229),\n", 234 | " (29.942038545701433, 22.54758915669338),\n", 235 | " (49.55877464037597, 26.478847246962477),\n", 236 | " (74.66978890404884, 50.46373073751617),\n", 237 | " (65.14708955580183, 46.989962381825165),\n", 238 | " (41.4270073874473, 56.03934831955177),\n", 239 | " (34.43215476679175, 41.175438858170196)],\n", 240 | " 'metadata': {'color': ['green'], 'size': [20]},\n", 241 | " 'number': 1},\n", 242 | " 'lvl3': {'coordinate': [(86.86032233428452, 28.494259754144128),\n", 243 | " (78.9366351230743, 51.195317734397776),\n", 244 | " (74.2985289078018, 23.120910775523008),\n", 245 | " (45.201342880287385, 52.15987653068231),\n", 246 | " (50.2872820713999, 33.06623005705342),\n", 247 | " (20.18077171588657, 53.82982881322048),\n", 248 | " (99.8531453862991, 49.62018274660693),\n", 249 | " (80.34019551603302, 56.807938895355996),\n", 250 | " (39.8447045267557, 32.04209797205437),\n", 251 | " (57.47266702460668, 32.49081272743543)],\n", 252 | " 'metadata': {'color': ['blue',\n", 253 | " 'blue',\n", 254 | " 'blue',\n", 255 | " 'blue',\n", 256 | " 'blue',\n", 257 | " 'blue',\n", 258 | " 'blue',\n", 259 | " 'blue',\n", 260 | " 'blue',\n", 261 | " 'blue'],\n", 262 | " 'size': [30, 30, 30, 30, 30, 10, 10, 10, 10, 10]},\n", 263 | " 'number': 10}}" 264 | ] 265 | }, 266 | "execution_count": 132, 267 | "metadata": {}, 268 | "output_type": "execute_result" 269 | } 270 | ], 271 | "source": [ 272 | "expand_short_syntax(datasets_short_syntax)" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": {}, 278 | "source": [ 279 | "## Refactoring data\n", 280 | "\n", 281 | "It is much easier to work with coordinate and distance matrix where entities are sorted according to their coordinates" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": 133, 287 | "metadata": { 288 | "code_folding": [], 289 | "collapsed": true 290 | }, 291 | "outputs": [], 292 | "source": [ 293 | "def sort_coordinates(datasets):\n", 294 | " \"\"\"\n", 295 | " Sort coordinate of each dataset in increasing order\n", 296 | " \"\"\"\n", 297 | "\n", 298 | " for dataset in datasets:\n", 299 | " d = datasets[dataset]\n", 300 | "\n", 301 | " d[\"coordinate\"] = sorted(d[\"coordinate\"], key=lambda k: [k[0], k[1]])" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 134, 307 | "metadata": {}, 308 | "outputs": [], 309 | "source": [ 310 | "sort_coordinates(datasets)" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": {}, 316 | "source": [ 317 | "# Dataset representation" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "## Dot Plot" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": 135, 330 | "metadata": { 331 | "collapsed": true 332 | }, 333 | "outputs": [], 334 | "source": [ 335 | "def draw_dataset(datasets):\n", 336 | " \"\"\"\n", 337 | " Draw a dot plot of the given dataset\n", 338 | " \"\"\"\n", 339 | " G = nx.Graph()\n", 340 | " nbr_nodes = 0\n", 341 | "\n", 342 | " for dataset in datasets:\n", 343 | " d = datasets[dataset]\n", 344 | "\n", 345 | " for i,xy in enumerate(d[\"coordinate\"]):\n", 346 | " G.add_node(i+nbr_nodes,\n", 347 | " pos=xy,color=d[\"metadata\"][\"color\"][i],\n", 348 | " size=d[\"metadata\"][\"size\"][i])\n", 349 | "\n", 350 | " nbr_nodes += d[\"number\"]\n", 351 | "\n", 352 | " # Prepare drawing\n", 353 | " pos = nx.get_node_attributes(G,'pos')\n", 354 | " colors = list(nx.get_node_attributes(G,'color').values())\n", 355 | " size = list(nx.get_node_attributes(G,'size').values())\n", 356 | "\n", 357 | " # Draw\n", 358 | " nx.draw_networkx(\n", 359 | " G,pos, node_color=colors,\n", 360 | " node_size=size, with_labels=False\n", 361 | " )" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 136, 367 | "metadata": { 368 | "scrolled": false 369 | }, 370 | "outputs": [ 371 | { 372 | "data": { 373 | "image/png": "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\nAvT/AbBBJwU/8ngwAAAAAElFTkSuQmCC\n", 374 | "text/plain": [ 375 | "" 376 | ] 377 | }, 378 | "metadata": {}, 379 | "output_type": "display_data" 380 | } 381 | ], 382 | "source": [ 383 | "draw_dataset(datasets)" 384 | ] 385 | }, 386 | { 387 | "cell_type": "markdown", 388 | "metadata": {}, 389 | "source": [ 390 | "## Distance Matrices" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": 137, 396 | "metadata": { 397 | "collapsed": true 398 | }, 399 | "outputs": [], 400 | "source": [ 401 | "def distance_matrices(datasets):\n", 402 | " \"\"\"\n", 403 | " Return a dictionary containing all the distance matrices for a\n", 404 | " given instance of the problem\n", 405 | " \"\"\"\n", 406 | " M = {}\n", 407 | "\n", 408 | " for dataset1 in datasets:\n", 409 | " d1 = datasets[dataset1]\n", 410 | " for dataset2 in datasets:\n", 411 | " d2 = datasets[dataset2]\n", 412 | " \n", 413 | " M[dataset1+dataset2] = np.zeros((d1[\"number\"],d2[\"number\"]))\n", 414 | "\n", 415 | " for i,ixy in enumerate(d1[\"coordinate\"]):\n", 416 | " for j,jxy in enumerate(d2[\"coordinate\"]):\n", 417 | " M[dataset1+dataset2][i][j] = LA.norm(np.subtract(ixy,jxy))\n", 418 | " \n", 419 | " return M" 420 | ] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "execution_count": 138, 425 | "metadata": { 426 | "code_folding": [], 427 | "collapsed": true 428 | }, 429 | "outputs": [], 430 | "source": [ 431 | "# distance_matrices(datasets)" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 139, 437 | "metadata": { 438 | "collapsed": true 439 | }, 440 | "outputs": [], 441 | "source": [ 442 | "def distance_matrices_plot(datasets):\n", 443 | " \"\"\"\n", 444 | " Plot the matrix representation of a dataset\n", 445 | " \"\"\"\n", 446 | " dist = distance_matrices(datasets)\n", 447 | " len_datasets = len(datasets)\n", 448 | " fig = plt.figure()\n", 449 | "\n", 450 | " for i,dataset1 in enumerate(datasets):\n", 451 | " for j,dataset2 in enumerate(datasets):\n", 452 | " if j <= i:\n", 453 | " ax = fig.add_subplot(len_datasets,len_datasets,i+len_datasets*j+1)\n", 454 | " ax.set_aspect('equal')\n", 455 | " plt.imshow(dist[dataset1+dataset2], interpolation='nearest', cmap=plt.cm.ocean)\n", 456 | " if i == len_datasets-1:\n", 457 | " plt.colorbar()\n", 458 | "\n", 459 | " plt.show()" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 140, 465 | "metadata": {}, 466 | "outputs": [ 467 | { 468 | "data": { 469 | "image/png": "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\nQmCC\n", 470 | "text/plain": [ 471 | "" 472 | ] 473 | }, 474 | "metadata": {}, 475 | "output_type": "display_data" 476 | } 477 | ], 478 | "source": [ 479 | "distance_matrices_plot(datasets)" 480 | ] 481 | }, 482 | { 483 | "cell_type": "markdown", 484 | "metadata": { 485 | "collapsed": true 486 | }, 487 | "source": [ 488 | "# Dataset Metrics" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": { 495 | "collapsed": true 496 | }, 497 | "outputs": [], 498 | "source": [] 499 | } 500 | ], 501 | "metadata": { 502 | "hide_input": false, 503 | "kernelspec": { 504 | "display_name": "Py35", 505 | "language": "python", 506 | "name": "py35" 507 | }, 508 | "language_info": { 509 | "codemirror_mode": { 510 | "name": "ipython", 511 | "version": 3 512 | }, 513 | "file_extension": ".py", 514 | "mimetype": "text/x-python", 515 | "name": "python", 516 | "nbconvert_exporter": "python", 517 | "pygments_lexer": "ipython3", 518 | "version": "3.5.3" 519 | }, 520 | "toc": { 521 | "colors": { 522 | "hover_highlight": "#DAA520", 523 | "running_highlight": "#FF0000", 524 | "selected_highlight": "#FFD700" 525 | }, 526 | "moveMenuLeft": true, 527 | "nav_menu": { 528 | "height": "66px", 529 | "width": "252px" 530 | }, 531 | "navigate_menu": true, 532 | "number_sections": true, 533 | "sideBar": true, 534 | "threshold": 4, 535 | "toc_cell": false, 536 | "toc_section_display": "block", 537 | "toc_window_display": true, 538 | "widenNotebook": false 539 | } 540 | }, 541 | "nbformat": 4, 542 | "nbformat_minor": 2 543 | } 544 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB I-Problem Instance 1-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false, 7 | "deletable": true, 8 | "editable": true 9 | }, 10 | "source": [ 11 | "Problem instance 1\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": { 19 | "collapsed": true, 20 | "deletable": true, 21 | "editable": true 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "import pandas as pd" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": { 31 | "deletable": true, 32 | "editable": true 33 | }, 34 | "source": [ 35 | "# Input" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": { 41 | "deletable": true, 42 | "editable": true, 43 | "heading_collapsed": true 44 | }, 45 | "source": [ 46 | "## Customer Data\n", 47 | "* $x_i,y_i$ geometric position (cadran) of customer i\n", 48 | "* $q_{iv}$ quantity of return product variety v from customer i" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 9, 54 | "metadata": { 55 | "collapsed": true, 56 | "deletable": true, 57 | "editable": true, 58 | "hidden": true 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "Cus_coor = [(x,y) for x in range(20,100,10) for y in range(20,80,10)] + [(100,20),(100,30)]" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 10, 68 | "metadata": { 69 | "collapsed": false, 70 | "deletable": true, 71 | "editable": true, 72 | "hidden": true 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "Cus_qi1 = '10 5 7 4 8 12 11 9 13 14 17 19 16 4 5 9 8 7 4 14 2 3 5 12 6 4 12 2 4 5 7 4 3 16 10 2 20 5 6 4 14 8 10 19 24 10 12 22 11 14'.split()" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 11, 82 | "metadata": { 83 | "collapsed": true, 84 | "deletable": true, 85 | "editable": true, 86 | "hidden": true 87 | }, 88 | "outputs": [], 89 | "source": [ 90 | "Cus_qi2 = '8 15 9 15 6 6 9 8 8 6 4 3 5 19 13 4 12 5 5 7 8 2 15 5 15 13 6 8 14 5 13 7 4 5 6 4 6 15 12 7 7 22 16 21 18 18 14 14 20 19'.split()" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 12, 96 | "metadata": { 97 | "collapsed": true, 98 | "deletable": true, 99 | "editable": true, 100 | "hidden": true 101 | }, 102 | "outputs": [], 103 | "source": [ 104 | "Cus_qi3 = '7 5 9 6 11 7 5 8 4 5 4 3 4 2 7 12 5 13 16 4 15 20 5 8 4 8 7 15 7 15 5 14 18 4 9 19 4 10 12 19 9 10 14 10 8 12 9 9 9 17'.split()" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 16, 110 | "metadata": { 111 | "collapsed": false, 112 | "deletable": true, 113 | "editable": true, 114 | "hidden": true 115 | }, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/html": [ 120 | "
\n", 121 | "\n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | "
0123456789...40414243444546474849
0(20, 20)(20, 30)(20, 40)(20, 50)(20, 60)(20, 70)(30, 20)(30, 30)(30, 40)(30, 50)...(80, 60)(80, 70)(90, 20)(90, 30)(90, 40)(90, 50)(90, 60)(90, 70)(100, 20)(100, 30)
1105748121191314...1481019241012221114
2815915669886...7221621181814142019
375961175845...910141081299917
\n", 247 | "

4 rows × 50 columns

\n", 248 | "
" 249 | ], 250 | "text/plain": [ 251 | " 0 1 2 3 4 5 6 \\\n", 252 | "0 (20, 20) (20, 30) (20, 40) (20, 50) (20, 60) (20, 70) (30, 20) \n", 253 | "1 10 5 7 4 8 12 11 \n", 254 | "2 8 15 9 15 6 6 9 \n", 255 | "3 7 5 9 6 11 7 5 \n", 256 | "\n", 257 | " 7 8 9 ... 40 41 42 \\\n", 258 | "0 (30, 30) (30, 40) (30, 50) ... (80, 60) (80, 70) (90, 20) \n", 259 | "1 9 13 14 ... 14 8 10 \n", 260 | "2 8 8 6 ... 7 22 16 \n", 261 | "3 8 4 5 ... 9 10 14 \n", 262 | "\n", 263 | " 43 44 45 46 47 48 49 \n", 264 | "0 (90, 30) (90, 40) (90, 50) (90, 60) (90, 70) (100, 20) (100, 30) \n", 265 | "1 19 24 10 12 22 11 14 \n", 266 | "2 21 18 18 14 14 20 19 \n", 267 | "3 10 8 12 9 9 9 17 \n", 268 | "\n", 269 | "[4 rows x 50 columns]" 270 | ] 271 | }, 272 | "execution_count": 16, 273 | "metadata": {}, 274 | "output_type": "execute_result" 275 | } 276 | ], 277 | "source": [ 278 | "pd.DataFrame([Cus_coor,Cus_qi1,Cus_qi2,Cus_qi3])" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": { 284 | "deletable": true, 285 | "editable": true, 286 | "heading_collapsed": true 287 | }, 288 | "source": [ 289 | "## Product Data\n", 290 | "* $P_k$ Range of probability for deciding the product quality level k of customer i\n", 291 | "* $nq$ number of product quality levels" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": 18, 297 | "metadata": { 298 | "collapsed": true, 299 | "deletable": true, 300 | "editable": true, 301 | "hidden": true 302 | }, 303 | "outputs": [], 304 | "source": [ 305 | "nq = 3" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 20, 311 | "metadata": { 312 | "collapsed": true, 313 | "deletable": true, 314 | "editable": true, 315 | "hidden": true 316 | }, 317 | "outputs": [], 318 | "source": [ 319 | "P_A = (0.6, 1.0)\n", 320 | "P_B = (0.4, 0.6)\n", 321 | "P_C = (0.01, 0.4)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": { 327 | "deletable": true, 328 | "editable": true, 329 | "heading_collapsed": true 330 | }, 331 | "source": [ 332 | "## ICP, CRC,Vehicle data\n", 333 | "* $t,s,a$ total number of ICP, CRC, Vehicle\n", 334 | "* $Q_j,Q_c,Q_b$ capacity of ICP j, CRC c, Vehicle b\n", 335 | "* $FTC_j,FCR_c,FCV_$ fixed cost of establishing ICP j" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 21, 341 | "metadata": { 342 | "collapsed": true, 343 | "deletable": true, 344 | "editable": true, 345 | "hidden": true 346 | }, 347 | "outputs": [], 348 | "source": [ 349 | "t = 8\n", 350 | "s = 2\n", 351 | "a = 2" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 24, 357 | "metadata": { 358 | "collapsed": true, 359 | "deletable": true, 360 | "editable": true, 361 | "hidden": true 362 | }, 363 | "outputs": [], 364 | "source": [ 365 | "Q_j = 200\n", 366 | "Q_c = 800\n", 367 | "Q_b = 800" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": 25, 373 | "metadata": { 374 | "collapsed": true, 375 | "deletable": true, 376 | "editable": true, 377 | "hidden": true 378 | }, 379 | "outputs": [], 380 | "source": [ 381 | "FTC_j = 100\n", 382 | "FCR_c = 200\n", 383 | "FCV_b = 300" 384 | ] 385 | }, 386 | { 387 | "cell_type": "markdown", 388 | "metadata": { 389 | "deletable": true, 390 | "editable": true, 391 | "heading_collapsed": true 392 | }, 393 | "source": [ 394 | "## Processing center Data\n", 395 | "x,y geometric position (cadran) of prcessing center" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 27, 401 | "metadata": { 402 | "collapsed": true, 403 | "deletable": true, 404 | "editable": true, 405 | "hidden": true 406 | }, 407 | "outputs": [], 408 | "source": [ 409 | "x = 100\n", 410 | "y = 60" 411 | ] 412 | }, 413 | { 414 | "cell_type": "markdown", 415 | "metadata": { 416 | "deletable": true, 417 | "editable": true 418 | }, 419 | "source": [ 420 | "# Inspection result" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": null, 426 | "metadata": { 427 | "collapsed": true, 428 | "deletable": true, 429 | "editable": true 430 | }, 431 | "outputs": [], 432 | "source": [] 433 | }, 434 | { 435 | "cell_type": "markdown", 436 | "metadata": { 437 | "deletable": true, 438 | "editable": true, 439 | "heading_collapsed": true 440 | }, 441 | "source": [ 442 | "# Outputs" 443 | ] 444 | }, 445 | { 446 | "cell_type": "markdown", 447 | "metadata": { 448 | "deletable": true, 449 | "editable": true, 450 | "hidden": true 451 | }, 452 | "source": [ 453 | "## ICP result\n", 454 | "* $N_j$ =1 if ICP j is open\n", 455 | "* $x_j,y_j$ geometric position of ICP\n", 456 | "* $V_j$ number of unit allocated\n", 457 | "* $n_j$ number of customer allocated" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": { 463 | "deletable": true, 464 | "editable": true, 465 | "hidden": true 466 | }, 467 | "source": [ 468 | "## CRC result\n", 469 | "* $N_c$ =1 if CRC j is open\n", 470 | "* $x_c,y_c$ geometric position of ICP\n", 471 | "* $V_c$ number of unit allocated\n", 472 | "* $n_c$ number of customer allocated" 473 | ] 474 | }, 475 | { 476 | "cell_type": "markdown", 477 | "metadata": { 478 | "deletable": true, 479 | "editable": true, 480 | "hidden": true 481 | }, 482 | "source": [ 483 | "## Vehicle routing result\n", 484 | "* $ Y_{ij} = 1$ if custoner i is associated to ICP j\n", 485 | "* $ X_{cj} = 1$ if ICP j is associated with CRC c\n", 486 | "* $ Z_{cjb} = 1$ if vehicle b trqvel from CRC b to ICP j on route b" 487 | ] 488 | }, 489 | { 490 | "cell_type": "markdown", 491 | "metadata": {}, 492 | "source": [ 493 | "# Solution visualization" 494 | ] 495 | } 496 | ], 497 | "metadata": { 498 | "kernelspec": { 499 | "display_name": "Python 3.5", 500 | "language": "python", 501 | "name": "py35" 502 | }, 503 | "language_info": { 504 | "codemirror_mode": { 505 | "name": "ipython", 506 | "version": 3 507 | }, 508 | "file_extension": ".py", 509 | "mimetype": "text/x-python", 510 | "name": "python", 511 | "nbconvert_exporter": "python", 512 | "pygments_lexer": "ipython3", 513 | "version": "3.5.3" 514 | }, 515 | "toc": { 516 | "colors": { 517 | "hover_highlight": "#DAA520", 518 | "running_highlight": "#FF0000", 519 | "selected_highlight": "#FFD700" 520 | }, 521 | "moveMenuLeft": true, 522 | "nav_menu": { 523 | "height": "210px", 524 | "width": "252px" 525 | }, 526 | "navigate_menu": true, 527 | "number_sections": true, 528 | "sideBar": true, 529 | "threshold": 4, 530 | "toc_cell": false, 531 | "toc_section_display": "block", 532 | "toc_window_display": false 533 | } 534 | }, 535 | "nbformat": 4, 536 | "nbformat_minor": 2 537 | } 538 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB II-Objective Function-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "# Objective function" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "$$\n", 26 | "\\begin{align}\n", 27 | " TC1 = \\\\\n", 28 | " &\\tag{1.1} \\sum_{i \\in I}\\sum_{j \\in J} [(x_i - \\bar{x_j})^2 + (y_i - \\bar{y_j})^2]^{1/2} Y_{ij} \\\\\n", 29 | " &\\tag{1.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+D_c) Z_{cjb} \\\\\n", 30 | " &\\tag{1.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 31 | " &\\tag{1.4} + \\sum_{c \\in C}FCR_c N_c \\\\\n", 32 | " &\\tag{1.5} + \\sum_{b \\in B}FCV_b\\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}Z_{ijb}\\\\\n", 33 | " &\\tag{1.6} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} IP_{ikv} \\\\\n", 34 | " &\\tag{1.7} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} PC_{ikv}\n", 35 | "\\end{align}\n", 36 | "$$" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "$$\n", 44 | "\\begin{align}\n", 45 | " TC2 = \\\\\n", 46 | " &\\tag{2.1} \\sum_{i \\in I}\\sum_{j \\in J} w_{ij} Y_{ij} \\\\\n", 47 | " &\\tag{2.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+FCV_b) Z_{cjb} \\\\\n", 48 | " &\\tag{2.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 49 | " &\\tag{2.4} + \\sum_{c \\in C}(FCR_c+D_c) N_c \\\\\n", 50 | " &\\tag{2.5} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} (PC_{ikv}+IP_{ikv})\n", 51 | "\\end{align}\n", 52 | "$$" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 14, 63 | "metadata": { 64 | "collapsed": true 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "def objective_lr_II(Y,Z,Nj,Nc,\n", 69 | " I,J,B,K,V,\n", 70 | " w,Dcj,FCV,FCT,FCR,Dc,q,PC,IP):\n", 71 | " \"\"\"\n", 72 | " Parameters:\n", 73 | " Sets:\n", 74 | " I,J,C,K,V,B -> customer, ICPs, CRCs, qualities, varieties, vehicles\n", 75 | " Costs:\n", 76 | " FCT, FCR, FCV, fixed cost for ICP, CRC, vehicle\n", 77 | " IP, PC acquisition and processiong cost\n", 78 | " Weight:\n", 79 | " q, nbr unit collected\n", 80 | " w, Dcj, Dc cost related to traveling distances cus-ICP, ICP-CRC, CRC-PC\n", 81 | " \n", 82 | " Decision Vqriables:\n", 83 | " Y_ij customer i associated to ICP j\n", 84 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 85 | " N_icp, N_crc -> ICP / CRC i is open\n", 86 | " \"\"\"\n", 87 | " sum2_1 = 0\n", 88 | " for i in range(I):\n", 89 | " for j in range(J):\n", 90 | " sum2_1 += w[i][j] + Y[i][j]\n", 91 | " \n", 92 | " sum2_2 = 0\n", 93 | " for c in range(C+J):\n", 94 | " for j in range(C+J):\n", 95 | " for b in range(B):\n", 96 | " sum2_2 += (Dcj[c][j] + FCV[b]) * Z[c][j][b]\n", 97 | " \n", 98 | " sum2_3 = 0\n", 99 | " for j in range(J):\n", 100 | " sum2_3 += FCT[j] * N[j]\n", 101 | " \n", 102 | " sum2_4 = 0\n", 103 | " for c in range(C):\n", 104 | " sum2_4 += (FCT[c] + D[c]) * N[c]\n", 105 | " \n", 106 | " return sum2_1+sum2_2+sum2_3+sum2_4, sum2_1, sum2_2, sum2_3, sum2_4" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": { 113 | "collapsed": true 114 | }, 115 | "outputs": [], 116 | "source": [] 117 | } 118 | ], 119 | "metadata": { 120 | "hide_input": false, 121 | "kernelspec": { 122 | "display_name": "Py35", 123 | "language": "python", 124 | "name": "py35" 125 | }, 126 | "language_info": { 127 | "codemirror_mode": { 128 | "name": "ipython", 129 | "version": 3 130 | }, 131 | "file_extension": ".py", 132 | "mimetype": "text/x-python", 133 | "name": "python", 134 | "nbconvert_exporter": "python", 135 | "pygments_lexer": "ipython3", 136 | "version": "3.5.3" 137 | }, 138 | "toc": { 139 | "colors": { 140 | "hover_highlight": "#DAA520", 141 | "running_highlight": "#FF0000", 142 | "selected_highlight": "#FFD700" 143 | }, 144 | "moveMenuLeft": true, 145 | "nav_menu": { 146 | "height": "30px", 147 | "width": "252px" 148 | }, 149 | "navigate_menu": true, 150 | "number_sections": true, 151 | "sideBar": true, 152 | "threshold": 4, 153 | "toc_cell": false, 154 | "toc_section_display": "block", 155 | "toc_window_display": false, 156 | "widenNotebook": false 157 | } 158 | }, 159 | "nbformat": 4, 160 | "nbformat_minor": 2 161 | } 162 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB III-LR linear programming-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 2 6 | } 7 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB IV - Problems Book R-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 2 6 | } 7 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/NB VI - Final Program-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import csv\n", 12 | "import math as m\n", 13 | "from random import uniform as unif\n", 14 | "import networkx as nx\n", 15 | "import pandas as pd\n", 16 | "import os\n", 17 | "\n", 18 | "import numpy as np\n", 19 | "import matplotlib as mpl\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from IPython.display import display, HTML\n", 22 | "%matplotlib inline\n", 23 | "\n", 24 | "%load_ext autoreload\n", 25 | "%autoreload 2" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": { 32 | "collapsed": true 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "expid = \"./exp3_run8\"" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "metadata": { 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "if not os.path.exists(expid):\n", 48 | " os.makedirs(expid)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "# Problem instance" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "heading_collapsed": true 62 | }, 63 | "source": [ 64 | "## Geographic data" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "collapsed": true, 72 | "hidden": true 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "from pkg.read_problem import read_problem, extract_problem" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": { 83 | "collapsed": true, 84 | "hidden": true 85 | }, 86 | "outputs": [], 87 | "source": [ 88 | "xy_customers, xy_icps, xy_crcs, xy_pc, q = read_problem('./datasets/original')" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": { 95 | "collapsed": true, 96 | "hidden": true 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "xy_icps = xy_icps + [[unif(20,100),unif(20,70)] for i in range(5)]\n", 101 | "xy_crcs = xy_crcs + [[unif(20,100),unif(20,70)] for i in range(5)]" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": true, 109 | "hidden": true, 110 | "run_control": { 111 | "marked": false 112 | } 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "I,J,C,B,K,V,W,DjUc,Dcj,Dc,FCV,FCT,FCR,U = extract_problem(xy_customers, xy_icps, xy_crcs, xy_pc, q)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": { 122 | "heading_collapsed": true 123 | }, 124 | "source": [ 125 | "## Capacity constraints" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": { 132 | "collapsed": true, 133 | "hidden": true 134 | }, 135 | "outputs": [], 136 | "source": [ 137 | "Q_icp = [200 for j in range(J)]\n", 138 | "Q_crc = [800 for c in range(C)]\n", 139 | "V = [Q_icp,Q_crc]" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": { 145 | "heading_collapsed": true 146 | }, 147 | "source": [ 148 | "## Adapting costs" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "metadata": { 155 | "collapsed": true, 156 | "hidden": true 157 | }, 158 | "outputs": [], 159 | "source": [ 160 | "# two-level cost\n", 161 | "FCRD = []\n", 162 | "for c in range(C):\n", 163 | " FCRD.append(FCR[c] + Dc[c])\n", 164 | "\n", 165 | "f = FCT+FCRD\n", 166 | "c = [[[W[i][j1] + Dcj[j1][j2] for j2 in range(C)] for j1 in range(J)] for i in range(I)]" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": { 172 | "heading_collapsed": true 173 | }, 174 | "source": [ 175 | "# Plot Problem" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "metadata": { 182 | "hidden": true 183 | }, 184 | "outputs": [], 185 | "source": [ 186 | "from pkg.lrp_nodes_graph import lrp_nodes_graph, lrp_draw_and_save\n", 187 | "G, pos, labels, colors, size = lrp_nodes_graph(xy_customers, xy_icps, xy_crcs, xy_pc)\n", 188 | "\n", 189 | "lrp_draw_and_save(G, pos, labels, colors, size, expid+\"/problem.png\")" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": { 196 | "hidden": true 197 | }, 198 | "outputs": [], 199 | "source": [ 200 | "%%file \"./pkg/draw_solution_II.py\"\n", 201 | "\n", 202 | "def draw_solution_II(I,J,C,\n", 203 | " N_crc, N_icp,\n", 204 | " Y1,Y2, routes, expid,\n", 205 | " G, pos, labels, colors, size, path=None):\n", 206 | " \n", 207 | " from IPython.display import display, HTML\n", 208 | " import pandas as pd\n", 209 | " from pkg.draw_solution_II import draw_solution_II\n", 210 | " from pkg.lrp_nodes_graph import lrp_nodes_graph, lrp_draw_and_save\n", 211 | " \n", 212 | " H1 = [j for j,vj in enumerate(N_icp) if vj > 0.5]\n", 213 | " \n", 214 | " ###############################\n", 215 | " # DataFrames\n", 216 | " display(pd.DataFrame(N_crc).transpose())\n", 217 | " display(pd.DataFrame(N_icp).transpose())\n", 218 | " display(pd.DataFrame(routes).transpose()) \n", 219 | " ###############################\n", 220 | " # Network\n", 221 | " G2 = G.copy()\n", 222 | " colors = colors[:];size = size[:]; labels = labels.copy()\n", 223 | " # ICP-Cus\n", 224 | " for j,vj in enumerate(Y1):\n", 225 | " for i,vi in enumerate(vj):\n", 226 | " if vi == 1:\n", 227 | " G2.add_edge(I+i,j)\n", 228 | " # ICP\n", 229 | " for j,vj in enumerate(N_icp):\n", 230 | " if vj < 0.5:\n", 231 | " colors[I+j] = \"grey\"\n", 232 | " labels[I+j] = \"\"\n", 233 | " size[I+j] = 50\n", 234 | "\n", 235 | " # ICP-CRC\n", 236 | " for j,vj in enumerate(Y2):\n", 237 | " for i,vi in enumerate(vj):\n", 238 | " if vi == 1:\n", 239 | " G2.add_edge(I+J+i,I+H1[j])\n", 240 | " # CRC\n", 241 | " for j,vj in enumerate(N_crc):\n", 242 | " if vj < 0.5:\n", 243 | " colors[I+J+j] = \"grey\"\n", 244 | " labels[I+J+j] = \"\"\n", 245 | " size[I+J+j] = 50\n", 246 | "\n", 247 | " # Routes\n", 248 | " for r,vr in enumerate(routes):\n", 249 | " for c, vc in enumerate(vr):\n", 250 | " G2.add_edge(I+vc[0],I+vc[1])\n", 251 | "\n", 252 | " lrp_draw_and_save(G2, pos, labels, colors, size, path)\n", 253 | " \n", 254 | " return G2" 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": {}, 260 | "source": [ 261 | "# Define Functions" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "## Capacity problem" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": null, 274 | "metadata": { 275 | "code_folding": [], 276 | "run_control": { 277 | "marked": false 278 | } 279 | }, 280 | "outputs": [], 281 | "source": [ 282 | "%%file \"./pkg/capacity_vector.py\"\n", 283 | "\n", 284 | "import numpy as np\n", 285 | "\n", 286 | "def capacity_vector(Y,U,J,Q):\n", 287 | " cluster_q = np.zeros(J)\n", 288 | " violated = []\n", 289 | " for i,vi in enumerate(Y):\n", 290 | " for j,vj in enumerate(vi):\n", 291 | " cluster_q[j] += U[i]*Y[i][j]\n", 292 | " \n", 293 | " for j,vj in enumerate(cluster_q):\n", 294 | " if cluster_q[j] > Q[j]:\n", 295 | " violated.append(j)\n", 296 | " \n", 297 | " return cluster_q, violated" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": null, 303 | "metadata": { 304 | "collapsed": true 305 | }, 306 | "outputs": [], 307 | "source": [ 308 | "from pkg.capacity_vector import capacity_vector" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": null, 314 | "metadata": { 315 | "code_folding": [ 316 | 0 317 | ] 318 | }, 319 | "outputs": [], 320 | "source": [ 321 | "%%file \"./pkg/capacity_balancing.py\"\n", 322 | "\n", 323 | "import numpy as np\n", 324 | "from pkg.capacity_vector import capacity_vector\n", 325 | "\n", 326 | "def capacity_balancing(Y,W,U,J,Q,N_icp):\n", 327 | " l = len(capacity_vector(Y,U,J,Q)[1])\n", 328 | " max_loop = 10;\n", 329 | "\n", 330 | " # capacity balancing\n", 331 | " Ycp = np.copy(Y)\n", 332 | " Wcp = np.copy(W)\n", 333 | " while l != 0:\n", 334 | " max_loop +=-1\n", 335 | " j = capacity_vector(Ycp,U,J,Q)[1][0]\n", 336 | " i = np.argmax(np.multiply(Ycp,W)[:,j])\n", 337 | " # Find condidate and update\n", 338 | " Ycp[i][j] = 0\n", 339 | " Wcp[i][j] = 100\n", 340 | " stop = False\n", 341 | " while not stop:\n", 342 | " candidate = np.argmin(Wcp[i])\n", 343 | " if N_icp[candidate] > 0.5 and candidate != j:\n", 344 | " stop = True\n", 345 | " else:\n", 346 | " Wcp[i][candidate] = 200\n", 347 | "\n", 348 | " print(i,j,candidate)\n", 349 | "\n", 350 | " Ycp[i][candidate] = 1\n", 351 | " Wcp[i][candidate] = 100\n", 352 | "\n", 353 | " l = len(capacity_vector(Ycp,U,J,Q)[1])\n", 354 | " \n", 355 | " return Ycp" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "metadata": { 362 | "collapsed": true 363 | }, 364 | "outputs": [], 365 | "source": [ 366 | "from pkg.capacity_balancing import capacity_balancing" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "metadata": {}, 372 | "source": [ 373 | "## Swap problem" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": { 380 | "code_folding": [] 381 | }, 382 | "outputs": [], 383 | "source": [ 384 | "%%file \"./pkg/swap_list_icp.py\"\n", 385 | "import numpy as np\n", 386 | "\n", 387 | "def swap_list_icp(Y,W,Djj,N):\n", 388 | " cluster_len = np.max(np.multiply(Y,W),axis=0)\n", 389 | " swaps = []\n", 390 | " for j,l in enumerate(cluster_len):\n", 391 | " for j_bis,n in enumerate(DjUc[j]):\n", 392 | " if n 0.5]\n", 552 | " asso = np.argmin(np.transpose(W)[H1],axis=0)\n", 553 | " new_Y = np.zeros((I,J))\n", 554 | " for a,va in enumerate(asso):\n", 555 | " new_Y[a][H1[va]] = 1\n", 556 | " return new_Y" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": null, 562 | "metadata": {}, 563 | "outputs": [], 564 | "source": [ 565 | "from pkg.draw_solution_II import draw_solution_II\n", 566 | "from pkg.new_assignement import new_assignement" 567 | ] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "metadata": {}, 572 | "source": [ 573 | "## final Algorithm" 574 | ] 575 | }, 576 | { 577 | "cell_type": "markdown", 578 | "metadata": {}, 579 | "source": [ 580 | "### Step 1\n", 581 | "\n", 582 | "Find the initial solution SO" 583 | ] 584 | }, 585 | { 586 | "cell_type": "code", 587 | "execution_count": null, 588 | "metadata": { 589 | "collapsed": true 590 | }, 591 | "outputs": [], 592 | "source": [ 593 | "best_solution = []" 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": {}, 599 | "source": [ 600 | "solving with Cplex two p-MD problem" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "execution_count": null, 606 | "metadata": {}, 607 | "outputs": [], 608 | "source": [ 609 | "%%time\n", 610 | "# %%file \"./pkg/pmd_first_tsp_second.py\"\n", 611 | "\n", 612 | "# def pmd_first_tsp_second(G,pos, labels, colors, size,\n", 613 | "# I,J,C,\n", 614 | "# W1,W2,W3,F1,F2,\n", 615 | "# U,Q_icp,Q_crc,\n", 616 | "# plots=True, expid=\"\"):\n", 617 | " \n", 618 | "from pkg.cflp_cplex import cflp_cplex\n", 619 | "from pkg.pm_flp_cplex import pm_flp_cplex\n", 620 | "from pkg.tsp_cplex import tsp_cplex\n", 621 | "from pkg.read_problem import read_problem, extract_problem\n", 622 | "from pkg.draw_solution_II import draw_solution_II\n", 623 | "from pkg.lrp_nodes_graph import lrp_nodes_graph, lrp_draw_and_save\n", 624 | "import numpy as np\n", 625 | "import pandas as pd\n", 626 | "from IPython.display import display, HTML\n", 627 | "\n", 628 | "W1,W2,W3,F1,F2 = W,Dcj,DjUc,FCT,FCRD\n", 629 | "plots = True\n", 630 | "\n", 631 | "#######################################################################\n", 632 | "# 1 Solve first problem\n", 633 | "prob1, Y1, N_icp = pm_flp_cplex(I,J,\n", 634 | " W1,8,\n", 635 | " relaxation=False)\n", 636 | "\n", 637 | "#######################################################################\n", 638 | "# 2 Prepare 2nd problem\n", 639 | "H1 = [j for j,vj in enumerate(N_icp) if vj > 0.5]\n", 640 | "\n", 641 | "# 12 Prepare 2nd problem\n", 642 | "Y1_capa = capacity_balancing(Y1,W,U,J,Q_icp,N_icp)\n", 643 | "\n", 644 | "c2=[]; u2=[];\n", 645 | "for j in H1:\n", 646 | " c2.append(W2[j])\n", 647 | " sqi = 0\n", 648 | " for i in range(I):\n", 649 | " sqi += U[i]*Y1[i][j]\n", 650 | " u2.append(sqi)\n", 651 | "\n", 652 | "####################################################################### \n", 653 | "# 3. Solve Second problem\n", 654 | "prob2, Y2, N_crc = pm_flp_cplex(len(u2),C,\n", 655 | " c2,2,\n", 656 | " relaxation=False)" 657 | ] 658 | }, 659 | { 660 | "cell_type": "markdown", 661 | "metadata": {}, 662 | "source": [ 663 | "Solving with Cplex p TSP" 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": null, 669 | "metadata": {}, 670 | "outputs": [], 671 | "source": [ 672 | "%%time\n", 673 | "#######################################################################\n", 674 | "# Preparing TSP\n", 675 | "H2 = [j for j,vj in enumerate(N_crc) if vj > 0.5]\n", 676 | "tY2 = np.transpose(Y2)\n", 677 | "W3 = np.asarray(W3)\n", 678 | "\n", 679 | "#/!\\ Use H1 as a labeling array\n", 680 | "\n", 681 | "S_tsp = [] #set of ICP in each TSP\n", 682 | "for c,vc in enumerate(H2):\n", 683 | " S_tsp.append([H1[j] for j,vj in enumerate(tY2[c]) if vj > 0.5]+[J+vc])\n", 684 | "\n", 685 | "w_tsp = []\n", 686 | "for submat in S_tsp:\n", 687 | " w_tsp.append(W3[submat,:][:,submat])\n", 688 | "#######################################################################\n", 689 | "# Solving TSP\n", 690 | "routes = []\n", 691 | "for c,vc in enumerate(w_tsp):\n", 692 | " prob, X = tsp_cplex(len(vc),vc, relaxation=False)\n", 693 | " # Extract routes\n", 694 | " path = []\n", 695 | " for j,xj in enumerate(X):\n", 696 | " for i,xij in enumerate(xj):\n", 697 | " if xij == 1:\n", 698 | " path.append((S_tsp[c][i],S_tsp[c][j]))\n", 699 | " routes.append(path)\n", 700 | "#######################################################################\n", 701 | "# Draw solution\n", 702 | "if(plots):\n", 703 | " draw_solution_II(I,J,C,N_crc, N_icp,\n", 704 | " Y1,Y2, routes, expid,\n", 705 | " G, pos, labels, colors, size)\n", 706 | "\n", 707 | "#######################################################################\n", 708 | "# Compute objective funtion\n", 709 | "obj = objective_III(Y1,routes,N_icp, N_crc,\n", 710 | " I,J,C,B,\n", 711 | " W,DjUc,Dc,\n", 712 | " FCV,FCT,FCR)\n", 713 | "\n", 714 | "best_solution = { \"obj\" : obj,\n", 715 | " \"Y1\" : Y1,\n", 716 | " \"Y2\" : Y2,\n", 717 | " \"N_crc\" : N_crc,\n", 718 | " \"N_icp\" : N_icp,\n", 719 | " \"routes\" : routes}\n", 720 | "\n", 721 | "obj" 722 | ] 723 | }, 724 | { 725 | "cell_type": "markdown", 726 | "metadata": {}, 727 | "source": [ 728 | "### Step 2\n", 729 | "\n", 730 | "Swapping loop for ICP" 731 | ] 732 | }, 733 | { 734 | "cell_type": "code", 735 | "execution_count": null, 736 | "metadata": { 737 | "scrolled": false 738 | }, 739 | "outputs": [], 740 | "source": [ 741 | "%%time\n", 742 | "# ICP swaping\n", 743 | "swap_list_icp = swap_list_byRoute(best_solution[\"Y1\"],W,DjUc,best_solution[\"N_icp\"],best_solution[\"routes\"])\n", 744 | "swap_result = []\n", 745 | "for iswap, swap in enumerate(swap_list_icp):\n", 746 | "\n", 747 | " routes_swap, N_icp_swap = swap_arcs(swap, best_solution[\"routes\"], best_solution[\"N_icp\"])\n", 748 | " new_Y = new_assignement(I,J,W,N_icp_swap)\n", 749 | " new_Y = capacity_balancing(new_Y,W,U,J,Q_icp,best_solution[\"N_icp\"])\n", 750 | " # Draw\n", 751 | " draw_solution_II(I,J,C,N_crc, N_icp_swap,\n", 752 | " new_Y, np.zeros((3,8)), routes_swap.tolist(), expid,\n", 753 | " G, pos, labels, colors, size, path=expid+ \"/\"+ str(iswap) +\"_swap.png\")\n", 754 | " plt.clf();plt.cla();plt.close()\n", 755 | " # Solution\n", 756 | " swap_result.append(objective_III(new_Y,routes_swap,N_icp_swap, N_crc,\n", 757 | " I,J,C,B,\n", 758 | " W,DjUc,Dc,\n", 759 | " FCV,FCT,FCR))" 760 | ] 761 | }, 762 | { 763 | "cell_type": "code", 764 | "execution_count": null, 765 | "metadata": {}, 766 | "outputs": [], 767 | "source": [ 768 | "len(swap_result)" 769 | ] 770 | }, 771 | { 772 | "cell_type": "markdown", 773 | "metadata": {}, 774 | "source": [ 775 | "### Step 3\n", 776 | "\n", 777 | "Swappinf loop for CRC" 778 | ] 779 | }, 780 | { 781 | "cell_type": "code", 782 | "execution_count": null, 783 | "metadata": { 784 | "collapsed": true 785 | }, 786 | "outputs": [], 787 | "source": [ 788 | "new_Dcj = [Dcj[j] for j,vj in enumerate(best_solution[\"N_icp\"]) if vj > 0.5]" 789 | ] 790 | }, 791 | { 792 | "cell_type": "code", 793 | "execution_count": null, 794 | "metadata": { 795 | "collapsed": true, 796 | "run_control": { 797 | "marked": false 798 | } 799 | }, 800 | "outputs": [], 801 | "source": [ 802 | "new_DjUc = [[DjUc[c][j] for c in range(J,C+J,1)] for j in range(J,C+J,1) ]" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | "execution_count": null, 808 | "metadata": {}, 809 | "outputs": [], 810 | "source": [ 811 | "range(J,C+J,1)" 812 | ] 813 | }, 814 | { 815 | "cell_type": "code", 816 | "execution_count": null, 817 | "metadata": {}, 818 | "outputs": [], 819 | "source": [ 820 | "swap_list_crc = swap_list_crc(best_solution[\"Y2\"],new_Dcj,new_DjUc,best_solution[\"N_crc\"])" 821 | ] 822 | }, 823 | { 824 | "cell_type": "code", 825 | "execution_count": null, 826 | "metadata": {}, 827 | "outputs": [], 828 | "source": [ 829 | "swap_list_crc" 830 | ] 831 | }, 832 | { 833 | "cell_type": "code", 834 | "execution_count": null, 835 | "metadata": { 836 | "collapsed": true 837 | }, 838 | "outputs": [], 839 | "source": [ 840 | "import copy" 841 | ] 842 | }, 843 | { 844 | "cell_type": "code", 845 | "execution_count": null, 846 | "metadata": {}, 847 | "outputs": [], 848 | "source": [ 849 | "# swap\n", 850 | "best_solution_route_to_swap = copy.deepcopy(best_solution[\"routes\"])\n", 851 | "swap_crc1 = swap_list_crc[2]\n", 852 | "\n", 853 | "remove = swap_crc1[0] + J\n", 854 | "introduce = swap_crc1[1] + J\n", 855 | "print(remove,introduce)\n", 856 | "\n", 857 | "N_crc_swap = copy.deepcopy(best_solution[\"N_crc\"])\n", 858 | "\n", 859 | "N_crc_swap[swap_crc1[0]] = 0\n", 860 | "N_crc_swap[swap_crc1[1]] = 1\n", 861 | "\n", 862 | "for iroute,route in enumerate(best_solution_route_to_swap):\n", 863 | " for iarc,arc in enumerate(route):\n", 864 | " if arc[0] == remove:\n", 865 | " best_solution_route_to_swap[iroute][iarc] = (introduce, best_solution_route_to_swap[iroute][iarc][1])\n", 866 | " if arc[1] == remove:\n", 867 | " best_solution_route_to_swap[iroute][iarc] = (best_solution_route_to_swap[iroute][iarc][0], introduce)" 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "execution_count": null, 873 | "metadata": {}, 874 | "outputs": [], 875 | "source": [ 876 | "best_solution_route_to_swap" 877 | ] 878 | }, 879 | { 880 | "cell_type": "code", 881 | "execution_count": null, 882 | "metadata": {}, 883 | "outputs": [], 884 | "source": [ 885 | "draw_solution_II(I,J,C,N_crc_swap, best_solution[\"N_icp\"],\n", 886 | " new_Y, np.zeros((3,8)), best_solution_route_to_swap, expid,\n", 887 | " G, pos, labels, colors, size, path=expid+ \"/\"+ str(iswap) +\"_swap_crc.png\")\n", 888 | "\n", 889 | "objective_III(new_Y,best_solution_route_to_swap,best_solution[\"N_icp\"], N_crc_swap,\n", 890 | " I,J,C,B,\n", 891 | " W,DjUc,Dc,\n", 892 | " FCV,FCT,FCR)" 893 | ] 894 | }, 895 | { 896 | "cell_type": "code", 897 | "execution_count": null, 898 | "metadata": { 899 | "code_folding": [] 900 | }, 901 | "outputs": [], 902 | "source": [ 903 | "# This is the loop vertion for creatinf picture of the each possible swap\n", 904 | "for iswap,swap_crc1 in enumerate(swap_list_crc):\n", 905 | " print(swap_crc1)\n", 906 | "\n", 907 | " best_solution_route_to_swap = copy.deepcopy(best_solution[\"routes\"])\n", 908 | "\n", 909 | " remove = swap_crc1[0] + J\n", 910 | " introduce = swap_crc1[1] + J\n", 911 | " print(remove,introduce)\n", 912 | "\n", 913 | " N_crc_swap = best_solution[\"N_crc\"]\n", 914 | "\n", 915 | " N_crc_swap[swap_crc1[0]] = 0\n", 916 | " N_crc_swap[swap_crc1[1]] = 1\n", 917 | "\n", 918 | " for iroute,route in enumerate(best_solution_route_to_swap):\n", 919 | " for iarc,arc in enumerate(route):\n", 920 | " if arc[0] == remove:\n", 921 | " best_solution_route_to_swap[iroute][iarc] = (introduce, best_solution_route_to_swap[iroute][iarc][1])\n", 922 | " if arc[1] == remove:\n", 923 | " best_solution_route_to_swap[iroute][iarc] = (best_solution_route_to_swap[iroute][iarc][0], introduce)\n", 924 | "\n", 925 | " draw_solution_II(I,J,C,N_crc_swap, best_solution[\"N_icp\"],\n", 926 | " new_Y, np.zeros((3,8)), best_solution_route_to_swap, expid,\n", 927 | " G, pos, labels, colors, size, path=expid+ \"/\"+ str(iswap) +\"_swap_crc.png\")\n", 928 | " plt.clf();plt.cla();plt.close()" 929 | ] 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "metadata": {}, 934 | "source": [ 935 | "## Step 4\n", 936 | "\n", 937 | "Go back to step 2" 938 | ] 939 | }, 940 | { 941 | "cell_type": "markdown", 942 | "metadata": {}, 943 | "source": [ 944 | "# Run experiment" 945 | ] 946 | }, 947 | { 948 | "cell_type": "markdown", 949 | "metadata": { 950 | "collapsed": true 951 | }, 952 | "source": [ 953 | "## Results" 954 | ] 955 | }, 956 | { 957 | "cell_type": "code", 958 | "execution_count": null, 959 | "metadata": {}, 960 | "outputs": [], 961 | "source": [ 962 | "objects = ('UFLP', 'CFLP', 'TUFLP', 'TCFLP')\n", 963 | "y_pos = np.arange(len(objects))\n", 964 | "performance = [result1.best,result2.best,result3.best,result4.best]\n", 965 | " \n", 966 | "plt.bar(y_pos, performance, align='center', alpha=0.5)\n", 967 | "plt.xticks(y_pos, objects)\n", 968 | "plt.ylabel('Time s')\n", 969 | "plt.title('Best processing time for each subproblem')\n", 970 | " \n", 971 | "plt.show()" 972 | ] 973 | } 974 | ], 975 | "metadata": { 976 | "hide_input": false, 977 | "kernelspec": { 978 | "display_name": "Py35", 979 | "language": "python", 980 | "name": "py35" 981 | }, 982 | "language_info": { 983 | "codemirror_mode": { 984 | "name": "ipython", 985 | "version": 3 986 | }, 987 | "file_extension": ".py", 988 | "mimetype": "text/x-python", 989 | "name": "python", 990 | "nbconvert_exporter": "python", 991 | "pygments_lexer": "ipython3", 992 | "version": "3.5.3" 993 | }, 994 | "toc": { 995 | "colors": { 996 | "hover_highlight": "#DAA520", 997 | "running_highlight": "#FF0000", 998 | "selected_highlight": "#FFD700" 999 | }, 1000 | "moveMenuLeft": true, 1001 | "nav_menu": { 1002 | "height": "192px", 1003 | "width": "252px" 1004 | }, 1005 | "navigate_menu": true, 1006 | "number_sections": true, 1007 | "sideBar": false, 1008 | "threshold": 4, 1009 | "toc_cell": false, 1010 | "toc_position": { 1011 | "height": "785px", 1012 | "left": "3px", 1013 | "right": "20px", 1014 | "top": "106px", 1015 | "width": "170px" 1016 | }, 1017 | "toc_section_display": "block", 1018 | "toc_window_display": true, 1019 | "widenNotebook": false 1020 | } 1021 | }, 1022 | "nbformat": 4, 1023 | "nbformat_minor": 2 1024 | } 1025 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Location routing problem problem 2 | --- 3 | 4 | This repository contains an implemetation of several MIP concerning the Location routing problem. The Iphython notebooks provide a mathematical discription of those problem and the code to solve them with Cplex thought the Python API. 5 | 6 | ## Faciliry Location Problem (FLP) 7 | 8 | ||| 9 | |--|--| 10 | |[UFLP](./linear_programming_facility_location/1_UFLP.ipynb)|Uncapacitated Facility location| 11 | |[CFLP](./linear_programming_facility_location/2_CFLP.ipynb)|Capacitated Facility location| 12 | |[TUFLP](./linear_programming_facility_location/3_TUFLP.ipynb)|Two-echelon Capacitated Facility location| 13 | 14 | ## Vehicle Routing Problem (VRP) 15 | 16 | ||| 17 | |--|--| 18 | |[TSP](./linear_programming_vehicle_routing/1_TSP.ipynb)|Traveling Salesman| 19 | |[mTSP](./linear_programming_vehicle_routing/2_mTSP.ipynb)|m Traveling Salesman| 20 | 21 | ## Creating your own script 22 | 23 | You can can use the following template to easily formulate 24 | 25 | ## Dependencies 26 | 27 | I created a custom wrapper around the cplex python API that I use in the above examples: https://github.com/xNok/OR_CPLEX_solve 28 | -------------------------------------------------------------------------------- /REFERENCES.md: -------------------------------------------------------------------------------- 1 | 1. Ortiz Astorquiza, C. (2017). Multi-level facility location problems (Doctoral dissertation, Concordia University). 2 | 2. Daskin, M. S. (2011). Network and discrete location: models, algorithms, and applications. John Wiley & Sons. 3 | 3. Drezner, E. (1996). Facility location: A survey of applications and methods. Journal of the Operational Research Society, 47(11), 1421-1421. -------------------------------------------------------------------------------- /cplex/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jupyter/scipy-notebook 2 | 3 | LABEL Name=or Version=0.0.1 4 | 5 | USER root 6 | 7 | EXPOSE 8888 8 | 9 | # Environment Variables 10 | ENV JUPYTER_ENABLE_LAB=yes 11 | ENV PROJ_LIB=/opt/conda/share/proj 12 | 13 | # Install Cplex 14 | ADD . /opt/cplex 15 | RUN chmod +x /opt/cplex/cplex_studio128.linux-x86-64.bin \ 16 | && /opt/cplex/cplex_studio128.linux-x86-64.bin -f ./installer.properties 17 | 18 | # Setup Cplex environnements 19 | RUN cd /opt/ibm/ILOG/CPLEX_Studio128/python \ 20 | && python setup.py install \ 21 | && jupyter labextension install @jupyterlab/github 22 | 23 | RUN conda install -y pymongo \ 24 | && conda install -y basemap 25 | 26 | # Collabortory compatibility 27 | #&& pip install jupyter_http_over_ws \ 28 | #&& jupyter serverextension enable --py jupyter_http_over_ws \ 29 | #&& jupyter notebook --NotebookApp.allow_origin='https://colab.research.google.com' --port=8889 --allow-root 30 | 31 | # Github extention 32 | # jupyter labextension install @jupyterlab/github 33 | # pip install jupyterlab_github 34 | # jupyter serverextension enable --sys-prefix jupyterlab_github 35 | 36 | # Git extention 37 | # jupyter labextension install @jupyterlab/git 38 | # pip install jupyterlab-git 39 | # jupyter serverextension enable --py jupyterlab_git 40 | -------------------------------------------------------------------------------- /cplex/installer.properties: -------------------------------------------------------------------------------- 1 | # https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.studio.help/Optimization_Studio/topics/td_silent_install.html 2 | # https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.studio.help/Optimization_Studio/topics/COS_installing.html 3 | INSTALLER_UI=silent 4 | LICENSE_ACCEPTED=TRUE -------------------------------------------------------------------------------- /helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/__init__.py -------------------------------------------------------------------------------- /helpers/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /helpers/__pycache__/expand_dataset_short_syntax.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/__pycache__/expand_dataset_short_syntax.cpython-35.pyc -------------------------------------------------------------------------------- /helpers/dataset/__init__.py: -------------------------------------------------------------------------------- 1 | from .distance_matrices import distance_matrices 2 | from .draw_dataset import draw_dataset -------------------------------------------------------------------------------- /helpers/dataset/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/dataset/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /helpers/dataset/__pycache__/distance_matrices.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/dataset/__pycache__/distance_matrices.cpython-35.pyc -------------------------------------------------------------------------------- /helpers/dataset/__pycache__/draw_dataset.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xNok/OR_location_routing_problem_study/312e6c8010e944ebeaef1c9f010d94b67970d80d/helpers/dataset/__pycache__/draw_dataset.cpython-35.pyc -------------------------------------------------------------------------------- /helpers/dataset/distance_matrices.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from numpy import linalg as LA 4 | 5 | def distance_matrices(datasets): 6 | """ 7 | Return a dictionary containing all the distance matrices for a 8 | given instance of the problem 9 | """ 10 | M = {} 11 | 12 | for dataset1 in datasets: 13 | d1 = datasets[dataset1] 14 | for dataset2 in datasets: 15 | d2 = datasets[dataset2] 16 | 17 | M[dataset1+dataset2] = np.zeros((d1["number"],d2["number"])) 18 | 19 | for i,ixy in enumerate(d1["coordinate"]): 20 | for j,jxy in enumerate(d2["coordinate"]): 21 | M[dataset1+dataset2][i][j] = LA.norm(np.subtract(ixy,jxy)) 22 | 23 | return M -------------------------------------------------------------------------------- /helpers/dataset/draw_dataset.py: -------------------------------------------------------------------------------- 1 | 2 | import networkx as nx 3 | 4 | def draw_dataset(datasets): 5 | """ 6 | Draw a dot plot of the given dataset 7 | """ 8 | G = nx.Graph() 9 | nbr_nodes = 0 10 | 11 | for dataset in datasets: 12 | d = datasets[dataset] 13 | 14 | for i,xy in enumerate(d["coordinate"]): 15 | G.add_node(i+nbr_nodes, 16 | pos=xy,color=d["metadata"]["color"][i], 17 | size=d["metadata"]["size"][i]) 18 | 19 | nbr_nodes += d["number"] 20 | 21 | # Prepare drawing 22 | pos = nx.get_node_attributes(G,'pos') 23 | colors = list(nx.get_node_attributes(G,'color').values()) 24 | size = list(nx.get_node_attributes(G,'size').values()) 25 | 26 | # Draw 27 | nx.draw_networkx( 28 | G,pos, node_color=colors, 29 | node_size=size, with_labels=False 30 | ) 31 | 32 | return G -------------------------------------------------------------------------------- /linear_programming_facility_location/.ipynb_checkpoints/1_UFLP-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "UFLP\n", 10 | "\n", 11 | "Uncapacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of facilities & **connect** customers to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "* $f_j$ fixed cost associated with opening the facility j\n", 29 | "* $c_{ij}$ variable cost of connecting customer i to facility j" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "$min_x$ \n", 37 | "\n", 38 | "$$\\sum_{j \\in J} f_{j} z_j + \\sum_{i \\in I}\\sum_{j \\in J} c_{ij} x_{ij}$$\n", 39 | "\n", 40 | "$s.t.$\n", 41 | "$$\\tag{1} \\sum_{j \\in J} x_{ij} = 1, \\forall i \\in I$$\n", 42 | "$$\\tag{2} x_{ij} \\le z_{j}, \\forall j \\in J, \\forall i \\in I$$\n", 43 | "$$x_{ij}, z_{j} \\in {0,1}$$\n" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "* $z_j$ decision variable associated with openning facility j\n", 51 | "* $x_{ij}$ decision variable associated with connecting customer i to facility j\n", 52 | "\n", 53 | "* (1) ensure that each customer is associated to a unique facility\n", 54 | "* (2) ensure that each customer is associated with an open facility" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "# Solve with Cplex" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 5, 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "Overwriting ../pkg/uflp_cplex.py\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "%%file \"../pkg/uflp_cplex.py\"\n", 79 | "\n", 80 | "import numpy as np # mathematic tools library\n", 81 | "import networkx as nx # network representation library\n", 82 | "from pkg.cplex_solve import cplex_solve\n", 83 | "\n", 84 | "def uflp_cplex(I,J,\n", 85 | " v,f,\n", 86 | " relaxation=False,path=None,verbose=False):\n", 87 | " \"\"\"\n", 88 | " I,J number of customer and facilities\n", 89 | " v,f cost matrices for variables cost and fixed cost\n", 90 | " \"\"\"\n", 91 | " #####################################################################\n", 92 | " # Decision variables\n", 93 | " \n", 94 | " def X(i,j):\n", 95 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 96 | "\n", 97 | " def Z(j):\n", 98 | " return \"Z_\" + str(j)\n", 99 | " \n", 100 | " I = range(I); J = range(J);\n", 101 | " #####################################################################\n", 102 | " # Objective function\n", 103 | " \n", 104 | " Xs = {\n", 105 | " \"name\" : [X(i,j) for i in I for j in J],\n", 106 | " \"coef\" : [c[i][j] for i in I for j in J],\n", 107 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j in J],\n", 108 | " \"ub\" : [1 for i in I for j in J],\n", 109 | " \"lb\" : [0 for i in I for j in J],\n", 110 | " }\n", 111 | " \n", 112 | " Zs = {\n", 113 | " \"name\" : [Z(j) for j in J],\n", 114 | " \"coef\" : [f[j] for j in J],\n", 115 | " \"type\" : [\"C\" if relaxation else \"I\" for j in J],\n", 116 | " \"ub\" : [1 for j in J],\n", 117 | " \"lb\" : [0 for j in J],\n", 118 | " }\n", 119 | " \n", 120 | " variables = [Xs, Zs]\n", 121 | " #####################################################################\n", 122 | " # Constraints\n", 123 | " \n", 124 | " c1 = {\n", 125 | " \"lin_expr\": [[[X(i,j) for j in J], [1 for j in J]]\n", 126 | " for i in I],\n", 127 | " \"senses\" : [\"E\" for i in I],\n", 128 | " \"rhs\" : [0 for i in I]\n", 129 | " }\n", 130 | " \n", 131 | " c1 = {\n", 132 | " \"lin_expr\": [[[X(i,j),Z(j)], [1,-1]]\n", 133 | " for i in range(I) for j in range(J)],\n", 134 | " \"senses\" : [\"E\" for i in range(I) for j in range(J)],\n", 135 | " \"rhs\" : [0 for i in range(I) for j in range(J)]\n", 136 | " }\n", 137 | " \n", 138 | " constraints = [c1, c2]\n", 139 | " #####################################################################\n", 140 | " # Solving\n", 141 | " prob = cplex_solve(variables,constraints,\n", 142 | " minimize=True, path=path, verbose=verbose)\n", 143 | "\n", 144 | " #####################################################################\n", 145 | " # Extract solution\n", 146 | " solution = prob.solution.get_values()\n", 147 | " I = len(I); J = len(J);\n", 148 | " \n", 149 | " X = np.reshape(solution[0:I*J],(I,J))\n", 150 | " Z = solution[I*J:I*J+J]\n", 151 | "\n", 152 | " return prob, X, Z" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": { 159 | "collapsed": true 160 | }, 161 | "outputs": [], 162 | "source": [] 163 | } 164 | ], 165 | "metadata": { 166 | "hide_input": false, 167 | "kernelspec": { 168 | "display_name": "Py35", 169 | "language": "python", 170 | "name": "py35" 171 | }, 172 | "language_info": { 173 | "codemirror_mode": { 174 | "name": "ipython", 175 | "version": 3 176 | }, 177 | "file_extension": ".py", 178 | "mimetype": "text/x-python", 179 | "name": "python", 180 | "nbconvert_exporter": "python", 181 | "pygments_lexer": "ipython3", 182 | "version": "3.5.3" 183 | }, 184 | "toc": { 185 | "colors": { 186 | "hover_highlight": "#DAA520", 187 | "running_highlight": "#FF0000", 188 | "selected_highlight": "#FFD700" 189 | }, 190 | "moveMenuLeft": true, 191 | "nav_menu": { 192 | "height": "12px", 193 | "width": "252px" 194 | }, 195 | "navigate_menu": true, 196 | "number_sections": true, 197 | "sideBar": true, 198 | "threshold": 4, 199 | "toc_cell": false, 200 | "toc_section_display": "block", 201 | "toc_window_display": false, 202 | "widenNotebook": false 203 | } 204 | }, 205 | "nbformat": 4, 206 | "nbformat_minor": 2 207 | } 208 | -------------------------------------------------------------------------------- /linear_programming_facility_location/.ipynb_checkpoints/2_CFLP-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "CFLP\n", 10 | "\n", 11 | "Capacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of facilities & **connect** customers to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "* $f_j$ fixed cost associated with opening the facility j\n", 29 | "* $c_{ij}$ variable cost of connecting customer i to facility j\n", 30 | "* $q_{i}$ demand associated to customer i\n", 31 | "* $V_j$ capacity of facility j" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "$min_x$ \n", 39 | "\n", 40 | "$$\\sum_{j \\in J} f_{j} z_j + \\sum_{i \\in I}\\sum_{j \\in J} c_{ij} x_{ij}$$\n", 41 | "\n", 42 | "$s.t.$\n", 43 | "$$\\tag{1} \\sum_{j \\in J} x_{ij} = 1, \\forall i \\in I$$\n", 44 | "$$\\tag{2} \\sum_{i \\in I} q_{i} x_{ij} \\le V_j z_j, \\forall j \\in J$$\n", 45 | "$$x_{ij}, z_{j} \\in {0,1}$$\n" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "* $z_j$ decision variable associated with openning facility j\n", 53 | "* $x_{ij}$ decision variable associated with connecting customer i to facility j\n", 54 | "\n", 55 | "* (1) ensure that each customer is associated to a unique facility\n", 56 | "* (2) ensure that each customer is associated with an open facility and that the capacity constraint is respected" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "# Solve with Cplex" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "Overwriting ../pkg/cflp_cplex.py\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "%%file \"../pkg/cflp_cplex.py\"\n", 81 | "\n", 82 | "import numpy as np # mathematic tools library\n", 83 | "import networkx as nx # network representation library\n", 84 | "from pkg.cplex_solve import cplex_solve\n", 85 | "\n", 86 | "def cflp_cplex(I,J,\n", 87 | " c,f,\n", 88 | " q,V,\n", 89 | " relaxation=False,path=None):\n", 90 | " \"\"\"\n", 91 | " I,J number of customer and facilities\n", 92 | " v,f cost matrices for variables cost and fixed cost\n", 93 | " q,V demand of customers and capacity of facilities\n", 94 | " \"\"\"\n", 95 | " #####################################################################\n", 96 | " # Decision variables\n", 97 | " \n", 98 | " def X(i,j):\n", 99 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 100 | "\n", 101 | " def Z(j):\n", 102 | " return \"Z_\" + str(j)\n", 103 | " \n", 104 | " I = range(I); J = range(J);\n", 105 | " #####################################################################\n", 106 | " # Objective function\n", 107 | " \n", 108 | " Xs = {\n", 109 | " \"name\" : [X(i,j) for i in I for j in J],\n", 110 | " \"coef\" : [c[i][j] for i in I for j in J],\n", 111 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j in J],\n", 112 | " \"ub\" : [1 for i in I for j in J],\n", 113 | " \"lb\" : [0 for i in I for j in J],\n", 114 | " }\n", 115 | " \n", 116 | " Zs = {\n", 117 | " \"name\" : [Z(j) for j in J],\n", 118 | " \"coef\" : [f[j] for j in J],\n", 119 | " \"type\" : [\"C\" if relaxation else \"I\" for j in J],\n", 120 | " \"ub\" : [1 for j in J],\n", 121 | " \"lb\" : [0 for j in J],\n", 122 | " }\n", 123 | " \n", 124 | " variables = [Xs, Zs]\n", 125 | " #####################################################################\n", 126 | " # Constraints\n", 127 | " \n", 128 | " c1 = {\n", 129 | " \"lin_expr\": [[[X(i,j) for j in J], [1 for j in J]]\n", 130 | " for i in I],\n", 131 | " \"senses\" : [\"E\" for i in I],\n", 132 | " \"rhs\" : [0 for i in I]\n", 133 | " }\n", 134 | " \n", 135 | " c1 = {\n", 136 | " \"lin_expr\": [[[X(i,j) for i in range(J)]+[Z(j)],\n", 137 | " [q[i] for i in range(J)]+[-V[j]]] \n", 138 | " for j in range(J)],\n", 139 | " \"senses\" : [\"L\" for j in range(J)],\n", 140 | " \"rhs\" : [0 for j in range(J)]\n", 141 | " }\n", 142 | " \n", 143 | " constraints = [c1, c2]\n", 144 | " #####################################################################\n", 145 | " # Solving\n", 146 | " prob = cplex_solve(variables,constraints,\n", 147 | " minimize=True, path=path, verbose=verbose)\n", 148 | "\n", 149 | " #####################################################################\n", 150 | " # Extract solution\n", 151 | " solution = prob.solution.get_values()\n", 152 | " I = len(I); J = len(J);\n", 153 | " \n", 154 | " X = np.reshape(solution[0:I*J],(I,J))\n", 155 | " Z = solution[I*J:I*J+J]\n", 156 | "\n", 157 | " return prob, X, Z" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "metadata": { 164 | "collapsed": true 165 | }, 166 | "outputs": [], 167 | "source": [] 168 | } 169 | ], 170 | "metadata": { 171 | "hide_input": false, 172 | "kernelspec": { 173 | "display_name": "Py35", 174 | "language": "python", 175 | "name": "py35" 176 | }, 177 | "language_info": { 178 | "codemirror_mode": { 179 | "name": "ipython", 180 | "version": 3 181 | }, 182 | "file_extension": ".py", 183 | "mimetype": "text/x-python", 184 | "name": "python", 185 | "nbconvert_exporter": "python", 186 | "pygments_lexer": "ipython3", 187 | "version": "3.5.3" 188 | }, 189 | "toc": { 190 | "colors": { 191 | "hover_highlight": "#DAA520", 192 | "running_highlight": "#FF0000", 193 | "selected_highlight": "#FFD700" 194 | }, 195 | "moveMenuLeft": true, 196 | "nav_menu": { 197 | "height": "12px", 198 | "width": "252px" 199 | }, 200 | "navigate_menu": true, 201 | "number_sections": true, 202 | "sideBar": true, 203 | "threshold": 4, 204 | "toc_cell": false, 205 | "toc_section_display": "block", 206 | "toc_window_display": false, 207 | "widenNotebook": false 208 | } 209 | }, 210 | "nbformat": 4, 211 | "nbformat_minor": 2 212 | } 213 | -------------------------------------------------------------------------------- /linear_programming_facility_location/.ipynb_checkpoints/3_TUFLP-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "TUFLP - $2/\\bar{R}/\\bar{R}$\n", 10 | "\n", 11 | "Two-level uncapacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of level 1 facilities & **connect** customers to _one facility each_ and open a **subset** of level 2 facilities & **connect** level 1 facilities to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "\n", 29 | "* $f_jr$ fixed cost associated with opening the facility j at level r\n", 30 | "* $c_{ij_1j_2}$ variable cost of connecting customer i to level 1 facility j1 to facility level 2 j2" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "$min_x$ \n", 38 | "\n", 39 | "$$\\sum_{r =1}^2 \\sum_{j \\in V_r} f_{jr} z_{jr} + \\sum_{i \\in I} \\sum_{j_1 \\in V_1} \\sum_{j_2 \\in V_2} c_{i j_1 j_2} x_{i j_1 j_2}$$\n", 40 | "\n", 41 | "$s.t.$\n", 42 | "$$\\tag{1} \\sum_{j_1 \\in V_1} \\sum_{j_2 \\in V_2} x_{i j_1 j_2} = 1, \\forall i \\in I$$\n", 43 | "$$\\tag{2} \\sum_{j_1 \\in V_1} x_{i j_1 j_2} \\le z_{j_1}, \\forall i \\in I, \\forall j_2 \\in V_2$$\n", 44 | "$$\\tag{3} \\sum_{j_2 \\in V_2} x_{i j_1 j_2} \\le z_{j_2}, \\forall i \\in I, \\forall j_1 \\in V_1$$\n", 45 | "$$x_{i j_1 j_2}, z_{j} \\in {0,1}$$\n" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "* $z_jr$ decision variable associated with opening facility j and level r\n", 53 | "* $x_{ij_1j_2}$ decision variable associated with connecting customer i to level 1 facility $j_1$ to level 2 facility $j_2$\n", 54 | "\n", 55 | "* (1) ensure that each customer is associated to a unique couple of facility one in level 1 the other in level 2\n", 56 | "* (2), (3) ensure that each customer is associated with an open facility" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "# Solve with Cplex" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 17, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "Overwriting ../pkg/tuflp_cplex.py\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "%%file \"../pkg/tuflp_cplex.py\"\n", 81 | "\n", 82 | "from pkg.cplex_solve import cplex_solve\n", 83 | "import numpy as np # mathematic tools library\n", 84 | "import networkx as nx # network representation library\n", 85 | "\n", 86 | "def tuflp_cplex(I,V1,V2,\n", 87 | " c,f,\n", 88 | " relaxation=False,path=None,verbose=False):\n", 89 | " \"\"\"\n", 90 | " I,V1,V2 number of customers, level 1 facility, level 2 facility\n", 91 | " c,f cost matrix for connection and setup\n", 92 | " \"\"\"\n", 93 | " #####################################################################\n", 94 | " # Decision variables\n", 95 | " \n", 96 | " def X(i,j1,j2):\n", 97 | " return \"X_\" + str(i) + \"_\" + str(j1) + \"_\" + str(j2)\n", 98 | "\n", 99 | " def Z(j,r):\n", 100 | " return \"Z_\" + str(j) + \"_\" + str(r)\n", 101 | " \n", 102 | " nbr_var = I*V1*V2+(V1+V2)\n", 103 | " I = range(I); V1 = range(V1); V2 = range(V2);\n", 104 | "\n", 105 | " #####################################################################\n", 106 | " # Objective function\n", 107 | " \n", 108 | " Xs = {\n", 109 | " \"name\" : [X(i,j) for i in I for j1 in V1 for j2 in V2],\n", 110 | " \"coef\" : [c[i][j1][j2] for i in I for j1 in V1 for j2 in V2],\n", 111 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j1 in V1 for j2 in V2],\n", 112 | " \"ub\" : [1 for i in I for j1 in V1 for j2 in V2],\n", 113 | " \"lb\" : [0 for i in I for j1 in V1 for j2 in V2],\n", 114 | " }\n", 115 | " \n", 116 | " Zs = {\n", 117 | " \"name\" : [Z(j) for j in range(len(V1)+len(V2))],\n", 118 | " \"coef\" : [f[j] for j in range(len(V1)+len(V2))],\n", 119 | " \"type\" : [\"C\" if relaxation else \"I\" for j in range(len(V1)+len(V2))],\n", 120 | " \"ub\" : [1 for j in range(len(V1)+len(V2))],\n", 121 | " \"lb\" : [0 for j in range(len(V1)+len(V2))],\n", 122 | " }\n", 123 | "\n", 124 | " #####################################################################\n", 125 | " # Constraints\n", 126 | " \n", 127 | " c1 = {\n", 128 | " \"lin_expr\": [[[X(i,j1,j2) for j1 in V1 for j2 in V2], [1 for j1 in V1 for j2 in V2]] \n", 129 | " for i in range(I)],\n", 130 | " \"senses\" : [\"E\" for i in range(I)],\n", 131 | " \"rhs\" : [0 for i in range(I)]\n", 132 | " }\n", 133 | " \n", 134 | " c2 = {\n", 135 | " \"lin_expr\": [[[X(i,j1,j2) for j1 in V1]+[Z(j2,2)], [1 for j1 in V1]+ [-1]]\n", 136 | " for i in I for j2 in V2],\n", 137 | " \"senses\" : [\"L\" for i in I for j2 in V2],\n", 138 | " \"rhs\" : [0 for i in I for j2 in V2]\n", 139 | " }\n", 140 | " \n", 141 | " c3 = {\n", 142 | " \"lin_expr\": [[[X(i,j1,j2) for j2 in V2]+[Z(j1,1)], [1 for j2 in V2]+ [-1]]\n", 143 | " for i in I for j1 in V1],\n", 144 | " \"senses\" : [\"L\" for i in I for j1 in V1],\n", 145 | " \"rhs\" : [0 for i in I for j1 in V1]\n", 146 | " }\n", 147 | " \n", 148 | " constraints = [c1, c2, c3]\n", 149 | "\n", 150 | " #####################################################################\n", 151 | " # Solving\n", 152 | " prob = cplex_solve(variables,constraints,\n", 153 | " minimize=True, path=path, verbose=verbose)\n", 154 | " #####################################################################\n", 155 | " # Extract solution\n", 156 | " I = len(I); V1 = len(V1); V2 = len(V2);\n", 157 | " solution = prob.solution.get_values()\n", 158 | " X = np.reshape(solution[0:I*V1*V2],(I,V1,V2))\n", 159 | " Z = solution[I*V1*V2:]\n", 160 | "\n", 161 | " return prob, X, Z" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": { 168 | "collapsed": true 169 | }, 170 | "outputs": [], 171 | "source": [] 172 | } 173 | ], 174 | "metadata": { 175 | "hide_input": false, 176 | "kernelspec": { 177 | "display_name": "Py35", 178 | "language": "python", 179 | "name": "py35" 180 | }, 181 | "language_info": { 182 | "codemirror_mode": { 183 | "name": "ipython", 184 | "version": 3 185 | }, 186 | "file_extension": ".py", 187 | "mimetype": "text/x-python", 188 | "name": "python", 189 | "nbconvert_exporter": "python", 190 | "pygments_lexer": "ipython3", 191 | "version": "3.5.3" 192 | }, 193 | "toc": { 194 | "colors": { 195 | "hover_highlight": "#DAA520", 196 | "running_highlight": "#FF0000", 197 | "selected_highlight": "#FFD700" 198 | }, 199 | "moveMenuLeft": true, 200 | "nav_menu": { 201 | "height": "12px", 202 | "width": "252px" 203 | }, 204 | "navigate_menu": true, 205 | "number_sections": true, 206 | "sideBar": true, 207 | "threshold": 4, 208 | "toc_cell": false, 209 | "toc_section_display": "block", 210 | "toc_window_display": false, 211 | "widenNotebook": false 212 | } 213 | }, 214 | "nbformat": 4, 215 | "nbformat_minor": 2 216 | } 217 | -------------------------------------------------------------------------------- /linear_programming_facility_location/.ipynb_checkpoints/CRAB_MB_modified-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "$min_{Y,Z,N}$\n", 15 | "$$\n", 16 | "\\begin{align}\n", 17 | " TC2 = \\\\\n", 18 | " &\\tag{2.1} \\sum_{i \\in I}\\sum_{j \\in J} w_{ij} Y_{ij} \\\\\n", 19 | " &\\tag{2.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+FCV_b) Z_{cjb} \\\\\n", 20 | " &\\tag{2.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 21 | " &\\tag{2.4} + \\sum_{c \\in C}(FCR_c+D_c) N_c \\\\\n", 22 | " &\\tag{2.5} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} (PC_{ikv}+IP_{ikv})\n", 23 | "\\end{align}\n", 24 | "$$" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "$s.t$\n", 32 | "$$\\tag{c2-UFLP-L1} \\sum_{j \\in J}Y_{ij} = 1, \\forall i \\in I $$\n", 33 | "$$\\tag{c4-CFLP-L1} \\sum_{i \\in I}q_iY_{ij} \\le Q_jN_j , \\forall j \\in J $$\n", 34 | "$$\\tag{c5-CFLP-L2} \\sum_{i \\in I}q_iY_{ij} = V_j , \\forall j \\in J $$" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "$$\\tag{c*} Z_{uub} = 0 , \\forall u \\in C \\cup J, \\forall b \\in b$$\n", 42 | "$$\\tag{c6-VRP} \\sum_{c \\in C \\cup J}\\sum_{b \\in B}Z_{cjb} = 1 , \\forall j \\in J$$\n", 43 | "$$\\tag{c11-VRP} \\sum_{c \\in C}\\sum_{j \\in J}Z_{cjb} \\le 1 , \\forall b \\in B$$\n", 44 | "$$\\tag{c12-VRP} \\sum_{j \\in J}\\sum_{c \\in C \\cup J}VZ_{cjb} \\le Q_b , \\forall c \\in C$$\n", 45 | "$$\\tag{c12.1} VZ_{cjb} \\le V_j , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 46 | "$$\\tag{c12.2} VZ_{cjb} \\le max(Q_j)Z_{cjb} , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 47 | "$$\\tag{c12.3} VZ_{cjb} \\ge V_j - max(Q_j)(1-Z_{cjb}) , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 48 | "\n", 49 | "$$\\tag{c14-VRP} \\sum_{j \\in C \\cup J}VZ_{cjb} - \\sum_{j \\in C \\cup J}VZ_{jcb} =0 , \\forall c \\in C \\cup J, \\forall b \\in B$$" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "metadata": { 56 | "collapsed": true 57 | }, 58 | "outputs": [], 59 | "source": [] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 74, 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "Overwriting ../pkg/crab_mb_m_cplex.py\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "%%file \"../pkg/crab_mb_m_cplex.py\"\n", 76 | "\n", 77 | "from pkg.cplex_solve import cplex_solve\n", 78 | "import numpy as np # mathematic tools library\n", 79 | "import networkx as nx # network representation library\n", 80 | "import cplex\n", 81 | "\n", 82 | "def crab_mb_m_cplex(I,J,C,B,K,V,\n", 83 | " w,Dcj,FCV,FCT,FCR,Dc,q,\n", 84 | " Q,relaxation=False,path=None):\n", 85 | " \"\"\"\n", 86 | " Parameters:\n", 87 | " Sets:\n", 88 | " I,J,C,K,V,B -> customer, ICPs, CRCs, qualities, varieties, vehicles\n", 89 | " Costs:\n", 90 | " FCT, FCR, FCV, fixed cost for ICP, CRC, vehicle\n", 91 | " IP, PC acquisition and processiong cost\n", 92 | " Weight:\n", 93 | " q, nbr unit collected\n", 94 | " w, Dcj, Dc cost related to traveling distances cus-ICP, ICP-CRC, CRC-PC\n", 95 | " Capacity:\n", 96 | " Q capacity matrix\n", 97 | " \n", 98 | " Decision Vqriables:\n", 99 | " Y_ij customer i associated to ICP j\n", 100 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 101 | " N_icp, N_crc -> ICP / CRC is open\n", 102 | " \"\"\"\n", 103 | " #####################################################################\n", 104 | " # Decision variables\n", 105 | " \n", 106 | " def Y(i,j):\n", 107 | " return \"Y_\" + str(i) + \"_\" + str(j)\n", 108 | " \n", 109 | " def Z(c,j,b):\n", 110 | " return \"Z_\" + str(c) + \"_\" + str(j) + \"_\" + str(b)\n", 111 | " \n", 112 | " def N(j):\n", 113 | " return \"N_\" + str(j)\n", 114 | " \n", 115 | " def V(j):\n", 116 | " return \"V_\" + str(j)\n", 117 | " \n", 118 | " def VZ(c,j,b):\n", 119 | " return \"VZ_\" + str(c) + \"_\" + str(j) + \"_\" + str(b)\n", 120 | "\n", 121 | " CuJ = range(C+J); C = range(J,C+J,1)\n", 122 | " I = range(I);J = range(J); B = range(B); \n", 123 | " \n", 124 | " #####################################################################\n", 125 | " ## variables\n", 126 | " Ys = {\n", 127 | " \"name\" : [Y(i,j) for i in I for j in J],\n", 128 | " \"coef\" : [w[i][j] for i in I for j in J],\n", 129 | " \"type\" : [\"I\" for i in I for j in J],\n", 130 | " \"ub\" : [1 for i in I for j in J],\n", 131 | " \"lb\" : [0 for i in I for j in J],\n", 132 | " }\n", 133 | " Zs = {\n", 134 | " \"name\" : [Z(c,j,b) for c in CuJ for j in CuJ for b in B],\n", 135 | " \"coef\" : [Dcj[c][j]+FCV[b] for c in CuJ for j in CuJ for b in B],\n", 136 | " \"type\" : [\"I\" for c in CuJ for j in CuJ for b in B],\n", 137 | " \"ub\" : [1 for c in CuJ for j in CuJ for b in B],\n", 138 | " \"lb\" : [0 for c in CuJ for j in CuJ for b in B],\n", 139 | " }\n", 140 | " Ns = {\n", 141 | " \"name\" : [N(j) for j in J] + [N(c) for c in C],\n", 142 | " \"coef\" : [FCT[j] for j in J] + [FCR[c-len(J)]+Dc[c-len(J)] for c in C],\n", 143 | " \"type\" : [\"I\" for j in J] + [\"I\" for c in C],\n", 144 | " \"ub\" : [1 for j in J] + [1 for c in C],\n", 145 | " \"lb\" : [0 for j in J] + [0 for c in C],\n", 146 | " }\n", 147 | " # Dummy variables\n", 148 | " Vs = {\n", 149 | " \"name\" : [V(j) for j in J],\n", 150 | " \"coef\" : [0 for j in J],\n", 151 | " \"type\" : [\"C\" for j in J],\n", 152 | " \"ub\" : [cplex.infinity for j in J],\n", 153 | " \"lb\" : [0 for j in J],\n", 154 | " }\n", 155 | " VZs = {\n", 156 | " \"name\" : [VZ(c,j,b) for c in CuJ for j in CuJ for b in B],\n", 157 | " \"coef\" : [0 for c in CuJ for j in CuJ for b in B],\n", 158 | " \"type\" : [\"C\" for c in CuJ for j in CuJ for b in B],\n", 159 | " \"ub\" : [cplex.infinity for c in CuJ for j in CuJ for b in B],\n", 160 | " \"lb\" : [0 for c in CuJ for j in CuJ for b in B],\n", 161 | " }\n", 162 | "\n", 163 | " Variables = [Ys,Zs,Ns,Vs,VZs]\n", 164 | " ## Objective function sum aggregation\n", 165 | " obj = [];ub = [];lb = [];colnames = [];types = [];\n", 166 | " for v in Variables:\n", 167 | " obj = obj + v[\"coef\"]\n", 168 | " ub = ub + v[\"ub\"]\n", 169 | " lb = lb + v[\"lb\"]\n", 170 | " colnames = colnames + v[\"name\"]\n", 171 | " types = types + v[\"type\"]\n", 172 | " \n", 173 | " #####################################################################\n", 174 | " # Constraints\n", 175 | " \n", 176 | " # Ys FLP constraints\n", 177 | " c2 = {\n", 178 | " \"lin_expr\": [[[Y(i,j) for j in J]\n", 179 | " ,[1 for j in J]] \n", 180 | " for i in I],\n", 181 | " \"senses\" : [\"E\" for i in I],\n", 182 | " \"rhs\" : [1 for i in I]\n", 183 | " }\n", 184 | " c4 = {\n", 185 | " \"lin_expr\": [[[Y(i,j) for i in I]+[N(j)],\n", 186 | " [q[i] for i in I]+[-Q[0][j]]] \n", 187 | " for j in J],\n", 188 | " \"senses\" : [\"L\" for j in J],\n", 189 | " \"rhs\" : [0 for j in J]\n", 190 | " }\n", 191 | " c5 = {\n", 192 | " \"lin_expr\": [[[Y(i,j) for i in I]+[V(j)]\n", 193 | " , [q[i] for i in I]+[-1]] \n", 194 | " for j in J],\n", 195 | " \"senses\" : [\"E\" for i in I],\n", 196 | " \"rhs\" : [0 for i in I]\n", 197 | " }\n", 198 | "\n", 199 | " # Zs FLP constraints\n", 200 | " cstar = {\n", 201 | " \"lin_expr\": [[[Z(c,j,b) for c in CuJ for b in B],\n", 202 | " [1 for c in CuJ for b in B]] \n", 203 | " for j in J],\n", 204 | " \"senses\" : [\"E\"],\n", 205 | " \"rhs\" : [0]\n", 206 | " }\n", 207 | " c6 = {\n", 208 | " \"lin_expr\": [[[Z(u,u,b) for u in CuJ for b in B],\n", 209 | " [1 for u in CuJ for b in B]] \n", 210 | " for j in J],\n", 211 | " \"senses\" : [\"E\" for j in J],\n", 212 | " \"rhs\" : [1 for j in J]\n", 213 | " }\n", 214 | " c11 = {\n", 215 | " \"lin_expr\": [[[Z(c,j,b) for c in C for j in J],\n", 216 | " [1 for c in C for j in J]] \n", 217 | " for b in B],\n", 218 | " \"senses\" : [\"L\"for b in B],\n", 219 | " \"rhs\" : [1 for b in B]]\n", 220 | " }\n", 221 | " c12 = {\n", 222 | " \"lin_expr\": [[[VZ(c,j,b) for c in CuJ for j in J],\n", 223 | " [1 for c in CuJ for j in J]] \n", 224 | " for b in B],\n", 225 | " \"senses\" : [\"L\" for c in CuJ],\n", 226 | " \"rhs\" : [Q[1][b] for b in B]\n", 227 | " }\n", 228 | " c14 = {\n", 229 | " \"lin_expr\": [[[Z(c,j,b) for j in CuJ for b in B]+[Z(j,c,b) for j in CuJ for b in B ], \n", 230 | " [1 for j in CuJ for b in B]+[1 for j in CuJ for b in B]] \n", 231 | " for c in CuJ],\n", 232 | " \"senses\" : [\"E\" for c in CuJ],\n", 233 | " \"rhs\" : [2 for c in CuJ]\n", 234 | " }\n", 235 | " \n", 236 | " # Zs VRP constraints\n", 237 | " \n", 238 | " Constraints = [c2,c4,c5]\n", 239 | " rows = []; senses = []; rhs = [];\n", 240 | " for c in Constraints\n", 241 | " rows = rows + c[\"lin_expr\"]\n", 242 | " senses = senses + c[\"senses\"]\n", 243 | " rhs = rhs + c[\"rhs\"]\n", 244 | " \n", 245 | " #####################################################################\n", 246 | " # Solving\n", 247 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path)\n", 248 | "\n", 249 | " #####################################################################\n", 250 | " # Extract solution\n", 251 | " CuJ = len(C)+len(J); I = len(I); J = len(J); B = len(B); C = len(C);\n", 252 | " \n", 253 | " solution = prob.solution.get_values()\n", 254 | " Y = np.reshape(solution[0:I*J],(I,J))\n", 255 | " Z = np.reshape(solution[I*J:I*J+CuJ*CuJ*B],(CuJ,CuJ,B))\n", 256 | " N = solution[I*J+CuJ*CuJ*B:I*J+CuJ*CuJ*B+J]\n", 257 | " V = solution[I*J+CuJ*CuJ*B+J+C:I*J+CuJ*CuJ*B+J+C+J]\n", 258 | "\n", 259 | " return prob, Y, Z, N, V" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": null, 265 | "metadata": { 266 | "collapsed": true 267 | }, 268 | "outputs": [], 269 | "source": [] 270 | } 271 | ], 272 | "metadata": { 273 | "hide_input": false, 274 | "kernelspec": { 275 | "display_name": "Py35", 276 | "language": "python", 277 | "name": "py35" 278 | }, 279 | "language_info": { 280 | "codemirror_mode": { 281 | "name": "ipython", 282 | "version": 3 283 | }, 284 | "file_extension": ".py", 285 | "mimetype": "text/x-python", 286 | "name": "python", 287 | "nbconvert_exporter": "python", 288 | "pygments_lexer": "ipython3", 289 | "version": "3.5.3" 290 | }, 291 | "toc": { 292 | "colors": { 293 | "hover_highlight": "#DAA520", 294 | "running_highlight": "#FF0000", 295 | "selected_highlight": "#FFD700" 296 | }, 297 | "moveMenuLeft": true, 298 | "nav_menu": { 299 | "height": "12px", 300 | "width": "252px" 301 | }, 302 | "navigate_menu": true, 303 | "number_sections": true, 304 | "sideBar": true, 305 | "threshold": 4, 306 | "toc_cell": false, 307 | "toc_section_display": "block", 308 | "toc_window_display": false, 309 | "widenNotebook": false 310 | } 311 | }, 312 | "nbformat": 4, 313 | "nbformat_minor": 2 314 | } 315 | -------------------------------------------------------------------------------- /linear_programming_facility_location/.ipynb_checkpoints/Objective Function-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "# Objective function" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "$$\n", 26 | "\\begin{align}\n", 27 | " TC1 = \\\\\n", 28 | " &\\tag{1.1} \\sum_{i \\in I}\\sum_{j \\in J} [(x_i - \\bar{x_j})^2 + (y_i - \\bar{y_j})^2]^{1/2} Y_{ij} \\\\\n", 29 | " &\\tag{1.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+D_c) Z_{cjb} \\\\\n", 30 | " &\\tag{1.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 31 | " &\\tag{1.4} + \\sum_{c \\in C}FCR_c N_c \\\\\n", 32 | " &\\tag{1.5} + \\sum_{b \\in B}FCV_b\\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}Z_{ijb}\\\\\n", 33 | " &\\tag{1.6} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} IP_{ikv} \\\\\n", 34 | " &\\tag{1.7} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} PC_{ikv}\n", 35 | "\\end{align}\n", 36 | "$$" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "$$\n", 44 | "\\begin{align}\n", 45 | " TC2 = \\\\\n", 46 | " &\\tag{2.1} \\sum_{i \\in I}\\sum_{j \\in J} w_{ij} Y_{ij} \\\\\n", 47 | " &\\tag{2.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+FCV_b) Z_{cjb} \\\\\n", 48 | " &\\tag{2.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 49 | " &\\tag{2.4} + \\sum_{c \\in C}(FCR_c+D_c) N_c \\\\\n", 50 | " &\\tag{2.5} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} (PC_{ikv}+IP_{ikv})\n", 51 | "\\end{align}\n", 52 | "$$" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 14, 63 | "metadata": { 64 | "collapsed": true 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "\n", 69 | "def objective_lr_II(Y,Z,Nj,Nc,\n", 70 | " I,J,B,K,V,\n", 71 | " w,Dcj,FCV,FCT,FCR,Dc,q,PC,IP):\n", 72 | " \"\"\"\n", 73 | " Parameters:\n", 74 | " Sets:\n", 75 | " I,J,C,K,V,B -> customer, ICPs, CRCs, qualities, varieties, vehicles\n", 76 | " Costs:\n", 77 | " FCT, FCR, FCV, fixed cost for ICP, CRC, vehicle\n", 78 | " IP, PC acquisition and processiong cost\n", 79 | " Weight:\n", 80 | " q, nbr unit collected\n", 81 | " w, Dcj, Dc cost related to traveling distances cus-ICP, ICP-CRC, CRC-PC\n", 82 | " \n", 83 | " Decision Vqriables:\n", 84 | " Y_ij customer i associated to ICP j\n", 85 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 86 | " N_icp, N_crc -> ICP / CRC i is open\n", 87 | " \"\"\"\n", 88 | " sum2_1 = 0\n", 89 | " for i in range(I):\n", 90 | " for j in range(J):\n", 91 | " sum2_1 += w[i][j] + Y[i][j]\n", 92 | " \n", 93 | " sum2_2 = 0\n", 94 | " for c in range(C+J):\n", 95 | " for j in range(C+J):\n", 96 | " for b in range(B):\n", 97 | " sum2_2 += (Dcj[c][j] + FCV[b]) * Z[c][j][b]\n", 98 | " \n", 99 | " sum2_3 = 0\n", 100 | " for j in range(J):\n", 101 | " sum2_3 += FCT[j] * N[j]\n", 102 | " \n", 103 | " sum2_4 = 0\n", 104 | " for c in range(C):\n", 105 | " sum2_4 += (FCT[c] + D[c]) * N[c]\n", 106 | " \n", 107 | " return sum2_1+sum2_2+sum2_3+sum2_4, sum2_1, sum2_2, sum2_3, sum2_4" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "collapsed": true 115 | }, 116 | "outputs": [], 117 | "source": [] 118 | } 119 | ], 120 | "metadata": { 121 | "hide_input": false, 122 | "kernelspec": { 123 | "display_name": "Py35", 124 | "language": "python", 125 | "name": "py35" 126 | }, 127 | "language_info": { 128 | "codemirror_mode": { 129 | "name": "ipython", 130 | "version": 3 131 | }, 132 | "file_extension": ".py", 133 | "mimetype": "text/x-python", 134 | "name": "python", 135 | "nbconvert_exporter": "python", 136 | "pygments_lexer": "ipython3", 137 | "version": "3.5.3" 138 | }, 139 | "toc": { 140 | "colors": { 141 | "hover_highlight": "#DAA520", 142 | "running_highlight": "#FF0000", 143 | "selected_highlight": "#FFD700" 144 | }, 145 | "moveMenuLeft": true, 146 | "nav_menu": { 147 | "height": "30px", 148 | "width": "252px" 149 | }, 150 | "navigate_menu": true, 151 | "number_sections": true, 152 | "sideBar": true, 153 | "threshold": 4, 154 | "toc_cell": false, 155 | "toc_section_display": "block", 156 | "toc_window_display": false, 157 | "widenNotebook": false 158 | } 159 | }, 160 | "nbformat": 4, 161 | "nbformat_minor": 2 162 | } 163 | -------------------------------------------------------------------------------- /linear_programming_facility_location/1_UFLP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "UFLP - $1/\\bar{R}$\n", 10 | "\n", 11 | "Uncapacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of facilities & **connect** customers to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "* $f_j$ fixed cost associated with opening the facility j\n", 29 | "* $c_{ij}$ variable cost of connecting customer i to facility j" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "$min_x$ \n", 37 | "\n", 38 | "$$\\sum_{j \\in J} f_{j} z_j + \\sum_{i \\in I}\\sum_{j \\in J} c_{ij} x_{ij}$$\n", 39 | "\n", 40 | "$s.t.$\n", 41 | "$$\\tag{1} \\sum_{j \\in J} x_{ij} = 1, \\forall i \\in I$$\n", 42 | "$$\\tag{2} x_{ij} \\le z_{j}, \\forall j \\in J, \\forall i \\in I$$\n", 43 | "$$x_{ij}, z_{j} \\in {0,1}$$\n" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "* $z_j$ decision variable associated with openning facility j\n", 51 | "* $x_{ij}$ decision variable associated with connecting customer i to facility j\n", 52 | "\n", 53 | "* (1) ensure that each customer is associated to a unique facility\n", 54 | "* (2) ensure that each customer is associated with an open facility" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "# Solve with Cplex" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 5, 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "Overwriting ../pkg/uflp_cplex.py\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "%%file \"../pkg/uflp_cplex.py\"\n", 79 | "\n", 80 | "import cplex_solve\n", 81 | "import numpy as np\n", 82 | "\n", 83 | "def uflp_cplex(I,J,\n", 84 | " d,f,\n", 85 | " relaxation=False,path=None,verbose=False):\n", 86 | " \"\"\"\n", 87 | " I,J number of customer and facilities\n", 88 | " d,f cost matrices for variables cost and fixed cost\n", 89 | " \"\"\"\n", 90 | " #####################################################################\n", 91 | " # Decision variables\n", 92 | " \n", 93 | " def X(i,j):\n", 94 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 95 | "\n", 96 | " def Z(j):\n", 97 | " return \"Z_\" + str(j)\n", 98 | " \n", 99 | " I = range(I); J = range(J);\n", 100 | " #####################################################################\n", 101 | " # Objective function\n", 102 | " \n", 103 | " Xs = {\n", 104 | " \"name\" : [X(i,j) for i in I for j in J],\n", 105 | " \"coef\" : [d[i][j] for i in I for j in J],\n", 106 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j in J],\n", 107 | " \"ub\" : [1 for i in I for j in J],\n", 108 | " \"lb\" : [0 for i in I for j in J],\n", 109 | " }\n", 110 | " \n", 111 | " Zs = {\n", 112 | " \"name\" : [Z(j) for j in J],\n", 113 | " \"coef\" : [f[j] for j in J],\n", 114 | " \"type\" : [\"C\" if relaxation else \"I\" for j in J],\n", 115 | " \"ub\" : [1 for j in J],\n", 116 | " \"lb\" : [0 for j in J],\n", 117 | " }\n", 118 | " \n", 119 | " variables = [Xs, Zs]\n", 120 | " #####################################################################\n", 121 | " # Constraints\n", 122 | " \n", 123 | " c1 = {\n", 124 | " \"lin_expr\": [[[X(i,j) for j in J], [1 for j in J]]\n", 125 | " for i in I],\n", 126 | " \"senses\" : [\"E\" for i in I],\n", 127 | " \"rhs\" : [1 for i in I]\n", 128 | " }\n", 129 | " \n", 130 | " c2 = {\n", 131 | " \"lin_expr\": [[[X(i,j),Z(j)], [1,-1]]\n", 132 | " for i in I for j in J],\n", 133 | " \"senses\" : [\"L\" for i in I for j in J],\n", 134 | " \"rhs\" : [0 for i in I for j in J]\n", 135 | " }\n", 136 | " \n", 137 | " constraints = [c1, c2]\n", 138 | " #####################################################################\n", 139 | " # Solving\n", 140 | " prob = cplex_solve.from_template(variables,constraints,\n", 141 | " minimize=True, path=path, verbose=verbose)\n", 142 | "\n", 143 | " #####################################################################\n", 144 | " # Extract solution\n", 145 | " solution = prob.solution.get_values()\n", 146 | " I = len(I); J = len(J);\n", 147 | " \n", 148 | " X = np.reshape(solution[0:I*J],(I,J))\n", 149 | " Z = solution[I*J:I*J+J]\n", 150 | "\n", 151 | " return prob, X, Z" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": null, 157 | "metadata": { 158 | "collapsed": true 159 | }, 160 | "outputs": [], 161 | "source": [] 162 | } 163 | ], 164 | "metadata": { 165 | "hide_input": false, 166 | "kernelspec": { 167 | "display_name": "Py35", 168 | "language": "python", 169 | "name": "py35" 170 | }, 171 | "language_info": { 172 | "codemirror_mode": { 173 | "name": "ipython", 174 | "version": 3 175 | }, 176 | "file_extension": ".py", 177 | "mimetype": "text/x-python", 178 | "name": "python", 179 | "nbconvert_exporter": "python", 180 | "pygments_lexer": "ipython3", 181 | "version": "3.5.3" 182 | }, 183 | "toc": { 184 | "colors": { 185 | "hover_highlight": "#DAA520", 186 | "running_highlight": "#FF0000", 187 | "selected_highlight": "#FFD700" 188 | }, 189 | "moveMenuLeft": true, 190 | "nav_menu": { 191 | "height": "12px", 192 | "width": "252px" 193 | }, 194 | "navigate_menu": true, 195 | "number_sections": true, 196 | "sideBar": true, 197 | "threshold": 4, 198 | "toc_cell": false, 199 | "toc_section_display": "block", 200 | "toc_window_display": false, 201 | "widenNotebook": false 202 | } 203 | }, 204 | "nbformat": 4, 205 | "nbformat_minor": 2 206 | } 207 | -------------------------------------------------------------------------------- /linear_programming_facility_location/2_CFLP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "CFLP\n", 10 | "\n", 11 | "Capacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of facilities & **connect** customers to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "* $f_j$ fixed cost associated with opening the facility j\n", 29 | "* $c_{ij}$ variable cost of connecting customer i to facility j\n", 30 | "* $q_{i}$ demand associated to customer i\n", 31 | "* $V_j$ capacity of facility j" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "$min_x$ \n", 39 | "\n", 40 | "$$\\sum_{j \\in J} f_{j} z_j + \\sum_{i \\in I}\\sum_{j \\in J} c_{ij} x_{ij}$$\n", 41 | "\n", 42 | "$s.t.$\n", 43 | "$$\\tag{1} \\sum_{j \\in J} x_{ij} = 1, \\forall i \\in I$$\n", 44 | "$$\\tag{2} \\sum_{i \\in I} q_{i} x_{ij} \\le V_j z_j, \\forall j \\in J$$\n", 45 | "$$x_{ij}, z_{j} \\in {0,1}$$\n" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "* $z_j$ decision variable associated with openning facility j\n", 53 | "* $x_{ij}$ decision variable associated with connecting customer i to facility j\n", 54 | "\n", 55 | "* (1) ensure that each customer is associated to a unique facility\n", 56 | "* (2) ensure that each customer is associated with an open facility and that the capacity constraint is respected" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "# Solve with Cplex" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 3, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "Overwriting ../pkg/cflp_cplex.py\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "%%file \"../pkg/cflp_cplex.py\"\n", 81 | "\n", 82 | "import numpy as np # mathematic tools library\n", 83 | "import networkx as nx # network representation library\n", 84 | "from pkg.cplex_solve import cplex_solve\n", 85 | "\n", 86 | "def cflp_cplex(I,J,\n", 87 | " c,f,\n", 88 | " q,V,\n", 89 | " relaxation=False,path=None):\n", 90 | " \"\"\"\n", 91 | " I,J number of customer and facilities\n", 92 | " v,f cost matrices for variables cost and fixed cost\n", 93 | " q,V demand of customers and capacity of facilities\n", 94 | " \"\"\"\n", 95 | " #####################################################################\n", 96 | " # Decision variables\n", 97 | " def X(i,j):\n", 98 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 99 | "\n", 100 | " def Z(j):\n", 101 | " return \"Z_\" + str(j)\n", 102 | " \n", 103 | " I = range(I); J = range(J);\n", 104 | " #####################################################################\n", 105 | " # Objective function\n", 106 | " \n", 107 | " Xs = {\n", 108 | " \"name\" : [X(i,j) for i in I for j in J],\n", 109 | " \"coef\" : [c[i][j] for i in I for j in J],\n", 110 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j in J],\n", 111 | " \"ub\" : [1 for i in I for j in J],\n", 112 | " \"lb\" : [0 for i in I for j in J],\n", 113 | " }\n", 114 | " \n", 115 | " Zs = {\n", 116 | " \"name\" : [Z(j) for j in J],\n", 117 | " \"coef\" : [f[j] for j in J],\n", 118 | " \"type\" : [\"C\" if relaxation else \"I\" for j in J],\n", 119 | " \"ub\" : [1 for j in J],\n", 120 | " \"lb\" : [0 for j in J],\n", 121 | " }\n", 122 | " \n", 123 | " variables = [Xs, Zs]\n", 124 | " #####################################################################\n", 125 | " # Constraints\n", 126 | " \n", 127 | " c1 = {\n", 128 | " \"lin_expr\": [[[X(i,j) for j in J], [1 for j in J]]\n", 129 | " for i in I],\n", 130 | " \"senses\" : [\"E\" for i in I],\n", 131 | " \"rhs\" : [0 for i in I]\n", 132 | " }\n", 133 | " \n", 134 | " c1 = {\n", 135 | " \"lin_expr\": [[[X(i,j) for i in range(J)]+[Z(j)],\n", 136 | " [q[i] for i in range(J)]+[-V[j]]] \n", 137 | " for j in range(J)],\n", 138 | " \"senses\" : [\"L\" for j in range(J)],\n", 139 | " \"rhs\" : [0 for j in range(J)]\n", 140 | " }\n", 141 | " \n", 142 | " constraints = [c1, c2]\n", 143 | " #####################################################################\n", 144 | " # Solving\n", 145 | " prob = cplex_solve(variables,constraints,\n", 146 | " minimize=True, path=path, verbose=verbose)\n", 147 | "\n", 148 | " #####################################################################\n", 149 | " # Extract solution\n", 150 | " solution = prob.solution.get_values()\n", 151 | " I = len(I); J = len(J);\n", 152 | " \n", 153 | " X = np.reshape(solution[0:I*J],(I,J))\n", 154 | " Z = solution[I*J:I*J+J]\n", 155 | "\n", 156 | " return prob, X, Z" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": { 163 | "collapsed": true 164 | }, 165 | "outputs": [], 166 | "source": [] 167 | } 168 | ], 169 | "metadata": { 170 | "hide_input": false, 171 | "kernelspec": { 172 | "display_name": "Py35", 173 | "language": "python", 174 | "name": "py35" 175 | }, 176 | "language_info": { 177 | "codemirror_mode": { 178 | "name": "ipython", 179 | "version": 3 180 | }, 181 | "file_extension": ".py", 182 | "mimetype": "text/x-python", 183 | "name": "python", 184 | "nbconvert_exporter": "python", 185 | "pygments_lexer": "ipython3", 186 | "version": "3.5.3" 187 | }, 188 | "toc": { 189 | "colors": { 190 | "hover_highlight": "#DAA520", 191 | "running_highlight": "#FF0000", 192 | "selected_highlight": "#FFD700" 193 | }, 194 | "moveMenuLeft": true, 195 | "nav_menu": { 196 | "height": "12px", 197 | "width": "252px" 198 | }, 199 | "navigate_menu": true, 200 | "number_sections": true, 201 | "sideBar": true, 202 | "threshold": 4, 203 | "toc_cell": false, 204 | "toc_section_display": "block", 205 | "toc_window_display": false, 206 | "widenNotebook": false 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 2 211 | } 212 | -------------------------------------------------------------------------------- /linear_programming_facility_location/3_TUFLP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "TUFLP - $2/\\bar{R}/\\bar{R}$\n", 10 | "\n", 11 | "Two-level uncapacitated facility location problem\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "Open a **subset** of level 1 facilities & **connect** customers to _one facility each_ and open a **subset** of level 2 facilities & **connect** level 1 facilities to _one facility each_ at a _minimal cost_\n", 27 | "\n", 28 | "\n", 29 | "* $f_jr$ fixed cost associated with opening the facility j at level r\n", 30 | "* $c_{ij_1j_2}$ cost of connecting customer i to level 1 facility j1 to facility level 2 j2" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "$min_x$ \n", 38 | "\n", 39 | "$$\\sum_{r =1}^2 \\sum_{j \\in V_r} f_{jr} z_{jr} + \\sum_{i \\in I} \\sum_{j_1 \\in V_1} \\sum_{j_2 \\in V_2} c_{i j_1 j_2} x_{i j_1 j_2}$$\n", 40 | "\n", 41 | "$s.t.$\n", 42 | "$$\\tag{1} \\sum_{j_1 \\in V_1} \\sum_{j_2 \\in V_2} x_{i j_1 j_2} = 1, \\forall i \\in I$$\n", 43 | "$$\\tag{2} \\sum_{j_1 \\in V_1} x_{i j_1 j_2} \\le z_{j_1}, \\forall i \\in I, \\forall j_2 \\in V_2$$\n", 44 | "$$\\tag{3} \\sum_{j_2 \\in V_2} x_{i j_1 j_2} \\le z_{j_2}, \\forall i \\in I, \\forall j_1 \\in V_1$$\n", 45 | "$$x_{i j_1 j_2}, z_{j} \\in {0,1}$$\n" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "* $z_jr$ decision variable associated with opening facility j and level r\n", 53 | "* $x_{ij_1j_2}$ decision variable associated with connecting customer i to level 1 facility $j_1$ to level 2 facility $j_2$\n", 54 | "\n", 55 | "* (1) ensure that each customer is associated to a unique couple of facility one in level 1 the other in level 2\n", 56 | "* (2), (3) ensure that each customer is associated with an open facility" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "# Solve with Cplex" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "Overwriting ../pkg/tuflp_cplex.py\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "%%file \"../pkg/tuflp_cplex.py\"\n", 81 | "\n", 82 | "from pkg.cplex_solve import cplex_solve\n", 83 | "import numpy as np # mathematic tools library\n", 84 | "import networkx as nx # network representation library\n", 85 | "\n", 86 | "def tuflp_cplex(I,V1,V2,\n", 87 | " c,f,\n", 88 | " relaxation=False,path=None,verbose=False):\n", 89 | " \"\"\"\n", 90 | " I,V1,V2 number of customers, level 1 facility, level 2 facility\n", 91 | " c,f cost matrix for connection and setup\n", 92 | " \"\"\"\n", 93 | " #####################################################################\n", 94 | " # Decision variables\n", 95 | " \n", 96 | " def X(i,j1,j2):\n", 97 | " return \"X_\" + str(i) + \"_\" + str(j1) + \"_\" + str(j2)\n", 98 | "\n", 99 | " def Z(j,r):\n", 100 | " return \"Z_\" + str(j) + \"_\" + str(r)\n", 101 | " \n", 102 | " nbr_var = I*V1*V2+(V1+V2)\n", 103 | " I = range(I); V1 = range(V1); V2 = range(V2);\n", 104 | "\n", 105 | " #####################################################################\n", 106 | " # Objective function\n", 107 | " \n", 108 | " Xs = {\n", 109 | " \"name\" : [X(i,j) for i in I for j1 in V1 for j2 in V2],\n", 110 | " \"coef\" : [c[i][j1][j2] for i in I for j1 in V1 for j2 in V2],\n", 111 | " \"type\" : [\"C\" if relaxation else \"I\" for i in I for j1 in V1 for j2 in V2],\n", 112 | " \"ub\" : [1 for i in I for j1 in V1 for j2 in V2],\n", 113 | " \"lb\" : [0 for i in I for j1 in V1 for j2 in V2],\n", 114 | " }\n", 115 | " \n", 116 | " Zs = {\n", 117 | " \"name\" : [Z(j) for j in range(len(V1)+len(V2))],\n", 118 | " \"coef\" : [f[j] for j in range(len(V1)+len(V2))],\n", 119 | " \"type\" : [\"C\" if relaxation else \"I\" for j in range(len(V1)+len(V2))],\n", 120 | " \"ub\" : [1 for j in range(len(V1)+len(V2))],\n", 121 | " \"lb\" : [0 for j in range(len(V1)+len(V2))],\n", 122 | " }\n", 123 | "\n", 124 | " #####################################################################\n", 125 | " # Constraints\n", 126 | " \n", 127 | " c1 = {\n", 128 | " \"lin_expr\": [[[X(i,j1,j2) for j1 in V1 for j2 in V2], [1 for j1 in V1 for j2 in V2]] \n", 129 | " for i in range(I)],\n", 130 | " \"senses\" : [\"E\" for i in range(I)],\n", 131 | " \"rhs\" : [0 for i in range(I)]\n", 132 | " }\n", 133 | " \n", 134 | " c2 = {\n", 135 | " \"lin_expr\": [[[X(i,j1,j2) for j1 in V1]+[Z(j2,2)], [1 for j1 in V1]+ [-1]]\n", 136 | " for i in I for j2 in V2],\n", 137 | " \"senses\" : [\"L\" for i in I for j2 in V2],\n", 138 | " \"rhs\" : [0 for i in I for j2 in V2]\n", 139 | " }\n", 140 | " \n", 141 | " c3 = {\n", 142 | " \"lin_expr\": [[[X(i,j1,j2) for j2 in V2]+[Z(j1,1)], [1 for j2 in V2]+ [-1]]\n", 143 | " for i in I for j1 in V1],\n", 144 | " \"senses\" : [\"L\" for i in I for j1 in V1],\n", 145 | " \"rhs\" : [0 for i in I for j1 in V1]\n", 146 | " }\n", 147 | " \n", 148 | " constraints = [c1, c2, c3]\n", 149 | "\n", 150 | " #####################################################################\n", 151 | " # Solving\n", 152 | " prob = cplex_solve(variables,constraints,\n", 153 | " minimize=True, path=path, verbose=verbose)\n", 154 | " #####################################################################\n", 155 | " # Extract solution\n", 156 | " I = len(I); V1 = len(V1); V2 = len(V2);\n", 157 | " solution = prob.solution.get_values()\n", 158 | " X = np.reshape(solution[0:I*V1*V2],(I,V1,V2))\n", 159 | " Z = solution[I*V1*V2:]\n", 160 | "\n", 161 | " return prob, X, Z" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": { 168 | "collapsed": true 169 | }, 170 | "outputs": [], 171 | "source": [] 172 | } 173 | ], 174 | "metadata": { 175 | "hide_input": false, 176 | "kernelspec": { 177 | "display_name": "Py35", 178 | "language": "python", 179 | "name": "py35" 180 | }, 181 | "language_info": { 182 | "codemirror_mode": { 183 | "name": "ipython", 184 | "version": 3 185 | }, 186 | "file_extension": ".py", 187 | "mimetype": "text/x-python", 188 | "name": "python", 189 | "nbconvert_exporter": "python", 190 | "pygments_lexer": "ipython3", 191 | "version": "3.5.3" 192 | }, 193 | "toc": { 194 | "colors": { 195 | "hover_highlight": "#DAA520", 196 | "running_highlight": "#FF0000", 197 | "selected_highlight": "#FFD700" 198 | }, 199 | "moveMenuLeft": true, 200 | "nav_menu": { 201 | "height": "12px", 202 | "width": "252px" 203 | }, 204 | "navigate_menu": true, 205 | "number_sections": true, 206 | "sideBar": true, 207 | "threshold": 4, 208 | "toc_cell": false, 209 | "toc_section_display": "block", 210 | "toc_window_display": false, 211 | "widenNotebook": false 212 | } 213 | }, 214 | "nbformat": 4, 215 | "nbformat_minor": 2 216 | } 217 | -------------------------------------------------------------------------------- /linear_programming_location_routing/CRAB_MB_modified.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "$min_{Y,Z,N}$\n", 15 | "$$\n", 16 | "\\begin{align}\n", 17 | " TC2 = \\\\\n", 18 | " &\\tag{2.1} \\sum_{i \\in I}\\sum_{j \\in J} w_{ij} Y_{ij} \\\\\n", 19 | " &\\tag{2.2} + \\sum_{c \\in C \\cup J}\\sum_{j \\in C \\cup J}\\sum_{b \\in B}(D_{cj}+FCV_b) Z_{cjb} \\\\\n", 20 | " &\\tag{2.3} + \\sum_{j \\in J}FCT_j N_j \\\\\n", 21 | " &\\tag{2.4} + \\sum_{c \\in C}(FCR_c+D_c) N_c \\\\\n", 22 | " &\\tag{2.5} + \\sum_{j \\in J}\\sum_{k \\in K}\\sum_{v \\in V}q_{iv} (PC_{ikv}+IP_{ikv})\n", 23 | "\\end{align}\n", 24 | "$$" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "$s.t$\n", 32 | "$$\\tag{c2-UFLP-L1} \\sum_{j \\in J}Y_{ij} = 1, \\forall i \\in I $$\n", 33 | "$$\\tag{c4-CFLP-L1} \\sum_{i \\in I}q_iY_{ij} \\le Q_jN_j , \\forall j \\in J $$\n", 34 | "$$\\tag{c5-CFLP-L2} \\sum_{i \\in I}q_iY_{ij} = V_j , \\forall j \\in J $$" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "$$\\tag{c*} \\sum_{u \\in C \\cup J}\\sum_{b \\in B}Z_{uub} = 0$$\n", 42 | "$$\\tag{c6-VRP} \\sum_{c \\in C \\cup J}\\sum_{b \\in B}Z_{cjb} = N_j , \\forall j \\in J$$\n", 43 | "$$\\tag{c11-VRP} \\sum_{c \\in C}\\sum_{j \\in J}Z_{cjb} \\le 1 , \\forall b \\in B$$" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "$$\\tag{c12-VRP} \\sum_{j \\in J}\\sum_{c \\in C \\cup J}VZ_{cjb} \\le Q_b , \\forall b \\in B$$\n", 51 | "$$\\tag{c12.1} VZ_{cjb} \\le V_j , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 52 | "$$\\tag{c12.2} VZ_{cjb} \\le max(Q_j)Z_{cjb} , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 53 | "$$\\tag{c12.3} VZ_{cjb} \\ge V_j - max(Q_j)(1-Z_{cjb}) , \\forall j \\in J, \\forall c \\in C, \\forall b \\in B$$\n", 54 | "$$\\tag{c13-VRP}U_c - U_j + (|C|+|J|)\\sum_{b \\in B}Z_{jcb} \\le (|C|+|J|-1), \\forall c,j \\in J, c \\neq j$$\n", 55 | "$$\\tag{c14-VRP} \\sum_{j \\in C \\cup J}Z_{cjb} - \\sum_{j \\in C \\cup J}Z_{jcb} =0 , \\forall c \\in C \\cup J, \\forall b \\in B$$" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 6, 61 | "metadata": {}, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "Overwriting ../pkg/crab_mb_m_cplex.py\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "%%file \"../pkg/crab_mb_m_cplex.py\"\n", 73 | "\n", 74 | "from pkg.cplex_solve import cplex_solve\n", 75 | "import numpy as np # mathematic tools library\n", 76 | "import networkx as nx # network representation library\n", 77 | "import cplex\n", 78 | "\n", 79 | "def crab_mb_m_cplex(I,J,C,B,K,V,\n", 80 | " w,Djc,FCV,FCT,FCR,Dc,q,\n", 81 | " Q,relaxation=False,path=None):\n", 82 | " \"\"\"\n", 83 | " Parameters:\n", 84 | " Sets:\n", 85 | " I,J,C,K,V,B -> customer, ICPs, CRCs, qualities, varieties, vehicles\n", 86 | " Costs:\n", 87 | " FCT, FCR, FCV, fixed cost for ICP, CRC, vehicle\n", 88 | " IP, PC acquisition and processiong cost\n", 89 | " Weight:\n", 90 | " q, nbr unit collected\n", 91 | " w, Djc, Dc cost related to traveling distances cus-ICP, ICP-CRC, CRC-PC\n", 92 | " Capacity:\n", 93 | " Q capacity matrix\n", 94 | " \n", 95 | " Decision Vqriables:\n", 96 | " Y_ij customer i associated to ICP j\n", 97 | " Z_cjb vehicle travel from CRC_c to ICP_j on route b\n", 98 | " N_icp, N_crc -> ICP / CRC is open\n", 99 | " \"\"\"\n", 100 | " #####################################################################\n", 101 | " # Decision variables\n", 102 | " \n", 103 | " def Y(i,j):\n", 104 | " return \"Y_\" + str(i) + \"_\" + str(j)\n", 105 | " \n", 106 | " def Z(c,j,b):\n", 107 | " return \"Z_\" + str(c) + \"_\" + str(j) + \"_\" + str(b)\n", 108 | " \n", 109 | " def N(j):\n", 110 | " return \"N_\" + str(j)\n", 111 | " \n", 112 | " def V(j):\n", 113 | " return \"V_\" + str(j)\n", 114 | " \n", 115 | " def VZ(c,j,b):\n", 116 | " return \"VZ_\" + str(c) + \"_\" + str(j) + \"_\" + str(b)\n", 117 | " \n", 118 | " def U(j):\n", 119 | " return \"L_\" + str(j)\n", 120 | "\n", 121 | " CuJ = range(C+J); C = range(J,C+J,1)\n", 122 | " I = range(I);J = range(J); B = range(B); \n", 123 | " \n", 124 | " #####################################################################\n", 125 | " ## variables\n", 126 | " Ys = {\n", 127 | " \"name\" : [Y(i,j) for i in I for j in J],\n", 128 | " \"coef\" : [w[i][j] for i in I for j in J],\n", 129 | " \"type\" : [\"I\" for i in I for j in J],\n", 130 | " \"ub\" : [1 for i in I for j in J],\n", 131 | " \"lb\" : [0 for i in I for j in J],\n", 132 | " }\n", 133 | " Zs = {\n", 134 | " \"name\" : [Z(c,j,b) for c in CuJ for j in CuJ for b in B],\n", 135 | " \"coef\" : [Djc[c][j] for c in CuJ for j in CuJ for b in B],\n", 136 | " \"type\" : [\"I\" for c in CuJ for j in CuJ for b in B],\n", 137 | " \"ub\" : [1 for c in CuJ for j in CuJ for b in B],\n", 138 | " \"lb\" : [0 for c in CuJ for j in CuJ for b in B],\n", 139 | " }\n", 140 | " Ns = {\n", 141 | " \"name\" : [N(j) for j in J] + [N(c) for c in C],\n", 142 | " \"coef\" : [FCT[j] for j in J] + [FCR[c-len(J)]+Dc[c-len(J)]+FCV[c-len(J)] for c in C],\n", 143 | " \"type\" : [\"I\" for j in J] + [\"I\" for c in C],\n", 144 | " \"ub\" : [1 for j in J] + [1 for c in C],\n", 145 | " \"lb\" : [0 for j in J] + [0 for c in C],\n", 146 | " }\n", 147 | " # Dummy variables\n", 148 | " Vs = {\n", 149 | " \"name\" : [V(j) for j in J],\n", 150 | " \"coef\" : [0 for j in J],\n", 151 | " \"type\" : [\"C\" for j in J],\n", 152 | " \"ub\" : [cplex.infinity for j in J],\n", 153 | " \"lb\" : [0 for j in J],\n", 154 | " }\n", 155 | " VZs = {\n", 156 | " \"name\" : [VZ(c,j,b) for c in CuJ for j in CuJ for b in B],\n", 157 | " \"coef\" : [0 for c in CuJ for j in CuJ for b in B],\n", 158 | " \"type\" : [\"C\" for c in CuJ for j in CuJ for b in B],\n", 159 | " \"ub\" : [cplex.infinity for c in CuJ for j in CuJ for b in B],\n", 160 | " \"lb\" : [0 for c in CuJ for j in CuJ for b in B],\n", 161 | " }\n", 162 | " Us = {\n", 163 | " \"name\" : [U(j) for j in CuJ],\n", 164 | " \"coef\" : [0 for j in CuJ],\n", 165 | " \"type\" : [\"C\" for j in CuJ],\n", 166 | " \"ub\" : [cplex.infinity for j in CuJ],\n", 167 | " \"lb\" : [0 for j in CuJ],\n", 168 | " }\n", 169 | "\n", 170 | " Variables = [Ys,Zs,Ns,Vs,Us]\n", 171 | " ## Objective function sum aggregation\n", 172 | " obj = [];ub = [];lb = [];colnames = [];types = [];\n", 173 | " for v in Variables:\n", 174 | " obj = obj + v[\"coef\"]\n", 175 | " ub = ub + v[\"ub\"]\n", 176 | " lb = lb + v[\"lb\"]\n", 177 | " colnames = colnames + v[\"name\"]\n", 178 | " types = types + v[\"type\"]\n", 179 | " \n", 180 | " #####################################################################\n", 181 | " # Constraints\n", 182 | " \n", 183 | " # Ys FLP constraints\n", 184 | " c2 = {\n", 185 | " \"lin_expr\": [[[Y(i,j) for j in J]\n", 186 | " ,[1 for j in J]] \n", 187 | " for i in I],\n", 188 | " \"senses\" : [\"E\" for i in I],\n", 189 | " \"rhs\" : [1 for i in I]\n", 190 | " }\n", 191 | " c4 = {\n", 192 | " \"lin_expr\": [[[Y(i,j) for i in I]+[N(j)],\n", 193 | " [q[i] for i in I]+[-Q[0][j]]] \n", 194 | " for j in J],\n", 195 | " \"senses\" : [\"L\" for j in J],\n", 196 | " \"rhs\" : [0 for j in J]\n", 197 | " }\n", 198 | " c5 = {\n", 199 | " \"lin_expr\": [[[Y(i,j) for i in I]+[V(j)]\n", 200 | " , [q[i] for i in I]+[-1]] \n", 201 | " for j in J],\n", 202 | " \"senses\" : [\"E\" for j in J],\n", 203 | " \"rhs\" : [0 for j in J]\n", 204 | " }\n", 205 | "\n", 206 | " # Zs FLP constraints\n", 207 | " cstar = {\n", 208 | " \"lin_expr\": [[[Z(c,c,b) for c in CuJ for b in B],\n", 209 | " [1 for c in CuJ for b in B]] \n", 210 | " ],\n", 211 | " \"senses\" : [\"E\"],\n", 212 | " \"rhs\" : [0]\n", 213 | " }\n", 214 | " c6 = {\n", 215 | " \"lin_expr\": [[[Z(j,c,b) for c in CuJ for b in B]+[N(j)],\n", 216 | " [1 for c in CuJ for b in B]+[-1]] \n", 217 | " for j in J],\n", 218 | " \"senses\" : [\"E\" for j in J],\n", 219 | " \"rhs\" : [0 for j in J]\n", 220 | " }\n", 221 | " c8 = {\n", 222 | " \"lin_expr\": [[[Z(c,j,b) for j in J for b in B]+[N(c)],\n", 223 | " [1 for j in J for b in B]+[-1]] \n", 224 | " for c in C],\n", 225 | " \"senses\" : [\"E\" for c in C],\n", 226 | " \"rhs\" : [0 for c in C]\n", 227 | " }\n", 228 | " c11 = {\n", 229 | " \"lin_expr\": [[[Z(c,j,b) for c in C for j in CuJ],\n", 230 | " [1 for c in C for j in CuJ]] \n", 231 | " for b in B],\n", 232 | " \"senses\" : [\"L\" for b in B],\n", 233 | " \"rhs\" : [1 for b in B]\n", 234 | " }\n", 235 | " c12 = {\n", 236 | " \"lin_expr\": [[[VZ(c,j,b) for c in CuJ for j in J],\n", 237 | " [1 for c in CuJ for j in J]] \n", 238 | " for b in B],\n", 239 | " \"senses\" : [\"L\" for c in CuJ],\n", 240 | " \"rhs\" : [Q[1][b] for b in B]\n", 241 | " }\n", 242 | " c13 = {\n", 243 | " \"lin_expr\": [[[U(c),U(j)]+[Z(c,j,b) for b in B],\n", 244 | " [1,-1]+[len(J)+len(C) for b in B]] \n", 245 | " for c in J for j in J if c!=j],\n", 246 | " \"senses\" : [\"L\" for c in J for j in J if c!=j],\n", 247 | " \"rhs\" : [len(J)+len(C)-1 for c in J for j in J if c!=j]\n", 248 | " }\n", 249 | " c14 = {\n", 250 | " \"lin_expr\": [[[Z(c,j,b) for c in CuJ if c!=j]+[Z(j,c,b) for c in CuJ if c!=j], \n", 251 | " [1 for c in CuJ if c!=j]+[-1 for c in CuJ if c!=j]] \n", 252 | " for j in CuJ for b in B],\n", 253 | " \"senses\" : [\"E\" for j in CuJ for b in B],\n", 254 | " \"rhs\" : [0 for j in CuJ for b in B]\n", 255 | " }\n", 256 | " \n", 257 | " # Zs VRP constraints\n", 258 | " \n", 259 | " Constraints = [c2,c4,c5,cstar,c6,c14,c13,c11]\n", 260 | " rows = []; senses = []; rhs = [];\n", 261 | " for c in Constraints:\n", 262 | " rows = rows + c[\"lin_expr\"]\n", 263 | " senses = senses + c[\"senses\"]\n", 264 | " rhs = rhs + c[\"rhs\"]\n", 265 | "\n", 266 | " print(len(rows),len(senses),len(rhs)) \n", 267 | " \n", 268 | " #####################################################################\n", 269 | " # Solving\n", 270 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path, verbose=True)\n", 271 | " \n", 272 | " #####################################################################\n", 273 | " # Extract solution\n", 274 | " CuJ = len(C)+len(J); I = len(I); J = len(J); B = len(B); C = len(C);\n", 275 | " \n", 276 | " solution = prob.solution.get_values()\n", 277 | " Y = np.reshape(solution[0:I*J],(I,J))\n", 278 | " Z = np.reshape(solution[I*J:I*J+CuJ*CuJ*B],(CuJ,CuJ,B))\n", 279 | " N = solution[I*J+CuJ*CuJ*B:I*J+CuJ*CuJ*B+J+C]\n", 280 | " V = solution[I*J+CuJ*CuJ*B+J+C:I*J+CuJ*CuJ*B+J+C+J]\n", 281 | "\n", 282 | " return prob, Y, Z, N, V" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": null, 288 | "metadata": { 289 | "collapsed": true 290 | }, 291 | "outputs": [], 292 | "source": [] 293 | } 294 | ], 295 | "metadata": { 296 | "hide_input": false, 297 | "kernelspec": { 298 | "display_name": "Py35", 299 | "language": "python", 300 | "name": "py35" 301 | }, 302 | "language_info": { 303 | "codemirror_mode": { 304 | "name": "ipython", 305 | "version": 3 306 | }, 307 | "file_extension": ".py", 308 | "mimetype": "text/x-python", 309 | "name": "python", 310 | "nbconvert_exporter": "python", 311 | "pygments_lexer": "ipython3", 312 | "version": "3.5.3" 313 | }, 314 | "toc": { 315 | "colors": { 316 | "hover_highlight": "#DAA520", 317 | "running_highlight": "#FF0000", 318 | "selected_highlight": "#FFD700" 319 | }, 320 | "moveMenuLeft": true, 321 | "nav_menu": { 322 | "height": "12px", 323 | "width": "252px" 324 | }, 325 | "navigate_menu": true, 326 | "number_sections": true, 327 | "sideBar": true, 328 | "threshold": 4, 329 | "toc_cell": false, 330 | "toc_section_display": "block", 331 | "toc_window_display": false, 332 | "widenNotebook": false 333 | } 334 | }, 335 | "nbformat": 4, 336 | "nbformat_minor": 2 337 | } 338 | -------------------------------------------------------------------------------- /linear_programming_vehicle_routing/.ipynb_checkpoints/VRP_2_T-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "TSP\n", 10 | "\n", 11 | "Traveling Sales Man\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "The Traveling Salesman Problem for a **complete graph** can be stated as:\n", 27 | "\n", 28 | "$min_x$\n", 29 | "$$ \\sum_{i,j \\in N, i < j, b \\in B} c_{ij}x_{ijb} $$\n", 30 | "$s.t$\n", 31 | "$$\\tag{c0} \\sum_{b \\in B}\\sum_{u \\in I \\cup J}x_{uub} = 0$$\n", 32 | "$$\\tag{c1} \\sum_{b \\in B}\\sum_{j \\in I \\cup J}x_{ijb} = N_j , \\forall i \\in I$$\n", 33 | "$$\\tag{c2} \\sum_{i \\in I \\cup J}x_{ijb} - \\sum_{i \\in C \\cup J}x_{jib} = 0 , \\forall j \\in I \\cup J, \\forall b \\in B$$\n", 34 | "$$\\tag{c3} \\sum_{i \\in I \\cup J}\\sum_{j \\in J}x_{ijb} \\le 1 , \\forall b \\in B$$\n", 35 | "$$\\tag{c4}U_i - U_j + (|I|+|J|)\\sum_{b \\in B}x_{ijb} \\le (|I|+|J|-1), \\forall i,j \\in I, i \\neq j$$" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "# Solve with Cplex" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "Overwriting ../pkg/vrp_2_t_cplex.py\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "%%file \"../pkg/vrp_2_t_cplex.py\"\n", 60 | "\n", 61 | "import numpy as np # mathematic tools library\n", 62 | "import networkx as nx # network representation library\n", 63 | "from pkg.cplex_solve import cplex_solve\n", 64 | "import cplex\n", 65 | "\n", 66 | "def vrp_2_t_cplex(I,J,B,\n", 67 | " c,f,\n", 68 | " relaxation=False,path=None):\n", 69 | "\n", 70 | " #####################################################################\n", 71 | " # Decision variables\n", 72 | " \n", 73 | " def X(i,j,b):\n", 74 | " return \"X_\" + str(i) + \"_\" + str(j) + \"_\" + str(b)\n", 75 | " def U(i):\n", 76 | " return \"U_\" + str(i)\n", 77 | " def N(j):\n", 78 | " return \"N_\" + str(j)\n", 79 | " \n", 80 | " IuJ = range(I+J); J = range(I,I+J,1)\n", 81 | " I = range(I); B = range(B); \n", 82 | " #####################################################################\n", 83 | " # Objective function\n", 84 | " Xs = {\n", 85 | " \"name\" : [X(i,j,b) for i in IuJ for j in IuJ for b in B],\n", 86 | " \"coef\" : [c[i][j] for i in IuJ for j in IuJ for b in B],\n", 87 | " \"type\" : [\"I\" for i in IuJ for j in IuJ for b in B],\n", 88 | " \"ub\" : [1 for i in IuJ for j in IuJ for b in B],\n", 89 | " \"lb\" : [0 for i in IuJ for j in IuJ for b in B],\n", 90 | " }\n", 91 | " Ns = {\n", 92 | " \"name\" : [N(j) for j in J],\n", 93 | " \"coef\" : [f[j-len(I)] for j in J],\n", 94 | " \"type\" : [\"I\" for j in J],\n", 95 | " \"ub\" : [1 for j in J],\n", 96 | " \"lb\" : [0 for j in J],\n", 97 | " }\n", 98 | " Us = {\n", 99 | " \"name\" : [U(i) for i in IuJ],\n", 100 | " \"coef\" : [0 for i in IuJ],\n", 101 | " \"type\" : [\"C\" for i in IuJ],\n", 102 | " \"ub\" : [cplex.infinity for i in IuJ],\n", 103 | " \"lb\" : [0 for i in IuJ],\n", 104 | " }\n", 105 | "\n", 106 | " Variables = [Xs,Ns,Us]\n", 107 | " ## Objective function sum aggregation\n", 108 | " obj = [];ub = [];lb = [];colnames = [];types = [];\n", 109 | " for v in Variables:\n", 110 | " obj = obj + v[\"coef\"]\n", 111 | " ub = ub + v[\"ub\"]\n", 112 | " lb = lb + v[\"lb\"]\n", 113 | " colnames = colnames + v[\"name\"]\n", 114 | " types = types + v[\"type\"]\n", 115 | "\n", 116 | " #####################################################################\n", 117 | " # Constraints\n", 118 | " c0 = {\n", 119 | " \"lin_expr\": [[[X(i,i,b) for i in IuJ for b in B],\n", 120 | " [1 for i in IuJ for b in B]] \n", 121 | " ],\n", 122 | " \"senses\" : [\"E\"],\n", 123 | " \"rhs\" : [0]\n", 124 | " }\n", 125 | " c1 = {\n", 126 | " \"lin_expr\": [[[X(i,j,b) for b in B for j in IuJ],\n", 127 | " [1 for b in B for j in IuJ]] \n", 128 | " for i in I],\n", 129 | " \"senses\" : [\"E\" for i in I],\n", 130 | " \"rhs\" : [1 for i in I]\n", 131 | " }\n", 132 | " c2 = {\n", 133 | " \"lin_expr\": [[[X(i,j,b) for i in IuJ if i!=j]+[X(j,i,b) for i in IuJ if i!=j], \n", 134 | " [1 for i in IuJ if i!=j]+[-1 for i in IuJ if i!=j]] \n", 135 | " for j in IuJ for b in B],\n", 136 | " \"senses\" : [\"E\" for j in IuJ for b in B],\n", 137 | " \"rhs\" : [0 for j in IuJ for b in B]\n", 138 | " }\n", 139 | " c3 = {\n", 140 | " \"lin_expr\": [[[X(i,j,b) for i in IuJ for j in J],\n", 141 | " [1 for i in IuJ for j in J]] \n", 142 | " for b in B],\n", 143 | " \"senses\" : [\"L\" for b in B],\n", 144 | " \"rhs\" : [1 for b in B]\n", 145 | " }\n", 146 | " c4 = {\n", 147 | " \"lin_expr\": [[[U(i),U(j)]+[X(i,j,b) for b in B],\n", 148 | " [1,-1]+[len(I)+len(J) for b in B]] \n", 149 | " for i in I for j in I if i!=j],\n", 150 | " \"senses\" : [\"L\" for i in I for j in I if i!=j],\n", 151 | " \"rhs\" : [len(I)+len(J)-1 for i in I for j in I if i!=j]\n", 152 | " }\n", 153 | "\n", 154 | " # Zs VRP constraints\n", 155 | " Constraints = [c0,c1,c2,c3,c4]\n", 156 | " rows = []; senses = []; rhs = [];\n", 157 | " for c in Constraints:\n", 158 | " rows = rows + c[\"lin_expr\"]\n", 159 | " senses = senses + c[\"senses\"]\n", 160 | " rhs = rhs + c[\"rhs\"]\n", 161 | "\n", 162 | " print(len(rows),len(senses),len(rhs))\n", 163 | " \n", 164 | " #####################################################################\n", 165 | " # Solving\n", 166 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path)\n", 167 | "\n", 168 | " #####################################################################\n", 169 | " # Extract solution\n", 170 | " IuJ = len(I)+len(J); J = len(J)\n", 171 | " I = len(I); B = len(B); \n", 172 | " \n", 173 | " solution = prob.solution.get_values()\n", 174 | " X = np.reshape(solution[0:IuJ*IuJ*B],(IuJ,IuJ,B))\n", 175 | " N = solution[IuJ*IuJ*B:IuJ*IuJ*B]\n", 176 | "\n", 177 | " return prob, X, N" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "metadata": { 184 | "collapsed": true 185 | }, 186 | "outputs": [], 187 | "source": [] 188 | } 189 | ], 190 | "metadata": { 191 | "hide_input": false, 192 | "kernelspec": { 193 | "display_name": "Py35", 194 | "language": "python", 195 | "name": "py35" 196 | }, 197 | "language_info": { 198 | "codemirror_mode": { 199 | "name": "ipython", 200 | "version": 3 201 | }, 202 | "file_extension": ".py", 203 | "mimetype": "text/x-python", 204 | "name": "python", 205 | "nbconvert_exporter": "python", 206 | "pygments_lexer": "ipython3", 207 | "version": "3.5.3" 208 | }, 209 | "toc": { 210 | "colors": { 211 | "hover_highlight": "#DAA520", 212 | "running_highlight": "#FF0000", 213 | "selected_highlight": "#FFD700" 214 | }, 215 | "moveMenuLeft": true, 216 | "nav_menu": { 217 | "height": "12px", 218 | "width": "252px" 219 | }, 220 | "navigate_menu": true, 221 | "number_sections": true, 222 | "sideBar": true, 223 | "threshold": 4, 224 | "toc_cell": false, 225 | "toc_section_display": "block", 226 | "toc_window_display": false, 227 | "widenNotebook": false 228 | } 229 | }, 230 | "nbformat": 4, 231 | "nbformat_minor": 2 232 | } 233 | -------------------------------------------------------------------------------- /linear_programming_vehicle_routing/1_TSP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "TSP\n", 10 | "\n", 11 | "Traveling Sales Man\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "The Traveling Salesman Problem for a **complete graph** can be stated as:\n", 27 | "\n", 28 | "$min_x$\n", 29 | "$$ \\sum_{i,j \\in N, i < j} c_{ij}x_{ij} $$\n", 30 | "$s.t$\n", 31 | "$$\\tag{1} \\sum_{i \\in N, i \\neq j} x_{ik} = 1, \\forall j \\in N$$\n", 32 | "$$\\tag{2} \\sum_{j \\in N, i \\neq j} x_{ik} = 1, \\forall i \\in N$$\n", 33 | "$$\\tag{3} u_i - u_j + |N|x_{ij} \\le |N|-1 , \\forall i,j \\in N\\setminus\\lbrace{1}\\rbrace, i \\neq j$$" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "# Solve with Cplex" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 77, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "Overwriting ../pkg/tsp_cplex.py\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "%%file \"../pkg/tsp_cplex.py\"\n", 58 | "\n", 59 | "import numpy as np # mathematic tools library\n", 60 | "import networkx as nx # network representation library\n", 61 | "from pkg.cplex_solve import cplex_solve\n", 62 | "import cplex\n", 63 | "\n", 64 | "def tsp_cplex(N,\n", 65 | " c,\n", 66 | " relaxation=False,path=None):\n", 67 | "\n", 68 | " #####################################################################\n", 69 | " # Decision variables\n", 70 | " \n", 71 | " def X(i,j):\n", 72 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 73 | " \n", 74 | " def U(i):\n", 75 | " return \"U_\" + str(i)\n", 76 | " \n", 77 | " N = range(N);\n", 78 | " #####################################################################\n", 79 | " # Objective function\n", 80 | " \n", 81 | " obj1 = [c[i][j] for i in N for j in N]\n", 82 | " obj2 = [0 for i in N]\n", 83 | " \n", 84 | " ## variables name\n", 85 | " Xs = [X(i,j) for i in N for j in N]\n", 86 | " Us = [U(i) for i in N]\n", 87 | "\n", 88 | " ## Objective function sum aggregation\n", 89 | " obj = obj1 + obj2\n", 90 | " colnames = Xs + Us\n", 91 | " if relaxation:\n", 92 | " types = \"C\" * (len(Xs)+len(Us)) #Integrality constraint\n", 93 | " else:\n", 94 | " types = \"I\" * len(Xs) + \"C\" * len(Us) #Integrality constraint\n", 95 | "\n", 96 | " #####################################################################\n", 97 | " # Constraints\n", 98 | " \n", 99 | " c1 = [\n", 100 | " [[X(i,j) for i in N if i != j], [1 for i in N if i != j]]\n", 101 | " for j in N]\n", 102 | " \n", 103 | " c2 = [\n", 104 | " [[X(i,j) for j in N if i != j], [1 for j in N if i != j]]\n", 105 | " for i in N]\n", 106 | " \n", 107 | " subtours = [(i,j) for i in N for j in N if i != j and j > 0 and i > 0]\n", 108 | " \n", 109 | " c3 = [\n", 110 | " [[U(i),U(j),X(i,j)], [1,-1,len(N)-1]]\n", 111 | " for i,j in subtours]\n", 112 | " \n", 113 | " s1 = \"E\" * len(N)\n", 114 | " s2 = \"E\" * len(N)\n", 115 | " s3 = \"L\" * len(subtours)\n", 116 | "\n", 117 | " r1 = [1 for i in N]\n", 118 | " r2 = [1 for i in N]\n", 119 | " r3 = [len(N)-2 for i in range(len(subtours))]\n", 120 | "\n", 121 | " rows = c1+c2+c3\n", 122 | " senses = s1+s2+s3\n", 123 | " rhs = r1+r2+r3\n", 124 | " \n", 125 | " #####################################################################\n", 126 | " # Bounds\n", 127 | " ub = [1 for i in range(len(Xs))] + [cplex.infinity for i in range(len(Us))]\n", 128 | " lb = [0 for i in range((len(Xs)+len(Us)))]\n", 129 | " \n", 130 | " #####################################################################\n", 131 | " # Solving\n", 132 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path)\n", 133 | "\n", 134 | " #####################################################################\n", 135 | " # Extract solution\n", 136 | " N = len(N)\n", 137 | " \n", 138 | " solution = prob.solution.get_values()\n", 139 | " X = np.reshape(solution[0:N*N],(N,N))\n", 140 | "\n", 141 | " return prob, X" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": { 148 | "collapsed": true 149 | }, 150 | "outputs": [], 151 | "source": [] 152 | } 153 | ], 154 | "metadata": { 155 | "hide_input": false, 156 | "kernelspec": { 157 | "display_name": "Py35", 158 | "language": "python", 159 | "name": "py35" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.5.3" 172 | }, 173 | "toc": { 174 | "colors": { 175 | "hover_highlight": "#DAA520", 176 | "running_highlight": "#FF0000", 177 | "selected_highlight": "#FFD700" 178 | }, 179 | "moveMenuLeft": true, 180 | "nav_menu": { 181 | "height": "12px", 182 | "width": "252px" 183 | }, 184 | "navigate_menu": true, 185 | "number_sections": true, 186 | "sideBar": true, 187 | "threshold": 4, 188 | "toc_cell": false, 189 | "toc_section_display": "block", 190 | "toc_window_display": false, 191 | "widenNotebook": false 192 | } 193 | }, 194 | "nbformat": 4, 195 | "nbformat_minor": 2 196 | } 197 | -------------------------------------------------------------------------------- /linear_programming_vehicle_routing/2_mTSP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "mTSP\n", 10 | "\n", 11 | "Multi-vehicle Traveling Sales Man\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "The Traveling Salesman Problem for a **complete graph** can be stated as:\n", 27 | "\n", 28 | "$min_x$\n", 29 | "$$ \\sum_{i,j \\in N, i < j} c_{ij}x_{ij} $$\n", 30 | "$s.t$\n", 31 | "$$\\tag{1} \\sum_{i \\in N, i \\neq j} x_{ij} = 1, \\forall j \\in N$$\n", 32 | "$$\\tag{2} \\sum_{j \\in N, i \\neq j} x_{ij} = 1, \\forall i \\in N$$\n", 33 | "$$\\tag{3} u_i - u_j + |N|x_{ij} \\le |N|-1 , \\forall (i,j) \\in\n", 34 | "N\\setminus\\lbrace{1}\\rbrace, i \\neq j$$\n", 35 | "\n", 36 | "$$\\tag{4} \\sum_{i \\in N\\setminus\\lbrace{1}\\rbrace} x_{1j} = m$$\n", 37 | "$$\\tag{5} \\sum_{j \\in N\\setminus\\lbrace{1}\\rbrace} x_{i1} = m$$" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "# Solve with Cplex" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 2, 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "Overwriting ../pkg/mtsp_cplex.py\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "%%file \"../pkg/mtsp_cplex.py\"\n", 62 | "\n", 63 | "import numpy as np # mathematic tools library\n", 64 | "import networkx as nx # network representation library\n", 65 | "from pkg.cplex_solve import cplex_solve\n", 66 | "import cplex\n", 67 | "\n", 68 | "def mtsp_cplex(N,m\n", 69 | " c,\n", 70 | " relaxation=False,path=None):\n", 71 | "\n", 72 | " #####################################################################\n", 73 | " # Decision variables\n", 74 | " \n", 75 | " def X(i,j):\n", 76 | " return \"X_\" + str(i) + \"_\" + str(j)\n", 77 | " \n", 78 | " def U(i):\n", 79 | " return \"U_\" + str(i)\n", 80 | " \n", 81 | " N = range(N);\n", 82 | " #####################################################################\n", 83 | " # Objective function\n", 84 | " \n", 85 | " obj1 = [c[i][j] for i in N for j in N]\n", 86 | " obj2 = [0 for i in N]\n", 87 | " \n", 88 | " ## variables name\n", 89 | " Xs = [X(i,j) for i in N for j in N]\n", 90 | " Us = [U(i) for i in N]\n", 91 | "\n", 92 | " ## Objective function sum aggregation\n", 93 | " obj = obj1 + obj2\n", 94 | " colnames = Xs + Us\n", 95 | " if relaxation:\n", 96 | " types = \"C\" * (len(Xs)+len(Us)) #Integrality constraint\n", 97 | " else:\n", 98 | " types = \"I\" * len(Xs) + \"C\" * len(Us) #Integrality constraint\n", 99 | "\n", 100 | " #####################################################################\n", 101 | " # Constraints\n", 102 | " \n", 103 | " c1 = [\n", 104 | " [[X(i,j) for i in N if i != j], [1 for i in N if i != j]]\n", 105 | " for j in N]\n", 106 | " \n", 107 | " c2 = [\n", 108 | " [[X(i,j) for j in N if i != j], [1 for j in N if i != j]]\n", 109 | " for i in N]\n", 110 | " \n", 111 | " subtours = [(i,j) for i in N for j in N if i != j and j > 0 and i > 0]\n", 112 | " \n", 113 | " c3 = [\n", 114 | " [[U(i),U(j),X(i,j)], [1,-1,len(N)-1]]\n", 115 | " for i,j in subtours]\n", 116 | " \n", 117 | " c4 = [\n", 118 | " [[X(i,0) for i in N if i > 0], [1 for i in N if i > 0 ]]\n", 119 | " ]\n", 120 | " \n", 121 | " c4 = [\n", 122 | " [[X(0,j) for i in N if j > 0], [1 for j in N if i > 0 ]]\n", 123 | " ]\n", 124 | " \n", 125 | " s1 = \"E\" * len(N)\n", 126 | " s2 = \"E\" * len(N)\n", 127 | " s3 = \"L\" * len(subtours)\n", 128 | " s4 = \"E\"\n", 129 | " s5 = \"E\"\n", 130 | "\n", 131 | " r1 = [1 for i in N]\n", 132 | " r2 = [1 for i in N]\n", 133 | " r3 = [len(N)-2 for i in range(len(subtours))]\n", 134 | " r4 = m\n", 135 | "\n", 136 | " rows = c1+c2+c3\n", 137 | " senses = s1+s2+s3\n", 138 | " rhs = r1+r2+r3\n", 139 | " \n", 140 | " #####################################################################\n", 141 | " # Bounds\n", 142 | " ub = [1 for i in range(len(Xs))] + [cplex.infinity for i in range(len(Us))]\n", 143 | " lb = [0 for i in range((len(Xs)+len(Us)))]\n", 144 | " \n", 145 | " #####################################################################\n", 146 | " # Solving\n", 147 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path)\n", 148 | "\n", 149 | " #####################################################################\n", 150 | " # Extract solution\n", 151 | " N = len(N)\n", 152 | " \n", 153 | " solution = prob.solution.get_values()\n", 154 | " X = np.reshape(solution[0:N*N],(N,N))\n", 155 | "\n", 156 | " return prob, X" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": { 163 | "collapsed": true 164 | }, 165 | "outputs": [], 166 | "source": [] 167 | } 168 | ], 169 | "metadata": { 170 | "hide_input": false, 171 | "kernelspec": { 172 | "display_name": "Py35", 173 | "language": "python", 174 | "name": "py35" 175 | }, 176 | "language_info": { 177 | "codemirror_mode": { 178 | "name": "ipython", 179 | "version": 3 180 | }, 181 | "file_extension": ".py", 182 | "mimetype": "text/x-python", 183 | "name": "python", 184 | "nbconvert_exporter": "python", 185 | "pygments_lexer": "ipython3", 186 | "version": "3.5.3" 187 | }, 188 | "toc": { 189 | "colors": { 190 | "hover_highlight": "#DAA520", 191 | "running_highlight": "#FF0000", 192 | "selected_highlight": "#FFD700" 193 | }, 194 | "moveMenuLeft": true, 195 | "nav_menu": { 196 | "height": "12px", 197 | "width": "252px" 198 | }, 199 | "navigate_menu": true, 200 | "number_sections": true, 201 | "sideBar": true, 202 | "threshold": 4, 203 | "toc_cell": false, 204 | "toc_section_display": "block", 205 | "toc_window_display": false, 206 | "widenNotebook": false 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 2 211 | } 212 | -------------------------------------------------------------------------------- /linear_programming_vehicle_routing/VRP_2_T.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "TSP\n", 10 | "\n", 11 | "Traveling Sales Man\n", 12 | "---" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "# Formulation" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "The Traveling Salesman Problem for a **complete graph** can be stated as:\n", 27 | "\n", 28 | "$min_x$\n", 29 | "$$ \\sum_{i,j \\in N, i < j, b \\in B} c_{ij}x_{ijb} $$\n", 30 | "$s.t$\n", 31 | "$$\\tag{c0} \\sum_{b \\in B}\\sum_{u \\in I \\cup J}x_{uub} = 0$$\n", 32 | "$$\\tag{c1} \\sum_{b \\in B}\\sum_{j \\in I \\cup J}x_{ijb} = N_j , \\forall i \\in I$$\n", 33 | "$$\\tag{c2} \\sum_{i \\in I \\cup J}x_{ijb} - \\sum_{i \\in C \\cup J}x_{jib} = 0 , \\forall j \\in I \\cup J, \\forall b \\in B$$\n", 34 | "$$\\tag{c3} \\sum_{i \\in I \\cup J}\\sum_{j \\in J}x_{ijb} \\le 1 , \\forall b \\in B$$\n", 35 | "$$\\tag{c4}U_i - U_j + (|I|+|J|)\\sum_{b \\in B}x_{ijb} \\le (|I|+|J|-1), \\forall i,j \\in I, i \\neq j$$" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "# Solve with Cplex" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "Overwriting ../pkg/vrp_2_t_cplex.py\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "%%file \"../pkg/vrp_2_t_cplex.py\"\n", 60 | "\n", 61 | "import numpy as np # mathematic tools library\n", 62 | "import networkx as nx # network representation library\n", 63 | "from pkg.cplex_solve import cplex_solve\n", 64 | "import cplex\n", 65 | "\n", 66 | "def vrp_2_t_cplex(I,J,B,\n", 67 | " c,f,\n", 68 | " relaxation=False,path=None):\n", 69 | "\n", 70 | " #####################################################################\n", 71 | " # Decision variables\n", 72 | " \n", 73 | " def X(i,j,b):\n", 74 | " return \"X_\" + str(i) + \"_\" + str(j) + \"_\" + str(b)\n", 75 | " def U(i):\n", 76 | " return \"U_\" + str(i)\n", 77 | " def N(j):\n", 78 | " return \"N_\" + str(j)\n", 79 | " \n", 80 | " IuJ = range(I+J); J = range(I,I+J,1)\n", 81 | " I = range(I); B = range(B); \n", 82 | " #####################################################################\n", 83 | " # Objective function\n", 84 | " Xs = {\n", 85 | " \"name\" : [X(i,j,b) for i in IuJ for j in IuJ for b in B],\n", 86 | " \"coef\" : [c[i][j] for i in IuJ for j in IuJ for b in B],\n", 87 | " \"type\" : [\"I\" for i in IuJ for j in IuJ for b in B],\n", 88 | " \"ub\" : [1 for i in IuJ for j in IuJ for b in B],\n", 89 | " \"lb\" : [0 for i in IuJ for j in IuJ for b in B],\n", 90 | " }\n", 91 | " Ns = {\n", 92 | " \"name\" : [N(j) for j in J],\n", 93 | " \"coef\" : [f[j-len(I)] for j in J],\n", 94 | " \"type\" : [\"I\" for j in J],\n", 95 | " \"ub\" : [1 for j in J],\n", 96 | " \"lb\" : [0 for j in J],\n", 97 | " }\n", 98 | " Us = {\n", 99 | " \"name\" : [U(i) for i in IuJ],\n", 100 | " \"coef\" : [0 for i in IuJ],\n", 101 | " \"type\" : [\"C\" for i in IuJ],\n", 102 | " \"ub\" : [cplex.infinity for i in IuJ],\n", 103 | " \"lb\" : [0 for i in IuJ],\n", 104 | " }\n", 105 | "\n", 106 | " Variables = [Xs,Ns,Us]\n", 107 | " ## Objective function sum aggregation\n", 108 | " obj = [];ub = [];lb = [];colnames = [];types = [];\n", 109 | " for v in Variables:\n", 110 | " obj = obj + v[\"coef\"]\n", 111 | " ub = ub + v[\"ub\"]\n", 112 | " lb = lb + v[\"lb\"]\n", 113 | " colnames = colnames + v[\"name\"]\n", 114 | " types = types + v[\"type\"]\n", 115 | "\n", 116 | " #####################################################################\n", 117 | " # Constraints\n", 118 | " c0 = {\n", 119 | " \"lin_expr\": [[[X(i,i,b) for i in IuJ for b in B],\n", 120 | " [1 for i in IuJ for b in B]] \n", 121 | " ],\n", 122 | " \"senses\" : [\"E\"],\n", 123 | " \"rhs\" : [0]\n", 124 | " }\n", 125 | " c1 = {\n", 126 | " \"lin_expr\": [[[X(i,j,b) for b in B for j in IuJ],\n", 127 | " [1 for b in B for j in IuJ]] \n", 128 | " for i in I],\n", 129 | " \"senses\" : [\"E\" for i in I],\n", 130 | " \"rhs\" : [1 for i in I]\n", 131 | " }\n", 132 | " c2 = {\n", 133 | " \"lin_expr\": [[[X(i,j,b) for i in IuJ if i!=j]+[X(j,i,b) for i in IuJ if i!=j], \n", 134 | " [1 for i in IuJ if i!=j]+[-1 for i in IuJ if i!=j]] \n", 135 | " for j in IuJ for b in B],\n", 136 | " \"senses\" : [\"E\" for j in IuJ for b in B],\n", 137 | " \"rhs\" : [0 for j in IuJ for b in B]\n", 138 | " }\n", 139 | " c3 = {\n", 140 | " \"lin_expr\": [[[X(i,j,b) for i in IuJ for j in J],\n", 141 | " [1 for i in IuJ for j in J]] \n", 142 | " for b in B],\n", 143 | " \"senses\" : [\"L\" for b in B],\n", 144 | " \"rhs\" : [1 for b in B]\n", 145 | " }\n", 146 | " c4 = {\n", 147 | " \"lin_expr\": [[[U(i),U(j)]+[X(i,j,b) for b in B],\n", 148 | " [1,-1]+[len(I)+len(J) for b in B]] \n", 149 | " for i in I for j in I if i!=j],\n", 150 | " \"senses\" : [\"L\" for i in I for j in I if i!=j],\n", 151 | " \"rhs\" : [len(I)+len(J)-1 for i in I for j in I if i!=j]\n", 152 | " }\n", 153 | "\n", 154 | " # Zs VRP constraints\n", 155 | " Constraints = [c0,c1,c2,c3,c4]\n", 156 | " rows = []; senses = []; rhs = [];\n", 157 | " for c in Constraints:\n", 158 | " rows = rows + c[\"lin_expr\"]\n", 159 | " senses = senses + c[\"senses\"]\n", 160 | " rhs = rhs + c[\"rhs\"]\n", 161 | "\n", 162 | " print(len(rows),len(senses),len(rhs))\n", 163 | " \n", 164 | " #####################################################################\n", 165 | " # Solving\n", 166 | " prob = cplex_solve(obj,ub,lb,colnames,types, rows, senses, rhs, minimize=True, path=path)\n", 167 | "\n", 168 | " #####################################################################\n", 169 | " # Extract solution\n", 170 | " IuJ = len(I)+len(J); J = len(J)\n", 171 | " I = len(I); B = len(B); \n", 172 | " \n", 173 | " solution = prob.solution.get_values()\n", 174 | " X = np.reshape(solution[0:IuJ*IuJ*B],(IuJ,IuJ,B))\n", 175 | " N = solution[IuJ*IuJ*B:IuJ*IuJ*B]\n", 176 | "\n", 177 | " return prob, X, N" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "metadata": { 184 | "collapsed": true 185 | }, 186 | "outputs": [], 187 | "source": [] 188 | } 189 | ], 190 | "metadata": { 191 | "hide_input": false, 192 | "kernelspec": { 193 | "display_name": "Py35", 194 | "language": "python", 195 | "name": "py35" 196 | }, 197 | "language_info": { 198 | "codemirror_mode": { 199 | "name": "ipython", 200 | "version": 3 201 | }, 202 | "file_extension": ".py", 203 | "mimetype": "text/x-python", 204 | "name": "python", 205 | "nbconvert_exporter": "python", 206 | "pygments_lexer": "ipython3", 207 | "version": "3.5.3" 208 | }, 209 | "toc": { 210 | "colors": { 211 | "hover_highlight": "#DAA520", 212 | "running_highlight": "#FF0000", 213 | "selected_highlight": "#FFD700" 214 | }, 215 | "moveMenuLeft": true, 216 | "nav_menu": { 217 | "height": "12px", 218 | "width": "252px" 219 | }, 220 | "navigate_menu": true, 221 | "number_sections": true, 222 | "sideBar": true, 223 | "threshold": 4, 224 | "toc_cell": false, 225 | "toc_section_display": "block", 226 | "toc_window_display": false, 227 | "widenNotebook": false 228 | } 229 | }, 230 | "nbformat": 4, 231 | "nbformat_minor": 2 232 | } 233 | --------------------------------------------------------------------------------