{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "1a48b160",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "579f25aa",
            "cell_type": "markdown",
            "source": "Consider the following problem:\n\n$$ \\min_{x_0, x_1} \\ -x_0 + 4x_1 & \\\\ \\mbox{such that} \\ -3x_0 + x_1 & \\leq 6,\\\\ -x_0 - 2x_1 & \\geq -4,\\\\ x_1 & \\geq -3. $$\nThe problem is not presented in the form accepted by `linprog`. This is\neasily remedied by converting the \"greater than\" inequality\nconstraint to a \"less than\" inequality constraint by\nmultiplying both sides by a factor of $-1$. Note also that the last\nconstraint is really the simple bound $-3 \\leq x_1 \\leq \\infty$.\nFinally, since there are no bounds on $x_0$, we must explicitly\nspecify the bounds $-\\infty \\leq x_0 \\leq \\infty$, as the\ndefault is for variables to be non-negative. After collecting coeffecients\ninto arrays and tuples, the input for this problem is:\n",
            "metadata": {}
        },
        {
            "id": "3d3dfaae",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "from scipy.optimize import linprog\nc = [-1, 4]\nA = [[-3, 1], [1, 2]]\nb = [6, 4]\nx0_bounds = (None, None)\nx1_bounds = (-3, None)\nres = linprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds])\nres.fun",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "-22.0"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "4777dd74",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "res.x",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([10., -3.])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "05c83754",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "res.message",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "'Optimization terminated successfully. (HiGHS Status 7: Optimal)'"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "9304ca41",
            "cell_type": "markdown",
            "source": "The marginals (AKA dual values / shadow prices / Lagrange multipliers)\nand residuals (slacks) are also available.\n",
            "metadata": {}
        },
        {
            "id": "55a81a5b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "res.ineqlin",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "  residual: [ 3.900e+01  0.000e+00]\n marginals: [-0.000e+00 -1.000e+00]"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "48002247",
            "cell_type": "markdown",
            "source": "For example, because the marginal associated with the second inequality\nconstraint is -1, we expect the optimal value of the objective function\nto decrease by ``eps`` if we add a small amount ``eps`` to the right hand\nside of the second inequality constraint:\n",
            "metadata": {}
        },
        {
            "id": "a40ea754",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "eps = 0.05\nb[1] += eps\nlinprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "-22.05"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "dcb2008b",
            "cell_type": "markdown",
            "source": "Also, because the residual on the first inequality constraint is 39, we\ncan decrease the right hand side of the first constraint by 39 without\naffecting the optimal solution.\n",
            "metadata": {}
        },
        {
            "id": "f571822b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "b = [6, 4]  # reset to original values\nb[0] -= 39\nlinprog(c, A_ub=A, b_ub=b, bounds=[x0_bounds, x1_bounds]).fun",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "-22.0"
                    },
                    "execution_count": null
                }
            ]
        }
    ]
}