{ "cells": [ { "cell_type": "markdown", "id": "3b6fc4e9", "metadata": {}, "source": [ "# Setup" ] }, { "cell_type": "code", "execution_count": null, "id": "0dcca96e", "metadata": {}, "outputs": [], "source": [ "from collections import defaultdict\n", "\n", "import gurobipy as grb\n", "import matplotlib.pyplot as plt\n", "import matplotlib.cm as cm\n", "import networkx as nx" ] }, { "cell_type": "code", "execution_count": null, "id": "dc341ae5", "metadata": {}, "outputs": [], "source": [ "pos = {'s': (0, 1), 'a': (1, 2), 'b': (3, 2), 'c': (2, 1),\n", " 'd': (1, 0), 'e': (3, 0), 't': (4, 1)}\n", "c = {('a', 'b'): 13, ('c', 'b'): 2, ('b', 't'): 8,\n", " ('a', 'c'): 3, ('c', 'e'): 8, ('d', 'c'): 7,\n", " ('d', 'e'): 5, ('e', 't'): 12, ('s', 'a'): 6,\n", " ('s', 'c'): 7, ('s', 'd'): 11}\n", "V = list(pos)\n", "E = list(c)\n", "E_hat = E + [('t', 's')]\n", "Vp_hat = defaultdict(set)\n", "Vm_hat = defaultdict(set)\n", "for (i, j) in E_hat:\n", " Vp_hat[j].add(i)\n", " Vm_hat[i].add(j)\n", "\n", "graph = nx.DiGraph()\n", "graph.add_edges_from(E)" ] }, { "cell_type": "markdown", "id": "49ca1e12", "metadata": {}, "source": [ "# LP Implementations" ] }, { "cell_type": "code", "execution_count": null, "id": "46c122f6", "metadata": { "scrolled": true }, "outputs": [], "source": [ "maxflow = grb.Model()\n", "x = maxflow.addVars(E_hat)\n", "con_z = maxflow.addConstrs(\n", " (sum(x[j, i] for j in Vp_hat[i])\n", " - sum(x[i, j] for j in Vm_hat[i]) == 0)\n", " for i in V\n", ")\n", "con_y = maxflow.addConstrs(x[i, j] <= c[i, j] for (i, j) in E)\n", "maxflow.setObjective(x['t', 's'], grb.GRB.MAXIMIZE)\n", "maxflow.optimize()" ] }, { "cell_type": "code", "execution_count": null, "id": "7e3193b8", "metadata": {}, "outputs": [], "source": [ "mincut = grb.Model()\n", "y = mincut.addVars(E)\n", "z = mincut.addVars(V, lb=-grb.GRB.INFINITY, ub=grb.GRB.INFINITY)\n", "con_x = mincut.addConstrs(\n", " y[i, j] >= z[i] - z[j]\n", " for (i, j) in E\n", ")\n", "z['s'].lb = z['s'].ub = 1\n", "z['t'].lb = z['t'].ub = 0\n", "mincut.setObjective(sum(c[i, j] * y[i, j] for (i, j) in E), grb.GRB.MINIMIZE)\n", "mincut.optimize()" ] }, { "cell_type": "markdown", "id": "fe71558d", "metadata": {}, "source": [ "# Optimal Solution Illustrations" ] }, { "cell_type": "code", "execution_count": null, "id": "97669392", "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(9, 5))\n", "ax.set_xlim([-0.25, 4.25])\n", "ax.set_ylim([-0.25, 2.25])\n", "\n", "node_size = 2000\n", "edgecolors = 'black'\n", "arrowsize = 15\n", "node_color = ['#49AF64' if con_z[i].Pi == con_z['s'].Pi else '#FE3F1C'\n", " for i in V]\n", "style = [(0, (5, 5)) if con_y[i, j].Pi else '-'\n", " for (i, j) in E]\n", "edge_color = [cm.binary(0.1 + 0.9 * x[(i, j)].X / c[i, j])\n", " for (i, j) in E]\n", "edge_labels = {(i, j): '{}/{}'.format(int(x[i, j].X), c[i, j])\n", " for (i, j) in E}\n", "\n", "nx.draw_networkx(graph, ax=ax, pos=pos, nodelist=V, edgelist=[],\n", " node_color=node_color, edgecolors=edgecolors,\n", " node_size=node_size)\n", "nx.draw_networkx_edges(graph, ax=ax, pos=pos, edgelist=E,\n", " edge_color=edge_color, style=style,\n", " node_size=node_size, arrowsize=arrowsize)\n", "nx.draw_networkx_edge_labels(graph, ax=ax, pos=pos,\n", " edge_labels=edge_labels)\n", "ax.axis('off')\n", "plt.savefig('maxflow-optimal.jpg', dpi=400)" ] }, { "cell_type": "code", "execution_count": null, "id": "40825032", "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(9, 9 * 15 / 23))\n", "ax.set_xlim([-0.25, 4.25])\n", "ax.set_ylim([1 - 9 * 15 / 23 / 4, 1 + 9 * 15 / 23 / 4])\n", "\n", "nx.draw_networkx(graph, ax=ax, pos=pos, nodelist=V, edgelist=[],\n", " node_color=node_color, edgecolors=edgecolors,\n", " node_size=node_size)\n", "nx.draw_networkx_edges(graph, ax=ax, pos=pos, edgelist=E,\n", " edge_color=edge_color, style=style,\n", " node_size=node_size, arrowsize=arrowsize)\n", "nx.draw_networkx_edge_labels(graph, ax=ax, pos=pos,\n", " edge_labels=edge_labels)\n", "ax.axis('off')\n", "plt.savefig('maxflow-optimal.webp', format='webp', dpi=2300/9)" ] }, { "cell_type": "code", "execution_count": null, "id": "56e7b284", "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(9, 5))\n", "ax.set_xlim([-0.25, 4.25])\n", "ax.set_ylim([-0.25, 2.25])\n", "\n", "node_size = 2000\n", "edgecolors = 'black'\n", "arrowsize = 15\n", "node_color = ['#49AF64' if z[i].X == z['s'].X else '#FE3F1C'\n", " for i in V]\n", "style = [(0, (5, 5)) if y[i, j].X == 1 else '-'\n", " for (i, j) in E]\n", "edge_color = [cm.binary(0.1 + 0.9 * con_x[(i, j)].Pi / c[i, j])\n", " for (i, j) in E]\n", "edge_labels = {(i, j): '{}/{}'.format(int(con_x[i, j].Pi), c[i, j])\n", " for (i, j) in E}\n", "\n", "nx.draw_networkx(graph, ax=ax, pos=pos, nodelist=V, edgelist=[],\n", " node_color=node_color, edgecolors=edgecolors,\n", " node_size=node_size)\n", "nx.draw_networkx_edges(graph, ax=ax, pos=pos, edgelist=E,\n", " edge_color=edge_color, style=style,\n", " node_size=node_size, arrowsize=arrowsize)\n", "nx.draw_networkx_edge_labels(graph, ax=ax, pos=pos,\n", " edge_labels=edge_labels)\n", "ax.axis('off')\n", "plt.savefig('mincut-optimal.jpg', dpi=400)" ] }, { "cell_type": "code", "execution_count": null, "id": "a9fbf902", "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=(9, 9 * 15 / 23))\n", "ax.set_xlim([-0.25, 4.25])\n", "ax.set_ylim([1 - 9 * 15 / 23 / 4, 1 + 9 * 15 / 23 / 4])\n", "\n", "nx.draw_networkx(graph, ax=ax, pos=pos, nodelist=V, edgelist=[],\n", " node_color=node_color, edgecolors=edgecolors,\n", " node_size=node_size)\n", "nx.draw_networkx_edges(graph, ax=ax, pos=pos, edgelist=E,\n", " edge_color=edge_color, style=style,\n", " node_size=node_size, arrowsize=arrowsize)\n", "nx.draw_networkx_edge_labels(graph, ax=ax, pos=pos,\n", " edge_labels=edge_labels)\n", "ax.axis('off')\n", "plt.savefig('mincut-optimal.webp', format='webp', dpi=2300/9)" ] } ], "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.6" } }, "nbformat": 4, "nbformat_minor": 5 }