{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "```{index} single: solver; cbc\n", "```\n", "```{index} single: solver; highs\n", "```\n", "\n", "# BIM production for worst case" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "5ssUqKOaPVaE", "outputId": "38c1005a-39f4-4307-e305-19a4c9819396" }, "outputs": [], "source": [ "# install dependencies and select solver\n", "%pip install -q amplpy\n", "\n", "SOLVER = \"highs\"\n", "\n", "from amplpy import AMPL, ampl_notebook\n", "\n", "ampl = ampl_notebook(\n", " modules=[\"highs\"], # modules to install\n", " license_uuid=\"default\", # license to use\n", ") # instantiate AMPL object and register magics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Minmax objective function\n", "\n", "Another class of seemingly complicated objective functions that can be easily rewritten as an LP are those stated as maxima over several linear functions. Given a finite set of indices $K$ and a collection of vectors $\\{c_k\\}_{k \\in K}$, the minimax problem given by\n", "\n", "$$\n", "\\begin{align}\n", " \\min \\; \\max_{k \\in K} \\; c^\\top_{k} x\n", "\\end{align}\n", "$$\n", "\n", "General expressions like the latter can be linearized by introducing an auxiliary variable $z$ and setting\n", "\n", "$$\n", "\\begin{align*}\n", " \\min \\quad & z \\\\\n", " \\text{s.t.} \\quad & c^\\top_{k} x \\leq z \\qquad \\forall\\, k \\in K.\n", "\\end{align*}\n", "$$\n", "\n", "This trick works because if *all* the quantities corresponding to different indices $ k \\in K$ are below the auxiliary variable $z$, then we are guaranteed that also their maximum is also below $z$ and vice versa. Note that the absolute value function can be rewritten $|x_i|= \\max\\{x_i,-x_i\\}$, hence the linearization of the optimization problem involving absolute values in the objective functions is a special case of this. \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## BIM problem variant: Maximizing the lowest possible profit\n", "\n", "In the same way we can minimize a maximum like above, we can also maximize the minimum. Let us consider the [BIM microchip production problem](bim.ipynb), but suppose that there is uncertainty regarding the selling prices of the microchips. Instead of just the nominal prices 12 € and 9 €, BIM estimates that the prices may more generally take the values $P=\\{ (12,9), (11,10), (8, 11) \\}$. The optimization problem for a production plan that achieves the maximum among the lowest possible profits can be formulated using the trick mentioned above and can be implemented in AMPL as follows." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing bim_maxmin.mod\n" ] } ], "source": [ "%%writefile bim_maxmin.mod\n", "\n", "var x1 >= 0;\n", "var x2 >= 0;\n", "var z;\n", "\n", "set costs dimen 2;\n", "\n", "maximize profit: z;\n", " \n", "s.t. maxmin {(c1,c2) in costs}:\n", " z <= c1 * x1 + c2 * x2;\n", "\n", "s.t. silicon: x1 <= 1000;\n", "s.t. germanium: x2 <= 1500;\n", "s.t. plastic: x1 + x2 <= 1750;\n", "s.t. copper: 4 * x1 + 2 * x2 <= 4800;" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "m33AGCU_PSJw" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HiGHS 1.5.1: HiGHS 1.5.1: optimal solution; objective 17500\n", "4 simplex iterations\n", "0 barrier iterations\n", "x=(583.3,1166.7) revenue=17500.000\n" ] } ], "source": [ "def BIM_maxmin(costs):\n", " ampl = AMPL()\n", " ampl.read(\"bim_maxmin.mod\")\n", "\n", " ampl.set[\"costs\"] = costs\n", "\n", " return ampl\n", "\n", "\n", "m = BIM_maxmin([[12, 9], [11, 10], [8, 11]])\n", "m.solve(solver=SOLVER)\n", "assert m.solve_result == \"solved\", m.solve_result\n", "print(\n", " \"x=({:.1f},{:.1f}) revenue={:.3f}\".format(\n", " m.var[\"x1\"].value(), m.var[\"x2\"].value(), m.obj[\"profit\"].value()\n", " )\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }