├── Airbus Cargo.ipynb
├── Airland.ipynb
├── Army (max queens)-V1.ipynb
├── Box packing-V1.ipynb
├── EX MTZ TSP-Ireland.ipynb
├── Facility allocation -twitter.ipynb
├── Friends v2.ipynb
├── Gcoloring Chess-toshare .ipynb
├── Gcoloring.ipynb
├── Ireland.dat
├── June challenge.ipynb
├── Linkedin EX26 (Curve fitting).ipynb
├── Multi line regression-V2.ipynb
├── Multi line regression-V3.ipynb
├── MultilineregressionV3.ipynb
├── Rectangle in a box with Obstacles .ipynb
├── ShiftScheduling.ipynb
├── Sparse.ipynb
├── Steiner Tree.ipynb
├── TEST. Facility allocation Ireland V2.ipynb
├── ie.csv
└── paper company Linkedin.ipynb
/Airland.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 42,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import pandas as pd"
12 | ]
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 45,
17 | "metadata": {},
18 | "outputs": [
19 | {
20 | "data": {
21 | "text/html": [
22 | "
\n",
23 | "\n",
36 | "
\n",
37 | " \n",
38 | " \n",
39 | " | \n",
40 | " a | \n",
41 | " s | \n",
42 | " t | \n",
43 | " f | \n",
44 | " ep | \n",
45 | " tp | \n",
46 | "
\n",
47 | " \n",
48 | " \n",
49 | " \n",
50 | " 0 | \n",
51 | " 54 | \n",
52 | " 129 | \n",
53 | " 155 | \n",
54 | " 559 | \n",
55 | " 10.0 | \n",
56 | " 10.0 | \n",
57 | "
\n",
58 | " \n",
59 | " 1 | \n",
60 | " 120 | \n",
61 | " 195 | \n",
62 | " 258 | \n",
63 | " 744 | \n",
64 | " 10.0 | \n",
65 | " 10.0 | \n",
66 | "
\n",
67 | " \n",
68 | " 2 | \n",
69 | " 14 | \n",
70 | " 89 | \n",
71 | " 98 | \n",
72 | " 510 | \n",
73 | " 30.0 | \n",
74 | " 30.0 | \n",
75 | "
\n",
76 | " \n",
77 | " 3 | \n",
78 | " 21 | \n",
79 | " 96 | \n",
80 | " 106 | \n",
81 | " 521 | \n",
82 | " 30.0 | \n",
83 | " 30.0 | \n",
84 | "
\n",
85 | " \n",
86 | " 4 | \n",
87 | " 35 | \n",
88 | " 110 | \n",
89 | " 123 | \n",
90 | " 555 | \n",
91 | " 30.0 | \n",
92 | " 30.0 | \n",
93 | "
\n",
94 | " \n",
95 | " 5 | \n",
96 | " 45 | \n",
97 | " 120 | \n",
98 | " 135 | \n",
99 | " 576 | \n",
100 | " 30.0 | \n",
101 | " 30.0 | \n",
102 | "
\n",
103 | " \n",
104 | " 6 | \n",
105 | " 49 | \n",
106 | " 124 | \n",
107 | " 138 | \n",
108 | " 577 | \n",
109 | " 30.0 | \n",
110 | " 30.0 | \n",
111 | "
\n",
112 | " \n",
113 | " 7 | \n",
114 | " 51 | \n",
115 | " 126 | \n",
116 | " 140 | \n",
117 | " 573 | \n",
118 | " 30.0 | \n",
119 | " 30.0 | \n",
120 | "
\n",
121 | " \n",
122 | " 8 | \n",
123 | " 60 | \n",
124 | " 135 | \n",
125 | " 150 | \n",
126 | " 591 | \n",
127 | " 30.0 | \n",
128 | " 30.0 | \n",
129 | "
\n",
130 | " \n",
131 | " 9 | \n",
132 | " 85 | \n",
133 | " 160 | \n",
134 | " 180 | \n",
135 | " 657 | \n",
136 | " 30.0 | \n",
137 | " 30.0 | \n",
138 | "
\n",
139 | " \n",
140 | "
\n",
141 | "
"
142 | ],
143 | "text/plain": [
144 | " a s t f ep tp\n",
145 | "0 54 129 155 559 10.0 10.0\n",
146 | "1 120 195 258 744 10.0 10.0\n",
147 | "2 14 89 98 510 30.0 30.0\n",
148 | "3 21 96 106 521 30.0 30.0\n",
149 | "4 35 110 123 555 30.0 30.0\n",
150 | "5 45 120 135 576 30.0 30.0\n",
151 | "6 49 124 138 577 30.0 30.0\n",
152 | "7 51 126 140 573 30.0 30.0\n",
153 | "8 60 135 150 591 30.0 30.0\n",
154 | "9 85 160 180 657 30.0 30.0"
155 | ]
156 | },
157 | "execution_count": 45,
158 | "metadata": {},
159 | "output_type": "execute_result"
160 | }
161 | ],
162 | "source": [
163 | "df = pd.read_csv(\"plane.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
164 | "df"
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": 51,
170 | "metadata": {},
171 | "outputs": [
172 | {
173 | "data": {
174 | "text/html": [
175 | "\n",
176 | "\n",
189 | "
\n",
190 | " \n",
191 | " \n",
192 | " | \n",
193 | " 1 | \n",
194 | " 2 | \n",
195 | " 3 | \n",
196 | " 4 | \n",
197 | " 5 | \n",
198 | " 6 | \n",
199 | " 7 | \n",
200 | " 8 | \n",
201 | " 9 | \n",
202 | " 10 | \n",
203 | "
\n",
204 | " \n",
205 | " \n",
206 | " \n",
207 | " 0 | \n",
208 | " 99999 | \n",
209 | " 3 | \n",
210 | " 15 | \n",
211 | " 15 | \n",
212 | " 15 | \n",
213 | " 15 | \n",
214 | " 15 | \n",
215 | " 15 | \n",
216 | " 15 | \n",
217 | " 15 | \n",
218 | "
\n",
219 | " \n",
220 | " 1 | \n",
221 | " 3 | \n",
222 | " 99999 | \n",
223 | " 15 | \n",
224 | " 15 | \n",
225 | " 15 | \n",
226 | " 15 | \n",
227 | " 15 | \n",
228 | " 15 | \n",
229 | " 15 | \n",
230 | " 15 | \n",
231 | "
\n",
232 | " \n",
233 | " 2 | \n",
234 | " 15 | \n",
235 | " 15 | \n",
236 | " 99999 | \n",
237 | " 8 | \n",
238 | " 8 | \n",
239 | " 8 | \n",
240 | " 8 | \n",
241 | " 8 | \n",
242 | " 8 | \n",
243 | " 8 | \n",
244 | "
\n",
245 | " \n",
246 | " 3 | \n",
247 | " 15 | \n",
248 | " 15 | \n",
249 | " 8 | \n",
250 | " 99999 | \n",
251 | " 8 | \n",
252 | " 8 | \n",
253 | " 8 | \n",
254 | " 8 | \n",
255 | " 8 | \n",
256 | " 8 | \n",
257 | "
\n",
258 | " \n",
259 | " 4 | \n",
260 | " 15 | \n",
261 | " 15 | \n",
262 | " 8 | \n",
263 | " 8 | \n",
264 | " 99999 | \n",
265 | " 8 | \n",
266 | " 8 | \n",
267 | " 8 | \n",
268 | " 8 | \n",
269 | " 8 | \n",
270 | "
\n",
271 | " \n",
272 | " 5 | \n",
273 | " 15 | \n",
274 | " 15 | \n",
275 | " 8 | \n",
276 | " 8 | \n",
277 | " 8 | \n",
278 | " 99999 | \n",
279 | " 8 | \n",
280 | " 8 | \n",
281 | " 8 | \n",
282 | " 8 | \n",
283 | "
\n",
284 | " \n",
285 | " 6 | \n",
286 | " 15 | \n",
287 | " 15 | \n",
288 | " 8 | \n",
289 | " 8 | \n",
290 | " 8 | \n",
291 | " 8 | \n",
292 | " 99999 | \n",
293 | " 8 | \n",
294 | " 8 | \n",
295 | " 8 | \n",
296 | "
\n",
297 | " \n",
298 | " 7 | \n",
299 | " 15 | \n",
300 | " 15 | \n",
301 | " 8 | \n",
302 | " 8 | \n",
303 | " 8 | \n",
304 | " 8 | \n",
305 | " 8 | \n",
306 | " 99999 | \n",
307 | " 8 | \n",
308 | " 8 | \n",
309 | "
\n",
310 | " \n",
311 | " 8 | \n",
312 | " 15 | \n",
313 | " 15 | \n",
314 | " 8 | \n",
315 | " 8 | \n",
316 | " 8 | \n",
317 | " 8 | \n",
318 | " 8 | \n",
319 | " 8 | \n",
320 | " 99999 | \n",
321 | " 8 | \n",
322 | "
\n",
323 | " \n",
324 | " 9 | \n",
325 | " 15 | \n",
326 | " 15 | \n",
327 | " 8 | \n",
328 | " 8 | \n",
329 | " 8 | \n",
330 | " 8 | \n",
331 | " 8 | \n",
332 | " 8 | \n",
333 | " 8 | \n",
334 | " 99999 | \n",
335 | "
\n",
336 | " \n",
337 | "
\n",
338 | "
"
339 | ],
340 | "text/plain": [
341 | " 1 2 3 4 5 6 7 8 9 10\n",
342 | "0 99999 3 15 15 15 15 15 15 15 15\n",
343 | "1 3 99999 15 15 15 15 15 15 15 15\n",
344 | "2 15 15 99999 8 8 8 8 8 8 8\n",
345 | "3 15 15 8 99999 8 8 8 8 8 8\n",
346 | "4 15 15 8 8 99999 8 8 8 8 8\n",
347 | "5 15 15 8 8 8 99999 8 8 8 8\n",
348 | "6 15 15 8 8 8 8 99999 8 8 8\n",
349 | "7 15 15 8 8 8 8 8 99999 8 8\n",
350 | "8 15 15 8 8 8 8 8 8 99999 8\n",
351 | "9 15 15 8 8 8 8 8 8 8 99999"
352 | ]
353 | },
354 | "execution_count": 51,
355 | "metadata": {},
356 | "output_type": "execute_result"
357 | }
358 | ],
359 | "source": [
360 | "dfD = pd.read_csv(\"planedelay.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
361 | "dfD"
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "execution_count": 57,
367 | "metadata": {},
368 | "outputs": [],
369 | "source": [
370 | "model = AbstractModel()\n",
371 | "model.N =Param(mutable=True, initialize=len(df)) \n",
372 | "model.i = RangeSet(1,model.N)\n",
373 | "model.j=Set(initialize=model.i)\n",
374 | "def limPlane(model,i):\n",
375 | " return (df.loc[i-1,'s'],df.loc[i-1,'f'])\n",
376 | "model.x = Var(model.i,domain=PositiveReals, bounds=limPlane)\n",
377 | "\n",
378 | "model.EN = Var(model.i,domain=PositiveReals, bounds=(0,500))\n",
379 | "model.TN = Var(model.i,domain=PositiveReals, bounds=(0,500))\n",
380 | "\n",
381 | "model.U = Var(model.i,model.j,domain=Binary)\n",
382 | "\n",
383 | "def rule_D(model,i,j):\n",
384 | " return dfD.iloc[i-1,j-1]\n",
385 | "model.D=Param(model.i,model.j, initialize=rule_D, mutable=True)\n",
386 | "model.ep = Param(model.i, mutable=True)\n",
387 | "model.tp = Param(model.i, mutable=True)\n",
388 | "model.target = Param(model.i, mutable=True)\n",
389 | "\n",
390 | "def rue_c1(model,i):\n",
391 | " return -model.x[i]+model.target[i]<=model.EN[i]\n",
392 | "model.C1 =Constraint(model.i,rule=rue_c1)\n",
393 | "\n",
394 | "def rue_c2(model,i):\n",
395 | " return model.x[i]-model.target[i]<=model.TN[i]\n",
396 | "model.C2 =Constraint(model.i, rule=rue_c2)\n",
397 | "\n",
398 | "def rue_c3(model,i,j):\n",
399 | " if i!=j:\n",
400 | " return model.x[i]+model.D[i,j]*model.U[i,j]- 1000*(1-model.U[i,j]) <=model.x[j] \n",
401 | " else:\n",
402 | " return Constraint.Skip \n",
403 | "model.C3 =Constraint(model.i,model.j, rule=rue_c3)\n",
404 | "\n",
405 | "def rue_c4(model,i,j):\n",
406 | " if i!=j:\n",
407 | " return model.U[i,j]+model.U[j,i]==1 \n",
408 | " else:\n",
409 | " return Constraint.Skip \n",
410 | "model.C4 =Constraint(model.i,model.j, rule=rue_c4)\n",
411 | "\n",
412 | "def rule_OF(model):\n",
413 | " return sum(model.ep[i]*model.EN[i]+model.tp[i]*model.TN[i] for i in model.i)\n",
414 | "model.obj = Objective(rule=rule_OF, sense=minimize)\n"
415 | ]
416 | },
417 | {
418 | "cell_type": "code",
419 | "execution_count": 58,
420 | "metadata": {},
421 | "outputs": [],
422 | "source": [
423 | "instance = model.create_instance()\n",
424 | "for i in instance.i:\n",
425 | " instance.target[i]=df.loc[i-1,'t']\n",
426 | " instance.ep[i]=df.loc[i-1,'ep']\n",
427 | " instance.tp[i]=df.loc[i-1,'tp']"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 59,
433 | "metadata": {},
434 | "outputs": [
435 | {
436 | "name": "stdout",
437 | "output_type": "stream",
438 | "text": [
439 | "OF= 700.0\n",
440 | "this is feasible and optimal\n"
441 | ]
442 | }
443 | ],
444 | "source": [
445 | "opt = SolverFactory('glpk')\n",
446 | "results=opt.solve(instance)\n",
447 | "print('OF= ',value(instance.obj))\n",
448 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
449 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
450 | " print (\"this is feasible and optimal\")\n",
451 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
452 | " print (\"do something about it? or exit?\")\n",
453 | "else:\n",
454 | " print (str(results.solver))"
455 | ]
456 | },
457 | {
458 | "cell_type": "code",
459 | "execution_count": 91,
460 | "metadata": {},
461 | "outputs": [
462 | {
463 | "data": {
464 | "image/png": "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\n",
465 | "text/plain": [
466 | ""
467 | ]
468 | },
469 | "metadata": {
470 | "needs_background": "light"
471 | },
472 | "output_type": "display_data"
473 | }
474 | ],
475 | "source": [
476 | "plt.figure(figsize=(10,8))\n",
477 | "for i in instance.i:\n",
478 | " #print(i,value(instance.x[i]),value(instance.EN[i]),value(instance.TN[i]) )\n",
479 | " plt.plot((df.loc[i-1,'s'],df.loc[i-1,'f']) ,(i,i),lw=5, c='grey', alpha=0.3)\n",
480 | " plt.scatter(value(instance.x[i]),i,marker='|', s=700, c='k')\n",
481 | " plt.scatter(value(instance.target[i]),i,marker='s',s=100)\n",
482 | "plt.xlim(80,280)\n",
483 | "plt.grid()\n",
484 | "plt.ylabel('Plane Number', fontweight='bold', fontsize=12)\n",
485 | "plt.xlabel('Landing Time', fontweight='bold', fontsize=12)\n",
486 | "plt.xticks(fontweight='bold', fontsize=12)\n",
487 | "plt.yticks([i for i in range(1,11)],fontweight='bold', fontsize=12)\n",
488 | "plt.rc('axes',edgecolor='w')\n"
489 | ]
490 | }
491 | ],
492 | "metadata": {
493 | "kernelspec": {
494 | "display_name": "Python 3",
495 | "language": "python",
496 | "name": "python3"
497 | },
498 | "language_info": {
499 | "codemirror_mode": {
500 | "name": "ipython",
501 | "version": 3
502 | },
503 | "file_extension": ".py",
504 | "mimetype": "text/x-python",
505 | "name": "python",
506 | "nbconvert_exporter": "python",
507 | "pygments_lexer": "ipython3",
508 | "version": "3.7.4"
509 | }
510 | },
511 | "nbformat": 4,
512 | "nbformat_minor": 4
513 | }
514 |
--------------------------------------------------------------------------------
/Box packing-V1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import pandas as pd\n",
12 | "import numpy as np \n",
13 | "import random"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 2,
19 | "metadata": {},
20 | "outputs": [
21 | {
22 | "data": {
23 | "text/html": [
24 | "\n",
25 | "\n",
38 | "
\n",
39 | " \n",
40 | " \n",
41 | " | \n",
42 | " | \n",
43 | " L | \n",
44 | " W | \n",
45 | "
\n",
46 | " \n",
47 | " \n",
48 | " \n",
49 | " 0 | \n",
50 | " pallet1 | \n",
51 | " 213 | \n",
52 | " 241 | \n",
53 | "
\n",
54 | " \n",
55 | " 1 | \n",
56 | " pallet2 | \n",
57 | " 256 | \n",
58 | " 279 | \n",
59 | "
\n",
60 | " \n",
61 | " 2 | \n",
62 | " pallet3 | \n",
63 | " 160 | \n",
64 | " 283 | \n",
65 | "
\n",
66 | " \n",
67 | " 3 | \n",
68 | " pallet4 | \n",
69 | " 121 | \n",
70 | " 188 | \n",
71 | "
\n",
72 | " \n",
73 | " 4 | \n",
74 | " pallet5 | \n",
75 | " 197 | \n",
76 | " 240 | \n",
77 | "
\n",
78 | " \n",
79 | " 5 | \n",
80 | " pallet6 | \n",
81 | " 179 | \n",
82 | " 289 | \n",
83 | "
\n",
84 | " \n",
85 | " 6 | \n",
86 | " pallet7 | \n",
87 | " 176 | \n",
88 | " 221 | \n",
89 | "
\n",
90 | " \n",
91 | " 7 | \n",
92 | " pallet8 | \n",
93 | " 122 | \n",
94 | " 285 | \n",
95 | "
\n",
96 | " \n",
97 | " 8 | \n",
98 | " pallet9 | \n",
99 | " 109 | \n",
100 | " 220 | \n",
101 | "
\n",
102 | " \n",
103 | " 9 | \n",
104 | " pallet10 | \n",
105 | " 120 | \n",
106 | " 200 | \n",
107 | "
\n",
108 | " \n",
109 | "
\n",
110 | "
"
111 | ],
112 | "text/plain": [
113 | " L W\n",
114 | "0 pallet1 213 241\n",
115 | "1 pallet2 256 279\n",
116 | "2 pallet3 160 283\n",
117 | "3 pallet4 121 188\n",
118 | "4 pallet5 197 240\n",
119 | "5 pallet6 179 289\n",
120 | "6 pallet7 176 221\n",
121 | "7 pallet8 122 285\n",
122 | "8 pallet9 109 220\n",
123 | "9 pallet10 120 200"
124 | ]
125 | },
126 | "execution_count": 2,
127 | "metadata": {},
128 | "output_type": "execute_result"
129 | }
130 | ],
131 | "source": [
132 | "df = pd.read_csv(\"box.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
133 | "df"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": 3,
139 | "metadata": {},
140 | "outputs": [],
141 | "source": [
142 | "M=1000\n",
143 | "model = AbstractModel()\n",
144 | "model.i = RangeSet(1,10)\n",
145 | "model.j = Set(initialize=model.i)\n",
146 | "model.v = RangeSet(1,4)\n",
147 | "\n",
148 | "def initvar(model):\n",
149 | " return 2000*random.random()\n",
150 | "\n",
151 | "def initvaB(model):\n",
152 | " return random.randint(0,1)\n",
153 | "\n",
154 | "model.xp = Var(model.i, initialize=initvar, bounds=(0,2000),domain=NonNegativeReals)\n",
155 | "model.yp = Var(model.i, initialize=initvar, bounds=(0,2000),domain=NonNegativeReals)\n",
156 | "model.L = Param(model.i, initialize=1, mutable=True)\n",
157 | "model.W = Param(model.i, initialize=1, mutable=True)\n",
158 | "model.R = Var(model.i,model.j, initialize=initvaB,domain=Binary)\n",
159 | "model.left = Var(model.i,model.j, initialize=initvaB,domain=Binary)\n",
160 | "model.U = Var(model.i,model.j, initialize=initvaB,domain=Binary)\n",
161 | "model.Down = Var(model.i,model.j, initialize=initvaB,domain=Binary)\n",
162 | "\n",
163 | "model.X=Var(initialize=0, bounds=(0,2000),domain=NonNegativeReals)\n",
164 | "model.Y=Var(initialize=0, bounds=(0,2000),domain=NonNegativeReals)\n",
165 | "\n",
166 | "def rue_c1(model,i,j):\n",
167 | " if i!=j:\n",
168 | " return -M*(1-model.R[i,j])+model.xp[i]+model.L[i] <= model.xp[j]-0.1\n",
169 | " else:\n",
170 | " return Constraint.Skip\n",
171 | "model.c1 =Constraint(model.i,model.j,rule=rue_c1) \n",
172 | "\n",
173 | "def rue_c1A(model,i,j):\n",
174 | " if i!=j:\n",
175 | " return +M*(model.R[i,j])+model.xp[i]+model.L[i] >= model.xp[j]+0.1\n",
176 | " else:\n",
177 | " return Constraint.Skip\n",
178 | "model.c1A =Constraint(model.i,model.j,rule=rue_c1A) \n",
179 | "\n",
180 | "\n",
181 | "def rue_c2(model,i,j):\n",
182 | " if i!=j:\n",
183 | " return model.xp[j]+model.L[j] -M*(1-model.left[i,j])<=model.xp[i]-0.1\n",
184 | " else:\n",
185 | " return Constraint.Skip\n",
186 | "model.c2 =Constraint(model.i,model.j,rule=rue_c2) \n",
187 | "\n",
188 | "def rue_c2A(model,i,j):\n",
189 | " if i!=j:\n",
190 | " return model.xp[j]+model.L[j] +M*(model.left[i,j])>=model.xp[i]+0.1\n",
191 | " else:\n",
192 | " return Constraint.Skip\n",
193 | "model.c2A =Constraint(model.i,model.j,rule=rue_c2A) \n",
194 | "\n",
195 | "\n",
196 | "def rue_c3(model,i,j):\n",
197 | " if i!=j:\n",
198 | " return -M*(1-model.U[i,j])+model.yp[i]+model.W[i] <= model.yp[j]-0.1\n",
199 | " else:\n",
200 | " return Constraint.Skip\n",
201 | "model.c3 =Constraint(model.i,model.j,rule=rue_c3) \n",
202 | "\n",
203 | "def rue_c3A(model,i,j):\n",
204 | " if i!=j:\n",
205 | " return M*(model.U[i,j])+model.yp[i]+model.W[i] >= model.yp[j]+0.1\n",
206 | " else:\n",
207 | " return Constraint.Skip\n",
208 | "model.c3A =Constraint(model.i,model.j,rule=rue_c3A) \n",
209 | "\n",
210 | "\n",
211 | "def rue_c4(model,i,j):\n",
212 | " if i!=j:\n",
213 | " return model.yp[j]+model.W[j] -M*(1-model.Down[i,j])<=model.yp[i]+0.1\n",
214 | " else:\n",
215 | " return Constraint.Skip\n",
216 | "model.c4 =Constraint(model.i,model.j,rule=rue_c4) \n",
217 | "\n",
218 | "def rue_c4A(model,i,j):\n",
219 | " if i!=j:\n",
220 | " return model.yp[j]+model.W[j] +M*(model.Down[i,j])>=model.yp[i]-0.1\n",
221 | " else:\n",
222 | " return Constraint.Skip\n",
223 | "model.c4A =Constraint(model.i,model.j,rule=rue_c4A) \n",
224 | "\n",
225 | "def rue_c5(model,i,j):\n",
226 | " if i!=j:\n",
227 | " return model.U[i,j]+model.Down[i,j]+model.R[i,j]+model.left[i,j]>=1\n",
228 | " else:\n",
229 | " return Constraint.Skip\n",
230 | "model.c5 =Constraint(model.i,model.j,rule=rue_c5) \n",
231 | " \n",
232 | "def rue_c7(model,i,j):\n",
233 | " if i!=j:\n",
234 | " return model.U[i,j]+model.Down[i,j]<=1\n",
235 | " else:\n",
236 | " return Constraint.Skip\n",
237 | "model.c7 =Constraint(model.i,model.j,rule=rue_c7) \n",
238 | " \n",
239 | " \n",
240 | "def rue_c8(model,i,j):\n",
241 | " if i!=j:\n",
242 | " return model.R[i,j]+model.left[i,j]<=1\n",
243 | " else:\n",
244 | " return Constraint.Skip\n",
245 | "model.c8 =Constraint(model.i,model.j,rule=rue_c8) \n",
246 | " \n",
247 | "def rue_c6A(model,i):\n",
248 | " return model.xp[i]+model.L[i]<=model.X\n",
249 | "model.c6A =Constraint(model.i,rule=rue_c6A) \n",
250 | "def rue_c6B(model,i):\n",
251 | " return model.yp[i]+model.W[i]<=model.Y\n",
252 | "model.c6B =Constraint(model.i,rule=rue_c6B) \n",
253 | "\n",
254 | "def rule_OF(model):\n",
255 | " return model.X+model.Y \n",
256 | "model.obj = Objective(rule=rule_OF, sense=minimize)"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": 4,
262 | "metadata": {},
263 | "outputs": [],
264 | "source": [
265 | "instance = model.create_instance()\n",
266 | "for i in instance.i:\n",
267 | " instance.L[i]=df.loc[i-1,'L']\n",
268 | " instance.W[i]=df.loc[i-1,'W']"
269 | ]
270 | },
271 | {
272 | "cell_type": "code",
273 | "execution_count": 5,
274 | "metadata": {},
275 | "outputs": [
276 | {
277 | "name": "stdout",
278 | "output_type": "stream",
279 | "text": [
280 | "this is feasible and optimal\n"
281 | ]
282 | }
283 | ],
284 | "source": [
285 | "opt = SolverFactory('gurobi')\n",
286 | "opt.options['mipgap'] = 0.1\n",
287 | "opt.options['Heuristics'] = 0.15\n",
288 | "opt.options['MIPFocus'] = 3\n",
289 | "\n",
290 | "#The MIPFocus parameter allows you to modify your high-level solution strategy, \n",
291 | "#depending on your goals. By default, the Gurobi MIP solver strikes a balance between finding new feasible solutions \n",
292 | "#and proving that the current solution is optimal. If you are more interested in finding feasible solutions quickly, \n",
293 | "#you can select MIPFocus=1. If you believe the solver is having no trouble finding good quality solutions, and wish to focus more attention on proving optimality, select MIPFocus=2. If the best objective bound is moving very slowly (or not at all), you may want to try MIPFocus=3 to focus on the bound.\n",
294 | "\n",
295 | "results=opt.solve(instance)\n",
296 | "\n",
297 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
298 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
299 | " print (\"this is feasible and optimal\")\n",
300 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
301 | " print (\"do something about it? or exit?\")\n",
302 | "else:\n",
303 | " print (str(results.solver))"
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": 9,
309 | "metadata": {},
310 | "outputs": [
311 | {
312 | "name": "stdout",
313 | "output_type": "stream",
314 | "text": [
315 | "1 0.0 240.10000000000002\n",
316 | "2 122.10000000000002 483.20000000000005\n",
317 | "3 213.10000000000002 200.10000000000002\n",
318 | "4 317.20000000000005 0.0\n",
319 | "5 0.0 0.0\n",
320 | "6 378.20000000000005 220.10000000000002\n",
321 | "7 378.20000000000005 509.20000000000005\n",
322 | "8 0.0 481.20000000000005\n",
323 | "9 438.30000000000007 0.0\n",
324 | "10 197.10000000000002 0.0\n",
325 | "OF= 1323.4\n"
326 | ]
327 | },
328 | {
329 | "data": {
330 | "text/plain": [
331 | "(-5.0, 800.0)"
332 | ]
333 | },
334 | "execution_count": 9,
335 | "metadata": {},
336 | "output_type": "execute_result"
337 | },
338 | {
339 | "data": {
340 | "image/png": "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\n",
341 | "text/plain": [
342 | ""
343 | ]
344 | },
345 | "metadata": {
346 | "needs_background": "light"
347 | },
348 | "output_type": "display_data"
349 | }
350 | ],
351 | "source": [
352 | "plt.figure(figsize=(8,6))\n",
353 | "K=[\"#1f77b4\", \"#ff7f0e\", \"#2ca02c\", \"#d62728\", \"#9467bd\", \"#8c564b\", \"#e377c2\", \"#7f7f7f\", \"#bcbd22\", \"#17becf\"]\n",
354 | "K=[\"blue\", \"red\", \"gold\", \"k\", \"brown\", \"teal\", \"#e377c2\", \"#7f7f7f\", \"#bcbd22\", \"#17becf\"]\n",
355 | "\n",
356 | "for i in instance.i:\n",
357 | " print(i,value(instance.xp[i]),value(instance.yp[i]))\n",
358 | " plt.plot( (value(instance.xp[i]),value(instance.xp[i]+instance.L[i])) , (value(instance.yp[i]),value(instance.yp[i])) , c=K[i-1], lw=4 )\n",
359 | " plt.plot( (value(instance.xp[i]),value(instance.xp[i]+instance.L[i])) , (value(instance.yp[i]+instance.W[i]),value(instance.yp[i]+instance.W[i])), c=K[i-1] , lw=4 )\n",
360 | " plt.plot( (value(instance.xp[i]),value(instance.xp[i])) , (value(instance.yp[i]),value(instance.yp[i]+instance.W[i])) , c=K[i-1], lw=4 )\n",
361 | " plt.plot( (value(instance.xp[i]+instance.L[i]),value(instance.xp[i]+instance.L[i])) , (value(instance.yp[i]),value(instance.yp[i]+instance.W[i])), c=K[i-1] , lw=4 )\n",
362 | " plt.text(value(instance.xp[i]+instance.L[i]/2),value(instance.yp[i]+instance.W[i]/2), s=str(i), fontweight='bold',fontsize=16,c=K[i-1] )\n",
363 | " \n",
364 | "print('OF= ',value(instance.obj))\n",
365 | "plt.xlim(-5,800)\n",
366 | "plt.ylim(-5,800)\n"
367 | ]
368 | },
369 | {
370 | "cell_type": "code",
371 | "execution_count": 7,
372 | "metadata": {},
373 | "outputs": [
374 | {
375 | "data": {
376 | "text/plain": [
377 | "\"for w in range(20):\\n plt.figure(figsize=(8,8))\\n for i in instance.i:\\n x=1000*random.random()\\n y=1000*random.random()\\n plt.plot( (x,x+value(instance.L[i]) ) , (y,y) , c=K[i-1], lw=4 )\\n plt.plot( (x,x+value(instance.L[i])) , (y+value(instance.W[i]),y+value(instance.W[i]) ), c=K[i-1] , lw=4 )\\n plt.plot( (x,x) , (y,y+value(instance.W[i])) , c=K[i-1], lw=4 )\\n plt.plot( (x+value(instance.L[i]),x+value(instance.L[i])) , (y,y+value(instance.W[i])), c=K[i-1] , lw=4 )\\n plt.text(x+value(instance.L[i]/2),y+value(instance.W[i]/2), s=str(i), fontweight='bold',fontsize=16,c=K[i-1] )\\n plt.xlim(0,1300)\\n plt.ylim(0,1300)\\n plt.savefig('Box '+str(w)+' .png', format='png', bbox_inches='tight', dpi=500)\\n\\n\""
378 | ]
379 | },
380 | "execution_count": 7,
381 | "metadata": {},
382 | "output_type": "execute_result"
383 | }
384 | ],
385 | "source": [
386 | "'''for w in range(20):\n",
387 | " plt.figure(figsize=(8,8))\n",
388 | " for i in instance.i:\n",
389 | " x=1000*random.random()\n",
390 | " y=1000*random.random()\n",
391 | " plt.plot( (x,x+value(instance.L[i]) ) , (y,y) , c=K[i-1], lw=4 )\n",
392 | " plt.plot( (x,x+value(instance.L[i])) , (y+value(instance.W[i]),y+value(instance.W[i]) ), c=K[i-1] , lw=4 )\n",
393 | " plt.plot( (x,x) , (y,y+value(instance.W[i])) , c=K[i-1], lw=4 )\n",
394 | " plt.plot( (x+value(instance.L[i]),x+value(instance.L[i])) , (y,y+value(instance.W[i])), c=K[i-1] , lw=4 )\n",
395 | " plt.text(x+value(instance.L[i]/2),y+value(instance.W[i]/2), s=str(i), fontweight='bold',fontsize=16,c=K[i-1] )\n",
396 | " plt.xlim(0,1300)\n",
397 | " plt.ylim(0,1300)\n",
398 | " plt.savefig('Box '+str(w)+' .png', format='png', bbox_inches='tight', dpi=500)\n",
399 | "\n",
400 | "'''"
401 | ]
402 | },
403 | {
404 | "cell_type": "code",
405 | "execution_count": null,
406 | "metadata": {},
407 | "outputs": [],
408 | "source": []
409 | }
410 | ],
411 | "metadata": {
412 | "kernelspec": {
413 | "display_name": "Python 3",
414 | "language": "python",
415 | "name": "python3"
416 | },
417 | "language_info": {
418 | "codemirror_mode": {
419 | "name": "ipython",
420 | "version": 3
421 | },
422 | "file_extension": ".py",
423 | "mimetype": "text/x-python",
424 | "name": "python",
425 | "nbconvert_exporter": "python",
426 | "pygments_lexer": "ipython3",
427 | "version": "3.7.4"
428 | }
429 | },
430 | "nbformat": 4,
431 | "nbformat_minor": 4
432 | }
433 |
--------------------------------------------------------------------------------
/Gcoloring.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "$$\\min \\sum_{i,j,k}i*j*k*X_{i,j,k}$$\n",
8 | "Each cell is assigned with a color \n",
9 | "$$ \\sum_{k}X_{i,j,k}=1$$ \n",
10 | "Each column has color k only one time \n",
11 | "$$ \\sum_{i}X_{i,j,k}=1$$\n",
12 | "Each row has color k only one time \n",
13 | "$$ \\sum_{j}X_{i,j,k}=1$$\n",
14 | "\n",
15 | "\n",
16 | "\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 1,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "from pyomo.environ import *\n",
26 | "import matplotlib.pyplot as plt\n",
27 | "import numpy as np\n",
28 | "import random \n",
29 | "cmap = plt.cm.Paired # define the colormap\n",
30 | "cmap = [cmap(i) for i in range(20)]"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 2,
36 | "metadata": {},
37 | "outputs": [],
38 | "source": [
39 | "model = AbstractModel()\n",
40 | "model.N =Param ( mutable=True)\n",
41 | "model.i = RangeSet(model.N)\n",
42 | "model.j = Set(initialize=model.i)\n",
43 | "model.k = Set(initialize=model.i)\n",
44 | "\n",
45 | "model.x = Var(model.i,model.j,model.k, within=Binary)\n",
46 | "model.OF = Var(within=NonNegativeReals)\n",
47 | "def r_c1(model,i,k):\n",
48 | " return sum(model.x[i,j,k] for j in model.j)==1\n",
49 | "model.C1=Constraint(model.i,model.k, rule=r_c1)\n",
50 | "\n",
51 | "def r_c2(model,j,k):\n",
52 | " return sum(model.x[i,j,k] for i in model.i)==1\n",
53 | "model.C2=Constraint(model.j,model.k, rule=r_c2)\n",
54 | "\n",
55 | "def r_c3(model,i,j):\n",
56 | " return sum(model.x[i,j,k] for k in model.k)==1\n",
57 | "model.C3=Constraint(model.i,model.k, rule=r_c3)\n",
58 | "\n",
59 | "def r_OF(model):\n",
60 | " return model.OF==sum(i*j*k*model.x[i,j,k] for i in model.i for j in model.j for k in model.k)\n",
61 | "model.C4=Constraint( rule=r_OF)\n",
62 | "\n",
63 | "model.obj = Objective(expr=model.OF , sense=minimize)\n"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": 3,
69 | "metadata": {},
70 | "outputs": [
71 | {
72 | "name": "stdout",
73 | "output_type": "stream",
74 | "text": [
75 | "feasible\n"
76 | ]
77 | }
78 | ],
79 | "source": [
80 | "model.N=8\n",
81 | "opt = SolverFactory('glpk')\n",
82 | "#opt.options[\"mipgap\"] = 0.05\n",
83 | "instance = model.create_instance()\n",
84 | "results = opt.solve(instance) # solves and updates instance\n",
85 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
86 | " print('feasible')\n",
87 | "elif (results.solver.termination_condition == TerminationCondition.infeasible):\n",
88 | " print('infeasible')\n",
89 | "else:\n",
90 | " print ('Solver Status:', results.solver.status)"
91 | ]
92 | },
93 | {
94 | "cell_type": "code",
95 | "execution_count": 4,
96 | "metadata": {},
97 | "outputs": [
98 | {
99 | "data": {
100 | "text/plain": [
101 | "(0.6215463577012281, 8.378453642298771, 0.6061889282485797, 8.393811071751418)"
102 | ]
103 | },
104 | "execution_count": 4,
105 | "metadata": {},
106 | "output_type": "execute_result"
107 | },
108 | {
109 | "data": {
110 | "image/png": "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\n",
111 | "text/plain": [
112 | ""
113 | ]
114 | },
115 | "metadata": {
116 | "needs_background": "light"
117 | },
118 | "output_type": "display_data"
119 | }
120 | ],
121 | "source": [
122 | "X=[]\n",
123 | "Y=[]\n",
124 | "K=[]\n",
125 | "for i in instance.i:\n",
126 | " for j in instance.j:\n",
127 | " for k in instance.k:\n",
128 | " if value(instance.x[i,j,k]) >0:\n",
129 | " #print(i,j,k)\n",
130 | " X.append(i)\n",
131 | " Y.append(j)\n",
132 | " K.append(k)\n",
133 | "Kn=[cmap[i-1] for i in K ]\n",
134 | "plt.scatter(X,Y,s=300,c=Kn)\n",
135 | "plt.axis('off')"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {},
142 | "outputs": [],
143 | "source": []
144 | }
145 | ],
146 | "metadata": {
147 | "kernelspec": {
148 | "display_name": "Python 3",
149 | "language": "python",
150 | "name": "python3"
151 | },
152 | "language_info": {
153 | "codemirror_mode": {
154 | "name": "ipython",
155 | "version": 3
156 | },
157 | "file_extension": ".py",
158 | "mimetype": "text/x-python",
159 | "name": "python",
160 | "nbconvert_exporter": "python",
161 | "pygments_lexer": "ipython3",
162 | "version": "3.7.4"
163 | }
164 | },
165 | "nbformat": 4,
166 | "nbformat_minor": 4
167 | }
168 |
--------------------------------------------------------------------------------
/Ireland.dat:
--------------------------------------------------------------------------------
1 | param N:= 43;
2 | param : i : xp yp :=
3 | 1 -415.13738711464 -3780.95762416648
4 | 2 -579.233398228436 -3888.22780525718
5 | 3 -598.742504864765 -3762.54362032143
6 | 4 -579.364645129012 -3820.13703627076
7 | 5 -483.2927321706 -3869.64326371621
8 | 6 -417.039898379657 -3747.33548777651
9 | 7 -417.65454854308 -3720.60173945406
10 | 8 -410.85628386411 -3770.90097676362
11 | 9 -656.667931082584 -3843.20034920601
12 | 10 -464.543682628871 -3821.05536576881
13 | 11 -407.24020981196 -3785.62831985528
14 | 12 -488.214771988288 -3834.4207246052
15 | 13 -442.906695818171 -3789.17512989601
16 | 14 -548.888885517813 -3680.03834815697
17 | 15 -567.878246418074 -3894.23405441888
18 | 16 -647.01410055207 -3863.42131431808
19 | 17 -595.021173590065 -3813.39746909931
20 | 18 -520.468627925688 -3880.2202668641
21 | 19 -459.544372801168 -3792.47511731215
22 | 20 -565.222875504125 -3890.28917899495
23 | 21 -451.768811409294 -3694.92831088039
24 | 22 -428.167329790405 -3772.55222551729
25 | 23 -520.70902275104 -3802.70000380206
26 | 24 -585.630548894819 -3904.28058592383
27 | 25 -537.718152239288 -3739.22538439321
28 | 26 -522.785451257758 -3611.9808017801
29 | 27 -532.154582758384 -3840.24989926671
30 | 28 -484.425277234273 -3755.52469142108
31 | 29 -420.644809454027 -3785.25658120011
32 | 30 -404.300677980049 -3815.01997697063
33 | 31 -521.62926296574 -3856.07642321204
34 | 32 -437.834141537282 -3868.33004255984
35 | 33 -600.648161713899 -3800.62866206348
36 | 34 -511.475504184761 -3733.86223950382
37 | 35 -447.578861584211 -3758.13951377928
38 | 36 -527.669023432355 -3712.24034207843
39 | 37 -497.361959677345 -3777.83915073223
40 | 38 -548.390971217337 -3807.12294566591
41 | 39 -479.863376700423 -3714.74171813905
42 | 40 -486.890806551037 -3800.35632094247
43 | 41 -607.349303008152 -3708.86113606146
44 | 42 -477.525437355137 -3638.00869610949;
--------------------------------------------------------------------------------
/June challenge.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {},
16 | "source": [
17 | "There are three boxes, but only one of them has gold inside. Additionally, each box has a message printed on it. One of these messages is true and the other two are lies.\n",
18 | "The first box says, “Gold is in this box”. F\n",
19 | "The second box says, “Gold is not in this box”.F\n",
20 | "The third box says, “Gold is in not in Box 1”.T"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": 2,
26 | "metadata": {},
27 | "outputs": [],
28 | "source": [
29 | "model = AbstractModel()\n",
30 | "model.x1 = Var(domain=Binary)\n",
31 | "model.x2 = Var(domain=Binary)\n",
32 | "model.x3 = Var(domain=Binary)\n",
33 | "model.U1 = Var(domain=Binary)\n",
34 | "model.U2 = Var(domain=Binary)\n",
35 | "model.U3 = Var(domain=Binary)\n",
36 | "model.c1 =Constraint(expr=model.x1==model.U1) \n",
37 | "model.c2 =Constraint(expr=(1-model.U2)==model.x2 ) \n",
38 | "model.c3 =Constraint(expr=(1-model.U1)==model.x3 ) \n",
39 | "model.c4 =Constraint(expr=model.x1+model.x2+model.x3==1 ) \n",
40 | "model.c5 =Constraint(expr=model.U1+model.U2+model.U3==1 ) \n",
41 | "model.obj = Objective(expr=model.x1+model.x2+model.x3, sense=minimize)"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": 3,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": [
50 | "instance = model.create_instance()"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 4,
56 | "metadata": {},
57 | "outputs": [
58 | {
59 | "name": "stdout",
60 | "output_type": "stream",
61 | "text": [
62 | "this is feasible and optimal\n"
63 | ]
64 | }
65 | ],
66 | "source": [
67 | "opt = SolverFactory('glpk')\n",
68 | "results=opt.solve(instance)\n",
69 | "\n",
70 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
71 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
72 | " print (\"this is feasible and optimal\")\n",
73 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
74 | " print (\"do something about it? or exit?\")\n",
75 | "else:\n",
76 | " print (str(results.solver))"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": 5,
82 | "metadata": {},
83 | "outputs": [
84 | {
85 | "name": "stdout",
86 | "output_type": "stream",
87 | "text": [
88 | "U1= 0.0 x1= 0.0\n",
89 | "U2= 1.0 x2= 0.0\n",
90 | "U3= 0.0 x3= 1.0\n"
91 | ]
92 | }
93 | ],
94 | "source": [
95 | "print('U1= ',value(instance.U1),'x1= ',value(instance.x1))\n",
96 | "print('U2= ',value(instance.U2),'x2= ',value(instance.x2))\n",
97 | "print('U3= ',value(instance.U3),'x3= ',value(instance.x3))\n"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": []
106 | }
107 | ],
108 | "metadata": {
109 | "kernelspec": {
110 | "display_name": "Python 3",
111 | "language": "python",
112 | "name": "python3"
113 | },
114 | "language_info": {
115 | "codemirror_mode": {
116 | "name": "ipython",
117 | "version": 3
118 | },
119 | "file_extension": ".py",
120 | "mimetype": "text/x-python",
121 | "name": "python",
122 | "nbconvert_exporter": "python",
123 | "pygments_lexer": "ipython3",
124 | "version": "3.7.4"
125 | }
126 | },
127 | "nbformat": 4,
128 | "nbformat_minor": 4
129 | }
130 |
--------------------------------------------------------------------------------
/Linkedin EX26 (Curve fitting).ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import pandas as pd "
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {},
19 | "source": [
20 | "$$y=a sin(b-x)+cx^2+d $$\n"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": 2,
26 | "metadata": {},
27 | "outputs": [
28 | {
29 | "name": "stdout",
30 | "output_type": "stream",
31 | "text": [
32 | " x y Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5\n",
33 | "0 107.608 60.323 NaN NaN NaN NaN\n",
34 | "1 108.632 61.122 NaN NaN NaN NaN\n",
35 | "2 109.773 60.171 NaN NaN NaN NaN\n",
36 | "3 110.929 61.187 NaN NaN NaN NaN\n",
37 | "4 112.075 63.221 NaN NaN NaN NaN\n",
38 | "5 113.270 63.639 NaN NaN NaN NaN\n",
39 | "6 115.094 64.012 NaN NaN NaN NaN\n",
40 | "7 116.219 63.761 NaN NaN NaN NaN\n",
41 | "8 117.388 66.019 NaN NaN NaN NaN\n",
42 | "9 118.734 67.857 NaN NaN NaN NaN\n",
43 | "10 120.445 67.869 NaN NaN NaN NaN\n",
44 | "11 121.950 66.913 NaN NaN NaN NaN\n",
45 | "12 123.366 68.655 NaN NaN NaN NaN\n",
46 | "13 125.368 69.564 NaN NaN NaN NaN\n",
47 | "14 127.852 69.731 NaN NaN NaN NaN\n",
48 | "15 130.081 70.551 NaN NaN NaN NaN\n",
49 | "61.122\n"
50 | ]
51 | }
52 | ],
53 | "source": [
54 | "df = pd.read_csv(\"dataCF.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
55 | "print(df)\n",
56 | "print(df.iloc[1,1])"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 3,
62 | "metadata": {},
63 | "outputs": [],
64 | "source": [
65 | "model = AbstractModel()\n",
66 | "model.N =Param(mutable=True) \n",
67 | "model.i = RangeSet(1,model.N)\n",
68 | "def initbound(model):\n",
69 | " return (-100,100)\n",
70 | "model.a = Var( bounds=initbound,within=Reals)\n",
71 | "model.b = Var( bounds=initbound,within=Reals)\n",
72 | "model.c = Var( bounds=initbound,within=Reals)\n",
73 | "model.d = Var( bounds=initbound,within=Reals)\n",
74 | "\n",
75 | "model.OF = Var(within=NonNegativeReals, initialize=5)\n",
76 | "def initvalx(model,i):\n",
77 | " return df.iloc[i-1,0]\n",
78 | "def initvaly(model,i):\n",
79 | " return df.iloc[i-1,1]\n",
80 | "\n",
81 | "\n",
82 | "model.Xloc=Param(model.i, within=NonNegativeReals, initialize=initvalx,mutable=True)\n",
83 | "model.Yloc=Param(model.i, within=NonNegativeReals, initialize=initvaly, mutable=True)\n",
84 | "\n",
85 | "def rule_OF(model):\n",
86 | " return model.OF==sum((model.a*sin(model.b-model.Xloc[i]) +model.c*model.Xloc[i]**2 +model.d-model.Yloc[i])**2 for i in model.i)\n",
87 | "model.C = Constraint(rule=rule_OF)\n",
88 | "\n",
89 | "model.obj1 = Objective(expr=model.OF, sense=minimize)\n"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 4,
95 | "metadata": {},
96 | "outputs": [],
97 | "source": [
98 | "opt = SolverFactory('Ipopt')"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": 5,
104 | "metadata": {},
105 | "outputs": [
106 | {
107 | "name": "stdout",
108 | "output_type": "stream",
109 | "text": [
110 | "OF= 7.406758504844819\n"
111 | ]
112 | }
113 | ],
114 | "source": [
115 | "model.N=len(df)\n",
116 | "instance = model.create_instance()\n",
117 | "results = opt.solve(instance) # solves and updates instance\n",
118 | "print('OF= ',value(instance.obj1))"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": 11,
124 | "metadata": {},
125 | "outputs": [
126 | {
127 | "data": {
128 | "image/png": "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\n",
129 | "text/plain": [
130 | ""
131 | ]
132 | },
133 | "metadata": {
134 | "needs_background": "light"
135 | },
136 | "output_type": "display_data"
137 | }
138 | ],
139 | "source": [
140 | "fig = plt.figure(figsize=(7,7))\n",
141 | "XC=np.linspace(min(df['x']),max(df['x']),100);\n",
142 | "\n",
143 | "Yc=[]\n",
144 | "for Xc in XC:\n",
145 | " Yc.append(value(instance.a)*sin(value(instance.b)-Xc)+value(instance.c)*Xc**2+value(instance.d))\n",
146 | "plt.plot(XC,Yc)\n",
147 | "for i in instance.i:\n",
148 | " plt.scatter(value(instance.Xloc[i]),value(instance.Yloc[i]),label=str(i)) \n",
149 | "plt.xlabel('X Values', fontweight='bold', fontsize=14)\n",
150 | "plt.ylabel('Y Values', fontweight='bold', fontsize=14)\n",
151 | "plt.grid()"
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": null,
157 | "metadata": {},
158 | "outputs": [],
159 | "source": []
160 | }
161 | ],
162 | "metadata": {
163 | "kernelspec": {
164 | "display_name": "Python 3",
165 | "language": "python",
166 | "name": "python3"
167 | },
168 | "language_info": {
169 | "codemirror_mode": {
170 | "name": "ipython",
171 | "version": 3
172 | },
173 | "file_extension": ".py",
174 | "mimetype": "text/x-python",
175 | "name": "python",
176 | "nbconvert_exporter": "python",
177 | "pygments_lexer": "ipython3",
178 | "version": "3.7.4"
179 | }
180 | },
181 | "nbformat": 4,
182 | "nbformat_minor": 4
183 | }
184 |
--------------------------------------------------------------------------------
/Multi line regression-V3.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import operator"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 2,
19 | "metadata": {},
20 | "outputs": [],
21 | "source": [
22 | "N=20\n",
23 | "nK=3\n",
24 | "df={}\n",
25 | "for i in range(N):\n",
26 | " df[i,'x']=random.random()\n",
27 | " df[i,'y']=random.random()\n"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": 3,
33 | "metadata": {},
34 | "outputs": [],
35 | "source": [
36 | "n=int(len(df)/2)\n",
37 | "model = AbstractModel()\n",
38 | "model.N =Param(mutable=True, default=n) \n",
39 | "model.i = RangeSet(1,model.N)\n",
40 | "model.k = RangeSet(1,nK)\n",
41 | "model.j = Set(initialize=model.i)\n",
42 | "model.Alpha = Var(model.k,bounds=(-2,2), within=Reals)\n",
43 | "model.Beta = Var(model.k, bounds=(-2,2), within=Reals)\n",
44 | "model.U = Var(model.i,model.k, initialize=0,bounds=(0,1), within=Binary)\n",
45 | "model.r = Var(model.i,bounds=(0,200), within=NonNegativeReals)\n",
46 | "\n",
47 | "\n",
48 | "def rule_C1(model,i,k):\n",
49 | " return model.r[i]>= df[i-1,'x']*model.Alpha[k]+model.Beta[k] -df[i-1,'y'] - 4*(1-model.U[i,k])\n",
50 | "model.C1 = Constraint(model.i,model.k,rule=rule_C1)\n",
51 | "\n",
52 | "def rule_C2(model,i,k):\n",
53 | " return model.r[i]>= -(df[i-1,'x']*model.Alpha[k]+model.Beta[k] -df[i-1,'y']) - 4*(1-model.U[i,k])\n",
54 | "model.C2 = Constraint(model.i,model.k,rule=rule_C2)\n",
55 | "\n",
56 | "def rule_C7(model,i):\n",
57 | " return sum(model.U[i,k] for k in model.k)==1\n",
58 | "model.C7 = Constraint(model.i,rule=rule_C7)\n",
59 | "\n",
60 | "def rule_C9(model,k):\n",
61 | " if k+1<=nK:\n",
62 | " return model.Alpha[k]<= model.Alpha[k+1]\n",
63 | " else:\n",
64 | " return Constraint.Skip\n",
65 | "model.C9 = Constraint(model.k,rule=rule_C9)\n",
66 | "\n",
67 | "def rule_OF(model):\n",
68 | " return sum(model.r[i] for i in model.i)\n",
69 | "model.obj1 = Objective(rule=rule_OF, sense=minimize)"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {},
76 | "outputs": [],
77 | "source": [
78 | "opt = SolverFactory('glpk')\n",
79 | "\n",
80 | "\n",
81 | "model.N=n\n",
82 | "instance = model.create_instance()\n",
83 | "\n",
84 | "results = opt.solve(instance) # solves and updates instance\n",
85 | "print('OF= ',value(instance.obj1))\n",
86 | "print (\"The solver returned a status of:\"+str(results.solver.status))\n",
87 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
88 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
89 | " print (\"this is feasible and optimal\")\n",
90 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
91 | " print (\"do something about it? or exit?\")\n",
92 | "else:\n",
93 | " print (str(results.solver))"
94 | ]
95 | }
96 | ],
97 | "metadata": {
98 | "kernelspec": {
99 | "display_name": "Python 3",
100 | "language": "python",
101 | "name": "python3"
102 | },
103 | "language_info": {
104 | "codemirror_mode": {
105 | "name": "ipython",
106 | "version": 3
107 | },
108 | "file_extension": ".py",
109 | "mimetype": "text/x-python",
110 | "name": "python",
111 | "nbconvert_exporter": "python",
112 | "pygments_lexer": "ipython3",
113 | "version": "3.7.4"
114 | }
115 | },
116 | "nbformat": 4,
117 | "nbformat_minor": 4
118 | }
119 |
--------------------------------------------------------------------------------
/MultilineregressionV3.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import operator"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 2,
19 | "metadata": {},
20 | "outputs": [],
21 | "source": [
22 | "N=20\n",
23 | "nK=3\n",
24 | "df={}\n",
25 | "for i in range(N):\n",
26 | " df[i,'x']=random.random()\n",
27 | " df[i,'y']=random.random()\n"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": 3,
33 | "metadata": {},
34 | "outputs": [],
35 | "source": [
36 | "n=int(len(df)/2)\n",
37 | "model = AbstractModel()\n",
38 | "model.N =Param(mutable=True, default=n) \n",
39 | "model.i = RangeSet(1,model.N)\n",
40 | "model.k = RangeSet(1,nK)\n",
41 | "model.j = Set(initialize=model.i)\n",
42 | "model.Alpha = Var(model.k,bounds=(-2,2), within=Reals)\n",
43 | "model.Beta = Var(model.k, bounds=(-2,2), within=Reals)\n",
44 | "model.U = Var(model.i,model.k, initialize=0,bounds=(0,1), within=Binary)\n",
45 | "model.r = Var(model.i,bounds=(0,200), within=NonNegativeReals)\n",
46 | "\n",
47 | "\n",
48 | "def rule_C1(model,i,k):\n",
49 | " return model.r[i]>= df[i-1,'x']*model.Alpha[k]+model.Beta[k] -df[i-1,'y'] - 4*(1-model.U[i,k])\n",
50 | "model.C1 = Constraint(model.i,model.k,rule=rule_C1)\n",
51 | "\n",
52 | "def rule_C2(model,i,k):\n",
53 | " return model.r[i]>= -(df[i-1,'x']*model.Alpha[k]+model.Beta[k] -df[i-1,'y']) - 4*(1-model.U[i,k])\n",
54 | "model.C2 = Constraint(model.i,model.k,rule=rule_C2)\n",
55 | "\n",
56 | "def rule_C7(model,i):\n",
57 | " return sum(model.U[i,k] for k in model.k)==1\n",
58 | "model.C7 = Constraint(model.i,rule=rule_C7)\n",
59 | "\n",
60 | "def rule_C9(model,k):\n",
61 | " if k+1<=nK:\n",
62 | " return model.Alpha[k]<= model.Alpha[k+1]\n",
63 | " else:\n",
64 | " return Constraint.Skip\n",
65 | "model.C9 = Constraint(model.k,rule=rule_C9)\n",
66 | "\n",
67 | "def rule_OF(model):\n",
68 | " return sum(model.r[i] for i in model.i)\n",
69 | "model.obj1 = Objective(rule=rule_OF, sense=minimize)"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {},
76 | "outputs": [],
77 | "source": [
78 | "opt = SolverFactory('gurobi')\n",
79 | "\n",
80 | "\n",
81 | "model.N=n\n",
82 | "instance = model.create_instance()\n",
83 | "\n",
84 | "results = opt.solve(instance) # solves and updates instance\n",
85 | "print('OF= ',value(instance.obj1))\n",
86 | "print (\"The solver returned a status of:\"+str(results.solver.status))\n",
87 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
88 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
89 | " print (\"this is feasible and optimal\")\n",
90 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
91 | " print (\"do something about it? or exit?\")\n",
92 | "else:\n",
93 | " print (str(results.solver))"
94 | ]
95 | }
96 | ],
97 | "metadata": {
98 | "kernelspec": {
99 | "display_name": "Python 3",
100 | "language": "python",
101 | "name": "python3"
102 | },
103 | "language_info": {
104 | "codemirror_mode": {
105 | "name": "ipython",
106 | "version": 3
107 | },
108 | "file_extension": ".py",
109 | "mimetype": "text/x-python",
110 | "name": "python",
111 | "nbconvert_exporter": "python",
112 | "pygments_lexer": "ipython3",
113 | "version": "3.7.4"
114 | }
115 | },
116 | "nbformat": 4,
117 | "nbformat_minor": 4
118 | }
119 |
--------------------------------------------------------------------------------
/ShiftScheduling.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import pandas as pd \n",
14 | "from scipy.spatial import ConvexHull\n",
15 | "import math "
16 | ]
17 | },
18 | {
19 | "cell_type": "code",
20 | "execution_count": 2,
21 | "metadata": {},
22 | "outputs": [
23 | {
24 | "data": {
25 | "text/plain": [
26 | "'df = pd.read_csv(\"opendss.csv\", delimiter=\\',\\', skiprows=0, low_memory=False)\\ndf'"
27 | ]
28 | },
29 | "execution_count": 2,
30 | "metadata": {},
31 | "output_type": "execute_result"
32 | }
33 | ],
34 | "source": [
35 | "'''df = pd.read_csv(\"opendss.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
36 | "df'''"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": 72,
42 | "metadata": {},
43 | "outputs": [
44 | {
45 | "name": "stdout",
46 | "output_type": "stream",
47 | "text": [
48 | "OF= 169.0\n",
49 | "The solver returned a status of:ok\n",
50 | "this is feasible and optimal\n",
51 | "Total = 162.0\n"
52 | ]
53 | }
54 | ],
55 | "source": [
56 | "model = AbstractModel()\n",
57 | "model.i = RangeSet(1,8)\n",
58 | "model.j = RangeSet(1,3)\n",
59 | "model.t = RangeSet(1,18)\n",
60 | "\n",
61 | "model.X = Var(model.i,model.j,model.t, within=Binary)\n",
62 | "model.Nshift= Var( within=NonNegativeReals)\n",
63 | "\n",
64 | "def Rule_C1(model,t,j):\n",
65 | " return sum(model.X[i,j,t] for i in model.i)==3\n",
66 | "model.C1=Constraint(model.t,model.j, rule=Rule_C1)\n",
67 | "\n",
68 | "def Rule_CA(model,t,i):\n",
69 | " return sum(model.X[i,j,t] for j in model.j)<=2\n",
70 | "model.CA=Constraint(model.t,model.i, rule=Rule_CA)\n",
71 | "\n",
72 | "def Rule_CB(model,t,i):\n",
73 | " return sum(model.X[i,j,t] for j in model.j)>=1\n",
74 | "model.CB=Constraint(model.t,model.i, rule=Rule_CB)\n",
75 | "\n",
76 | "def Rule_C2(model,t,i):\n",
77 | " if t<18:\n",
78 | " return model.X[i,3,t]+ model.X[i,3,t+1] <=1\n",
79 | " else:\n",
80 | " return Constraint.Skip\n",
81 | "model.C2=Constraint(model.t,model.i, rule=Rule_C2)\n",
82 | "\n",
83 | "def Rule_C3(model,t,i):\n",
84 | " if t<18:\n",
85 | " return model.X[i,3,t]+ model.X[i,1,t+1] <=1\n",
86 | " else:\n",
87 | " return Constraint.Skip\n",
88 | "model.C3=Constraint(model.t,model.i, rule=Rule_C3)\n",
89 | "\n",
90 | "def Rule_C4(model,i):\n",
91 | " return sum(model.X[i,3,t] for t in model.t) <=model.Nshift\n",
92 | "model.C4=Constraint(model.i, rule=Rule_C4)\n",
93 | "\n",
94 | "def rule_OF(model):\n",
95 | " #return quicksum(model.X[i,j,t] for i in model.i for j in model.j for t in model.t )\n",
96 | " return model.Nshift+quicksum(model.X[i,j,t] for i in model.i for j in model.j for t in model.t ) \n",
97 | "model.obj1 = Objective(rule=rule_OF, sense=minimize)\n",
98 | "\n",
99 | "opt = SolverFactory('gurobi')\n",
100 | "instance = model.create_instance()\n",
101 | "results = opt.solve(instance) # solves and updates instance\n",
102 | "print('OF= ',value(instance.obj1))\n",
103 | "print (\"The solver returned a status of:\"+str(results.solver.status))\n",
104 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
105 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
106 | " print (\"this is feasible and optimal\")\n",
107 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
108 | " print (\"do something about it? or exit?\")\n",
109 | "else:\n",
110 | " print (str(results.solver))\n",
111 | " \n",
112 | "print('Total = ',sum( value(instance.X[i,j,t]) for i in instance.i for j in instance.j for t in instance.t )) \n",
113 | " "
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": 81,
119 | "metadata": {},
120 | "outputs": [
121 | {
122 | "name": "stdout",
123 | "output_type": "stream",
124 | "text": [
125 | "1 7.0\n",
126 | "2 7.0\n",
127 | "3 7.0\n",
128 | "4 7.0\n",
129 | "5 6.0\n",
130 | "6 7.0\n",
131 | "7 7.0\n",
132 | "8 6.0\n"
133 | ]
134 | },
135 | {
136 | "data": {
137 | "image/png": "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\n",
138 | "text/plain": [
139 | ""
140 | ]
141 | },
142 | "metadata": {
143 | "needs_background": "light"
144 | },
145 | "output_type": "display_data"
146 | }
147 | ],
148 | "source": [
149 | "color=['r' ,'b','k','green','grey','yellow','brown' ,'k']\n",
150 | "MK=['o','s','p','^','*','.','d','x','+']\n",
151 | "cmap = plt.cm.Dark2 # define the colormap\n",
152 | "color = [cmap(i) for i in range(20)]\n",
153 | "plt.figure(figsize=(12,7) )\n",
154 | "for t in instance.t:\n",
155 | " for i in instance.i:\n",
156 | " for j in instance.j:\n",
157 | " if value(instance.X[i,j,t])>0:\n",
158 | " #print(t,i,j)\n",
159 | " plt.scatter(t,1.8*j+0.15*i,s=90,color=color[i-1],marker=MK[i-1])\n",
160 | " \n",
161 | "plt.xticks([i for i in range(1,19)], fontweight='bold', fontsize=12)\n",
162 | "\n",
163 | "plt.yticks([i*2 for i in range(1,4)] ,['Morning', 'Afternoon', 'Night'] , fontweight='bold', fontsize=12)\n",
164 | "\n",
165 | "for i in instance.i:\n",
166 | " print(i, sum(value(instance.X[i,j,t]) for t in instance.t) )\n",
167 | "plt.xlabel('Day', fontweight='bold', fontsize=12)\n",
168 | "plt.grid()\n",
169 | "plt.rc('axes',edgecolor='w')\n",
170 | "plt.savefig('ShiftStaff .png', format='png', bbox_inches='tight', dpi=400)\n"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {},
177 | "outputs": [],
178 | "source": []
179 | }
180 | ],
181 | "metadata": {
182 | "kernelspec": {
183 | "display_name": "Python 3",
184 | "language": "python",
185 | "name": "python3"
186 | },
187 | "language_info": {
188 | "codemirror_mode": {
189 | "name": "ipython",
190 | "version": 3
191 | },
192 | "file_extension": ".py",
193 | "mimetype": "text/x-python",
194 | "name": "python",
195 | "nbconvert_exporter": "python",
196 | "pygments_lexer": "ipython3",
197 | "version": "3.7.4"
198 | }
199 | },
200 | "nbformat": 4,
201 | "nbformat_minor": 4
202 | }
203 |
--------------------------------------------------------------------------------
/Steiner Tree.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import operator"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 7,
19 | "metadata": {},
20 | "outputs": [
21 | {
22 | "data": {
23 | "image/png": "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\n",
24 | "text/plain": [
25 | ""
26 | ]
27 | },
28 | "metadata": {
29 | "needs_background": "light"
30 | },
31 | "output_type": "display_data"
32 | }
33 | ],
34 | "source": [
35 | "N=20\n",
36 | "location={}\n",
37 | "iteration=1\n",
38 | "for i in range(N):\n",
39 | " for j in range(N):\n",
40 | " plt.scatter(i,j,s=100,c='k')\n",
41 | " location[iteration]=(i,j)\n",
42 | " iteration+=1"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 3,
48 | "metadata": {},
49 | "outputs": [
50 | {
51 | "name": "stdout",
52 | "output_type": "stream",
53 | "text": [
54 | "OF= 28.0\n",
55 | "The solver returned a status of:ok\n",
56 | "this is feasible and optimal\n"
57 | ]
58 | }
59 | ],
60 | "source": [
61 | "for n in [iteration-1]:\n",
62 | " Xdic={}\n",
63 | " for i in range(1,iteration):\n",
64 | " Xdic[i,'x']=location[i][0]\n",
65 | " Xdic[i,'y']=location[i][1]\n",
66 | " Xdic[i,'D']=np.random.uniform()\n",
67 | " \n",
68 | " AllTour={}\n",
69 | " for i in range(1,n+1):\n",
70 | " for j in range(1,n+1):\n",
71 | " if i!=j and sqrt((Xdic[i,'x']-Xdic[j,'x'])**2+(Xdic[i,'y']-Xdic[j,'y'])**2)<=1.1:\n",
72 | " AllTour[i,j]=Xdic[i,'D']*Xdic[j,'D']\n",
73 | " else:\n",
74 | " AllTour[i,j]=100\n",
75 | " allowed={}\n",
76 | " for i in range(1,n+1):\n",
77 | " for j in range(1,n+1):\n",
78 | " if i!=j and AllTour[i,j]<=1.1:\n",
79 | " allowed[i,j]=1\n",
80 | "\n",
81 | " model = AbstractModel()\n",
82 | " model.N =Param(mutable=True, default=n) \n",
83 | " model.i = RangeSet(1,model.N)\n",
84 | " model.j = Set(initialize=model.i)\n",
85 | " model.U = Var(model.i,model.j, initialize=1, within=Binary)\n",
86 | " model.flow = Var(model.i,model.j,bounds=(0,1), within=NonNegativeReals)\n",
87 | " model.G = Var(bounds=(0,1), within=NonNegativeReals)\n",
88 | " \n",
89 | " def initvalTerminal(model,i):\n",
90 | " if random.uniform(0,1)<0.1:\n",
91 | " return 1\n",
92 | " else:\n",
93 | " return 0\n",
94 | " model.Terminal=Param(model.i, mutable=True, initialize=initvalTerminal) \n",
95 | " def initval(model,i):\n",
96 | " return random.uniform(0,1)\n",
97 | " model.Xloc=Param(model.i, initialize=initval,mutable=True)\n",
98 | " model.Yloc=Param(model.i, initialize=initval, mutable=True)\n",
99 | "\n",
100 | " def Rule_D(model,i,j):\n",
101 | " return AllTour[i,j] \n",
102 | " model.D=Param(model.i,model.j, initialize=Rule_D, mutable=True)\n",
103 | "\n",
104 | " def rule_C1(model,i):\n",
105 | " if i==1:\n",
106 | " return model.G ==sum(model.flow[i,j]-model.flow[j,i] for j in model.j if (i,j) in allowed )\n",
107 | " else:\n",
108 | " return -model.Terminal[i]/model.N==sum(model.flow[i,j]-model.flow[j,i] for j in model.j if (i,j) in allowed )\n",
109 | " model.C1 = Constraint(model.i,rule=rule_C1)\n",
110 | "\n",
111 | " def rule_C2(model,i,j):\n",
112 | " if (i,j) in allowed:\n",
113 | " return model.flow[i,j]<=1.2*model.U[i,j]\n",
114 | " else:\n",
115 | " return Constraint.Skip\n",
116 | " model.C2 = Constraint(model.i,model.j,rule=rule_C2)\n",
117 | " def rule_OF(model):\n",
118 | " return sum(model.U[r,c]*model.D[r,c] for (r,c) in allowed )\n",
119 | " model.obj1 = Objective(rule=rule_OF, sense=minimize)\n",
120 | "\n",
121 | " opt = SolverFactory('gurobi')\n",
122 | " model.N=n\n",
123 | " instance = model.create_instance()\n",
124 | " for i in instance.i:\n",
125 | " instance.Yloc[i]=Xdic[i,'y']\n",
126 | " instance.Xloc[i]=Xdic[i,'x']\n",
127 | " for j in instance.j:\n",
128 | " instance.D[i,j]=sqrt((Xdic[i,'x']-Xdic[j,'x'])**2+(Xdic[i,'y']-Xdic[j,'y'])**2)\n",
129 | "\n",
130 | " results = opt.solve(instance) # solves and updates instance\n",
131 | " print('OF= ',value(instance.obj1))\n",
132 | " print (\"The solver returned a status of:\"+str(results.solver.status))\n",
133 | " from pyomo.opt import SolverStatus, TerminationCondition\n",
134 | " if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
135 | " print (\"this is feasible and optimal\")\n",
136 | " elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
137 | " print (\"do something about it? or exit?\")\n",
138 | " else:\n",
139 | " print (str(results.solver))"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": 6,
145 | "metadata": {},
146 | "outputs": [
147 | {
148 | "data": {
149 | "image/png": "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\n",
150 | "text/plain": [
151 | ""
152 | ]
153 | },
154 | "metadata": {
155 | "needs_background": "light"
156 | },
157 | "output_type": "display_data"
158 | }
159 | ],
160 | "source": [
161 | "fig = plt.figure(figsize=(9,9))\n",
162 | "for (i,j) in allowed:\n",
163 | " if value(instance.U[i,j])>0:\n",
164 | " plt.plot((Xdic[i,'x'],Xdic[j,'x']),(Xdic[i,'y'],Xdic[j,'y']) , lw=3,c='orange', alpha=1)\n",
165 | "for i in instance.i:\n",
166 | " plt.scatter(value(instance.Xloc[i]),value(instance.Yloc[i]),label=str(i), s=100,c='k')\n",
167 | " if value(instance.Terminal[i]) >0 or i==1:\n",
168 | " plt.scatter(value(instance.Xloc[i]),value(instance.Yloc[i]),label=str(i), s=200,c='r')\n",
169 | "\n",
170 | "plt.axis('off')\n",
171 | "plt.savefig('TSP and MST for '+str(n)+' cities .png', format='png', bbox_inches='tight', dpi=200)\n",
172 | "\n"
173 | ]
174 | },
175 | {
176 | "cell_type": "code",
177 | "execution_count": 5,
178 | "metadata": {},
179 | "outputs": [
180 | {
181 | "data": {
182 | "text/plain": [
183 | "360"
184 | ]
185 | },
186 | "execution_count": 5,
187 | "metadata": {},
188 | "output_type": "execute_result"
189 | }
190 | ],
191 | "source": [
192 | "len(allowed)"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {},
199 | "outputs": [],
200 | "source": []
201 | }
202 | ],
203 | "metadata": {
204 | "kernelspec": {
205 | "display_name": "Python 3",
206 | "language": "python",
207 | "name": "python3"
208 | },
209 | "language_info": {
210 | "codemirror_mode": {
211 | "name": "ipython",
212 | "version": 3
213 | },
214 | "file_extension": ".py",
215 | "mimetype": "text/x-python",
216 | "name": "python",
217 | "nbconvert_exporter": "python",
218 | "pygments_lexer": "ipython3",
219 | "version": "3.7.4"
220 | }
221 | },
222 | "nbformat": 4,
223 | "nbformat_minor": 4
224 | }
225 |
--------------------------------------------------------------------------------
/ie.csv:
--------------------------------------------------------------------------------
1 | city,lat,lng,country,,,,,X,Y,,,Xp,Yp,,,iso2,admin_name,capital,population,population_proper
2 | Dublin,53.3425,-6.2658,Ireland,6371,0.5970,0.9940,1,3780.95762416648,-415.13738711464,,1,-415.13738711464,-3780.95762416648,,,IE,Dublin,primary,1173179,1173179
3 | Cork,51.9000,-8.4731,Ireland,6371,0.6170,0.9891,2,3888.22780525718,-579.233398228436,,2,-579.233398228436,-3888.22780525718,,,IE,Cork,admin,208669,208669
4 | Galway,53.2729,-9.0418,Ireland,6371,0.5980,0.9876,3,3762.54362032143,-598.742504864765,,3,-598.742504864765,-3762.54362032143,,,IE,Galway,admin,79504,79504
5 | Limerick,52.6653,-8.6238,Ireland,6371,0.6065,0.9887,4,3820.13703627076,-579.364645129012,,4,-579.364645129012,-3820.13703627076,,,IE,Limerick,admin,58319,58319
6 | Waterford,52.2583,-7.1190,Ireland,6371,0.6121,0.9923,5,3869.64326371621,-483.2927321706,,5,-483.2927321706,-3869.64326371621,,,IE,Waterford,admin,48369,48369
7 | Drogheda,53.7139,-6.3503,Ireland,6371,0.5918,0.9939,6,3747.33548777651,-417.039898379657,,6,-417.039898379657,-3747.33548777651,,,IE,Louth,,40956,40956
8 | Dún Dealgan,54.0090,-6.4049,Ireland,6371,0.5877,0.9938,7,3720.60173945406,-417.65454854308,,7,-417.65454854308,-3720.60173945406,,,IE,Louth,admin,39004,39004
9 | Swords,53.4597,-6.2181,Ireland,6371,0.5954,0.9941,8,3770.90097676362,-410.85628386411,,8,-410.85628386411,-3770.90097676362,,,IE,Fingal,admin,33998,33998
10 | Tralee,52.2675,-9.6962,Ireland,6371,0.6120,0.9857,9,3843.20034920601,-656.667931082584,,9,-656.667931082584,-3843.20034920601,,,IE,Kerry,admin,26384,22941
11 | Carlow,52.8306,-6.9317,Ireland,6371,0.6042,0.9927,10,3821.05536576881,-464.543682628871,,10,-464.543682628871,-3821.05536576881,,,IE,Carlow,admin,24272,24272
12 | Dunleary,53.3000,-6.1400,Ireland,6371,0.5976,0.9943,11,3785.62831985528,-407.24020981196,,11,-407.24020981196,-3785.62831985528,,,IE,Dún Laoghaire-Rathdown,admin,23857,23857
13 | Kilkenny,52.6477,-7.2561,Ireland,6371,0.6067,0.9920,12,3834.4207246052,-488.214771988288,,12,-488.214771988288,-3834.4207246052,,,IE,Kilkenny,admin,22179,22179
14 | Naas,53.2158,-6.6669,Ireland,6371,0.5988,0.9932,13,3789.17512989601,-442.906695818171,,13,-442.906695818171,-3789.17512989601,,,IE,Kildare,admin,21393,21393
15 | Sligo,54.2667,-8.4833,Ireland,6371,0.5840,0.9891,14,3680.03834815697,-548.888885517813,,14,-548.888885517813,-3680.03834815697,,,IE,Sligo,admin,19452,19452
16 | Cobh,51.8510,-8.2967,Ireland,6371,0.6177,0.9895,15,3894.23405441888,-567.878246418074,,15,-567.878246418074,-3894.23405441888,,,IE,Cork,,12347,12347
17 | Killarney,52.0588,-9.5072,Ireland,6371,0.6149,0.9863,16,3863.42131431808,-647.01410055207,,16,-647.01410055207,-3863.42131431808,,,IE,Kerry,,11902,7300
18 | Shannon,52.7137,-8.8686,Ireland,6371,0.6058,0.9880,17,3813.39746909931,-595.021173590065,,17,-595.021173590065,-3813.39746909931,,,IE,Clare,,8781,7506
19 | Dungarvan,52.0845,-7.6397,Ireland,6371,0.6145,0.9911,18,3880.2202668641,-520.468627925688,,18,-520.468627925688,-3880.2202668641,,,IE,Waterford,,7991,7991
20 | Kildare,53.1569,-6.9090,Ireland,6371,0.5996,0.9927,19,3792.47511731215,-459.544372801168,,19,-459.544372801168,-3792.47511731215,,,IE,Kildare,,7538,7538
21 | Carrigtohill,51.9000,-8.2667,Ireland,6371,0.6170,0.9896,20,3890.28917899495,-565.222875504125,,20,-565.222875504125,-3890.28917899495,,,IE,Cork,,6665,6665
22 | Monaghan,54.2479,-6.9708,Ireland,6371,0.5843,0.9926,21,3694.92831088039,-451.768811409294,,21,-451.768811409294,-3694.92831088039,,,IE,Monaghan,admin,5937,5937
23 | Dunboyne,53.4199,-6.4751,Ireland,6371,0.5959,0.9936,22,3772.55222551729,-428.167329790405,,22,-428.167329790405,-3772.55222551729,,,IE,Meath,,5713,5713
24 | Roscrea,52.9547,-7.7971,Ireland,6371,0.6024,0.9908,23,3802.70000380206,-520.70902275104,,23,-520.70902275104,-3802.70000380206,,,IE,Tipperary,,4910,4910
25 | Kinsale,51.7075,-8.5306,Ireland,6371,0.6197,0.9889,24,3904.28058592383,-585.630548894819,,24,-585.630548894819,-3904.28058592383,,,IE,Cork,,4893,4893
26 | Ros Comáin,53.6333,-8.1833,Ireland,6371,0.5930,0.9898,25,3739.22538439321,-537.718152239288,,25,-537.718152239288,-3739.22538439321,,,IE,Roscommon,admin,4860,4860
27 | Gweedore,55.0509,-8.2356,Ireland,6371,0.5728,0.9897,26,3611.9808017801,-522.785451257758,,26,-522.785451257758,-3611.9808017801,,,IE,Donegal,,4065,4065
28 | Cashel,52.5167,-7.8894,Ireland,6371,0.6085,0.9905,27,3840.24989926671,-532.154582758384,,27,-532.154582758384,-3840.24989926671,,,IE,Tipperary,,2936,2936
29 | Mullingar,53.5333,-7.3500,Ireland,6371,0.5944,0.9918,28,3755.52469142108,-484.425277234273,,28,-484.425277234273,-3755.52469142108,,,IE,Westmeath,admin,,
30 | Tallaght,53.2878,-6.3411,Ireland,6371,0.5978,0.9939,29,3785.25658120011,-420.644809454027,,29,-420.644809454027,-3785.25658120011,,,IE,South Dublin,admin,,
31 | Wicklow,52.9750,-6.0494,Ireland,6371,0.6022,0.9944,30,3815.01997697063,-404.300677980049,,30,-404.300677980049,-3815.01997697063,,,IE,Wicklow,admin,,
32 | Clonmel,52.3550,-7.7039,Ireland,6371,0.6108,0.9910,31,3856.07642321204,-521.62926296574,,31,-521.62926296574,-3856.07642321204,,,IE,Tipperary,admin,,
33 | Wexford,52.3342,-6.4575,Ireland,6371,0.6111,0.9937,32,3868.33004255984,-437.834141537282,,32,-437.834141537282,-3868.33004255984,,,IE,Wexford,admin,,
34 | Ennis,52.8463,-8.9807,Ireland,6371,0.6040,0.9877,33,3800.62866206348,-600.648161713899,,33,-600.648161713899,-3800.62866206348,,,IE,Clare,admin,,
35 | Longford,53.7333,-7.8000,Ireland,6371,0.5915,0.9907,34,3733.86223950382,-511.475504184761,,34,-511.475504184761,-3733.86223950382,,,IE,Longford,admin,,
36 | Trim,53.5550,-6.7917,Ireland,6371,0.5941,0.9930,35,3758.13951377928,-447.578861584211,,35,-447.578861584211,-3758.13951377928,,,IE,Meath,admin,,
37 | Carrick on Shannon,53.9469,-8.0900,Ireland,6371,0.5885,0.9900,36,3712.24034207843,-527.669023432355,,36,-527.669023432355,-3712.24034207843,,,IE,Leitrim,admin,,
38 | Tullamore,53.2667,-7.5000,Ireland,6371,0.5981,0.9914,37,3777.83915073223,-497.361959677345,,37,-497.361959677345,-3777.83915073223,,,IE,Offaly,admin,,
39 | Nenagh,52.8619,-8.1967,Ireland,6371,0.6037,0.9898,38,3807.12294566591,-548.390971217337,,38,-548.390971217337,-3807.12294566591,,,IE,Tipperary,admin,,
40 | An Cabhán,53.9908,-7.3606,Ireland,6371,0.5879,0.9918,39,3714.74171813905,-479.863376700423,,39,-479.863376700423,-3714.74171813905,,,IE,Cavan,admin,,
41 | Port Laoise,53.0309,-7.3008,Ireland,6371,0.6014,0.9919,40,3800.35632094247,-486.890806551037,,40,-486.890806551037,-3800.35632094247,,,IE,Laois,admin,,
42 | Castlebar,53.8500,-9.3000,Ireland,6371,0.5899,0.9869,41,3708.86113606146,-607.349303008152,,41,-607.349303008152,-3708.86113606146,,,IE,Mayo,admin,,
43 | Lifford,54.8356,-7.4779,Ireland,6371,0.5759,0.9915,42,3638.00869610949,-477.525437355137,,42,-477.525437355137,-3638.00869610949,,,IE,Donegal,admin,,
--------------------------------------------------------------------------------
/paper company Linkedin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "from pyomo.environ import *\n",
10 | "import matplotlib.pyplot as plt\n",
11 | "import numpy as np\n",
12 | "import random \n",
13 | "import pandas as pd"
14 | ]
15 | },
16 | {
17 | "cell_type": "code",
18 | "execution_count": 2,
19 | "metadata": {},
20 | "outputs": [
21 | {
22 | "data": {
23 | "text/html": [
24 | "\n",
25 | "\n",
38 | "
\n",
39 | " \n",
40 | " \n",
41 | " | \n",
42 | " w | \n",
43 | " n | \n",
44 | "
\n",
45 | " \n",
46 | " \n",
47 | " \n",
48 | " 0 | \n",
49 | " 14 | \n",
50 | " 211 | \n",
51 | "
\n",
52 | " \n",
53 | " 1 | \n",
54 | " 31 | \n",
55 | " 395 | \n",
56 | "
\n",
57 | " \n",
58 | " 2 | \n",
59 | " 36 | \n",
60 | " 610 | \n",
61 | "
\n",
62 | " \n",
63 | " 3 | \n",
64 | " 45 | \n",
65 | " 97 | \n",
66 | "
\n",
67 | " \n",
68 | "
\n",
69 | "
"
70 | ],
71 | "text/plain": [
72 | " w n\n",
73 | "0 14 211\n",
74 | "1 31 395\n",
75 | "2 36 610\n",
76 | "3 45 97"
77 | ]
78 | },
79 | "execution_count": 2,
80 | "metadata": {},
81 | "output_type": "execute_result"
82 | }
83 | ],
84 | "source": [
85 | "df = pd.read_csv(\"paper.csv\", delimiter=',', skiprows=0, low_memory=False)\n",
86 | "df"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": 25,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "model = AbstractModel()\n",
96 | "model.N =Param(mutable=True, initialize=455) \n",
97 | "model.i = RangeSet(1,model.N)\n",
98 | "model.j = RangeSet(1,4)\n",
99 | "model.U = Var(model.i, within=Binary, initialize=0)\n",
100 | "model.x = Var(model.i, model.j, bounds=(0,5), domain=NonNegativeIntegers,initialize=0)\n",
101 | "model.W =Param(model.j, mutable=True, initialize=1) \n",
102 | "model.number =Param(model.j, mutable=True, initialize=1) \n",
103 | "def rule_C1(model,i):\n",
104 | " return sum(model.W[j]*model.x[i,j] for j in model.j) <=100*model.U[i]\n",
105 | "model.C1 = Constraint(model.i,rule=rule_C1)\n",
106 | "def rule_C2(model,j):\n",
107 | " return sum(model.x[i,j] for i in model.i) ==model.number[j]\n",
108 | "model.C2 = Constraint(model.j,rule=rule_C2)\n",
109 | "def rule_OF(model):\n",
110 | " return sum(model.U[i] for i in model.i)\n",
111 | "model.obj1 = Objective(rule=rule_OF, sense=minimize)"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": 26,
117 | "metadata": {},
118 | "outputs": [],
119 | "source": [
120 | "instance = model.create_instance()\n",
121 | "for j in instance.j:\n",
122 | " instance.number[j]=df.iloc[j-1,1]\n",
123 | " instance.W[j]=df.iloc[j-1,0]"
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": 27,
129 | "metadata": {},
130 | "outputs": [
131 | {
132 | "name": "stdout",
133 | "output_type": "stream",
134 | "text": [
135 | "OF= 453.0\n",
136 | "this is feasible and optimal\n"
137 | ]
138 | }
139 | ],
140 | "source": [
141 | "opt = SolverFactory('gurobi')\n",
142 | "results=opt.solve(instance)\n",
143 | "print('OF= ',value(instance.obj1))\n",
144 | "from pyomo.opt import SolverStatus, TerminationCondition\n",
145 | "if (results.solver.status == SolverStatus.ok) and (results.solver.termination_condition == TerminationCondition.optimal):\n",
146 | " print (\"this is feasible and optimal\")\n",
147 | "elif results.solver.termination_condition == TerminationCondition.infeasible:\n",
148 | " print (\"do something about it? or exit?\")\n",
149 | "else:\n",
150 | " print (str(results.solver))"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": 18,
156 | "metadata": {},
157 | "outputs": [
158 | {
159 | "name": "stdout",
160 | "output_type": "stream",
161 | "text": [
162 | " U x \n",
163 | "1 200.0\n",
164 | "1 1 4.0\n",
165 | "1 3 4.0\n",
166 | "2 198.0\n",
167 | "2 3 3.0\n",
168 | "2 4 2.0\n",
169 | "3 200.0\n",
170 | "3 1 4.0\n",
171 | "3 3 4.0\n",
172 | "4 200.0\n",
173 | "4 1 4.0\n",
174 | "4 3 4.0\n",
175 | "5 198.0\n",
176 | "5 3 3.0\n",
177 | "5 4 2.0\n",
178 | "6 194.0\n",
179 | "6 1 1.0\n",
180 | "6 3 5.0\n",
181 | "7 198.0\n",
182 | "7 3 3.0\n",
183 | "7 4 2.0\n",
184 | "8 194.0\n",
185 | "8 1 1.0\n",
186 | "8 3 5.0\n",
187 | "9 198.0\n",
188 | "9 1 2.0\n",
189 | "9 2 2.0\n",
190 | "9 3 3.0\n",
191 | "10 198.0\n",
192 | "10 1 1.0\n",
193 | "10 2 1.0\n",
194 | "10 3 3.0\n",
195 | "10 4 1.0\n",
196 | "11 198.0\n",
197 | "11 3 3.0\n",
198 | "11 4 2.0\n",
199 | "12 194.0\n",
200 | "12 1 1.0\n",
201 | "12 3 5.0\n",
202 | "13 200.0\n",
203 | "13 1 4.0\n",
204 | "13 3 4.0\n",
205 | "14 196.0\n",
206 | "14 2 4.0\n",
207 | "14 3 2.0\n",
208 | "15 196.0\n",
209 | "15 2 4.0\n",
210 | "15 3 2.0\n",
211 | "16 198.0\n",
212 | "16 3 3.0\n",
213 | "16 4 2.0\n",
214 | "17 200.0\n",
215 | "17 1 4.0\n",
216 | "17 3 4.0\n",
217 | "18 198.0\n",
218 | "18 1 1.0\n",
219 | "18 2 1.0\n",
220 | "18 3 3.0\n",
221 | "18 4 1.0\n",
222 | "19 196.0\n",
223 | "19 2 4.0\n",
224 | "19 3 2.0\n",
225 | "20 198.0\n",
226 | "20 3 3.0\n",
227 | "20 4 2.0\n",
228 | "21 196.0\n",
229 | "21 2 4.0\n",
230 | "21 3 2.0\n",
231 | "22 194.0\n",
232 | "22 1 1.0\n",
233 | "22 3 5.0\n",
234 | "23 200.0\n",
235 | "23 1 4.0\n",
236 | "23 3 4.0\n",
237 | "24 196.0\n",
238 | "24 2 4.0\n",
239 | "24 3 2.0\n",
240 | "25 194.0\n",
241 | "25 1 1.0\n",
242 | "25 3 5.0\n",
243 | "26 198.0\n",
244 | "26 3 3.0\n",
245 | "26 4 2.0\n",
246 | "27 194.0\n",
247 | "27 1 1.0\n",
248 | "27 3 5.0\n",
249 | "28 196.0\n",
250 | "28 2 4.0\n",
251 | "28 3 2.0\n",
252 | "29 198.0\n",
253 | "29 1 2.0\n",
254 | "29 2 2.0\n",
255 | "29 3 3.0\n",
256 | "30 200.0\n",
257 | "30 1 4.0\n",
258 | "30 3 4.0\n",
259 | "31 196.0\n",
260 | "31 2 4.0\n",
261 | "31 3 2.0\n",
262 | "32 196.0\n",
263 | "32 2 4.0\n",
264 | "32 3 2.0\n",
265 | "33 200.0\n",
266 | "33 1 4.0\n",
267 | "33 3 4.0\n",
268 | "34 198.0\n",
269 | "34 3 3.0\n",
270 | "34 4 2.0\n",
271 | "35 196.0\n",
272 | "35 2 4.0\n",
273 | "35 3 2.0\n",
274 | "36 196.0\n",
275 | "36 2 4.0\n",
276 | "36 3 2.0\n",
277 | "37 196.0\n",
278 | "37 2 4.0\n",
279 | "37 3 2.0\n",
280 | "38 200.0\n",
281 | "38 1 4.0\n",
282 | "38 3 4.0\n",
283 | "39 198.0\n",
284 | "39 3 3.0\n",
285 | "39 4 2.0\n",
286 | "40 196.0\n",
287 | "40 2 4.0\n",
288 | "40 3 2.0\n",
289 | "41 194.0\n",
290 | "41 1 1.0\n",
291 | "41 3 5.0\n",
292 | "42 194.0\n",
293 | "42 1 1.0\n",
294 | "42 3 5.0\n",
295 | "43 196.0\n",
296 | "43 2 4.0\n",
297 | "43 3 2.0\n",
298 | "44 196.0\n",
299 | "44 2 4.0\n",
300 | "44 3 2.0\n",
301 | "45 200.0\n",
302 | "45 1 4.0\n",
303 | "45 3 4.0\n",
304 | "46 194.0\n",
305 | "46 1 1.0\n",
306 | "46 3 5.0\n",
307 | "47 196.0\n",
308 | "47 2 4.0\n",
309 | "47 3 2.0\n",
310 | "48 200.0\n",
311 | "48 1 4.0\n",
312 | "48 3 4.0\n",
313 | "49 196.0\n",
314 | "49 2 4.0\n",
315 | "49 3 2.0\n",
316 | "50 196.0\n",
317 | "50 2 4.0\n",
318 | "50 3 2.0\n",
319 | "51 194.0\n",
320 | "51 1 1.0\n",
321 | "51 3 5.0\n",
322 | "52 196.0\n",
323 | "52 2 4.0\n",
324 | "52 3 2.0\n",
325 | "53 198.0\n",
326 | "53 3 3.0\n",
327 | "53 4 2.0\n",
328 | "54 194.0\n",
329 | "54 1 1.0\n",
330 | "54 3 5.0\n",
331 | "55 194.0\n",
332 | "55 1 1.0\n",
333 | "55 3 5.0\n",
334 | "56 189.0\n",
335 | "56 3 4.0\n",
336 | "56 4 1.0\n",
337 | "57 200.0\n",
338 | "57 1 4.0\n",
339 | "57 3 4.0\n",
340 | "58 198.0\n",
341 | "58 3 3.0\n",
342 | "58 4 2.0\n",
343 | "59 194.0\n",
344 | "59 1 1.0\n",
345 | "59 3 5.0\n",
346 | "60 194.0\n",
347 | "60 1 1.0\n",
348 | "60 3 5.0\n",
349 | "61 200.0\n",
350 | "61 1 4.0\n",
351 | "61 3 4.0\n",
352 | "62 198.0\n",
353 | "62 3 3.0\n",
354 | "62 4 2.0\n",
355 | "63 194.0\n",
356 | "63 1 1.0\n",
357 | "63 3 5.0\n",
358 | "64 200.0\n",
359 | "64 1 4.0\n",
360 | "64 3 4.0\n",
361 | "65 196.0\n",
362 | "65 2 4.0\n",
363 | "65 3 2.0\n",
364 | "66 196.0\n",
365 | "66 2 4.0\n",
366 | "66 3 2.0\n",
367 | "67 196.0\n",
368 | "67 2 4.0\n",
369 | "67 3 2.0\n",
370 | "68 200.0\n",
371 | "68 1 4.0\n",
372 | "68 3 4.0\n",
373 | "69 200.0\n",
374 | "69 1 4.0\n",
375 | "69 3 4.0\n",
376 | "70 194.0\n",
377 | "70 1 1.0\n",
378 | "70 3 5.0\n",
379 | "71 198.0\n",
380 | "71 3 3.0\n",
381 | "71 4 2.0\n",
382 | "72 200.0\n",
383 | "72 1 4.0\n",
384 | "72 3 4.0\n",
385 | "73 198.0\n",
386 | "73 3 3.0\n",
387 | "73 4 2.0\n",
388 | "74 196.0\n",
389 | "74 2 4.0\n",
390 | "74 3 2.0\n",
391 | "75 194.0\n",
392 | "75 1 1.0\n",
393 | "75 3 5.0\n",
394 | "76 200.0\n",
395 | "76 1 4.0\n",
396 | "76 3 4.0\n",
397 | "77 198.0\n",
398 | "77 1 2.0\n",
399 | "77 2 2.0\n",
400 | "77 3 3.0\n",
401 | "78 198.0\n",
402 | "78 1 2.0\n",
403 | "78 2 2.0\n",
404 | "78 3 3.0\n",
405 | "79 194.0\n",
406 | "79 1 1.0\n",
407 | "79 3 5.0\n",
408 | "80 194.0\n",
409 | "80 1 1.0\n",
410 | "80 3 5.0\n",
411 | "81 200.0\n",
412 | "81 1 4.0\n",
413 | "81 3 4.0\n",
414 | "82 200.0\n",
415 | "82 1 4.0\n",
416 | "82 3 4.0\n",
417 | "83 194.0\n",
418 | "83 1 1.0\n",
419 | "83 3 5.0\n",
420 | "84 194.0\n",
421 | "84 1 1.0\n",
422 | "84 3 5.0\n",
423 | "85 198.0\n",
424 | "85 1 2.0\n",
425 | "85 2 2.0\n",
426 | "85 3 3.0\n",
427 | "86 196.0\n",
428 | "86 2 4.0\n",
429 | "86 3 2.0\n",
430 | "87 189.0\n",
431 | "87 3 4.0\n",
432 | "87 4 1.0\n",
433 | "88 198.0\n",
434 | "88 3 3.0\n",
435 | "88 4 2.0\n",
436 | "89 198.0\n",
437 | "89 3 3.0\n",
438 | "89 4 2.0\n",
439 | "90 200.0\n",
440 | "90 1 4.0\n",
441 | "90 3 4.0\n",
442 | "91 200.0\n",
443 | "91 1 4.0\n",
444 | "91 3 4.0\n",
445 | "92 200.0\n",
446 | "92 1 4.0\n",
447 | "92 3 4.0\n",
448 | "93 198.0\n",
449 | "93 1 1.0\n",
450 | "93 2 1.0\n",
451 | "93 3 3.0\n",
452 | "93 4 1.0\n",
453 | "94 191.0\n",
454 | "94 2 5.0\n",
455 | "94 3 1.0\n",
456 | "95 191.0\n",
457 | "95 2 5.0\n",
458 | "95 3 1.0\n",
459 | "96 196.0\n",
460 | "96 2 4.0\n",
461 | "96 3 2.0\n",
462 | "97 196.0\n",
463 | "97 2 4.0\n",
464 | "97 3 2.0\n",
465 | "98 194.0\n",
466 | "98 1 1.0\n",
467 | "98 3 5.0\n",
468 | "99 199.0\n",
469 | "99 1 2.0\n",
470 | "99 3 1.0\n",
471 | "99 4 3.0\n",
472 | "100 191.0\n",
473 | "100 2 5.0\n",
474 | "100 3 1.0\n",
475 | "101 199.0\n",
476 | "101 1 4.0\n",
477 | "101 2 2.0\n",
478 | "101 3 1.0\n",
479 | "101 4 1.0\n",
480 | "102 194.0\n",
481 | "102 1 1.0\n",
482 | "102 3 5.0\n",
483 | "103 194.0\n",
484 | "103 1 1.0\n",
485 | "103 3 5.0\n",
486 | "104 199.0\n",
487 | "104 1 5.0\n",
488 | "104 2 3.0\n",
489 | "104 3 1.0\n",
490 | "105 196.0\n",
491 | "105 2 4.0\n",
492 | "105 3 2.0\n",
493 | "106 198.0\n",
494 | "106 3 3.0\n",
495 | "106 4 2.0\n",
496 | "107 198.0\n",
497 | "107 3 3.0\n",
498 | "107 4 2.0\n",
499 | "108 198.0\n",
500 | "108 3 3.0\n",
501 | "108 4 2.0\n",
502 | "109 199.0\n",
503 | "109 1 2.0\n",
504 | "109 3 1.0\n",
505 | "109 4 3.0\n",
506 | "110 196.0\n",
507 | "110 2 4.0\n",
508 | "110 3 2.0\n",
509 | "111 196.0\n",
510 | "111 2 4.0\n",
511 | "111 3 2.0\n",
512 | "112 198.0\n",
513 | "112 3 3.0\n",
514 | "112 4 2.0\n",
515 | "113 194.0\n",
516 | "113 1 1.0\n",
517 | "113 3 5.0\n",
518 | "114 196.0\n",
519 | "114 2 4.0\n",
520 | "114 3 2.0\n",
521 | "116 194.0\n",
522 | "116 1 1.0\n",
523 | "116 3 5.0\n",
524 | "117 200.0\n",
525 | "117 1 1.0\n",
526 | "117 2 6.0\n",
527 | "121 200.0\n",
528 | "121 2 5.0\n",
529 | "121 4 1.0\n",
530 | "127 200.0\n",
531 | "127 1 1.0\n",
532 | "127 2 6.0\n",
533 | "129 200.0\n",
534 | "129 2 5.0\n",
535 | "129 4 1.0\n",
536 | "132 198.0\n",
537 | "132 1 2.0\n",
538 | "132 2 2.0\n",
539 | "132 3 3.0\n",
540 | "134 194.0\n",
541 | "134 1 1.0\n",
542 | "134 3 5.0\n",
543 | "135 198.0\n",
544 | "135 3 3.0\n",
545 | "135 4 2.0\n",
546 | "138 194.0\n",
547 | "138 1 1.0\n",
548 | "138 3 5.0\n",
549 | "139 200.0\n",
550 | "139 1 4.0\n",
551 | "139 3 4.0\n",
552 | "145 194.0\n",
553 | "145 1 1.0\n",
554 | "145 3 5.0\n",
555 | "147 194.0\n",
556 | "147 1 1.0\n",
557 | "147 3 5.0\n",
558 | "148 194.0\n",
559 | "148 1 1.0\n",
560 | "148 3 5.0\n",
561 | "153 198.0\n",
562 | "153 1 1.0\n",
563 | "153 2 1.0\n",
564 | "153 3 3.0\n",
565 | "153 4 1.0\n",
566 | "155 194.0\n",
567 | "155 1 1.0\n",
568 | "155 3 5.0\n",
569 | "160 194.0\n",
570 | "160 1 1.0\n",
571 | "160 3 5.0\n",
572 | "161 194.0\n",
573 | "161 1 1.0\n",
574 | "161 3 5.0\n",
575 | "163 196.0\n",
576 | "163 2 4.0\n",
577 | "163 3 2.0\n",
578 | "169 200.0\n",
579 | "169 2 5.0\n",
580 | "169 4 1.0\n",
581 | "178 198.0\n",
582 | "178 1 1.0\n",
583 | "178 2 1.0\n",
584 | "178 3 3.0\n",
585 | "178 4 1.0\n",
586 | "181 198.0\n",
587 | "181 1 1.0\n",
588 | "181 2 1.0\n",
589 | "181 3 3.0\n",
590 | "181 4 1.0\n",
591 | "182 200.0\n",
592 | "182 2 5.0\n",
593 | "182 4 1.0\n",
594 | "183 194.0\n",
595 | "183 1 1.0\n",
596 | "183 3 5.0\n",
597 | "187 194.0\n",
598 | "187 1 1.0\n",
599 | "187 3 5.0\n",
600 | "188 200.0\n",
601 | "188 2 5.0\n",
602 | "188 4 1.0\n",
603 | "189 194.0\n",
604 | "189 1 1.0\n",
605 | "189 3 5.0\n",
606 | "194 194.0\n",
607 | "194 1 1.0\n",
608 | "194 3 5.0\n",
609 | "210 194.0\n",
610 | "210 1 1.0\n",
611 | "210 3 5.0\n",
612 | "222 200.0\n",
613 | "222 2 5.0\n",
614 | "222 4 1.0\n",
615 | "223 194.0\n",
616 | "223 1 1.0\n",
617 | "223 3 5.0\n",
618 | "227 200.0\n",
619 | "227 1 1.0\n",
620 | "227 2 6.0\n",
621 | "238 198.0\n",
622 | "238 1 1.0\n",
623 | "238 2 1.0\n",
624 | "238 3 3.0\n",
625 | "238 4 1.0\n",
626 | "242 194.0\n",
627 | "242 1 1.0\n",
628 | "242 3 5.0\n",
629 | "243 194.0\n",
630 | "243 1 1.0\n",
631 | "243 3 5.0\n",
632 | "244 198.0\n",
633 | "244 3 3.0\n",
634 | "244 4 2.0\n",
635 | "246 200.0\n",
636 | "246 1 1.0\n",
637 | "246 2 6.0\n",
638 | "248 198.0\n",
639 | "248 1 1.0\n",
640 | "248 2 1.0\n",
641 | "248 3 3.0\n",
642 | "248 4 1.0\n",
643 | "249 200.0\n",
644 | "249 1 1.0\n",
645 | "249 2 6.0\n",
646 | "253 198.0\n",
647 | "253 3 3.0\n",
648 | "253 4 2.0\n",
649 | "254 200.0\n",
650 | "254 1 1.0\n",
651 | "254 2 6.0\n",
652 | "265 200.0\n",
653 | "265 2 5.0\n",
654 | "265 4 1.0\n",
655 | "270 194.0\n",
656 | "270 1 1.0\n",
657 | "270 3 5.0\n",
658 | "278 194.0\n",
659 | "278 1 1.0\n",
660 | "278 3 5.0\n",
661 | "280 200.0\n",
662 | "280 2 5.0\n",
663 | "280 4 1.0\n",
664 | "287 200.0\n",
665 | "287 1 1.0\n",
666 | "287 2 6.0\n",
667 | "289 194.0\n",
668 | "289 1 1.0\n",
669 | "289 3 5.0\n",
670 | "290 189.0\n",
671 | "290 3 4.0\n",
672 | "290 4 1.0\n",
673 | "295 200.0\n",
674 | "295 2 5.0\n",
675 | "295 4 1.0\n",
676 | "301 200.0\n",
677 | "301 2 5.0\n",
678 | "301 4 1.0\n",
679 | "304 194.0\n",
680 | "304 1 1.0\n",
681 | "304 3 5.0\n",
682 | "307 194.0\n",
683 | "307 1 1.0\n",
684 | "307 3 5.0\n",
685 | "308 200.0\n",
686 | "308 1 1.0\n",
687 | "308 2 6.0\n",
688 | "309 194.0\n",
689 | "309 1 1.0\n",
690 | "309 3 5.0\n",
691 | "314 176.0\n",
692 | "314 1 2.0\n",
693 | "314 2 1.0\n",
694 | "314 3 2.0\n",
695 | "314 4 1.0\n",
696 | "319 200.0\n",
697 | "319 1 1.0\n",
698 | "319 2 6.0\n",
699 | "323 200.0\n",
700 | "323 2 5.0\n",
701 | "323 4 1.0\n",
702 | "324 200.0\n",
703 | "324 2 5.0\n",
704 | "324 4 1.0\n",
705 | "338 200.0\n",
706 | "338 2 5.0\n",
707 | "338 4 1.0\n",
708 | "342 194.0\n",
709 | "342 1 1.0\n",
710 | "342 3 5.0\n",
711 | "347 200.0\n",
712 | "347 2 5.0\n",
713 | "347 4 1.0\n",
714 | "349 198.0\n",
715 | "349 1 1.0\n",
716 | "349 2 1.0\n",
717 | "349 3 3.0\n",
718 | "349 4 1.0\n",
719 | "350 194.0\n",
720 | "350 1 1.0\n",
721 | "350 3 5.0\n",
722 | "351 194.0\n",
723 | "351 1 1.0\n",
724 | "351 3 5.0\n",
725 | "354 200.0\n",
726 | "354 1 1.0\n",
727 | "354 2 6.0\n",
728 | "356 200.0\n",
729 | "356 2 5.0\n",
730 | "356 4 1.0\n",
731 | "361 200.0\n",
732 | "361 2 5.0\n",
733 | "361 4 1.0\n",
734 | "369 200.0\n",
735 | "369 2 5.0\n",
736 | "369 4 1.0\n",
737 | "372 200.0\n",
738 | "372 2 5.0\n",
739 | "372 4 1.0\n",
740 | "373 194.0\n",
741 | "373 1 1.0\n",
742 | "373 3 5.0\n",
743 | "374 200.0\n",
744 | "374 2 5.0\n",
745 | "374 4 1.0\n",
746 | "378 200.0\n",
747 | "378 1 1.0\n",
748 | "378 2 6.0\n",
749 | "387 194.0\n",
750 | "387 1 1.0\n",
751 | "387 3 5.0\n",
752 | "389 196.0\n",
753 | "389 2 4.0\n",
754 | "389 3 2.0\n",
755 | "390 200.0\n",
756 | "390 2 5.0\n",
757 | "390 4 1.0\n",
758 | "392 194.0\n",
759 | "392 1 1.0\n",
760 | "392 3 5.0\n",
761 | "393 194.0\n",
762 | "393 1 1.0\n",
763 | "393 3 5.0\n",
764 | "398 194.0\n",
765 | "398 1 1.0\n",
766 | "398 3 5.0\n",
767 | "401 200.0\n",
768 | "401 1 1.0\n",
769 | "401 2 6.0\n",
770 | "404 198.0\n",
771 | "404 1 1.0\n",
772 | "404 2 1.0\n",
773 | "404 3 3.0\n",
774 | "404 4 1.0\n",
775 | "406 200.0\n",
776 | "406 1 1.0\n",
777 | "406 2 6.0\n",
778 | "414 198.0\n",
779 | "414 1 1.0\n",
780 | "414 2 1.0\n",
781 | "414 3 3.0\n",
782 | "414 4 1.0\n",
783 | "415 200.0\n",
784 | "415 2 5.0\n",
785 | "415 4 1.0\n",
786 | "418 198.0\n",
787 | "418 3 3.0\n",
788 | "418 4 2.0\n",
789 | "419 200.0\n",
790 | "419 1 1.0\n",
791 | "419 2 6.0\n",
792 | "422 200.0\n",
793 | "422 2 5.0\n",
794 | "422 4 1.0\n",
795 | "423 200.0\n",
796 | "423 2 5.0\n",
797 | "423 4 1.0\n",
798 | "424 196.0\n",
799 | "424 2 4.0\n",
800 | "424 3 2.0\n",
801 | "428 200.0\n",
802 | "428 2 5.0\n",
803 | "428 4 1.0\n",
804 | "430 194.0\n",
805 | "430 1 1.0\n",
806 | "430 3 5.0\n",
807 | "431 198.0\n",
808 | "431 1 1.0\n",
809 | "431 2 1.0\n",
810 | "431 3 3.0\n",
811 | "431 4 1.0\n",
812 | "438 200.0\n",
813 | "438 2 5.0\n",
814 | "438 4 1.0\n",
815 | "440 189.0\n",
816 | "440 3 4.0\n",
817 | "440 4 1.0\n",
818 | "447 196.0\n",
819 | "447 2 4.0\n",
820 | "447 3 2.0\n",
821 | "450 194.0\n",
822 | "450 1 1.0\n",
823 | "450 3 5.0\n",
824 | "451 196.0\n",
825 | "451 2 4.0\n",
826 | "451 3 2.0\n",
827 | "454 197.0\n",
828 | "454 1 3.0\n",
829 | "454 2 5.0\n",
830 | "455 194.0\n",
831 | "455 1 1.0\n",
832 | "455 3 5.0\n",
833 | "1 211.0\n",
834 | "2 395.0\n",
835 | "3 610.0\n",
836 | "4 97.0\n"
837 | ]
838 | }
839 | ],
840 | "source": [
841 | "print(' U x ')\n",
842 | "for i in instance.i:\n",
843 | " if value(instance.U[i])==1:\n",
844 | " print(i,sum(value(instance.W[j]*instance.x[i,j]) for j in instance.j) ) \n",
845 | " for j in instance.j:\n",
846 | " if value(instance.x[i,j])>0:\n",
847 | " print(i,j,value(instance.x[i,j]))\n",
848 | " \n",
849 | "for j in instance.j:\n",
850 | " print(j, sum(value(instance.x[i,j]) for i in instance.i))"
851 | ]
852 | },
853 | {
854 | "cell_type": "code",
855 | "execution_count": null,
856 | "metadata": {},
857 | "outputs": [],
858 | "source": []
859 | }
860 | ],
861 | "metadata": {
862 | "kernelspec": {
863 | "display_name": "Python 3",
864 | "language": "python",
865 | "name": "python3"
866 | },
867 | "language_info": {
868 | "codemirror_mode": {
869 | "name": "ipython",
870 | "version": 3
871 | },
872 | "file_extension": ".py",
873 | "mimetype": "text/x-python",
874 | "name": "python",
875 | "nbconvert_exporter": "python",
876 | "pygments_lexer": "ipython3",
877 | "version": "3.7.4"
878 | }
879 | },
880 | "nbformat": 4,
881 | "nbformat_minor": 4
882 | }
883 |
--------------------------------------------------------------------------------