{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Vinar\n", "\n", "Vinar Janez je pridelal $2000$ litrov rumenega muškata, $10000$ litrov laškega rizlinga in $5000$ litrov renskega rizlinga. Njegovi kupci so bara Kocka in Luka ter župnišče Sv. Martin in občina Duplek. Vsak od njih je pripravljen kupiti največ določeno količino vina po fiksni ceni, ne glede na sorto:\n", "\n", "\n", "| kupec | Kocka | Luka | župnišče | občina |\n", "| -------------------------- | ------- | ------ | -------- | ------ |\n", "| cena za liter | $1.0$ | $1.1$ | $1.5$ | $1.8$ |\n", "| največja količina v litrih | $15000$ | $5000$ | $500$ | $1000$ |\n", "\n", "\n", "Janez se je odločil, da bo vsako sorto prodal največ enemu kupcu, in sicer v maksimalni količini (če kupec ne kupi vsega vina iste sorte, ga Janez ohrani zase). Župan pravi, da občina drugega vina kot renskega rizlinga ne bo kupila. Bar Luka želi rumeni muškat, če bar Kocka dobi laški rizling. Pri Kocki so se dogovorili, da če občina in župnišče ne kupijo nič,\n", "tudi oni ne bodo kupili ničesar. Janezova žena pa vztraja, da če kupec $A$ kupi sorto $s_A$ in kupec $B$ kupi sorto $s_B$, potem naj sorta $s_C$ ostane doma ali jo kupi kupec $C$ (za neke $A, B, C$). Kako naj Janez proda vino, da bo čim več zaslužil?\n", "\n", "Zapiši problem kot celoštevilski linearni program." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Parametri\n", "\n", "Sorte in stranke bomo označili s kraticami, ki jih zbremo v sledečih seznamih." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "sorte = [\"RM\", \"LR\", \"RR\"] # rumeni muškat, laški rizling, renski rizling\n", "stranke = [\"K\", \"L\", \"Z\", \"O\"] # bar Kocka, bar Luka, župnišče sv. Martin, občina Duplek" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "V zadnjem pogoju vrednosti $A, B, C$ niso znane vnaprej. Določimo jim neko vrednost, da bomo lahko rešili celoštevilski linearni program. Seveda lahko vrednosti zamenjamo, pa bo optimalna rešitev potem morda drugačna." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "A, B, C = \"O\", \"L\", \"Z\"\n", "sA, sB, sC = \"RR\", \"LR\", \"RM\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Celoštevilski linearni program\n", "\n", "Zapisali bomo sledeči celoštevilski linearni program:\n", "\n", "\\begin{align*}\n", "\\max &\\ 2000 x_{RM, K} + 2200 x_{RM, L} + 750 x_{RM, Z} + 1800 x_{RM, O} \\\\\n", "{}+ &\\ 10000 x_{LR, K} + 5500 x_{LR, L} + 750 x_{LR, Z} + 1800 x_{LR, O} \\\\\n", "{}+ &\\ 5000 x_{RR, K} + 5500 x_{RR, L} + 750 x_{RR, Z} + 1800 x_{RR, O} \\\\\n", "\\text{p. p.} \\quad\n", "\\forall i \\ \\forall j. \\ 0 \\le x_{ij} &\\le 1, \\ x_{ij} \\in \\mathbb{Z} \\\\\n", "\\forall i. \\sum_j x_{ij} &\\le 1 \\\\\n", "\\forall j. \\sum_i x_{ij} &\\le 1 \\\\\n", "x_{RM, O} + x_{LR, O} &= 0 \\\\\n", "x_{LR, K} - x_{RM, L} &\\le 0 \\\\\n", "\\sum_i (x_{i, O} + x_{i, Z} - x_{i, K}) &\\ge 0 \\\\\n", "x_{s_A, A} + x_{s_B, B} + \\sum_{j \\ne C} x_{s_C, j} &\\le 2 \\\\\n", "\\end{align*}\n", "\n", "Tukaj smo predpostavili, da indeks $i$ teče po sortah, indeks $j$ pa po strankah." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "p = MixedIntegerLinearProgram(maximization=True)\n", "x = p.new_variable(binary=True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "p.set_objective(x[\"RM\", \"K\"] * 2000 + x[\"RM\", \"L\"] * 2200 + x[\"RM\", \"Z\"] * 750 + x[\"RM\", \"O\"] * 1800 +\n", " x[\"LR\", \"K\"] * 10000 + x[\"LR\", \"L\"] * 5500 + x[\"LR\", \"Z\"] * 750 + x[\"LR\", \"O\"] * 1800 +\n", " x[\"RR\", \"K\"] * 5000 + x[\"RR\", \"L\"] * 5500 + x[\"RR\", \"Z\"] * 750 + x[\"RR\", \"O\"] * 1800)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "for i in sorte:\n", " p.add_constraint(sum(x[i, j] for j in stranke) <= 1)\n", "for j in stranke:\n", " p.add_constraint(sum(x[i, j] for i in sorte) <= 1)\n", "p.add_constraint(x[\"RM\", \"O\"] + x[\"LR\", \"O\"] == 0)\n", "p.add_constraint(x[\"LR\", \"K\"] <= x[\"RM\", \"L\"])\n", "p.add_constraint(sum(x[i, \"O\"] + x[i, \"Z\"] - x[i, \"K\"] for i in sorte) >= 0)\n", "p.add_constraint(x[sA, A] + x[sB, B] + sum(x[sC, j] for j in stranke if j != C) <= 2)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "14000.0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.solve()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{('RM', 'K'): 0,\n", " ('RM', 'L'): 1,\n", " ('RM', 'Z'): 0,\n", " ('RM', 'O'): 0,\n", " ('LR', 'K'): 1,\n", " ('LR', 'L'): 0,\n", " ('LR', 'Z'): 0,\n", " ('LR', 'O'): 0,\n", " ('RR', 'K'): 0,\n", " ('RR', 'L'): 0,\n", " ('RR', 'Z'): 0,\n", " ('RR', 'O'): 1}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res = p.get_values(x)\n", "res" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'RM': 'L', 'LR': 'K', 'RR': 'O'}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{i: j for (i, j), v in res.items() if v == 1}" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.2.rc2", "language": "sage", "name": "sagemath" }, "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.8.5" } }, "nbformat": 4, "nbformat_minor": 1 }