├── 1_Introduction_to_Linear_Programming.ipynb
├── 2_Integer_vs_Linear_Programming.ipynb
├── 3_Constraint_Programming.ipynb
├── 4_Maximize_Your_Marketing_ROI_with_Nonlinear_Optimization.ipynb
├── README.md
└── images
└── colab.svg
/1_Introduction_to_Linear_Programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "1. Introduction to Linear Programming.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "authorship_tag": "ABX9TyMlv+2eBVwWBjLrSDwHaHr5",
10 | "include_colab_link": true
11 | },
12 | "kernelspec": {
13 | "name": "python3",
14 | "display_name": "Python 3"
15 | },
16 | "language_info": {
17 | "name": "python"
18 | }
19 | },
20 | "cells": [
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {
24 | "id": "view-in-github",
25 | "colab_type": "text"
26 | },
27 | "source": [
28 | "
"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "source": [
34 | "# Introduction to Linear Programming\n",
35 | "\n",
36 | "> Chapter 1 of the [Linear Programming Course](https://github.com/mlabonne/Linear-Programming-Course)\n",
37 | "\n",
38 | "❤️ Created by [@maximelabonne](https://twitter.com/maximelabonne).\n",
39 | "\n",
40 | "Companion notebook to execute the code from the following article: https://mlabonne.github.io/blog/linearoptimization/\n",
41 | "\n",
42 | "
\n",
43 | "\n",
44 | "| Unit | 🌾Food | 🪵Wood | 🪙Gold | 💪Power |\n",
45 | "| :--- | :---: | :---: | :---: | :---: |\n",
46 | "| 🗡️Swordsman | 60 | 20 | 0 | 70 |\n",
47 | "| 🏹Bowman | 80 | 10 | 40 | 95 |\n",
48 | "| 🐎Horseman | 140 | 0 |100 | 230 |\n",
49 | "\n",
50 | "
\n",
51 | "\n",
52 | "**Goal**: optimizing the power of an army composed of swordsmen, bowmen, and horsemen with 1200 🌾food, 800 🪵wood, and 600 🪙gold."
53 | ],
54 | "metadata": {
55 | "id": "2ywEZ_RkknQC"
56 | }
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": null,
61 | "metadata": {
62 | "id": "ZK0c0hhQklGb"
63 | },
64 | "outputs": [],
65 | "source": [
66 | "!python -m pip install --upgrade --user -q ortools"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "source": [
72 | "# Setup\n",
73 | "\n",
74 | "If the following cell fails, click on `Runtime > Restart and run all`."
75 | ],
76 | "metadata": {
77 | "id": "94uu3qEbFn_X"
78 | }
79 | },
80 | {
81 | "cell_type": "code",
82 | "source": [
83 | "# Import OR-Tools' wrapper for linear solvers\n",
84 | "from ortools.linear_solver import pywraplp\n",
85 | "\n",
86 | "# Create a linear solver using the GLOP backend\n",
87 | "solver = pywraplp.Solver('Maximize army power', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)"
88 | ],
89 | "metadata": {
90 | "id": "l4RYui9hxcJG"
91 | },
92 | "execution_count": null,
93 | "outputs": []
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "source": [
98 | "# 1. Declare variables to optimize\n",
99 | "\n",
100 | "We have three variables: the numbers of swordsmen, bowmen, and horsemen."
101 | ],
102 | "metadata": {
103 | "id": "PuX75dGGFpXP"
104 | }
105 | },
106 | {
107 | "cell_type": "code",
108 | "source": [
109 | "# Create the variables we want to optimize\n",
110 | "swordsmen = solver.IntVar(0, solver.infinity(), 'swordsmen')\n",
111 | "bowmen = solver.IntVar(0, solver.infinity(), 'bowmen')\n",
112 | "horsemen = solver.IntVar(0, solver.infinity(), 'horsemen')"
113 | ],
114 | "metadata": {
115 | "id": "7Oqc6nBg0ea2"
116 | },
117 | "execution_count": null,
118 | "outputs": []
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "source": [
123 | "# 2. Declare constraints\n",
124 | "\n",
125 | "We have three constraints: the food, wood, and gold spent cannot exceed our current resources (1200 food, 800 wood, and 600 gold)."
126 | ],
127 | "metadata": {
128 | "id": "6J2Xrn-VFrOT"
129 | }
130 | },
131 | {
132 | "cell_type": "code",
133 | "source": [
134 | "# Add constraints for each resource\n",
135 | "solver.Add(swordsmen*60 + bowmen*80 + horsemen*140 <= 1200) # Food\n",
136 | "solver.Add(swordsmen*20 + bowmen*10 <= 800) # Wood\n",
137 | "solver.Add(bowmen*40 + horsemen*100 <= 600) # Gold"
138 | ],
139 | "metadata": {
140 | "id": "jtD0ZPevY5CO",
141 | "colab": {
142 | "base_uri": "https://localhost:8080/"
143 | },
144 | "outputId": "8d714ae5-1feb-45f1-d0b3-1dd1162648d0"
145 | },
146 | "execution_count": null,
147 | "outputs": [
148 | {
149 | "output_type": "execute_result",
150 | "data": {
151 | "text/plain": [
152 | " >"
153 | ]
154 | },
155 | "metadata": {},
156 | "execution_count": 4
157 | }
158 | ]
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "source": [
163 | "# 3. Declare objective\n",
164 | "\n",
165 | "The goal is to maximize the power of the army, which the sum of the power of each unit."
166 | ],
167 | "metadata": {
168 | "id": "MpRvec7AFtYo"
169 | }
170 | },
171 | {
172 | "cell_type": "code",
173 | "source": [
174 | "# Maximize the objective function\n",
175 | "solver.Maximize(swordsmen*70 + bowmen*95 + horsemen*230)"
176 | ],
177 | "metadata": {
178 | "id": "HLkXypIKY8Bm"
179 | },
180 | "execution_count": null,
181 | "outputs": []
182 | },
183 | {
184 | "cell_type": "markdown",
185 | "source": [
186 | "# Optimize!"
187 | ],
188 | "metadata": {
189 | "id": "Y3B1e_f2Fz8D"
190 | }
191 | },
192 | {
193 | "cell_type": "code",
194 | "source": [
195 | "# Solve problem\n",
196 | "status = solver.Solve()\n",
197 | "\n",
198 | "# If an optimal solution has been found, print results\n",
199 | "if status == pywraplp.Solver.OPTIMAL:\n",
200 | " print('================= Solution =================')\n",
201 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
202 | " print()\n",
203 | " print(f'Optimal power = {solver.Objective().Value()} 💪power')\n",
204 | " print('Army:')\n",
205 | " print(f' - 🗡️Swordsmen = {swordsmen.solution_value()}')\n",
206 | " print(f' - 🏹Bowmen = {bowmen.solution_value()}')\n",
207 | " print(f' - 🐎Horsemen = {horsemen.solution_value()}')\n",
208 | "else:\n",
209 | " print('The solver could not find an optimal solution.')"
210 | ],
211 | "metadata": {
212 | "id": "ddA-aNJMY-V6",
213 | "colab": {
214 | "base_uri": "https://localhost:8080/"
215 | },
216 | "outputId": "252fe084-42f0-41b3-c164-f3d3b8ebf909"
217 | },
218 | "execution_count": null,
219 | "outputs": [
220 | {
221 | "output_type": "stream",
222 | "name": "stdout",
223 | "text": [
224 | "================= Solution =================\n",
225 | "Solved in 49.00 milliseconds in 2 iterations\n",
226 | "\n",
227 | "Optimal power = 1800.0 💪power\n",
228 | "Army:\n",
229 | " - 🗡️Swordsmen = 6.0000000000000036\n",
230 | " - 🏹Bowmen = 0.0\n",
231 | " - 🐎Horsemen = 5.999999999999999\n"
232 | ]
233 | }
234 | ]
235 | }
236 | ]
237 | }
--------------------------------------------------------------------------------
/2_Integer_vs_Linear_Programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "view-in-github",
7 | "colab_type": "text"
8 | },
9 | "source": [
10 | "
"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {
16 | "id": "5kf_NODHE9yc"
17 | },
18 | "source": [
19 | "# Integer vs. Linear Programming\n",
20 | "\n",
21 | "> Chapter 2 of the [Linear Programming Course](https://github.com/mlabonne/Linear-Programming-Course)\n",
22 | "\n",
23 | "❤️ Created by [@maximelabonne](https://twitter.com/maximelabonne).\n",
24 | "\n",
25 | "Companion notebook to execute the code from the following article: https://towardsdatascience.com/integer-programming-vs-linear-programming-in-python-f1be5bb4e60e"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 1,
31 | "metadata": {
32 | "id": "ZK0c0hhQklGb"
33 | },
34 | "outputs": [],
35 | "source": [
36 | "!python -m pip install --upgrade --user -q ortools"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "source": [
42 | "# MIP solution with CBC\n",
43 | "\n",
44 | "The goal is to maximize the army with the following resources: 1200 food, 800 wood, 600 gold.\n",
45 | "\n",
46 | "
\n",
47 | "\n",
48 | "| Unit | 🌾Food | 🪵Wood | 🪙Gold | 💪Power |\n",
49 | "| :--- | :---: | :---: | :---: | :---: |\n",
50 | "| 🗡️Swordsman | 60 | 20 | 0 | 70 |\n",
51 | "| 🏹Bowman | 80 | 10 | 40 | 95 |\n",
52 | "| 🐎Horseman | 140 | 0 |100 | 230 |\n",
53 | "\n",
54 | "
\n",
55 | "\n",
56 | "If the following cell fails, click on `Runtime > Restart and run all`."
57 | ],
58 | "metadata": {
59 | "id": "xVJzzODwFX7c"
60 | }
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": 2,
65 | "metadata": {
66 | "colab": {
67 | "base_uri": "https://localhost:8080/"
68 | },
69 | "id": "Dvxq9hyCk8uW",
70 | "outputId": "08ae1162-c5dd-43b3-ec22-e13ed3a3417e"
71 | },
72 | "outputs": [
73 | {
74 | "output_type": "stream",
75 | "name": "stdout",
76 | "text": [
77 | "================= Solution =================\n",
78 | "Solved in 4.00 milliseconds in 0 iterations\n",
79 | "\n",
80 | "Optimal value = 1800.0 💪power\n",
81 | "Army:\n",
82 | " - 🗡️Swordsmen = 6.0\n",
83 | " - 🏹Bowmen = 0.0\n",
84 | " - 🐎Horsemen = 6.0\n"
85 | ]
86 | }
87 | ],
88 | "source": [
89 | "# Import OR-Tools wrapper for linear programming\n",
90 | "from ortools.linear_solver import pywraplp\n",
91 | "\n",
92 | "# Create the linear solver using the CBC backend\n",
93 | "solver = pywraplp.Solver('Maximize army power', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
94 | "\n",
95 | "# 1. Create the variables we want to optimize\n",
96 | "swordsmen = solver.IntVar(0, solver.infinity(), 'swordsmen')\n",
97 | "bowmen = solver.IntVar(0, solver.infinity(), 'bowmen')\n",
98 | "horsemen = solver.IntVar(0, solver.infinity(), 'horsemen')\n",
99 | "\n",
100 | "# 2. Add constraints for each resource\n",
101 | "solver.Add(swordsmen*60 + bowmen*80 + horsemen*140 <= 1200)\n",
102 | "solver.Add(swordsmen*20 + bowmen*10 <= 800)\n",
103 | "solver.Add(bowmen*40 + horsemen*100 <= 600)\n",
104 | "\n",
105 | "# 3. Maximize the objective function\n",
106 | "solver.Maximize(swordsmen*70 + bowmen*95 + horsemen*230)\n",
107 | "\n",
108 | "# Solve problem\n",
109 | "status = solver.Solve()\n",
110 | "\n",
111 | "# If an optimal solution has been found, print results\n",
112 | "if status == pywraplp.Solver.OPTIMAL:\n",
113 | " print('================= Solution =================')\n",
114 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
115 | " print()\n",
116 | " print(f'Optimal value = {solver.Objective().Value()} 💪power')\n",
117 | " print('Army:')\n",
118 | " print(f' - 🗡️Swordsmen = {swordsmen.solution_value()}')\n",
119 | " print(f' - 🏹Bowmen = {bowmen.solution_value()}')\n",
120 | " print(f' - 🐎Horsemen = {horsemen.solution_value()}')\n",
121 | "else:\n",
122 | " print('The solver could not find an optimal solution.')"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {
128 | "id": "vHTmOQzUK295"
129 | },
130 | "source": [
131 | "# Abstract model as a Python function\n",
132 | "\n",
133 | "Same problem but with a function and parameters instead of a static model."
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 3,
139 | "metadata": {
140 | "colab": {
141 | "base_uri": "https://localhost:8080/"
142 | },
143 | "id": "qR-fbnruehR4",
144 | "outputId": "6f0ebc4c-c8b7-4bbc-dfd0-fc565cc032a3"
145 | },
146 | "outputs": [
147 | {
148 | "output_type": "stream",
149 | "name": "stdout",
150 | "text": [
151 | "================= Solution =================\n",
152 | "Solved in 3.00 milliseconds in 0 iterations\n",
153 | "\n",
154 | "Optimal value = 1800.0 💪power\n",
155 | "Army:\n",
156 | " - 🗡️Swordsmen = 6.0\n",
157 | " - 🏹Bowmen = 0.0\n",
158 | " - 🐎Horsemen = 6.0\n"
159 | ]
160 | }
161 | ],
162 | "source": [
163 | "# Inputs\n",
164 | "UNITS = ['🗡️Swordsmen', '🏹Bowmen', '🐎Horsemen']\n",
165 | "\n",
166 | "DATA = [[60, 20, 0, 70],\n",
167 | " [80, 10, 40, 95],\n",
168 | " [140, 0, 100, 230]]\n",
169 | "\n",
170 | "RESOURCES = [1200, 800, 600]\n",
171 | "\n",
172 | "\n",
173 | "def solve_army(UNITS, DATA, RESOURCES):\n",
174 | " # Create the linear solver using the CBC backend\n",
175 | " solver = pywraplp.Solver('Maximize army power', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
176 | "\n",
177 | " # 1. Create the variables we want to optimize\n",
178 | " units = [solver.IntVar(0, solver.infinity(), unit) for unit in UNITS]\n",
179 | "\n",
180 | " # 2. Add constraints for each resource\n",
181 | " for r, _ in enumerate(RESOURCES):\n",
182 | " solver.Add(sum(DATA[u][r] * units[u] for u, _ in enumerate(units)) <= RESOURCES[r])\n",
183 | "\n",
184 | " # 3. Maximize the objective function\n",
185 | " solver.Maximize(sum(DATA[u][-1] * units[u] for u, _ in enumerate(units)))\n",
186 | "\n",
187 | " # Solve problem\n",
188 | " status = solver.Solve()\n",
189 | "\n",
190 | " # If an optimal solution has been found, print results\n",
191 | " if status == pywraplp.Solver.OPTIMAL:\n",
192 | " print('================= Solution =================')\n",
193 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
194 | " print()\n",
195 | " print(f'Optimal value = {solver.Objective().Value()} 💪power')\n",
196 | " print('Army:')\n",
197 | " for u, _ in enumerate(units):\n",
198 | " print(f' - {units[u].name()} = {units[u].solution_value()}')\n",
199 | " else:\n",
200 | " print('The solver could not find an optimal solution.')\n",
201 | "\n",
202 | "solve_army(UNITS, DATA, RESOURCES)"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {
208 | "id": "qj6lzFPsT6MS"
209 | },
210 | "source": [
211 | "# Optimize a new problem\n",
212 | "\n",
213 | "The goal is to maximize the power of the army with the following resources: 183000 food, 90512 wood, 80150 gold.\n",
214 | "\n",
215 | "
\n",
216 | "\n",
217 | "| Unit | 🌾Food | 🪵Wood | 🪙Gold | 💪Attack | ❤️Health\n",
218 | "| :--- | :---: | :---: | :---: | :---: | :---: |\n",
219 | "| 🗡️Swordsman | 60 | 20 | 0 | 6 | 70 |\n",
220 | "| 🛡️Man-at-arms | 100 | 0 | 20 | 12 | 155 |\n",
221 | "| 🏹Bowman | 30 | 50 | 0 | 5 | 70 |\n",
222 | "| ❌Crossbowman | 80 | 0 | 40 | 12 | 80 |\n",
223 | "| 🔫Handcannoneer | 120 | 0 | 120 | 35 | 150 |\n",
224 | "| 🐎Horseman | 100 | 20 | 0 | 9 | 125 |\n",
225 | "| ♞Knight | 140 | 0 | 100 | 24 | 230 | \n",
226 | "| 🐏Battering ram | 0 | 300 | 0 | 200 | 700 |\n",
227 | "| 🎯Springald | 0 | 250 | 250 | 30 | 200 |\n",
228 | "\n",
229 | ""
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": 4,
235 | "metadata": {
236 | "colab": {
237 | "base_uri": "https://localhost:8080/"
238 | },
239 | "id": "Y2EUFqCETvLZ",
240 | "outputId": "f5f36d84-961d-4637-8625-21c0a47a2fab"
241 | },
242 | "outputs": [
243 | {
244 | "output_type": "stream",
245 | "name": "stdout",
246 | "text": [
247 | "================= Solution =================\n",
248 | "Solved in 113.00 milliseconds in 412 iterations\n",
249 | "\n",
250 | "Optimal value = 1393145.0 💪power\n",
251 | "Army:\n",
252 | " - 🗡️Swordsmen = 2.0\n",
253 | " - 🛡️Men-at-arms = 1283.0\n",
254 | " - 🏹Bowmen = 3.0\n",
255 | " - ❌Crossbowmen = 0.0\n",
256 | " - 🔫Handcannoneers = 454.0\n",
257 | " - 🐎Horsemen = 0.0\n",
258 | " - ♞Knights = 0.0\n",
259 | " - 🐏Battering rams = 301.0\n",
260 | " - 🎯Springalds = 0.0\n",
261 | " - 🪨Mangonels = 0.0\n"
262 | ]
263 | }
264 | ],
265 | "source": [
266 | "UNITS = [\n",
267 | " '🗡️Swordsmen',\n",
268 | " '🛡️Men-at-arms',\n",
269 | " '🏹Bowmen',\n",
270 | " '❌Crossbowmen',\n",
271 | " '🔫Handcannoneers',\n",
272 | " '🐎Horsemen',\n",
273 | " '♞Knights',\n",
274 | " '🐏Battering rams',\n",
275 | " '🎯Springalds',\n",
276 | " '🪨Mangonels',\n",
277 | "]\n",
278 | "\n",
279 | "DATA = [\n",
280 | " [60, 20, 0, 6, 70],\n",
281 | " [100, 0, 20, 12, 155],\n",
282 | " [30, 50, 0, 5, 70],\n",
283 | " [80, 0, 40, 12, 80],\n",
284 | " [120, 0, 120, 35, 150],\n",
285 | " [100, 20, 0, 9, 125],\n",
286 | " [140, 0, 100, 24, 230],\n",
287 | " [0, 300, 0, 200, 700],\n",
288 | " [0, 250, 250, 30, 200],\n",
289 | " [0, 400, 200, 12*3, 240]\n",
290 | "]\n",
291 | "\n",
292 | "RESOURCES = [183000, 90512, 80150]\n",
293 | "\n",
294 | "\n",
295 | "def solve_army(UNITS, DATA, RESOURCES):\n",
296 | " # Create the linear solver using the CBC backend\n",
297 | " solver = pywraplp.Solver('Maximize army power', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
298 | "\n",
299 | " # 1. Create the variables we want to optimize\n",
300 | " units = [solver.IntVar(0, solver.infinity(), unit) for unit in UNITS]\n",
301 | "\n",
302 | " # 2. Add constraints for each resource\n",
303 | " for r, _ in enumerate(RESOURCES):\n",
304 | " solver.Add(sum(DATA[u][r] * units[u] for u, _ in enumerate(units)) <= RESOURCES[r])\n",
305 | "\n",
306 | " # 3. Maximize the new objective function\n",
307 | " solver.Maximize(sum((10*DATA[u][-2] + DATA[u][-1]) * units[u] for u, _ in enumerate(units)))\n",
308 | "\n",
309 | " # Solve problem\n",
310 | " status = solver.Solve()\n",
311 | "\n",
312 | " # If an optimal solution has been found, print results\n",
313 | " if status == pywraplp.Solver.OPTIMAL:\n",
314 | " print('================= Solution =================')\n",
315 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
316 | " print()\n",
317 | " print(f'Optimal value = {solver.Objective().Value()} 💪power')\n",
318 | " print('Army:')\n",
319 | " for u, _ in enumerate(units):\n",
320 | " print(f' - {units[u].name()} = {units[u].solution_value()}')\n",
321 | " else:\n",
322 | " print('The solver could not find an optimal solution.')\n",
323 | "\n",
324 | "solve_army(UNITS, DATA, RESOURCES)"
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "source": [
330 | "# Minimize resource consumption\n",
331 | "\n",
332 | "The goal is to minimize the resources that are used to get an army power >= 1,000,001."
333 | ],
334 | "metadata": {
335 | "id": "8HEf61kAGQZ-"
336 | }
337 | },
338 | {
339 | "cell_type": "code",
340 | "execution_count": 10,
341 | "metadata": {
342 | "colab": {
343 | "base_uri": "https://localhost:8080/"
344 | },
345 | "id": "nz5244z9nBYw",
346 | "outputId": "ad6c57ff-4d59-4641-8a38-8497027bbff7"
347 | },
348 | "outputs": [
349 | {
350 | "output_type": "stream",
351 | "name": "stdout",
352 | "text": [
353 | "================= Solution =================\n",
354 | "Solved in 3.00 milliseconds in 0 iterations\n",
355 | "\n",
356 | "Optimal value = 111300.0 🌾🪵🪙resources\n",
357 | "Power = 💪1001700.0\n",
358 | "Army:\n",
359 | " - 🗡️Swordsmen = 0.0\n",
360 | " - 🛡️Men-at-arms = 0.0\n",
361 | " - 🏹Bowmen = 0.0\n",
362 | " - ❌Crossbowmen = 0.0\n",
363 | " - 🔫Handcannoneers = 0.0\n",
364 | " - 🐎Horsemen = 0.0\n",
365 | " - ♞Knights = 0.0\n",
366 | " - 🐏Battering rams = 371.0\n",
367 | " - 🎯Springalds = 0.0\n",
368 | " - 🪨Mangonels = 0.0\n",
369 | "\n",
370 | "Resources:\n",
371 | " - 🌾Food = 0.0\n",
372 | " - 🪵Wood = 111300.0\n",
373 | " - 🪙Gold = 0.0\n"
374 | ]
375 | }
376 | ],
377 | "source": [
378 | "def solve_army(UNITS, DATA, RESOURCES):\n",
379 | " # Create the linear solver using the CBC backend\n",
380 | " solver = pywraplp.Solver('Minimize resource consumption', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
381 | "\n",
382 | " # 1. Create the variables we want to optimize\n",
383 | " units = [solver.IntVar(0, solver.infinity(), unit) for unit in UNITS]\n",
384 | "\n",
385 | " # 2. Add power constraint\n",
386 | " solver.Add(sum((10 * DATA[u][-2] + DATA[u][-1]) * units[u] for u, _ in enumerate(units)) >= 1000001)\n",
387 | "\n",
388 | " # 3. Minimize the objective function\n",
389 | " solver.Minimize(sum((DATA[u][0] + DATA[u][1] + DATA[u][2]) * units[u] for u, _ in enumerate(units)))\n",
390 | "\n",
391 | " # Solve problem\n",
392 | " status = solver.Solve()\n",
393 | "\n",
394 | " # If an optimal solution has been found, print results\n",
395 | " if status == pywraplp.Solver.OPTIMAL:\n",
396 | " print('================= Solution =================')\n",
397 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
398 | " print()\n",
399 | "\n",
400 | " power = sum((10 * DATA[u][-2] + DATA[u][-1]) * units[u].solution_value() for u, _ in enumerate(units))\n",
401 | " print(f'Optimal value = {solver.Objective().Value()} 🌾🪵🪙resources')\n",
402 | " print(f'Power = 💪{power}')\n",
403 | " print('Army:')\n",
404 | " for u, _ in enumerate(units):\n",
405 | " print(f' - {units[u].name()} = {units[u].solution_value()}')\n",
406 | " print()\n",
407 | "\n",
408 | " food = sum((DATA[u][0]) * units[u].solution_value() for u, _ in enumerate(units))\n",
409 | " wood = sum((DATA[u][1]) * units[u].solution_value() for u, _ in enumerate(units))\n",
410 | " gold = sum((DATA[u][2]) * units[u].solution_value() for u, _ in enumerate(units))\n",
411 | " print('Resources:')\n",
412 | " print(f' - 🌾Food = {food}')\n",
413 | " print(f' - 🪵Wood = {wood}')\n",
414 | " print(f' - 🪙Gold = {gold}')\n",
415 | " else:\n",
416 | " print('The solver could not find an optimal solution.')\n",
417 | "\n",
418 | "solve_army(UNITS, DATA, RESOURCES)"
419 | ]
420 | },
421 | {
422 | "cell_type": "markdown",
423 | "metadata": {
424 | "id": "Qxeyd7vV3YmH"
425 | },
426 | "source": [
427 | "# Minimize resource consumption + limited resources\n",
428 | "\n",
429 | "The goal is to minimize the resources that are used to get an army power > 1,000,00 but the resources cannot exceed: 183000 food, 90512 wood, 80150 gold."
430 | ]
431 | },
432 | {
433 | "cell_type": "code",
434 | "execution_count": 6,
435 | "metadata": {
436 | "colab": {
437 | "base_uri": "https://localhost:8080/"
438 | },
439 | "id": "lyi0eVvu1I8Q",
440 | "outputId": "3b7a1b1d-42b0-4e9d-e7f9-5993e1c275d2"
441 | },
442 | "outputs": [
443 | {
444 | "output_type": "stream",
445 | "name": "stdout",
446 | "text": [
447 | "================= Solution =================\n",
448 | "Solved in 31.00 milliseconds in 1 iterations\n",
449 | "\n",
450 | "Optimal value = 172100.0 🌾🪵🪙resources\n",
451 | "Power = 💪1000105.0\n",
452 | "Army:\n",
453 | " - 🗡️Swordsmen = 1.0\n",
454 | " - 🛡️Men-at-arms = 681.0\n",
455 | " - 🏹Bowmen = 0.0\n",
456 | " - ❌Crossbowmen = 0.0\n",
457 | " - 🔫Handcannoneers = 0.0\n",
458 | " - 🐎Horsemen = 0.0\n",
459 | " - ♞Knights = 0.0\n",
460 | " - 🐏Battering rams = 301.0\n",
461 | " - 🎯Springalds = 0.0\n",
462 | " - 🪨Mangonels = 0.0\n",
463 | "\n",
464 | "Resources:\n",
465 | " - 🌾Food = 68160.0\n",
466 | " - 🪵Wood = 90320.0\n",
467 | " - 🪙Gold = 13620.0\n"
468 | ]
469 | }
470 | ],
471 | "source": [
472 | "def solve_army(UNITS, DATA, RESOURCES):\n",
473 | " # Create the linear solver using the CBC backend\n",
474 | " solver = pywraplp.Solver('Minimize resource consumption', pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
475 | "\n",
476 | " # 1. Create the variables we want to optimize\n",
477 | " units = [solver.IntVar(0, solver.infinity(), unit) for unit in UNITS]\n",
478 | "\n",
479 | " # 2. Add constraints for each resource\n",
480 | " for r, _ in enumerate(RESOURCES):\n",
481 | " solver.Add(sum((10 * DATA[u][-2] + DATA[u][-1]) * units[u] for u, _ in enumerate(units)) >= 1000001)\n",
482 | "\n",
483 | " # Old constraints for limited resources\n",
484 | " for r, _ in enumerate(RESOURCES):\n",
485 | " solver.Add(sum(DATA[u][r] * units[u] for u, _ in enumerate(units)) <= RESOURCES[r])\n",
486 | "\n",
487 | " # 3. Minimize the objective function\n",
488 | " solver.Minimize(sum((DATA[u][0] + DATA[u][1] + DATA[u][2]) * units[u] for u, _ in enumerate(units)))\n",
489 | "\n",
490 | " # Solve problem\n",
491 | " status = solver.Solve()\n",
492 | "\n",
493 | " # If an optimal solution has been found, print results\n",
494 | " if status == pywraplp.Solver.OPTIMAL:\n",
495 | " print('================= Solution =================')\n",
496 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
497 | " print()\n",
498 | "\n",
499 | " power = sum((10 * DATA[u][-2] + DATA[u][-1]) * units[u].solution_value() for u, _ in enumerate(units))\n",
500 | " print(f'Optimal value = {solver.Objective().Value()} 🌾🪵🪙resources')\n",
501 | " print(f'Power = 💪{power}')\n",
502 | " print('Army:')\n",
503 | " for u, _ in enumerate(units):\n",
504 | " print(f' - {units[u].name()} = {units[u].solution_value()}')\n",
505 | " print()\n",
506 | " \n",
507 | " food = sum((DATA[u][0]) * units[u].solution_value() for u, _ in enumerate(units))\n",
508 | " wood = sum((DATA[u][1]) * units[u].solution_value() for u, _ in enumerate(units))\n",
509 | " gold = sum((DATA[u][2]) * units[u].solution_value() for u, _ in enumerate(units))\n",
510 | " print('Resources:')\n",
511 | " print(f' - 🌾Food = {food}')\n",
512 | " print(f' - 🪵Wood = {wood}')\n",
513 | " print(f' - 🪙Gold = {gold}')\n",
514 | " else:\n",
515 | " print('The solver could not find an optimal solution.')\n",
516 | "\n",
517 | "solve_army(UNITS, DATA, RESOURCES)"
518 | ]
519 | }
520 | ],
521 | "metadata": {
522 | "colab": {
523 | "name": "2. Integer vs. Linear Programming.ipynb",
524 | "provenance": [],
525 | "include_colab_link": true
526 | },
527 | "kernelspec": {
528 | "display_name": "Python 3",
529 | "name": "python3"
530 | },
531 | "language_info": {
532 | "name": "python",
533 | "version": "3.8.12"
534 | }
535 | },
536 | "nbformat": 4,
537 | "nbformat_minor": 0
538 | }
--------------------------------------------------------------------------------
/3_Constraint_Programming.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "3. Constraint Programming.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "authorship_tag": "ABX9TyP+XS+2mWjt11uObJ0hmqn6",
10 | "include_colab_link": true
11 | },
12 | "kernelspec": {
13 | "name": "python3",
14 | "display_name": "Python 3"
15 | },
16 | "language_info": {
17 | "name": "python"
18 | }
19 | },
20 | "cells": [
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {
24 | "id": "view-in-github",
25 | "colab_type": "text"
26 | },
27 | "source": [
28 | "
"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "source": [
34 | "# Constraint Programming\n",
35 | "\n",
36 | "> Chapter 3 of the [Linear Programming Course](https://github.com/mlabonne/Linear-Programming-Course)\n",
37 | "\n",
38 | "❤️ Created by [@maximelabonne](https://twitter.com/maximelabonne).\n",
39 | "\n",
40 | "Companion notebook to execute the code from the following article: "
41 | ],
42 | "metadata": {
43 | "id": "Ti4Xsm_RpqxE"
44 | }
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {
50 | "id": "lRgbfs48pYOA"
51 | },
52 | "outputs": [],
53 | "source": [
54 | "!python -m pip install --upgrade --user -q ortools"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "source": [
60 | "# Satisfiability\n",
61 | "\n",
62 | "Find the number of soldiers in the enemy army, called $army$.\n",
63 | "\n",
64 | "$$\n",
65 | " \\left\\{\\begin{array}{@{}l@{}}\n",
66 | " army \\equiv 0 \\mod 13\\\\\n",
67 | " army \\equiv 0 \\mod 19\\\\\n",
68 | " army \\equiv 0 \\mod 37\\\\\n",
69 | " 1 \\leq army \\leq 10\\ 000\n",
70 | " \\end{array}\\right.\\,\n",
71 | "$$\n",
72 | "\n",
73 | "If the following cell fails, click on `Runtime > Restart and run all`."
74 | ],
75 | "metadata": {
76 | "id": "f-8tYRrcp4Y7"
77 | }
78 | },
79 | {
80 | "cell_type": "code",
81 | "source": [
82 | "from ortools.sat.python import cp_model\n",
83 | "\n",
84 | "# Instantiate model and solver\n",
85 | "model = cp_model.CpModel()\n",
86 | "solver = cp_model.CpSolver()\n",
87 | "\n",
88 | "# 1. Variable\n",
89 | "army = model.NewIntVar(1, 10000, 'army')\n",
90 | "\n",
91 | "# 2. Constraints\n",
92 | "# variable % mod = target → (target, variable, mod)\n",
93 | "model.AddModuloEquality(0, army, 13)\n",
94 | "model.AddModuloEquality(0, army, 19)\n",
95 | "model.AddModuloEquality(0, army, 37)\n",
96 | "\n",
97 | "# Find the variable that satisfies these constraints\n",
98 | "status = solver.Solve(model)\n",
99 | "\n",
100 | "# If a solution has been found, print results\n",
101 | "if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:\n",
102 | " print('================= Solution =================')\n",
103 | " print(f'Solved in {solver.WallTime():.2f} milliseconds')\n",
104 | " print()\n",
105 | " print(f'🪖 Army = {solver.Value(army)}')\n",
106 | " print()\n",
107 | " print('Check solution:')\n",
108 | " print(f' - Constraint 1: {solver.Value(army)} % 13 = {solver.Value(army) % 13}')\n",
109 | " print(f' - Constraint 2: {solver.Value(army)} % 19 = {solver.Value(army) % 19}')\n",
110 | " print(f' - Constraint 3: {solver.Value(army)} % 37 = {solver.Value(army) % 37}')\n",
111 | "\n",
112 | "else:\n",
113 | " print('The solver could not find a solution.')"
114 | ],
115 | "metadata": {
116 | "id": "y9ITXS14pcps",
117 | "colab": {
118 | "base_uri": "https://localhost:8080/"
119 | },
120 | "outputId": "fd6192b0-a757-4f80-d0a6-f5b3dd8bc156"
121 | },
122 | "execution_count": null,
123 | "outputs": [
124 | {
125 | "output_type": "stream",
126 | "name": "stdout",
127 | "text": [
128 | "================= Solution =================\n",
129 | "Solved in 0.00 milliseconds\n",
130 | "\n",
131 | "🪖 Army = 9139\n",
132 | "\n",
133 | "Check solution:\n",
134 | " - Constraint 1: 9139 % 13 = 0\n",
135 | " - Constraint 2: 9139 % 19 = 0\n",
136 | " - Constraint 3: 9139 % 37 = 0\n"
137 | ]
138 | }
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "source": [
144 | "Print every solution with a callback with a new upper bound:\n",
145 | "\n",
146 | "$$1 \\leq army \\leq 100\\ 000$$"
147 | ],
148 | "metadata": {
149 | "id": "Naa_73V_qG8r"
150 | }
151 | },
152 | {
153 | "cell_type": "code",
154 | "source": [
155 | "model = cp_model.CpModel()\n",
156 | "solver = cp_model.CpSolver()\n",
157 | "\n",
158 | "# 1. Variable\n",
159 | "army = model.NewIntVar(1, 100000, 'army')\n",
160 | "\n",
161 | "# 2. Constraints\n",
162 | "model.AddModuloEquality(0, army, 13)\n",
163 | "model.AddModuloEquality(0, army, 19)\n",
164 | "model.AddModuloEquality(0, army, 37)\n",
165 | "\n",
166 | "\n",
167 | "class PrintSolutions(cp_model.CpSolverSolutionCallback):\n",
168 | " \"\"\"Callback to print every solution.\"\"\"\n",
169 | "\n",
170 | " def __init__(self, variable):\n",
171 | " cp_model.CpSolverSolutionCallback.__init__(self)\n",
172 | " self.__variable = variable\n",
173 | "\n",
174 | " def on_solution_callback(self):\n",
175 | " print(self.Value(self.__variable))\n",
176 | "\n",
177 | "# Solve with callback\n",
178 | "solution_printer = PrintSolutions(army)\n",
179 | "solver.parameters.enumerate_all_solutions = True\n",
180 | "status = solver.Solve(model, solution_printer)"
181 | ],
182 | "metadata": {
183 | "id": "gTkTq-K1pcnT",
184 | "colab": {
185 | "base_uri": "https://localhost:8080/"
186 | },
187 | "outputId": "f597e8b1-0f77-466e-b5dc-e9b410849e71"
188 | },
189 | "execution_count": null,
190 | "outputs": [
191 | {
192 | "output_type": "stream",
193 | "name": "stdout",
194 | "text": [
195 | "9139\n",
196 | "18278\n",
197 | "27417\n",
198 | "36556\n",
199 | "45695\n",
200 | "54834\n",
201 | "63973\n",
202 | "73112\n",
203 | "82251\n",
204 | "91390\n"
205 | ]
206 | }
207 | ]
208 | },
209 | {
210 | "cell_type": "markdown",
211 | "source": [
212 | "# Optimization\n",
213 | "\n",
214 | "The goal is to maximize the popularity of the rations without exceeding the capacity of 19.\n",
215 | "\n",
216 | "| | 🥖Bread | 🥩Meat | 🍺Beer |\n",
217 | "| :--- | :---: | :---: | :---: |\n",
218 | "| Size | 1 | 3 | 7 |\n",
219 | "| Popularity | 3 | 10 | 26 |\n",
220 | "\n",
221 | "## 1. Constraint Programming solution:"
222 | ],
223 | "metadata": {
224 | "id": "WYqQqKe9qTbi"
225 | }
226 | },
227 | {
228 | "cell_type": "code",
229 | "source": [
230 | "from ortools.sat.python import cp_model\n",
231 | "\n",
232 | "# Instantiate model and solver\n",
233 | "model = cp_model.CpModel()\n",
234 | "solver = cp_model.CpSolver()\n",
235 | "\n",
236 | "# 1. Variables\n",
237 | "capacity = 19\n",
238 | "bread = model.NewIntVar(0, capacity, 'bread')\n",
239 | "meat = model.NewIntVar(0, capacity, 'meat')\n",
240 | "beer = model.NewIntVar(0, capacity, 'beer')\n",
241 | "\n",
242 | "# 2. Constraints\n",
243 | "model.Add(1 * bread\n",
244 | " + 3 * meat \n",
245 | " + 7 * beer <= capacity)\n",
246 | "\n",
247 | "# 3. Objective\n",
248 | "model.Maximize(3 * bread\n",
249 | " + 10 * meat\n",
250 | " + 26 * beer)\n",
251 | "\n",
252 | "# Solve problem\n",
253 | "status = solver.Solve(model)\n",
254 | "\n",
255 | "# If an optimal solution has been found, print results\n",
256 | "if status == cp_model.OPTIMAL:\n",
257 | " print('================= Solution =================')\n",
258 | " print(f'Solved in {solver.WallTime():.2f} milliseconds')\n",
259 | " print()\n",
260 | " print(f'Optimal value = {3*solver.Value(bread)+10*solver.Value(meat)+26*solver.Value(beer)} popularity')\n",
261 | " print('Food:')\n",
262 | " print(f' - 🥖Bread = {solver.Value(bread)}')\n",
263 | " print(f' - 🥩Meat = {solver.Value(meat)}')\n",
264 | " print(f' - 🍺Beer = {solver.Value(beer)}')\n",
265 | " print()\n",
266 | " print(f'Constraint: 1*{solver.Value(bread)}🥖 + 3*{solver.Value(meat)}🥩 + 7*{solver.Value(beer)}🍺')\n",
267 | " print(f' = {1*solver.Value(bread)+3*solver.Value(meat)+7*solver.Value(beer)} (<= {capacity})')\n",
268 | "else:\n",
269 | " print('The solver could not find an optimal solution.')"
270 | ],
271 | "metadata": {
272 | "id": "LNdnehD5pck0",
273 | "colab": {
274 | "base_uri": "https://localhost:8080/"
275 | },
276 | "outputId": "39e8c0b4-666e-47ee-9328-6ed927dfa81f"
277 | },
278 | "execution_count": null,
279 | "outputs": [
280 | {
281 | "output_type": "stream",
282 | "name": "stdout",
283 | "text": [
284 | "================= Solution =================\n",
285 | "Solved in 0.00 milliseconds\n",
286 | "\n",
287 | "Optimal value = 68 popularity\n",
288 | "Food:\n",
289 | " - 🥖Bread = 2\n",
290 | " - 🥩Meat = 1\n",
291 | " - 🍺Beer = 2\n",
292 | "\n",
293 | "Constraint: 1*2🥖 + 3*1🥩 + 7*2🍺\n",
294 | " = 19 (<= 19)\n"
295 | ]
296 | }
297 | ]
298 | },
299 | {
300 | "cell_type": "markdown",
301 | "source": [
302 | "## 2. Linear Programming solution:"
303 | ],
304 | "metadata": {
305 | "id": "b0kQYdd4rWBU"
306 | }
307 | },
308 | {
309 | "cell_type": "code",
310 | "source": [
311 | "from ortools.linear_solver import pywraplp\n",
312 | "\n",
313 | "# Instantiate solver with CBC backend\n",
314 | "solver = pywraplp.Solver('',\n",
315 | " pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)\n",
316 | "\n",
317 | "# 1. Variables\n",
318 | "capacity = 19\n",
319 | "bread = solver.IntVar(0, capacity, 'bread')\n",
320 | "meat = solver.IntVar(0, capacity, 'meat')\n",
321 | "beer = solver.IntVar(0, capacity, 'beer')\n",
322 | "\n",
323 | "# 2. Constraints\n",
324 | "solver.Add(1 * bread\n",
325 | " + 3 * meat\n",
326 | " + 7 * beer <= capacity)\n",
327 | "\n",
328 | "# 3. Objective\n",
329 | "solver.Maximize(3 * bread\n",
330 | " + 10 * meat\n",
331 | " + 26 * beer)\n",
332 | "\n",
333 | "# Solve problem\n",
334 | "status = solver.Solve()\n",
335 | "\n",
336 | "# If an optimal solution has been found, print results\n",
337 | "if status == pywraplp.Solver.OPTIMAL:\n",
338 | " print('================= Solution =================')\n",
339 | " print(f'Solved in {solver.wall_time():.2f} milliseconds in {solver.iterations()} iterations')\n",
340 | " print()\n",
341 | " print(f'Optimal value = {solver.Objective().Value()} popularity')\n",
342 | " print('Food:')\n",
343 | " print(f' - 🥖Bread = {bread.solution_value()}')\n",
344 | " print(f' - 🥩Meat = {meat.solution_value()}')\n",
345 | " print(f' - 🍺Beer = {beer.solution_value()}')\n",
346 | " print()\n",
347 | " print(f'Constraint: 1*{bread.solution_value()}🥖 + 3*{meat.solution_value()}🥩 + 7*{beer.solution_value()}🍺')\n",
348 | " print(f' = {1*bread.solution_value()+3*meat.solution_value()+7*beer.solution_value()} (<= {capacity})')\n",
349 | "else:\n",
350 | " print('The solver could not find an optimal solution.')"
351 | ],
352 | "metadata": {
353 | "id": "XQz8YzsspciE",
354 | "colab": {
355 | "base_uri": "https://localhost:8080/"
356 | },
357 | "outputId": "7eb617f5-102e-41e0-9cce-034035ecb522"
358 | },
359 | "execution_count": null,
360 | "outputs": [
361 | {
362 | "output_type": "stream",
363 | "name": "stdout",
364 | "text": [
365 | "================= Solution =================\n",
366 | "Solved in 97.00 milliseconds in 1 iterations\n",
367 | "\n",
368 | "Optimal value = 68.0 popularity\n",
369 | "Food:\n",
370 | " - 🥖Bread = 2.0\n",
371 | " - 🥩Meat = 1.0\n",
372 | " - 🍺Beer = 2.0\n",
373 | "\n",
374 | "Constraint: 1*2.0🥖 + 3*1.0🥩 + 7*2.0🍺\n",
375 | " = 19.0 (<= 19)\n"
376 | ]
377 | }
378 | ]
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "source": [
383 | "Count the number of possible solutions (it takes hours and hours with a capacity of 1000)."
384 | ],
385 | "metadata": {
386 | "id": "xC86ceQUrgMh"
387 | }
388 | },
389 | {
390 | "cell_type": "code",
391 | "source": [
392 | "class CountSolutions(cp_model.CpSolverSolutionCallback):\n",
393 | " \"\"\"Count the number of solutions.\"\"\"\n",
394 | "\n",
395 | " def __init__(self):\n",
396 | " cp_model.CpSolverSolutionCallback.__init__(self)\n",
397 | " self.__solution_count = 0\n",
398 | "\n",
399 | " def on_solution_callback(self):\n",
400 | " self.__solution_count += 1\n",
401 | "\n",
402 | " def solution_count(self):\n",
403 | " return self.__solution_count\n",
404 | "\n",
405 | "solution_printer = CountSolutions()\n",
406 | "\n",
407 | "# Instantiate model and solver\n",
408 | "model = cp_model.CpModel()\n",
409 | "solver = cp_model.CpSolver()\n",
410 | "\n",
411 | "# 1. Variables\n",
412 | "capacity = 1000\n",
413 | "bread = model.NewIntVar(0, capacity, 'bread')\n",
414 | "meat = model.NewIntVar(0, capacity, 'meat')\n",
415 | "beer = model.NewIntVar(0, capacity, 'beer')\n",
416 | "\n",
417 | "# 2. Constraints\n",
418 | "model.Add(1 * bread\n",
419 | " + 3 * meat \n",
420 | " + 7 * beer <= capacity)\n",
421 | "\n",
422 | "# Print results\n",
423 | "solver.parameters.enumerate_all_solutions = True\n",
424 | "status = solver.Solve(model, solution_printer)\n",
425 | "print(solution_printer.solution_count())"
426 | ],
427 | "metadata": {
428 | "id": "JEVgIrPapcbY"
429 | },
430 | "execution_count": null,
431 | "outputs": []
432 | }
433 | ]
434 | }
--------------------------------------------------------------------------------
/4_Maximize_Your_Marketing_ROI_with_Nonlinear_Optimization.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "authorship_tag": "ABX9TyNHab9ktZjoXYWpvzLjJNem",
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | "
"
27 | ]
28 | },
29 | {
30 | "cell_type": "markdown",
31 | "source": [
32 | "# Optimize Your Marketing Budget with Nonlinear Programming\n",
33 | "> Chapter 4 of the [Linear Programming Course](https://github.com/mlabonne/linear-programming-course)\n",
34 | "\n",
35 | "❤️ Created by [@maximelabonne](https://twitter.com/maximelabonne).\n",
36 | "\n",
37 | "Companion notebook to execute the code from the following article: https://mlabonne.github.io/blog/posts/2023-05-21-Nonlinear_optimization.html"
38 | ],
39 | "metadata": {
40 | "id": "GSZ3y8PnGgtF"
41 | }
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {
47 | "colab": {
48 | "base_uri": "https://localhost:8080/",
49 | "height": 465
50 | },
51 | "id": "Vlikf7bbGfvR",
52 | "outputId": "c28adcfc-cc1c-452a-c4e4-a93ce781eca0"
53 | },
54 | "outputs": [
55 | {
56 | "output_type": "display_data",
57 | "data": {
58 | "text/plain": [
59 | ""
60 | ],
61 | "image/png": "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6iH4HxgiIiIiInPGQGbJmMeIiIiIqJxdv34dCoUC0dHRVeq9jYWBjIiIiIiokomJicH48eNRr1492NnZwcfHB23btsXixYuRnp5u6vIeS1BQEFQqFWJiYkxdSoVgILNAefch4xAZERERkaW5evUqmjdvjr/++gsffvghjh8/jsjISEyZMgWbN2/G33//beoSy2zfvn3IyMjA888/j1WrVpm6nArBQEZEREREBABCAGlpFd+EeHRt+bz22muwtrbGkSNHMGDAAAQHB6NOnTro3bs3tmzZgl69esl9b968id69e8PJyQlqtRoDBgxAbGys3v4WL16MunXrwtbWFg0aNMDq1av1tp8/fx5PPfUU7OzsEBISgr///hsKhQKbNm0qtsbTp0+je/fucHJygo+PD4YOHYr79+8/8rMtX74cL774IoYOHYrvvvuu0PZDhw6hefPmsLOzQ2hoKI4fP663PSEhAYMHD4aXlxfs7e1Rv359rFix4pHva0q8D5lF0o2QEREREVGppacDTk4V/76pqYCjY6m6PnjwQB4ZcyzmNbrZ/7RarRzG9u7di9zcXIwdOxYvvPAC9uzZAwD49ddfMX78eHz22WcIDw/H5s2bMWLECNSoUQOdOnWCRqNBnz59ULNmTURFRSElJQVvvvlmiTUmJiaic+fOePnll/Hpp58iIyMDU6dOxYABA7Br165iX5eSkoINGzYgKioKQUFBSEpKwr///ot27do9/JpS8cwzz+Dpp5/GmjVrcO3aNYwfP15vHzNnzsTZs2fx559/wtPTE5cvX0ZGRkapvltTYSCzaIxkRERERJbk8uXLEEKgQYMGeus9PT2RmZkJABg7diw++ugj7Ny5E6dOncK1a9fg7+8PAPj+++/RsGFDHD58GE888QQ++eQTDB8+HK+99hoAYNKkSTh48CA++eQTdOrUCTt27MCVK1ewZ88e+Pr6AgDmzJmDp59+utgav/zySzRv3hwffvihvO67776Dv78/Ll68iMDAwCJft27dOtSvXx8NGzYEAAwcOBDLly+XA9kPP/wArVaL5cuXw87ODg0bNsTt27cxZswYeR83b95E8+bNERoaCgCoXbt2qb9bU+EpixZIyEHMsOFvIiIioirNwUEararoZoSbUx86dAjR0dFo2LAhsrKyAADnzp2Dv7+/HMYAICQkBK6urjh37pzcp23btnr7atu2rbz9woUL8Pf3l8MYALRq1arEWk6cOIHdu3fDyclJbkFBQQCAK1euFPu67777DkOGDJGfDxkyBBs2bEBKSopca5MmTWBnZyf3CQsL09vHmDFjsG7dOjRr1gxTpkzBgQMHSqzVHHCEzCJxUg8iIiIigykUpT510FTq1asHhUKBCxcu6K2vU6cOAMDe3t4UZelJTU1Fr1698NFHHxXaVq1atSJfc/bsWRw8eBCHDh3C1KlT5fUajQbr1q3D6NGjS/Xe3bt3x40bN7B161bs2LEDXbp0wdixY/HJJ5+U7cNUAI6QWSB5XIx5jIiIiMiieHh44Omnn8aXX36JtLS0EvsGBwfj1q1buHXrlrzu7NmzSExMREhIiNxn//79eq/bv3+/vL1Bgwa4deuW3kQghw8fLvF9W7RogTNnzqB27dqoV6+eXivuurfly5ejffv2OHHiBKKjo+U2adIkLF++XK715MmT8qmZAHDw4MFC+/Ly8sKwYcOwZs0afPbZZ1i6dGmJ9ZoaA5lFejhCJpjIiIiIiCzN119/jdzcXISGhmL9+vU4d+4cLly4gDVr1uD8+fNQKpUAgPDwcDRu3BiDBw/GsWPHcOjQIbz00kvo0KGDfI3V5MmTsXLlSixevBiXLl3CwoULsXHjRrz11lsAgKeffhp169bFsGHDcPLkSezfvx9vv/02gLzJQwoaO3Ys4uPjMWjQIBw+fBhXrlzB9u3bMWLECGg0mkL9c3JysHr1agwaNAiNGjXSay+//DKioqJw5swZvPjii1AoFBg9ejTOnj2LrVu3Fhr5mjVrFn777TdcvnwZZ86cwebNmxEcHGy07748MJBZMuYxIiIiIotTt25dHD9+HOHh4Zg+fTqaNm2K0NBQfPHFF3jrrbfw/vvvA5AC02+//QY3Nze0b98e4eHhqFOnDtavXy/vq0+fPli0aBE++eQTNGzYEN988w1WrFiBjh07AgCUSiU2bdqE1NRUPPHEE3j55ZcxY8YMANC7lis/Pz8/7N+/HxqNBl27dkXjxo0xYcIEuLq6wsqqcPz4/fff8eDBA/Tt27fQtuDgYAQHB2P58uVwcnLCH3/8gVOnTqF58+aYMWNGodMibW1tMX36dDRp0gTt27eHUqnEunXryvQ9VxSFEAbe+MDCffXVV/j4448RExODpk2b4osvvnjkhYsAkJycDBcXFyQlJUGtVldApcULfKknLtXdiq7XX8b2FctMWgsRERGROcrMzMS1a9cQEBBQbLCgou3fvx9PPfUULl++jLp165q6HJMp6RgyJBtwhCyf9evXY9KkSXjnnXdw7NgxNG3aFBEREYiLizN1aUREREREJvHrr79ix44duH79Ov7++2+88soraNu2bZUOY8bEQJbPwoULMXr0aIwYMQIhISFYsmQJHBwcirxLeGVQzGm9RERERESllpKSgrFjxyIoKAjDhw/HE088gd9++83UZVkMTnv/UHZ2No4ePYrp06fL66ysrBAeHo7IyMhC/bOysuR7PADSsKT50J2FykRGRERERI/npZdewksvvWTqMiwWR8geun//PjQaDXx8fPTW+/j4ICYmplD/uXPnwsXFRW75b7hnPhjIiIiIiIjMGQNZGU2fPh1JSUlyy39/B1MT8o2hOV8LEREREZE54ymLD3l6ekKpVOrd9A4AYmNj4evrW6i/SqWCSqWqqPLKiCNkRERERETmjCNkD9na2qJly5bYuXOnvE6r1WLnzp0ICwszYWWG4xVkRERERESVA0fI8pk0aRKGDRuG0NBQtGrVCp999hnS0tIwYsQIU5dGREREREQWiIEsnxdeeAH37t3DrFmzEBMTg2bNmmHbtm2FJvogIiIiIiIyBp6yWMC4ceNw48YNZGVlISoqCq1btzZ1SQaTJ/XgOYtEREREZER79uyBQqFAYmJiub7PypUr4erqWq7voTN8+HD06dOnQt6rKAxklkwwkRERERFZmuHDh0OhUBRqly9fNnVpZuHHH3+EUqnE2LFjTV1KqTCQWTAFh8iIiIiILFK3bt1w9+5dvRYQEGDqsszC8uXLMWXKFPz444/IzMw0dTmPxEBmiRScZ5GIiIjIUEIAaWkV30QZbh2rUqng6+ur15RKJRYuXIjGjRvD0dER/v7+eO2115Camqr32v3796Njx45wcHCAm5sbIiIikJCQAECaZXzu3LkICAiAvb09mjZtip9//rnQ++/fvx9NmjSBnZ0d2rRpg9OnT+tt/+WXX9CwYUOoVCrUrl0bCxYs0NuekJCAl156CW5ubnBwcED37t1x6dKlYj/vvXv3EBoair59+yIrK6vYfteuXcOBAwcwbdo0BAYGYuPGjXrbNRoNJk2aBFdXV3h4eGDKlCkQBf4AP//8Mxo3bgx7e3t4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iY+Px9mzZxEaGqq3/vjx43jppZfQoUMHuLi4oFOnTvjoo49gZ2en169Vq1b4999/S/35iYio4lmbugAiIiJj2Lx5M5ycnAAAaWlpqFatGjZv3gwrq9L/2+OiRYvQrVs3TJkyBQAQGBiIAwcOYNu2bXKfL774AqNGjcKIESMAALNmzcJff/2F1NRUuc8777yDBQsW4LnnngMgjYidPXsW33zzDYYNGwYvLy8AgIeHB3x9fYut5+bNmxBCwM/PT29927ZtsWLFCjRt2rTEz+Pn54dbt25Bq9Ua9D0QEVHF4X+diYjIInTq1AnR0dGIjo7GoUOHEBERge7du+PGjRul3se5c+fQunVrvXVhYWF6zy9cuIBWrVrprcv/PC0tDVeuXMGoUaPg5OQktw8++ABXrlwx6DNlZGQAQKGRr4ULF+KFF17AxIkT8f3336NZs2ZYsmRJodfb29tDq9UiKyvLoPclIqKKwxEyIiKyCI6OjqhXr578/Ntvv4WLiwuWLVuGDz74QB4hEkLIfXJycoxeh26kbNmyZYXCnVKpNGhfnp6eAICEhAR5VA2QPuucOXMwZ84c9OnTB927d8fEiRNhZWWlNz1+fHw8HB0dYW9vX9aPQ0RE5YwjZEREZJEUCgWsrKzkUSZdoLl7967cp+C088HBwYiKitJbd/DgQb3nDRo0wOHDh/XW5X/u4+MDPz8/XL16FfXq1dNrusk8bG1tAQAajabEz1C3bl2o1WqcPXu22D6urq743//+h+7duxe6Xuz06dNo3rx5ie9BRESmxUBGREQWISsrCzExMYiJicG5c+fw+uuvIzU1VZ6hsF69evD398e7776LS5cuYcuWLViwYIHePt544w1s27YNn3zyCS5duoQvv/xS7/oxAHj99dexfPlyrFq1CpcuXcIHH3yAkydPQqFQyH1mz56NuXPn4vPPP8fFixdx6tQprFixAgsXLgQAeHt7w97eHtu2bUNsbCySkpKK/ExWVlYIDw/Hvn379NZPnDgRe/fuRVJSEjQaDXbv3o29e/eiZcuWev3+/fdfdO3atWxfKBERVQxBRERUyQ0bNkwAkJuzs7N44oknxM8//6zXb9++faJx48bCzs5OtGvXTmzYsEEAENeuXZP7LF++XNSoUUPY29uLXr16iU8++US4uLjo7ee9994Tnp6ewsnJSYwcOVK88cYbok2bNnp91q5dK5o1ayZsbW2Fm5ubaN++vdi4caO8fdmyZcLf319YWVmJDh06FPvZtm7dKqpXry40Go28buHChaJFixbC2dlZWFlZiRo1aojJkyeL3Nxcuc/t27eFjY2NuHXrlgHfJBERVTSFEPlOpiciIiKDPf300/D19cXq1auNvm8hBFq3bo2JEydi0KBBhbYPHz4cK1euLLR+6tSpSEhIwNKlS41eExERGQ8n9SAiIjJAeno6lixZgoiICCiVSvz444/4+++/sWPHjnJ5P4VCgaVLl+LUqVMGvc7b2xuTJk0ql5qIiMh4OEJGRERkgIyMDPTq1QvHjx9HZmYmGjRogLffflu+5xgREZEhGMiIiIiIiIhMhLMsEhERERERmQgDGRERERERkYkwkBEREREREZkIAxkREREREZGJMJARERERERGZCAMZERERERGRiTCQERERERERmQgDGRERERERkYkwkBEREREREZnI/wMSc07PAL/NuQAAAABJRU5ErkJggg==\n"
62 | },
63 | "metadata": {}
64 | }
65 | ],
66 | "source": [
67 | "import matplotlib.pyplot as plt\n",
68 | "import numpy as np\n",
69 | "np.random.seed(0)\n",
70 | "\n",
71 | "TOTAL_BUDGET = 100_000\n",
72 | "\n",
73 | "# Alpha and beta constants\n",
74 | "alphas = np.array([-9453.72, -8312.84, -7371.33])\n",
75 | "betas = np.array([8256.21, 7764.20, 7953.36])\n",
76 | "\n",
77 | "# Linearly spaced numbers\n",
78 | "x = np.linspace(1, TOTAL_BUDGET, TOTAL_BUDGET)\n",
79 | "\n",
80 | "# Plot the response curves\n",
81 | "fig = plt.figure(figsize=(10, 5), dpi=100)\n",
82 | "plt.plot(x, alphas[0] + betas[0] * np.log(x), color='red', label='Google Ads')\n",
83 | "plt.plot(x, alphas[1] + betas[1] * np.log(x), color='blue', label='Facebook Ads')\n",
84 | "plt.plot(x, alphas[2] + betas[2] * np.log(x), color='green', label='Twitter Ads')\n",
85 | "plt.xlabel('Budget ($)')\n",
86 | "plt.ylabel('Returns ($)') \n",
87 | "plt.legend()\n",
88 | "plt.show()"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "source": [
94 | "## Greedy algorithm"
95 | ],
96 | "metadata": {
97 | "id": "T8s69rGuLC2A"
98 | }
99 | },
100 | {
101 | "cell_type": "code",
102 | "source": [
103 | "def greedy_optimization(TOTAL_BUDGET, alphas, betas, num_iterations=1_000):\n",
104 | " # Initialize the budget allocation and the best objective value\n",
105 | " google_budget = facebook_budget = twitter_budget = TOTAL_BUDGET / 3\n",
106 | " obj = alphas[0] + betas[0] * np.log(google_budget) + alphas[1] + betas[1] * np.log(facebook_budget) + alphas[2] + betas[2] * np.log(twitter_budget)\n",
107 | "\n",
108 | " for _ in range(num_iterations):\n",
109 | " # Generate a new random allocation\n",
110 | " random_allocation = np.random.dirichlet(np.ones(3)) * TOTAL_BUDGET\n",
111 | " google_budget_new, facebook_budget_new, twitter_budget_new = random_allocation\n",
112 | "\n",
113 | " # Calculate the new objective value\n",
114 | " new_obj = alphas[0] + betas[0] * np.log(google_budget_new) + alphas[1] + betas[1] * np.log(facebook_budget_new) + alphas[2] + betas[2] * np.log(twitter_budget_new)\n",
115 | "\n",
116 | " # If the new allocation improves the objective value, keep it\n",
117 | " if new_obj > obj:\n",
118 | " google_budget, facebook_budget, twitter_budget = google_budget_new, facebook_budget_new, twitter_budget_new\n",
119 | " obj = new_obj\n",
120 | "\n",
121 | " # Return the best allocation and the corresponding objective value\n",
122 | " return (google_budget, facebook_budget, twitter_budget), obj"
123 | ],
124 | "metadata": {
125 | "id": "z9mbbYsaFflz"
126 | },
127 | "execution_count": null,
128 | "outputs": []
129 | },
130 | {
131 | "cell_type": "code",
132 | "source": [
133 | "%%time\n",
134 | "\n",
135 | "# Run the greedy optimization\n",
136 | "(best_google, best_facebook, best_twitter), obj = greedy_optimization(TOTAL_BUDGET, alphas, betas)\n",
137 | "\n",
138 | "# Print the result\n",
139 | "print('='*59 + '\\n' + ' '*24 + 'Solution' + ' '*24 + '\\n' + '='*59)\n",
140 | "print(f'Returns = ${round(obj):,}\\n')\n",
141 | "print('Marketing allocation:')\n",
142 | "print(f' - Google Ads = ${round(best_google):,}')\n",
143 | "print(f' - Facebook Ads = ${round(best_facebook):,}')\n",
144 | "print(f' - Twitter Ads = ${round(best_twitter):,}')"
145 | ],
146 | "metadata": {
147 | "colab": {
148 | "base_uri": "https://localhost:8080/"
149 | },
150 | "id": "pRWUe8juMpzS",
151 | "outputId": "a7921e11-e61c-4b6b-a5b9-42ae1fcb1357"
152 | },
153 | "execution_count": null,
154 | "outputs": [
155 | {
156 | "output_type": "stream",
157 | "name": "stdout",
158 | "text": [
159 | "===========================================================\n",
160 | " Solution \n",
161 | "===========================================================\n",
162 | "Returns = $224,534\n",
163 | "\n",
164 | "Marketing allocation:\n",
165 | " - Google Ads = $35,476\n",
166 | " - Facebook Ads = $31,722\n",
167 | " - Twitter Ads = $32,802\n",
168 | "CPU times: user 39.8 ms, sys: 0 ns, total: 39.8 ms\n",
169 | "Wall time: 40.7 ms\n"
170 | ]
171 | }
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "source": [
177 | "## Nonlinear optimization"
178 | ],
179 | "metadata": {
180 | "id": "DGaY8dinJb1t"
181 | }
182 | },
183 | {
184 | "cell_type": "code",
185 | "source": [
186 | "import cvxpy as cp\n",
187 | "\n",
188 | "# Variables\n",
189 | "google = cp.Variable(pos=True)\n",
190 | "facebook = cp.Variable(pos=True)\n",
191 | "twitter = cp.Variable(pos=True)\n",
192 | "\n",
193 | "# Constraint\n",
194 | "constraint = [google + facebook + twitter <= TOTAL_BUDGET]\n",
195 | "\n",
196 | "# Objective\n",
197 | "obj = cp.Maximize(alphas[0] + betas[0] * cp.log(google)\n",
198 | " + alphas[1] + betas[1] * cp.log(facebook)\n",
199 | " + alphas[2] + betas[2] * cp.log(twitter))"
200 | ],
201 | "metadata": {
202 | "id": "_Whl0tzJJfbF"
203 | },
204 | "execution_count": null,
205 | "outputs": []
206 | },
207 | {
208 | "cell_type": "code",
209 | "source": [
210 | "%%time\n",
211 | "\n",
212 | "# Solve\n",
213 | "prob = cp.Problem(obj, constraint)\n",
214 | "prob.solve(solver='ECOS', verbose=False)\n",
215 | "\n",
216 | "# Print solution\n",
217 | "print('='*59 + '\\n' + ' '*24 + 'Solution' + ' '*24 + '\\n' + '='*59)\n",
218 | "print(f'Status = {prob.status}')\n",
219 | "print(f'Returns = ${round(prob.value):,}\\n')\n",
220 | "print('Marketing allocation:')\n",
221 | "print(f' - Google Ads = ${round(google.value):,}')\n",
222 | "print(f' - Facebook Ads = ${round(facebook.value):,}')\n",
223 | "print(f' - Twitter Ads = ${round(twitter.value):,}')"
224 | ],
225 | "metadata": {
226 | "colab": {
227 | "base_uri": "https://localhost:8080/"
228 | },
229 | "id": "ZQbNrSMDEMV3",
230 | "outputId": "89a0539a-cff5-4609-9048-56fccfd1b3ac"
231 | },
232 | "execution_count": null,
233 | "outputs": [
234 | {
235 | "output_type": "stream",
236 | "name": "stdout",
237 | "text": [
238 | "===========================================================\n",
239 | " Solution \n",
240 | "===========================================================\n",
241 | "Status = optimal\n",
242 | "Returns = $224,540\n",
243 | "\n",
244 | "Marketing allocation:\n",
245 | " - Google Ads = $34,439\n",
246 | " - Facebook Ads = $32,386\n",
247 | " - Twitter Ads = $33,175\n",
248 | "CPU times: user 28.6 ms, sys: 31 µs, total: 28.7 ms\n",
249 | "Wall time: 56 ms\n"
250 | ]
251 | }
252 | ]
253 | },
254 | {
255 | "cell_type": "code",
256 | "source": [
257 | "# Plot the functions and the results\n",
258 | "fig = plt.figure(figsize=(10, 5), dpi=100)\n",
259 | "\n",
260 | "plt.plot(x, alphas[0] + betas[0] * np.log(x), color='red', label='Google Ads')\n",
261 | "plt.plot(x, alphas[1] + betas[1] * np.log(x), color='blue', label='Facebook Ads')\n",
262 | "plt.plot(x, alphas[2] + betas[2] * np.log(x), color='green', label='Twitter Ads')\n",
263 | "\n",
264 | "# Plot optimal points\n",
265 | "plt.scatter([google.value, facebook.value, twitter.value],\n",
266 | " [alphas[0] + betas[0] * np.log(google.value),\n",
267 | " alphas[1] + betas[1] * np.log(facebook.value),\n",
268 | " alphas[2] + betas[2] * np.log(twitter.value)],\n",
269 | " marker=\"+\", color='black', zorder=10)\n",
270 | "\n",
271 | "plt.xlabel('Budget ($)')\n",
272 | "plt.ylabel('Returns ($)') \n",
273 | "plt.legend()\n",
274 | "plt.show()"
275 | ],
276 | "metadata": {
277 | "colab": {
278 | "base_uri": "https://localhost:8080/",
279 | "height": 465
280 | },
281 | "id": "OqTb8GSHJlMg",
282 | "outputId": "81e993dc-9bc8-496a-aaea-2bd672339eeb"
283 | },
284 | "execution_count": null,
285 | "outputs": [
286 | {
287 | "output_type": "display_data",
288 | "data": {
289 | "text/plain": [
290 | ""
291 | ],
292 | "image/png": "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wdnZWb5ey8XFBfb29nBxccHIkSMxceJEuLu7Q61W480330RYWBjatGkDAOjatStCQkIwZMgQzJs3DzExMXj33XcxZswYeQTr9ddfx1dffYXJkydjxIgR2LVrF3766Sds2bJFrmXixIkYOnQoQkND0apVK3z++edIS0vD8OHDK/6LeUy6ae+teMoiEREREZFZM2kgW7RoEQCgY8eOeutXrFiBYcOGAQA+++wzWFlZoV+/fsjKykJERAS++eYbua9SqcTmzZsxevRohIWFwdHREUOHDsUHH3wg9wkICMCWLVswYcIELFy4EDVq1MB3332HiIgIuc+LL76Ie/fuYebMmYiJiUGzZs2wbdu2QhN9VAbyNWSc1IOIiIiIyKyZ1X3IKjNzug/ZM6+PxJZqy1HnwrO48sNvJq2FiIiIiKiqqbT3ISPjkKe955+XiIiIiMis8Re7BdLwGjIiIiIiokqBgcwCaXkfMiIiIiKiSoGBzAJx2nsiIiIiosqBv9gtkBYPA5mCI2REREREROaMgcwC6ebNZBwjIiIiIjJvDGQWSKsLZExkRERERERmjYHMAulGyHjKIhERERGReWMgs0B5t/rmPb+JiIiIiMwZA5kFEg+DGAfIiIiIiIjMGwOZBRJCSmK8MTQRERERkXljILNECp6qSERERERUGTCQWSDBPEZEREREVCkwkFkwnrBIRERERGTeGMgskODsikRERERElQIDmUXjGBkRERERkTljILNIHCEjIiIiIqoMGMgskHg4MqbgCBkRERERkVljILNIosAjERERERGZIwYyC8QYRkRERERUOTCQWTCeskhEREREZN4YyCyQ4J2hiYiIiIgqBQYyC8YRMiIiIiIi88ZAZokUHCEjIiIiIqoMGMgsEfMYEREREVGlwEBmwRQKnrJIRERERGTOGMgskGAOIyIiIiKqFBjILBhzGRERERGReWMgs0Cc9p6IiIiIqHJgICMiIiIiIjIRBjILxvuQERERERGZNwYyC8QTFomIiIiIKgcGMgvGETIiIiIiIvPGQGaBBMfIiIiIiIgqBQYyIiIiIiIiE2Egs2A8ZZGIiIiIyLwxkFkgnrJIRERERFQ5MJBZMI6PERERERGZNwYyCySPkDGRERERERGZNQYyIiIiIiIiE2Egs2Cc1IOIiIiIyLwxkBEREREREZkIA5kF4/gYEREREZF5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\n"
293 | },
294 | "metadata": {}
295 | }
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "source": [
301 | "## Comparison"
302 | ],
303 | "metadata": {
304 | "id": "oqg32ZuZJhKq"
305 | }
306 | },
307 | {
308 | "cell_type": "code",
309 | "source": [
310 | "%%time\n",
311 | "\n",
312 | "# List to store the best objective value for each number of iterations\n",
313 | "best_obj_list = []\n",
314 | "\n",
315 | "# Range of number of iterations to test\n",
316 | "num_iterations_range = np.logspace(0, 6, 20).astype(int)\n",
317 | "\n",
318 | "# Run the greedy algorithm for each number of iterations and store the best objective value\n",
319 | "for num_iterations in num_iterations_range:\n",
320 | " _, best_obj = greedy_optimization(TOTAL_BUDGET, alphas, betas, num_iterations)\n",
321 | " best_obj_list.append(best_obj)"
322 | ],
323 | "metadata": {
324 | "colab": {
325 | "base_uri": "https://localhost:8080/"
326 | },
327 | "id": "KtsErbkTGys8",
328 | "outputId": "d2ba20aa-fa86-47d4-ed50-d0e9fb857149"
329 | },
330 | "execution_count": null,
331 | "outputs": [
332 | {
333 | "output_type": "stream",
334 | "name": "stdout",
335 | "text": [
336 | "CPU times: user 1min, sys: 2.37 s, total: 1min 2s\n",
337 | "Wall time: 1min 14s\n"
338 | ]
339 | }
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "source": [
345 | "# Plot the results\n",
346 | "plt.figure(figsize=(10, 5), dpi=100)\n",
347 | "plt.ticklabel_format(useOffset=False)\n",
348 | "plt.plot(num_iterations_range, best_obj_list, label='Greedy algorithm')\n",
349 | "plt.axhline(y=prob.value, color='r', linestyle='--', label='Optimal solution (CVXPY)')\n",
350 | "plt.xlabel('Number of iterations')\n",
351 | "plt.xticks(num_iterations_range)\n",
352 | "plt.xscale(\"log\")\n",
353 | "plt.ylabel('Best returns ($)')\n",
354 | "plt.title('Best returns found by the greedy algorithm for different numbers of iterations')\n",
355 | "plt.legend()\n",
356 | "plt.show()"
357 | ],
358 | "metadata": {
359 | "colab": {
360 | "base_uri": "https://localhost:8080/",
361 | "height": 492
362 | },
363 | "id": "Yx7Kvex1HUlU",
364 | "outputId": "f1803df4-bee0-4c10-cebe-85ff997fd73d"
365 | },
366 | "execution_count": null,
367 | "outputs": [
368 | {
369 | "output_type": "display_data",
370 | "data": {
371 | "text/plain": [
372 | ""
373 | ],
374 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2wAAAHbCAYAAAC3PBm1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAADA5UlEQVR4nOzde1zT9f4H8NcubAwYQ4EpCohCEVc101JPhppammk3f1mmlpUl6tHseLLOSbNjVFra6YKVpWV6LDWqY8dr3sqyTLNAyxTvXERAGNfBtu/vj/H9wuTihoNt8Ho+Hnvovvvs+/1sbN/tvc/78/7IBEEQQERERERERG5H7uoOEBERERERUcMYsBEREREREbkpBmxERERERERuigEbERERERGRm2LARkRERERE5KYYsBEREREREbkpBmxERERERERuigEbERERERGRm2LARkRERERE5KYYsBFRow4cOIABAwbA19cXMpkMhw8fdnWXGrRgwQLIZLIrtktKSkJ8fHwr9KhhkydPhp+fn8uO745Onz4NmUyGVatWtepxd+/eDZlMht27d7fqcUWOPG6x7ZIlS1q+Y40oLS3Fo48+is6dO0Mmk2HWrFku6YdMJsOCBQuk66tWrYJMJsPp06dt2i1evBg9evSAQqFAr169AAAmkwlz585FWFgY5HI5xo4d22r9bo/a4vmuoddVQyZPnoyIiIhW65czJCUlISkpydXdoEYwYKNWJX641r3o9XoMHjwYmzdvbrHjlpeXY8GCBa365ex///ufzRcLT1NdXY377rsPhYWFWLp0KVavXo1u3bq5ultuzxWvNWob3Pmc8dJLL2HVqlV48sknsXr1ajz00EOu7lKjtm3bhrlz52LgwIFYuXIlXnrpJQDAhx9+iMWLF+Pee+/FRx99hNmzZ7u4p41z59dCe9XY68oe7vK5cPToUSxYsKDeDxzk/pSu7gC1TwsXLkT37t0hCAIuXLiAVatWYeTIkfjvf/+LO+64w+nHKy8vxwsvvAAArfYL0v/+9z+8/fbbHvuhm5mZiTNnzuD999/Ho48+6urueAxXvNbI83Tr1g0VFRXw8vKStrnzOWPnzp246aabMH/+fFd3xcZDDz2E+++/H2q1Wtq2c+dOyOVyfPDBB1CpVDbbu3btiqVLl7qiqw5x59dCe9XY66oh77//PiwWi3TdXT4Xjh49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\n"
375 | },
376 | "metadata": {}
377 | }
378 | ]
379 | }
380 | ]
381 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🥇 Linear Programming Course
2 |
3 | Series of articles about **linear programming** and **mathematical optimization**.
4 |
5 | In this course, you'll learn to use **Google OR-Tools** in order to **solve optimization and satisfiability problems** by building **mathematical models** in Python.
6 |
7 | | Chapter | Description | Article | Notebook |
8 | |---------------------------------------|-------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
9 | | 1. Introduction to Linear Programming | Learn to optimize an army with a simple problem using Google OR-Tools. | [Article](https://towardsdatascience.com/introduction-to-linear-programming-in-python-9261e7eb44b) |
|
10 | | 2. Integer vs. Linear Programming | Understand the difference between linear vs. other types of programming. | [Article](https://towardsdatascience.com/integer-programming-vs-linear-programming-in-python-f1be5bb4e60e) |
|
11 | | 3. Constraint Programming | Introduction to Constraint Programming with CP-SAT and comparison with LP. | [Article](https://towardsdatascience.com/constraint-programming-67ac16fa0c81) |
|
12 | | 4. Nonlinear Programming | Find the best allocation for marketing channels with diminishing returns. | [Article](https://mlabonne.github.io/blog/nonlinearprogramming) |
|
13 |
14 | ## 👨💻 Contact
15 |
16 | * Email: labonne.maxime@gmail.com
17 | * Twitter: @maximelabonne
18 | * Medium: https://medium.com/@mlabonne
19 | * Blog: https://mlabonne.github.io/blog/
20 |
21 | Let's connect on [Twitter](https://twitter.com/maximelabonne) and [Medium](https://medium.com/@mlabonne)!
22 |
--------------------------------------------------------------------------------
/images/colab.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------