{ "metadata": { "name": "", "signature": "sha256:cc446624bc247de8aec94bb4f51712ac172b328e4627c20ae5db5cf4d8796185" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Examples from _Geometric Programming_\n", "\n", "Duffin, Peterseon, Zener. (1967)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import gpkit\n", "import gpkit.interactive" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Transporting Gravel\n", "\n", "Suppose that 400 cubic yards of gravel must be ferried across a river. Suppose that the gravel is to be shipped in an open box of length $t_1$, width $t_2$, and height $t_3$. The sides and bottom of the box cost \\$10 per square yard and the ends of the box cost \\$20 per squared yard. The box will have no salvage value and each round trip of the box on the ferry will cost 10 cents. What is the minimum cost of transporting the 400 cubic yards of gravel?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# transporting gravel across a river:\n", "# how large of a box should be used / how many trips should be taken?\n", "\n", "V1 = gpkit.Variable(\"V_1\", 400, \"cubic yards\", \"volume of gravel to transport\")\n", "\n", "l = gpkit.Variable(\"l\", \"yards\", \"box length\")\n", "w = gpkit.Variable(\"w\", \"yards\", \"box width\")\n", "h = gpkit.Variable(\"h\", \"yards\", \"box height\")\n", "\n", "c_sides = gpkit.Variable(\"c_{sides}\", 10, \"1/yard^2\", \"cost of box sides and bottom\")\n", "c_ends = gpkit.Variable(\"c_{ends}\", 20, \"1/yard^2\", \"cost of box ends\")\n", "c_ferry = gpkit.Variable(\"c_{ferry}\", 0.10, \"-\", \"cost of ferry trip\")\n", "\n", "A_end = w*h\n", "A_side = l*h\n", "A_bottom = w*l\n", "\n", "total_cost = c_ferry*V1/(l*w*h) + c_ends*2*A_end + c_sides*(2*A_side + A_bottom)\n", "\n", "gp = gpkit.GP(total_cost)\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 3 variables.\n", "Solving took 0.0517 seconds." ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", " |\n", " Cost : 100 \n", " | \n", " | Variables\n", " V_1 : 400 [yd**3] volume of gravel to transport\n", " c_{ends} : 20 [1/yd**2] cost of box ends\n", " c_{ferry} : 0.1 cost of ferry trip\n", " c_{sides} : 10 [1/yd**2] cost of box sides and bottom\n", " h : 0.5 [yd] box height\n", " l : 2 [yd] box length\n", " w : 1 [yd] box width\n", " |\n", " | Constant sensitivities\n", " V_1 : 0.4 volume of gravel to transport\n", " c_{ends} : 0.2 cost of box ends\n", " c_{ferry} : 0.4 cost of ferry trip\n", " c_{sides} : 0.4 cost of box sides and bottom\n", " |\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "As above, except to facilitate handling of the box it is required that its height be 1 yard." ] }, { "cell_type": "code", "collapsed": false, "input": [ "gp.sub(h, 1)\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 2 variables.\n", "Solving took 0.0091 seconds.\n", " |\n", " Cost : 107 \n", " | \n", " | Variables\n", " V_1 : 400 [yd**3] volume of gravel to transport\n", " c_{ends} : 20 [1/yd**2] cost of box ends\n", " c_{ferry} : 0.1 cost of ferry trip\n", " c_{sides} : 10 [1/yd**2] cost of box sides and bottom\n", " h : 1 [yd] box height\n", " l : 1.43 [yd] box length\n", " w : 0.717 [yd] box width\n", " |\n", " | Constant sensitivities\n", " V_1 : 0.365 volume of gravel to transport\n", " c_{ends} : 0.269 cost of box ends\n", " c_{ferry} : 0.365 cost of ferry trip\n", " c_{sides} : 0.365 cost of box sides and bottom\n", " h : 0.173 box height\n", " |\n" ] } ], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now instead of setting the height, it is required that the sides and bottom of the box are made from scrap material. Only four square yards of this scrap material are available." ] }, { "cell_type": "code", "collapsed": false, "input": [ "A_scrap = gpkit.Variable(\"A_{scrap}\", 4, \"yards^2\", \"scrap material available\")\n", "\n", "gp = gpkit.GP(c_ferry*V1/(l*w*h) + c_ends*2*A_end,\n", " [2*A_side + A_bottom <= A_scrap])\n", "gp" ], "language": "python", "metadata": {}, "outputs": [ { "latex": [ "$$\\begin{array}[ll]\n", "\\text{}\n", "\\text{minimize}\n", " & 2w h c_{ends} + \\frac{c_{ferry} V_1}{w l h}\\mathrm{\\left[ - \\right]} \\\\\n", "\\text{subject to}\n", " & A_{scrap} \\geq 2l h + w l \\\\\n", "\\text{substituting}\n", " & A_{scrap} = 4 \\\\\n", " & V_1 = 400 \\\\\n", " & c_{ends} = 20 \\\\\n", " & c_{ferry} = 0.1 \\\\\n", "\\end{array}$$" ], "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ " gpkit.GP( # minimize \n", " 2*w*h*c_{ends} + w**-1*l**-1*h**-1*c_{ferry}*V_1, units='-', \n", " [ # subject to \n", " A_{scrap} >= 2*l*h + w*l, \n", " ], \n", " substitutions={ A_{scrap}: 4, c_{ends}: 20, c_{ferry}: 0.1, V_1: 400\n", " solver=\"cvxopt\") \n", "\n", " \n", " \n", " \n", " \n", " \n", " },\n", " " ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "print gp.solve().table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 3 variables.\n", "Solving took 0.00784 seconds.\n", " |\n", " Cost : 60 \n", " | \n", " | Variables\n", " A_{scrap} : 4 [yd**2] scrap material available\n", " V_1 : 400 [yd**3] volume of gravel to transport\n", " c_{ends} : 20 [1/yd**2] cost of box ends\n", " c_{ferry} : 0.1 cost of ferry trip\n", " h : 0.5 [yd] box height\n", " l : 2 [yd] box length\n", " w : 1 [yd] box width\n", " |\n", " | Constant sensitivities\n", " A_{scrap} : -0.667 scrap material available\n", " V_1 : 0.667 volume of gravel to transport\n", " c_{ends} : 0.333 cost of box ends\n", " c_{ferry} : 0.667 cost of ferry trip\n", " |\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Designing a three-sided fence\n", "\n", "One side of an open field is bounded by a straight river. How would you put a fence around the other three sides of a rectangular plot to enclose an area as great as possible with a length of fence not greater than $L$?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "L = gpkit.Variable(\"L\", 1, \"yards\", \"total fence length\")\n", "\n", "l = gpkit.Variable(\"l\", \"yards\", \"plot side parallel to river\")\n", "w = gpkit.Variable(\"w\", \"yards\", \"plot side perpendicular to river\")\n", "\n", "A_plot = l*w\n", "\n", "gp = gpkit.GP(1/A_plot, [2*w + l <= L])\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 2 variables.\n", "Solving took 0.0083 seconds.\n", " |\n", " Cost : 8 \n", " | \n", " | Variables\n", " L : 1 [yd] total fence length\n", " l : 0.5 [yd] plot side parallel to river\n", " w : 0.25 [yd] plot side perpendicular to river\n", " |\n", " | Constant sensitivities\n", " L : -2 total fence length\n", " |\n" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cutting a rectangular beam from a log\n", "\n", "The stiffness of a rectangular beam is proportional to the product of its width with the cube of its depth. Find the dimensions of the stiffest beam that can be cut from a circular cylindrical log of radius $R$." ] }, { "cell_type": "code", "collapsed": false, "input": [ "R = gpkit.Variable(\"R\", 1, \"inches\", \"log radius\")\n", "\n", "d = gpkit.Variable(\"d\", \"inches\", \"beam depth\")\n", "w = gpkit.Variable(\"w\", \"inches\", \"beam width\")\n", "\n", "gp = gpkit.GP(1/(w*d**3), [(d/2)**2 + (w/2)**2 <= R**2])\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 2 variables.\n", "Solving took 0.00883 seconds.\n", " |\n", " Cost : 0.192 \n", " | \n", " | Variables\n", " R : 1 [in] log radius\n", " d : 1.73 [in] beam depth\n", " w : 1 [in] beam width\n", " |\n", " | Constant sensitivities\n", " R : -4 log radius\n", " |\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sheet-metal box\n", "\n", "A square sheet of tin $L$ inches on a side is to be used to make an open-top box by cutting a small square of tin from each corner and bending up the sides. How large a square should be cut from each corner in order that the box shall have a volume as large as possible?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "L = gpkit.Variable(\"L\", 1, \"inches\", \"tin sheet side length\")\n", "\n", "l = gpkit.Variable(\"l\", \"inches\", \"box length\")\n", "w = gpkit.Variable(\"w\", \"inches\", \"box width\")\n", "h = gpkit.Variable(\"h\", \"inches\", \"box height\")\n", "\n", "cx = gpkit.Variable(\"c_x\", \"inches\", \"corner cutout length in x dimension\")\n", "cy = gpkit.Variable(\"c_y\", \"inches\", \"corner cutout length in y dimension\")\n", "\n", "gp = gpkit.GP(1/(l*w*h),\n", " [L >= w + 2*cx,\n", " L >= l + 2*cy,\n", " cx >= h,\n", " cy >= h])\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 5 variables.\n", "Solving took 0.0111 seconds.\n", " |\n", " Cost : 13.5 \n", " | \n", " | Variables\n", " L : 1 [in] tin sheet side length\n", " c_x : 0.167 [in] corner cutout length in x dimension\n", " c_y : 0.167 [in] corner cutout length in y dimension\n", " h : 0.167 [in] box height\n", " l : 0.667 [in] box length\n", " w : 0.667 [in] box width\n", " |\n", " | Constant sensitivities\n", " L : -3 tin sheet side length\n", " |\n" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ivan Petrovich's productivity\n", "\n", "Ivan Petrovich is a brilliant student of psychology and mathematics. Unfortunately, after his second year of graduate study he had to take a year off to recoup his finances. He worked as a consultant to Z corporation, his recompense being strictly proportional to his productivity. After a thorough study of his productivity, Ivan concluded that his recompense would be\n", "\n", "$ \\$ 0.5 \\tau_W^{1.5} \\tau_S^{0.75} \\tau_M^{0.1} $ per day, \n", "\n", "where $\\tau_W$, $\\tau_S$, and $\\tau_M$ are the hours spent each day in work, in sleep, and in listening to new classical records. Ivan was under strict doctor's orders to take at least three hours a day for his meals, during which he could, however, also listen to music. His only variable expense was the purchase of new records, which cost $ \\$ 5 \\tau_M $. Ivan therefore allotted his time to maximize\n", "\n", "$ \\$ 0.5 \\tau_W^{1.5} \\tau_S^{0.75} \\tau_M^{0.1} - \\$ 5 \\tau_M $\n", "\n", "subject, of course, to the condition\n", "\n", "$ \\tau_W + \\tau_S + 3 \\leq 24$.\n", "\n", "How did Ivan allot his time?" ] }, { "cell_type": "code", "collapsed": false, "input": [ "tw = gpkit.Variable(\"\\\\tau_W\", \"-\", \"hours spent working\")\n", "ts = gpkit.Variable(\"\\\\tau_S\", \"-\", \"hours spent sleeping\")\n", "to = gpkit.Variable(\"\\\\tau_O\", \"-\", \"hours spent eating and/or listening\")\n", "tm = gpkit.Variable(\"\\\\tau_M\", \"-\", \"hours spent listening to music\")\n", "s = gpkit.Variable(\"s\", \"-\", \"savings accrued per day\")\n", "\n", "p = gpkit.Variable(\"p\", 0.5, \"-\", \"pay rate per unit productivity\")\n", "c = gpkit.Variable(\"c\", 5, \"-\", \"cost of new records, per hour\")\n", "te = gpkit.Variable(\"\\\\tau_E\", 3 ,\"-\", \"hours required to be spent eating\")\n", "\n", "gp = gpkit.GP( 1/s,\n", " [p*tw**1.5*ts**0.75*tm**0.1 >= s + c*tm,\n", " tw + ts + to <= 24,\n", " to >= tm,\n", " to >= te])\n", "sol = gp.solve()\n", "print sol.table()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Using solver 'cvxopt'\n", "Solving for 5 variables.\n", "Solving took 0.0106 seconds.\n", " |\n", " Cost : 0.00901 \n", " | \n", " | Variables\n", " \\tau_E : 3 hours required to be spent eating\n", " \\tau_M : 2.47 hours spent listening to music\n", " \\tau_O : 3 hours spent eating and/or listening\n", " \\tau_S : 7 hours spent sleeping\n", " \\tau_W : 14 hours spent working\n", " c : 5 cost of new records, per hour\n", " p : 0.5 pay rate per unit productivity\n", " s : 111 savings accrued per day\n", " |\n", " | Constant sensitivities\n", " \\tau_E : 0.357 hours required to be spent eating\n", " c : 0.111 cost of new records, per hour\n", " p : -1.11 pay rate per unit productivity\n", " |\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import CSS for nbviewer\n", "\n", "If you have a local iPython stylesheet installed, this will add it to the iPython Notebook:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython import utils\n", "from IPython.core.display import HTML\n", "import os\n", "def css_styling():\n", " \"\"\"Load default custom.css file from ipython profile\"\"\"\n", " base = utils.path.get_ipython_dir()\n", " styles = \"\" % (open(os.path.join(base,'profile_default/static/custom/custom.css'),'r').read())\n", " return HTML(styles)\n", "css_styling()" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "" ] } ], "prompt_number": 11 } ], "metadata": {} } ] }