diff --git a/examples/cp/basic/plant_location_with_kpis.py b/examples/cp/basic/plant_location_with_kpis.py new file mode 100644 index 0000000..d66b986 --- /dev/null +++ b/examples/cp/basic/plant_location_with_kpis.py @@ -0,0 +1,120 @@ +# -------------------------------------------------------------------------- +# Source file provided under Apache License, Version 2.0, January 2004, +# http://www.apache.org/licenses/ +# (c) Copyright IBM Corp. 2015, 2016, 2018 +# -------------------------------------------------------------------------- + +""" +A ship-building company has a certain number of customers. Each customer is supplied +by exactly one plant. In turn, a plant can supply several customers. The problem is +to decide where to set up the plants in order to supply every customer while minimizing +the cost of building each plant and the transportation cost of supplying the customers. + +For each possible plant location there is a fixed cost and a production capacity. +Both take into account the country and the geographical conditions. + +For every customer, there is a demand and a transportation cost with respect to +each plant location. + +While a first solution of this problem can be found easily by CP Optimizer, it can take +quite some time to improve it to a very good one. We illustrate the warm start capabilities +of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. +This solution could be one from an expert or the result of another optimization engine +applied to the problem. + +In the solution we only give a value to the variables that determine which plant delivers +a customer. This is sufficient to define a complete solution on all model variables. +CP Optimizer first extends the solution to all variables and then starts to improve it. + +The model has been enriched by the addition of KPIs (key performance indicators), operational with a +version of COS greater or equal to 12.9.0.0. +These are named expressions which are of interest to help get an idea of the performance of the model. +Here, we are interested in two indicators: + - the first is the `occupancy'' defined as the total demand divided by the total plant capacity. + - the second indicator is the occupancy which is the lowest of all the plants. + +The KPIs are displayed in the log whenever an improving solution is found and at the end of the search. +""" + +from docplex.cp.model import CpoModel +from docplex.cp.config import context +from docplex.cp.utils import compare_natural +from collections import deque +import os + +#----------------------------------------------------------------------------- +# Initialize the problem data +#----------------------------------------------------------------------------- + +# Read problem data from a file and convert it as a list of integers +filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" +data = deque() +with open(filename, "r") as file: + for val in file.read().split(): + data.append(int(val)) + +# Read number of customers and locations +nbCustomer = data.popleft() +nbLocation = data.popleft() + +# Initialize cost. cost[c][p] = cost to deliver customer c from plant p +cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) + +# Initialize demand of each customer +demand = list([data.popleft() for c in range(nbCustomer)]) + +# Initialize fixed cost of each location +fixedCost = list([data.popleft() for p in range(nbLocation)]) + +# Initialize capacity of each location +capacity = list([data.popleft() for p in range(nbLocation)]) + + +#----------------------------------------------------------------------------- +# Build the model +#----------------------------------------------------------------------------- + +mdl = CpoModel() + +# Create variables identifying which location serves each customer +cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") + +# Create variables indicating which plant location is open +open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") + +# Create variables indicating load of each plant +load = [mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] + +# Associate plant openness to its load +for p in range(nbLocation): + mdl.add(open[p] == (load[p] > 0)) + +# Add constraints +mdl.add(mdl.pack(load, cust, demand)) + +# Add objective +obj = mdl.scal_prod(fixedCost, open) +for c in range(nbCustomer): + obj += mdl.element(cust[c], cost[c]) +mdl.add(mdl.minimize(obj)) + +# Add KPIs +if compare_natural(context.model.version, '12.9') >= 0: + mdl.add_kpi(mdl.sum(demand) / mdl.scal_prod(open, capacity), "Occupancy") + mdl.add_kpi(mdl.min([load[l] / capacity[l] + (1 - open[l]) for l in range(nbLocation)]), "Min occupancy") + + +#----------------------------------------------------------------------------- +# Solve the model and display the result +#----------------------------------------------------------------------------- + +# Solve the model +print("Solve the model") +msol = mdl.solve(TimeLimit=10, trace_log=False) # Set trace_log=True to have a real-time view of the KPIs +if msol: + print(" Objective value: {}".format(msol.get_objective_values()[0])) + if context.model.version >= '12.9': + print(" KPIs: {}".format(msol.get_kpis())) +else: + print(" No solution") + diff --git a/examples/cp/visu/data/plant_location.data b/examples/cp/visu/data/plant_location.data new file mode 100644 index 0000000..9aabd58 --- /dev/null +++ b/examples/cp/visu/data/plant_location.data @@ -0,0 +1,287 @@ +90 +30 +28 30 25 60 8 95 93 19 34 57 +79 27 38 43 80 54 48 2 46 22 +3 57 45 75 85 37 88 83 98 98 +4 73 85 86 9 63 42 6 67 8 +55 77 7 29 62 81 4 11 70 1 +77 99 7 23 52 28 46 1 43 15 +88 91 65 92 76 69 86 7 58 87 +84 1 5 20 43 67 72 25 37 47 +89 14 21 79 52 91 2 31 82 79 +99 4 62 44 58 86 68 55 12 41 +72 25 28 57 74 98 60 54 92 44 +31 67 40 81 51 27 36 26 20 79 +52 78 68 21 30 68 98 25 9 13 +4 78 25 17 18 93 83 62 88 53 +45 66 89 45 25 36 59 92 66 20 +22 91 10 32 98 47 62 69 58 9 +60 17 79 36 32 75 42 55 22 47 +51 40 55 69 14 96 83 96 73 23 +16 63 3 86 92 50 84 23 31 62 +61 84 47 48 94 98 98 37 40 40 +41 94 71 27 27 42 23 42 31 13 +96 49 25 79 76 75 90 29 38 11 +26 80 80 90 72 52 94 52 92 95 +9 85 93 67 82 89 63 30 12 3 +23 97 22 8 5 37 18 49 61 68 +56 61 53 20 55 80 5 1 81 92 +18 4 53 63 68 52 49 90 40 72 +71 33 99 4 51 8 84 80 83 95 +77 45 7 46 33 4 61 30 12 94 +92 84 66 93 1 55 69 18 7 59 +13 23 59 73 72 30 77 6 61 72 +63 8 99 67 5 86 85 38 20 46 +51 52 89 82 70 11 87 81 28 60 +73 75 49 27 89 0 73 79 64 59 +83 6 9 51 51 98 63 9 7 96 +70 32 0 21 49 77 16 51 40 24 +63 3 48 68 53 13 52 48 42 77 +89 30 4 83 49 12 59 22 7 14 +19 61 48 73 60 63 4 4 95 83 +73 70 44 38 84 63 99 44 16 79 +60 55 43 67 68 7 55 24 33 76 +62 69 26 96 81 16 88 36 22 63 +53 22 25 56 28 36 70 33 63 76 +87 84 37 42 12 77 64 19 93 37 +18 54 89 49 48 53 66 44 0 99 +61 65 27 13 80 85 23 14 86 95 +42 80 62 75 48 45 61 51 92 59 +84 27 72 26 50 25 45 14 84 86 +14 82 76 42 30 79 83 26 17 95 +56 12 53 65 40 44 22 2 59 6 +25 58 87 32 18 20 10 78 78 53 +51 3 33 82 30 28 50 62 32 80 +71 82 73 29 88 96 71 31 54 56 +21 7 35 66 92 52 60 56 49 68 +3 60 39 66 4 48 29 83 32 35 +81 4 8 65 11 86 72 10 98 81 +80 79 84 57 43 30 39 2 44 51 +19 27 83 60 68 98 60 41 45 57 +27 29 7 6 14 38 90 19 65 66 +10 26 14 6 71 64 40 10 96 3 +62 49 34 35 40 61 4 72 45 70 +7 55 45 59 81 60 13 4 7 38 +21 1 0 4 67 11 69 56 25 80 +93 34 6 32 60 17 92 90 51 5 +97 42 73 41 81 63 15 42 79 6 +26 6 58 37 5 27 57 25 23 49 +59 72 77 55 81 99 17 11 94 57 +45 98 44 11 0 45 71 7 67 59 +26 46 69 60 71 4 2 50 13 82 +41 50 11 28 7 44 77 52 95 51 +73 20 72 12 68 37 52 48 31 28 +2 26 42 5 9 96 88 38 22 46 +77 39 0 84 32 80 75 74 72 10 +50 91 33 27 98 26 54 97 21 63 +94 7 4 54 79 59 35 11 1 31 +69 80 6 87 67 57 30 82 77 29 +22 18 28 13 6 73 56 46 9 39 +52 56 80 77 0 8 14 52 71 20 +81 49 6 67 21 41 97 78 83 85 +66 58 77 81 35 98 67 19 69 59 +0 73 44 78 77 82 34 42 26 7 +90 86 63 8 16 63 96 1 62 93 +6 0 93 77 44 38 39 95 65 84 +91 51 64 88 47 20 93 24 2 8 +70 43 6 15 14 81 87 74 59 97 +18 65 16 69 59 41 12 23 10 92 +21 82 55 30 80 8 97 98 71 51 +16 76 59 66 75 26 78 77 41 50 +58 54 25 58 58 80 30 8 25 77 +17 42 5 9 57 26 79 92 45 94 +36 14 3 34 39 23 72 85 45 68 +75 90 9 70 19 92 52 16 20 25 +21 4 78 48 93 31 16 80 80 24 +41 20 80 36 79 46 15 22 77 2 +35 12 74 44 70 66 48 64 52 89 +11 75 28 51 76 32 61 98 68 2 +65 41 28 13 50 93 5 83 47 67 +61 98 17 71 61 10 59 12 78 23 +23 22 84 50 77 90 70 56 80 94 +80 76 18 99 61 37 85 31 92 44 +36 96 81 8 81 7 58 83 29 43 +27 13 28 11 87 30 60 40 23 50 +68 63 19 31 85 51 91 35 58 60 +19 25 51 10 98 30 48 69 79 58 +36 89 41 44 78 60 90 19 70 32 +64 45 17 99 73 2 90 86 58 89 +44 1 22 30 66 32 25 77 38 94 +44 13 16 76 16 83 87 36 65 49 +82 17 99 3 11 77 89 75 48 58 +56 38 19 98 82 40 83 13 53 55 +0 52 72 0 83 44 12 11 71 13 +58 16 44 73 80 87 2 40 31 50 +15 82 93 19 34 40 12 77 18 28 +25 29 91 40 74 10 51 12 17 89 +34 5 13 68 13 73 55 16 30 34 +42 80 1 3 4 8 75 87 56 13 +38 19 12 46 53 86 46 64 56 47 +98 3 1 43 17 58 40 3 19 62 +41 47 73 79 38 76 82 9 66 91 +15 64 23 95 73 28 10 9 27 38 +33 90 35 34 79 90 90 36 8 15 +83 42 68 15 84 45 17 22 24 75 +88 71 12 62 74 2 10 54 31 84 +80 31 4 25 97 10 78 16 68 16 +48 76 79 5 47 53 63 59 48 87 +9 56 33 72 73 58 90 70 46 21 +94 4 55 47 80 8 7 34 88 86 +7 70 65 73 77 31 11 70 6 18 +20 51 20 1 8 95 62 20 51 33 +10 40 63 81 9 22 29 3 60 6 +16 56 8 65 45 22 23 32 46 99 +70 90 72 22 28 96 17 59 57 35 +19 4 70 28 5 87 22 21 88 7 +77 36 36 10 54 33 11 93 27 69 +96 4 94 81 44 53 70 33 30 31 +93 87 93 94 87 65 10 48 87 83 +48 33 24 75 40 29 77 98 91 15 +17 26 97 40 47 62 77 58 46 20 +80 78 96 62 79 49 8 50 62 86 +97 90 11 94 50 81 61 69 67 66 +37 89 6 82 41 8 83 10 89 66 +7 58 17 71 97 55 14 94 25 33 +58 35 53 95 1 10 67 93 73 66 +11 5 42 56 60 95 34 58 30 16 +61 30 5 96 5 75 95 87 40 56 +77 3 24 29 7 56 49 81 97 78 +58 83 24 45 25 61 41 87 2 25 +3 5 41 53 28 72 42 9 57 21 +74 64 76 51 80 31 8 40 1 99 +68 70 35 77 6 19 69 62 68 51 +99 67 28 26 43 15 77 87 47 59 +38 62 85 7 92 42 19 10 81 38 +18 13 93 70 89 88 50 87 73 4 +97 42 79 75 57 65 46 54 12 96 +25 68 96 9 38 49 36 66 26 67 +91 41 9 72 92 23 9 60 52 88 +46 6 26 52 4 14 13 43 92 61 +41 99 35 25 67 11 90 50 41 61 +31 63 28 73 90 90 63 66 56 43 +2 92 36 38 60 90 56 89 14 92 +31 26 70 84 0 77 93 76 64 0 +66 16 99 17 16 20 32 10 99 75 +23 81 38 76 95 94 76 16 0 13 +66 22 23 75 47 47 31 76 89 0 +71 84 43 59 4 77 58 46 48 89 +20 71 86 69 62 81 16 56 69 46 +64 93 18 47 39 79 54 65 17 29 +46 36 71 76 89 58 72 45 1 18 +48 83 25 5 7 11 15 24 0 87 +43 57 95 14 27 74 27 14 60 24 +81 28 26 30 31 75 92 51 92 96 +15 77 19 67 41 21 59 36 18 27 +94 85 0 64 88 83 57 86 96 6 +33 71 5 95 30 65 44 34 25 61 +70 86 69 11 80 96 80 26 44 66 +91 66 54 25 38 1 75 77 88 42 +74 59 39 70 75 0 98 8 87 3 +72 89 37 14 93 98 45 99 63 23 +71 58 68 24 58 30 4 62 52 23 +70 91 85 90 46 93 74 82 90 24 +12 98 6 77 42 15 93 24 35 6 +13 31 52 3 24 25 33 28 91 12 +63 97 8 49 12 93 3 26 55 59 +19 26 42 99 8 73 18 40 64 96 +43 42 12 2 75 97 26 22 40 99 +56 92 11 15 85 13 19 7 29 50 +39 47 24 60 97 7 62 95 6 0 +28 98 95 99 94 75 20 73 43 77 +7 38 32 19 12 6 94 59 69 17 +5 89 37 70 95 71 12 41 18 16 +8 24 41 68 65 6 54 17 94 52 +99 19 0 78 75 37 16 66 74 25 +87 74 71 61 73 67 18 99 60 30 +98 64 2 92 98 80 22 30 14 24 +14 81 88 47 64 36 33 89 3 98 +24 57 16 52 6 2 3 14 82 76 +49 15 27 32 74 31 91 86 21 79 +10 26 88 18 24 20 25 1 96 84 +25 82 59 63 87 16 23 80 29 10 +8 87 46 30 55 0 26 87 28 16 +19 44 48 54 95 49 77 50 92 1 +59 81 55 20 96 48 29 60 68 9 +11 11 79 49 85 62 68 87 56 19 +87 39 38 5 33 60 4 20 97 85 +32 92 31 93 78 86 78 21 41 51 +32 70 89 2 96 67 56 45 95 82 +56 60 58 0 79 55 12 78 24 79 +91 88 13 82 78 88 26 76 12 79 +6 73 64 5 15 87 79 3 12 73 +25 13 60 67 93 46 50 65 78 22 +15 77 18 17 53 79 46 58 48 99 +41 2 33 97 25 99 90 81 45 11 +68 12 14 6 43 81 42 32 89 78 +93 86 17 43 14 99 99 76 69 46 +10 11 78 95 95 12 29 49 82 92 +92 67 90 72 10 87 83 77 53 70 +70 83 50 73 96 71 19 67 99 75 +64 65 37 21 65 25 29 7 65 12 +60 49 70 41 28 98 60 42 58 15 +84 30 95 88 7 55 94 74 29 94 +11 41 87 24 95 72 61 20 92 38 +39 58 6 89 14 20 28 39 54 78 +78 65 9 66 62 77 4 78 6 20 +81 6 87 15 42 72 4 80 73 24 +17 13 28 6 26 93 34 55 15 52 +70 98 92 78 78 43 31 15 72 58 +55 61 94 66 71 67 97 63 7 41 +67 29 99 85 54 66 46 42 23 50 +94 60 51 18 72 98 37 38 13 91 +79 22 97 57 96 67 42 43 41 50 +37 41 14 3 40 54 47 45 91 91 +54 77 49 7 75 0 58 89 93 56 +8 32 2 94 79 70 16 10 84 67 +57 81 94 93 99 76 19 35 28 53 +88 95 9 41 93 96 20 46 80 8 +0 13 76 73 82 31 43 37 40 67 +22 82 2 28 71 70 78 51 69 10 +75 71 14 56 69 71 47 44 71 93 +33 33 89 81 93 8 93 7 26 34 +63 14 54 1 25 86 84 91 54 49 +56 57 85 83 79 78 72 48 68 42 +86 63 70 8 40 60 72 79 73 33 +3 20 26 15 53 24 20 91 4 46 +64 81 90 14 55 24 89 96 50 67 +62 15 14 34 34 12 87 24 41 7 +82 7 95 69 41 3 76 44 62 61 +22 53 51 16 18 10 9 89 11 41 +55 80 95 76 65 12 77 14 48 37 +41 39 64 22 38 91 98 0 4 18 +0 77 26 41 68 1 76 7 99 85 +6 85 95 22 10 29 53 74 0 1 +98 83 9 91 51 14 1 18 42 22 +52 62 71 59 5 35 90 91 17 5 +33 50 69 14 63 17 13 62 40 90 +83 85 44 25 81 1 98 46 76 37 +6 15 27 38 18 68 53 15 84 71 +28 47 35 74 13 19 52 13 17 38 +35 20 53 45 76 69 48 34 13 34 +75 27 59 30 20 23 19 87 43 88 +84 67 23 84 42 43 22 78 90 68 +93 72 64 52 66 48 27 15 42 18 +31 10 16 89 53 59 74 61 41 45 +58 31 57 71 31 98 92 38 89 55 +34 57 72 49 68 86 39 19 66 25 +74 73 14 16 50 47 73 73 64 45 +90 2 71 83 98 5 49 30 72 5 +94 73 67 53 71 15 30 29 29 5 +75 22 32 44 22 18 13 25 54 4 +87 80 72 40 31 3 14 1 84 61 +15 85 56 40 90 63 59 31 50 18 +18 56 38 21 40 51 33 46 11 14 +47 53 34 59 44 15 29 28 58 29 +59 16 58 24 21 16 20 47 44 31 +46 43 49 20 14 26 24 10 41 51 +47 16 36 15 18 13 20 31 45 15 +42 31 21 53 58 42 23 11 14 53 +56 16 57 10 53 11 32 19 21 11 +48 10 19 25 40 43 56 53 20 48 +56 32 17 17 13 52 42 13 29 37 +2375 5305 3067 1141 5881 4215 2801 1154 1049 4205 +4572 1668 5032 1491 1453 5719 3439 1739 4060 1183 +2352 4861 4586 2631 5227 1135 4784 4732 1585 3492 +137 122 87 125 120 47 42 157 60 134 +35 120 185 86 110 115 184 107 188 96 +82 68 161 123 36 49 178 179 108 90 \ No newline at end of file diff --git a/examples/cp/visu/plant_location_with_solver_listener.py b/examples/cp/visu/plant_location_with_solver_listener.py new file mode 100644 index 0000000..a340a1a --- /dev/null +++ b/examples/cp/visu/plant_location_with_solver_listener.py @@ -0,0 +1,120 @@ +# -------------------------------------------------------------------------- +# Source file provided under Apache License, Version 2.0, January 2004, +# http://www.apache.org/licenses/ +# (c) Copyright IBM Corp. 2015, 2016, 2018 +# -------------------------------------------------------------------------- + +""" +A ship-building company has a certain number of customers. Each customer is supplied +by exactly one plant. In turn, a plant can supply several customers. The problem is +to decide where to set up the plants in order to supply every customer while minimizing +the cost of building each plant and the transportation cost of supplying the customers. + +For each possible plant location there is a fixed cost and a production capacity. +Both take into account the country and the geographical conditions. + +For every customer, there is a demand and a transportation cost with respect to +each plant location. + +While a first solution of this problem can be found easily by CP Optimizer, it can take +quite some time to improve it to a very good one. We illustrate the warm start capabilities +of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. +This solution could be one from an expert or the result of another optimization engine +applied to the problem. + +In the solution we only give a value to the variables that determine which plant delivers +a customer. This is sufficient to define a complete solution on all model variables. +CP Optimizer first extends the solution to all variables and then starts to improve it. + +This model has been enriched by the addition of KPIs (key performance indicators), operational with a +version of COS greater or equal to 12.9.0.0. +These are named expressions which are of interest to help get an idea of the performance of the model. +Here, we are interested in two indicators: + - the first is the `occupancy'' defined as the total demand divided by the total plant capacity. + - the second indicator is the occupancy which is the lowest of all the plants. + +The KPIs are displayed using a SolverProgressPanelListener that displays solve progress in real time +and allows to stop solve when good enough objective or KPIs are reached. +Log parsing is also activated to retrieve runtime information from it. +""" + +from docplex.cp.model import CpoModel +from docplex.cp.solver.solver_listener import * +from docplex.cp.config import context +from docplex.cp.utils import compare_natural +from collections import deque +import os + +#----------------------------------------------------------------------------- +# Initialize the problem data +#----------------------------------------------------------------------------- + +# Read problem data from a file and convert it as a list of integers +filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" +data = deque() +with open(filename, "r") as file: + for val in file.read().split(): + data.append(int(val)) + +# Read number of customers and locations +nbCustomer = data.popleft() +nbLocation = data.popleft() + +# Initialize cost. cost[c][p] = cost to deliver customer c from plant p +cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) + +# Initialize demand of each customer +demand = list([data.popleft() for c in range(nbCustomer)]) + +# Initialize fixed cost of each location +fixedCost = list([data.popleft() for p in range(nbLocation)]) + +# Initialize capacity of each location +capacity = list([data.popleft() for p in range(nbLocation)]) + + +#----------------------------------------------------------------------------- +# Build the model +#----------------------------------------------------------------------------- + +mdl = CpoModel() + +# Create variables identifying which location serves each customer +cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") + +# Create variables indicating which plant location is open +open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") + +# Create variables indicating load of each plant +load = [mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] + +# Associate plant openness to its load +for p in range(nbLocation): + mdl.add(open[p] == (load[p] > 0)) + +# Add constraints +mdl.add(mdl.pack(load, cust, demand)) + +# Add objective +obj = mdl.scal_prod(fixedCost, open) +for c in range(nbCustomer): + obj += mdl.element(cust[c], cost[c]) +mdl.add(mdl.minimize(obj)) + +# Add KPIs +if compare_natural(context.model.version, '12.9') >= 0: + mdl.add_kpi(mdl.sum(demand) / mdl.scal_prod(open, capacity), "Average Occupancy") + mdl.add_kpi(mdl.min([load[l] / capacity[l] + (1 - open[l]) for l in range(nbLocation)]), "Min occupancy") + + +#----------------------------------------------------------------------------- +# Solve the model and display the result +#----------------------------------------------------------------------------- + +if context.visu_enabled: + mdl.add_solver_listener(SolverProgressPanelListener(parse_log=True)) + +# Solve the model +print("Solve the model") +msol = mdl.solve(TimeLimit=20, LogPeriod=1000) +msol.write() diff --git a/examples/mp/jupyter/Benders_decomposition.ipynb b/examples/mp/jupyter/Benders_decomposition.ipynb index 6793871..ad9dec7 100644 --- a/examples/mp/jupyter/Benders_decomposition.ipynb +++ b/examples/mp/jupyter/Benders_decomposition.ipynb @@ -15,7 +15,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n", + ">This notebook is part of the **[Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)**\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -594,7 +594,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n" diff --git a/examples/mp/jupyter/Progress_callbacks.ipynb b/examples/mp/jupyter/Progress_callbacks.ipynb index e131ec1..e019fa2 100644 --- a/examples/mp/jupyter/Progress_callbacks.ipynb +++ b/examples/mp/jupyter/Progress_callbacks.ipynb @@ -15,7 +15,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n", + ">This notebook is part of the **[Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)**\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -414,7 +414,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n" diff --git a/examples/mp/jupyter/boxes.ipynb b/examples/mp/jupyter/boxes.ipynb index d95030f..3f6d590 100644 --- a/examples/mp/jupyter/boxes.ipynb +++ b/examples/mp/jupyter/boxes.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">Running the sample requires the installation of\n", " [CPLEX Optimization studio](https://www.ibm.com/products/ilog-cplex-optimization-studio)\n", @@ -604,7 +604,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/chicago_coffee_shops.ipynb b/examples/mp/jupyter/chicago_coffee_shops.ipynb index bd60899..2e64df5 100644 --- a/examples/mp/jupyter/chicago_coffee_shops.ipynb +++ b/examples/mp/jupyter/chicago_coffee_shops.ipynb @@ -12,7 +12,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -652,7 +652,7 @@ }, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/efficient.ipynb b/examples/mp/jupyter/efficient.ipynb index 32511b1..b9f1281 100644 --- a/examples/mp/jupyter/efficient.ipynb +++ b/examples/mp/jupyter/efficient.ipynb @@ -22,20 +22,11 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "fibonacci(30) = 832040\n", - "<-- fibonacci 30, time: 277 ms\n" - ] - } - ], + "outputs": [], "source": [ "import time\n", "import math\n", @@ -106,7 +97,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": true }, @@ -138,25 +129,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench1_size_1000, time: 4602 ms\n", - "Model: bench1\n", - " - number of variables: 1000\n", - " - binary=1000, integer=0, continuous=0\n", - " - number of constraints: 1000\n", - " - linear=1000\n", - " - parameters: defaults\n" - ] - } - ], + "outputs": [], "source": [ "with ContextTimer(\"bench1_size_1000\"):\n", " m11k = build_bench_model1(1000)\n", @@ -173,19 +150,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench1 size=3000, time: 41211 ms\n" - ] - } - ], + "outputs": [], "source": [ "N=3000\n", "with ContextTimer(\"bench1 size={0}\".format(N)):\n", @@ -213,19 +182,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench3 size=3000, time: 25222 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model2(size=10):\n", " m = Model(name=\"bench2\")\n", @@ -256,19 +217,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench2.1 size=3000, time: 24599 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model21(size=10):\n", " m = Model(name=\"bench2.1\")\n", @@ -303,19 +256,11 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench3 size=3000, time: 24341 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model3(size=10):\n", " m = Model(name=\"bench3\")\n", @@ -346,19 +291,11 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench4 size=3000, time: 20162 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model4(size=10):\n", " m = Model(name=\"bench4\")\n", @@ -393,19 +330,11 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench6 size=3000, time: 19171 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model5(size=10):\n", " m = Model(name=\"bench5\", ignore_names=True)\n", @@ -436,19 +365,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench6 size=3000, time: 14026 ms\n" - ] - } - ], + "outputs": [], "source": [ "def build_bench_model6(size=10):\n", " m = Model(name=\"bench6\", ignore_names=True, checker=\"off\")\n", @@ -489,19 +410,11 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "<-- bench7 size=3000, time: 10350 ms\n" - ] - } - ], + "outputs": [], "source": [ "from docplex.mp.advmodel import AdvModel\n", "\n", @@ -556,57 +469,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* start computing performance data\n", - "* start computing results...\n", - "<-- [1/36] use build_bench_model1 with size=100, time: 71 ms\n", - "<-- [2/36] use build_bench_model2 with size=100, time: 40 ms\n", - "<-- [3/36] use build_bench_model4 with size=100, time: 40 ms\n", - "<-- [4/36] use build_bench_model5 with size=100, time: 41 ms\n", - "<-- [5/36] use build_bench_model6 with size=100, time: 30 ms\n", - "<-- [6/36] use build_bench_model7 with size=100, time: 20 ms\n", - "<-- [7/36] use build_bench_model1 with size=300, time: 397 ms\n", - "<-- [8/36] use build_bench_model2 with size=300, time: 218 ms\n", - "<-- [9/36] use build_bench_model4 with size=300, time: 170 ms\n", - "<-- [10/36] use build_bench_model5 with size=300, time: 161 ms\n", - "<-- [11/36] use build_bench_model6 with size=300, time: 131 ms\n", - "<-- [12/36] use build_bench_model7 with size=300, time: 105 ms\n", - "<-- [13/36] use build_bench_model1 with size=600, time: 1412 ms\n", - "<-- [14/36] use build_bench_model2 with size=600, time: 921 ms\n", - "<-- [15/36] use build_bench_model4 with size=600, time: 620 ms\n", - "<-- [16/36] use build_bench_model5 with size=600, time: 694 ms\n", - "<-- [17/36] use build_bench_model6 with size=600, time: 540 ms\n", - "<-- [18/36] use build_bench_model7 with size=600, time: 380 ms\n", - "<-- [19/36] use build_bench_model1 with size=1000, time: 4073 ms\n", - "<-- [20/36] use build_bench_model2 with size=1000, time: 3056 ms\n", - "<-- [21/36] use build_bench_model4 with size=1000, time: 1804 ms\n", - "<-- [22/36] use build_bench_model5 with size=1000, time: 1857 ms\n", - "<-- [23/36] use build_bench_model6 with size=1000, time: 1241 ms\n", - "<-- [24/36] use build_bench_model7 with size=1000, time: 956 ms\n", - "<-- [25/36] use build_bench_model1 with size=3000, time: 35654 ms\n", - "<-- [26/36] use build_bench_model2 with size=3000, time: 20981 ms\n", - "<-- [27/36] use build_bench_model4 with size=3000, time: 15859 ms\n", - "<-- [28/36] use build_bench_model5 with size=3000, time: 16211 ms\n", - "<-- [29/36] use build_bench_model6 with size=3000, time: 13961 ms\n", - "<-- [30/36] use build_bench_model7 with size=3000, time: 10397 ms\n", - "<-- [31/36] use build_bench_model1 with size=5000, time: 102102 ms\n", - "<-- [32/36] use build_bench_model2 with size=5000, time: 64073 ms\n", - "<-- [33/36] use build_bench_model4 with size=5000, time: 45006 ms\n", - "<-- [34/36] use build_bench_model5 with size=5000, time: 45088 ms\n", - "<-- [35/36] use build_bench_model6 with size=5000, time: 32424 ms\n", - "<-- [36/36] use build_bench_model7 with size=5000, time: 26294 ms\n", - "* end computing results\n" - ] - } - ], + "outputs": [], "source": [ "# various sizes to sample performance\n", "sizes = [100, 300, 600, 1000, 3000, 5000]\n", @@ -638,22 +505,11 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6gAAAGfCAYAAABSof8UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlUVeXixvHvBpFRUQQVFecBBASVwbE0LS3LnK2r3sy6\nVqb1UzNLK61rZWV1u1qZlZplN9FSm8shM2dBwXkWFXEERUDGc/bvD8zVYIkC7gM8n7VcHjZ7eM45\n6OI5797vNkzTRERERERERMRqTlYHEBEREREREQEVVBEREREREXEQKqgiIiIiIiLiEFRQRURERERE\nxCGooIqIiIiIiIhDUEEVERERERERh6CCKiIiIiIiIg5BBVVEREREREQcggqqiIiIiIiIOIQKVgcA\n8PX1NevXr291DBERERERESkBcXFxZ03T9Lvaeg5RUOvXr09sbKzVMURERERERKQEGIZxpDDr6RRf\nERERERERcQgqqCIiIiIiIuIQVFBFRERERETEITjENahXkpeXR1JSEtnZ2VZHkb/h5uZGnTp1cHFx\nsTqKiIiIiIiUcg5bUJOSkqhUqRL169fHMAyr48gVmKZJSkoKSUlJNGjQwOo4IiIiIiJSyjnsKb7Z\n2dlUq1ZN5dSBGYZBtWrVNMotIiIiIiLFwmELKqByWgroPRIRERERkeLi0AVVREREREREyg8V1L/R\nrl27q67z4IMPsmvXLgBeeumla97ey8vr+sKJiIiIiIiUMYZpmlZnICIiwoyNjf3dst27dxMUFGRR\nouvj5eVFRkZGiW/jaErjeyUiIiIiIjeOYRhxpmlGXG09jaD+jV9HN1etWkWnTp3o168fgYGBDBo0\niF+LfadOnYiNjeWpp54iKyuL8PBwBg0a9LvtMzIy6NKlC61atSI0NJSlS5da84REREREREQcmMPe\nZua3nv9qJ7uSLxTrPpvXqsyku4ILvf7WrVvZuXMntWrVon379qxdu5YOHTpc/v7UqVOZMWMG8fHx\nf9rWzc2NxYsXU7lyZc6ePUubNm3o2bOnJhgSERERERH5DY2gFlJUVBR16tTBycmJ8PBwEhMTC72t\naZpMmDCBFi1a0LVrV44fP86pU6dKLqyIiIiIiEgpVCpGUK9lpLOkuLq6Xn7s7OxMfn5+obedP38+\nZ86cIS4uDhcXF+rXr697h4qIiIiIiPyBRlCLkYuLC3l5eX9anpaWRvXq1XFxceGnn37iyJEjFqQT\n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\nFa53TE6sUJhZfO/9i291+Yv1XwReLEqoPzr50kvk7N5TnLvENSiQmhMmFGrdL774gsTERHbt2sXp\n06cJCgpi2LBhl7/v6+vLli1beOedd5g2bRoffPABkyZNomXLlixZsoSVK1fyz3/+k/j4eAB27drF\nmjVrcHd3Z9asWXh7e7N582ZycnJo3749t912Gw0aNLhilq1bt7Jz505q1apF+/btWbt2LR06dGDk\nyJE899xzAAwZMoSvv/6au+66C4CKFSsSGxvLW2+9xd13301cXBw+Pj40atSI0aNHc/r0aRYsWMDa\ntWtxcXFhxIgRzJ8/n+DgYI4fP86OHTsAOH/+/HW/3iIiIiIiJWXH8TTGxMSz71QGg6LrMuGOIDxd\nizzdjlhAHycUwpo1a+jfvz9OTk7UrFmTzp07/+77ffr0AaB169YkJiZe3mbIkCEA3HLLLaSkpHDh\nwgUAevbsibu7OwA//vgj8+bNIzw8nOjoaFJSUti/f/9fZomKiqJOnTo4OTkRHh5++Xg//fQT0dHR\nhIaGsnLlSnbu3Hl5m549ewIQGhpKcHAw/v7+uLq60rBhQ44dO8aKFSuIi4sjMjKS8PBwVqxYwaFD\nh2jYsCGHDh1i1KhRfP/991SuXLnoL6aIiIiISDHJt9l5+6cD9H5nLecv5jHn/khe7B2qclqKlYp3\nrrAjnVZxdS24ua+zs3Ohriv19PS8/Ng0TaZPn063bt2u6Vi/PV52djYjRowgNjaWgIAAJk+eTHZ2\n9p+2cXJy+t32Tk5O5OfnY5om9913Hy+//PKfjpeQkMAPP/zAzJkziYmJYfbs2YXKKSIiIiJSkg6f\nzWRsTDxbjp6nRwt/ptwdQlXPilbHkiLSCGohtG/fns8//xy73c6pU6dYtWrVVbfp2LEj8+fPBwqu\nHfX19b3iCGS3bt149913ycvLA2Dfvn1kZmZeU75fy6ivry8ZGRmXr48trC5durBo0SJOny6YjDk1\nNZUjR45w9uxZ7HY7ffv2ZcqUKWzZsuWa9isiIiIiUtxM0+TjDUe4461fOHA6g7fuCWfGvS1VTsuI\nUjGCarW+ffuyYsUKmjdvTkBAAK1atcLb2/tvt5k8eTLDhg2jRYsWeHh48NFHH11xvQcffJDExERa\ntWqFaZr4+fmxZMmSa8pXpUoV/vWvfxESEkLNmjWJjIy8pu2bN2/OlClTuO2227Db7bi4uPD222/j\n7u7O/fffj91uB7jiCKuIiIiIyI1y6kI24xZtY/W+M3Rs4sur/Vrg7+1udSwpRsavs71aKSIiwoyN\njf3dst27dxMUFGRRoj/LyMjAy8uLlJQUoqKiWLt2LTVr1rQ6lkNwtPdKRERERMqerxKSeWbJDnLy\nbUy4I4jB0fVw0n1NSw3DMOJM04y42noaQS2kO++8k/Pnz5Obm8uzzz6rcioiIiIicgOcv5jLc0t3\n8mVCMmEBVXhzQBgN/bysjiUlRAW1kApz3Wlx2b59++UZgH/l6urKxo0bb1gGERERERGrrd53hnGL\nEkjJyGXMrU0Z0akRFZw1jU5ZpoLqgEJDQy/fM1VEREREpLy5mJvP1O/2MG/9ERpX9+KDf0YSWufv\n54CRskEFVUREREREHMaWo+cYG5PA4bOZDGvfgCe7N8PNxdnqWHKDqKCKiIiIiIjlcvPtTF+5n7d/\nOkDNym58+q9o2jXytTqW3GAqqCIiIiIiYqn9p9IZHRPPjuMX6NuqDpN6Nqeym4vVscQCKqgiIiIi\nImIJu91k9trDvPrDXrxcKzBzcGu6h+huGeWZpsC6RkOHDmXRokUOs5/COHPmDNHR0bRs2ZJffvmF\nhQsXEhQUROfOnW/I8UVERERE/ijp3EX+8cEGpnyzm5ua+PLD/92kcioaQS2N8vPzqVCh8G/dihUr\nCA0N5YMPPgCge/fuvP/++3To0KGkIoqIiIiIXJFpmny+5TjPf7kTu2nyat8W9I+og2EYVkcTB1Aq\nCuovMfs4eyyjWPfpG+BFxwFNr7revHnzmDZtGoZh0KJFC5ydnVm9ejVvvPEGJ0+e5NVXX6Vfv34A\nvPbaa8TExJCTk0Pv3r15/vnnr7iPjz/++HfHePbZZzl27Bgffvgh8fHxjBkzhoyMDHx9fZk7dy7+\n/v506tSJ8PBw1qxZw7333svYsWP/lDUxMZFhw4Zx9uxZ/Pz8mDNnDqmpqTz55JNkZWURGxtL7969\nWbNmDQ888AA9e/bktddeK4ZXU0RERETk6s5m5DDhi+38uOsUUfV9eH1AGAE+HlbHEgdSKgqqVXbu\n3MmUKVNYt24dvr6+pKamMmbMGE6cOMGaNWvYs2cPPXv2pF+/fvz444/s37+fTZs2YZomPXv2ZPXq\n1VSrVu1P+/itcePGkZ6ezpw5c8jPz2fUqFEsXboUPz8/FixYwMSJE5k9ezYAubm5xMbG/mXeUaNG\ncd9993Hfffcxe/ZsHnvsMZYsWcILL7xAbGwsM2bMAOCnn35i2rRpRERElNyLJyIiIiLyG8t2neLp\nL7ZxISufCXcE8kCHhjg7adRUfq9UFNTCjHSWhJUrV9K/f398fQumt/bx8QGgV69eODk50bx5c06d\nOgXAjz/+yI8//kjLli0ByMjIYP/+/SQkJFxxHwD//ve/iY6OZtasWQDs3buXHTt2cOuttwJgs9nw\n9/e/vP7AgQP/Nu/69ev54osvABgyZAhPPvlkkV8DEREREZGiSM/O499f7yImNokg/8p88mAYgTUr\nWx1LHFSpKKiOxtXV9fJj0zQv//3000/z0EMP/W7d6dOn/+V+IiMjiYuLIzU1FR8fH0zTJDg4mPXr\n119xfU9Pz2JILyIiIiJyY2w8lMLYhQkkn89iRKdGPN61Ca4VnK2OJQ5Ms/j+jVtuuYWFCxeSkpIC\n8KfTc3+rW7duzJ49m4yMgmtljx8/zunTp/92H927d+epp56iR48epKen06xZM86cOXO5oObl5bFz\n585C523Xrh2fffYZAPPnz6djx47X9oRFRERERIpBdp6NF7/ZxT3vb8DZyWDhw215snugyqlclUZQ\n/0ZwcDATJ07k5ptvxtnZ+fLpu1dy2223sXv3btq2bQuAl5cXn3zyyRX3MXfu3Mvb9e/fn/T0dHr2\n7Mm3337LokWLeOyxx0hLSyM/P5//+7//Izg4uFB5p0+fzv33389rr712eZIkEREREZEbaWdyGmMW\nJLD3VDr/iK7LxDuC8HRV7ZDCMX49RdVKERER5h8n/9m9ezdBQUEWJZJrofdKRERERPJtdt5bfYj/\nLN9HFY+KvNqvBZ2bVbc6ljgIwzDiTNO86iyt+ihDRERERESKJPFsJmNi4tly9Dw9Qv2Z0iuEqp4V\nrY4lpZAKain04osvsnDhwt8t69+/PxMnTrQokYiIiIiUR6ZpMn/jUV78ZjcuzgZv3RNOz7BaGIZu\nHyPXRwW1FJo4caLKqIiIiIhY6tSFbJ5ctI2f952hQ2NfXuvfAn9vd6tjSSmngioiIiIiItfk623J\nPLNkB9l5Nl64O5jB0fVwctKoqRSdCqqIiIiIiBRK2sU8nl26gy8TkgkLqMIbA8Jo5OdldSwpQ1RQ\nRURERETkqn7Zf4ZxC7dxNiOHMbc2ZUSnRlRwdrI6lpQx+okqorlz5zJy5MgbdrzJkyczbdq0Iq8j\nIiIiIlIYF3PzeW7pDoZ8uAlPV2e+GNGOx7o0UTmVEqERVBERERERuaKtR88xJiaBw2czGda+AU92\nb4abi7PVsaQM08ceV9GrVy9at25NcHAws2bNAmDOnDk0bdqUqKgo1q5dC0BaWhr16tXDbrcDkJmZ\nSUBAAHl5eXTq1InRo0cTERFBUFAQmzdvpk+fPjRp0oRnnnnm8rHeeOMNQkJCCAkJ4T//+c/l5S++\n+CJNmzalQ4cO7N279/LygwcP0r17d1q3bk3Hjh3Zs2fPjXhJRERERKSMy7PZef3HvfR9dx05eTY+\nfTCa5+5qrnIqJa5UjKD+NHcWp48cKtZ9Vq/XkM5Dh191vdmzZ+Pj40NWVhaRkZH06NGDSZMmERcX\nh7e3N507d6Zly5Z4e3sTHh7Ozz//TOfOnfn666/p1q0bLi4uAFSsWJHY2Fjeeust7r77buLi4vDx\n8aFRo0aMHj2axMRE5syZw8aNGzFNk+joaG6++WbsdjufffYZ8fHx5Ofn06pVK1q3bg3A8OHDmTlz\nJk2aNGHjxo2MGDGClStXFuvrJCIiIiLly/5T6YyOiWfH8Qv0aVWbyT2DqezmYnUsKSdKRUG10n//\n+18WL14MwLFjx/j444/p1KkTfn5+AAwcOJB9+/ZdfrxgwQI6d+7MZ599xogRIy7vp2fPngCEhoYS\nHByMv78/AA0bNuTYsWOsWbOG3r174+npCUCfPn345ZdfsNvt9O7dGw8Pj9/tJyMjg3Xr1tG/f//L\nx8jJySnJl0JEREREyjC73WT22sO8+sNevFwrMHNwK7qH+FsdS8qZUlFQCzPSWRJWrVrF8uXLWb9+\nPR4eHnTq1InAwEB27dp1xfV79uzJhAkTSE1NJS4ujltuueXy91xdXQFwcnK6/PjXr/Pz8685m91u\np0qVKsTHx1/ztiIiIiIiv3X8fBZPxCSw/lAKXQKr83LfUKpXcrM6lpRDugb1b6SlpVG1alU8PDzY\ns2cPGzZsICsri59//pmUlBTy8vJYuHDh5fW9vLyIjIzk8ccf584778TZufDn6Hfs2JElS5Zw8eJF\nMjMzWbx4MR07duSmm25iyZIlZGVlkZ6ezldffQVA5cqVadCgweXjm6ZJQkJC8b4AIiIiIlKmmabJ\norgkur+5mm1J53mlbygf3BehciqWKRUjqFbp3r07M2fOJCgoiGbNmtGmTRv8/f2ZPHkybdu2pUqV\nKoSHh/9um4EDB9K/f39WrVp1Tcdq1aoVQ4cOJSoqCoAHH3yQli1bXt5nWFgY1atXJzIy8vI28+fP\n55FHHmF+g/1WAAAgAElEQVTKlCnk5eVxzz33EBYWVrQnLSIiIiLlQkpGDhMWb+eHnaeIrF+V1/uH\nU7eah9WxpJwzTNO0OgMRERFmbGzs75bt3r2boKAgixLJtdB7JSIiIlK6LNt1iqe/2MaFrHzG3taU\nBzs2xNnJsDqWlGGGYcSZphlxtfU0gioiIiIiUk6kZ+fx7693ERObRJB/ZT55MIzAmpWtjiVymQqq\niIiIiEg5sPFQCmMXJpB8PosRnRrxeNcmuFbQfU3FsaigioiIiIiUYdl5Nt5Yto/3fzlEQFUPYh5q\nS0R9H6tjiVyRQxdU0zQxDJ0L78gc4RpmEREREbmynclpjFmQwN5T6fwjui4T7wjC09WhK4CUcw77\n0+nm5kZKSgrVqlVTSXVQpmmSkpKCm5umIRcRERFxJPk2O++tPsR/lu+jikdF5gyNpHNgdatjiVyV\nwxbUOnXqkJSUxJkzZ6yOIn/Dzc2NOnXqWB1DRERERC5JPJvJmJh4thw9zx2hNZnSKxQfz4pWxxIp\nFIctqC4uLjRo0MDqGCIiIiIipYJpmszfeJQXv9mNi7PBW/eE0zOsls5GlFLFYQuqiIiIiIgUzukL\n2Tz5+TZW7T1Dh8a+vNa/Bf7e7lbHErlmKqgiIiIiIqXY19uSeWbJDrLzbDzfM5ghberh5KRRUymd\nVFBFREREREqhtIt5PPflDpbGJxNWx5s3BobTyM/L6lgiRaKCKiIiIiJSyvyy/wzjFm7jTEYOo7s2\n5dHOjajg7GR1LJEiU0EVERERESklsnJtTP1uNx+tP0IjP09m/bMdLepUsTqWSLFRQRURERERKQW2\nHj3H2JgEDp3NZFj7BjzZvRluLs5WxxIpViqoIiIiIiIOLM9mZ/qK/by96iA1Krny6YPRtGvsa3Us\nkRKhgioiIiIi4qD2n0pndEw8O45foE+r2ky6KxhvdxerY4mUGBVUEREREREHY7ebzFmXyCvf78Gz\nojPvDmrF7aH+VscSKXEqqCIiIiIiDuT4+SyeiElg/aEUugRW5+W+oVSv5GZ1LJEbokgF1TCM0cCD\ngAlsB+4HPIAFQH0gERhgmua5IqUUERERESnjTNPkiy3HmfzlTuymydQ+oQyMDMAwDKujidww132z\nJMMwagOPARGmaYYAzsA9wFPACtM0mwArLn0tIiIiIiJ/ISUjh4c/iWPswgQC/Svx3eM3cU9UXZVT\nKXeKeopvBcDdMIw8CkZOk4GngU6Xvv8RsAoYX8TjiIiIiIiUSct3neKpL7ZxISufp28P5MGODXF2\nUjGV8um6C6ppmscNw5gGHAWygB9N0/zRMIwapmmeuLTaSaDGlbY3DGM4MBygbt261xtDRERERKRU\nysjJ599f7WJB7DECa1bi4weiCfKvbHUsEUtdd0E1DKMqcDfQADgPLDQMY/Bv1zFN0zQMw7zS9qZp\nzgJmAURERFxxHRERERGRsmjT4VTGxMSTfD6LRzo14v+6NsG1grPVsUQsV5RTfLsCh03TPANgGMYX\nQDvglGEY/qZpnjAMwx84XQw5RURERERKvZx8G2/8uI9ZvxwioKoHMQ+1JaK+j9WxRBxGUQrqUaCN\nYRgeFJzi2wWIBTKB+4Cpl/5eWtSQIiIiIiKl3a7kC4xeEM/eU+ncG1WXZ3oE4emquz6K/FZRrkHd\naBjGImALkA9speCUXS8gxjCMB4AjwIDiCCoiIiIiUhrZ7CbvrT7Im8v24e1ekdlDI7gl8IrTtIiU\ne0X6yMY0zUnApD8szqFgNFVEREREpFxLPJvJ2IUJxB05xx2hNZnSKxQfz4pWxxJxWDqnQERERESk\nmJmmyaebjvLiN7txdjL4z8Bw7g6vpfuailyFCqqIiIiISDE6fSGbJz/fxqq9Z2jfuBqv9QujVhV3\nq2OJlAoqqCIiIiIixeSbbSeYuGQ7Wbk2Jt/VnH+2rY+Tk0ZNRQpLBVVEREREpIjSLuYx6csdLIlP\nJqyON68PCKdxdS+rY4mUOiqoIiIiIiJF8Mv+M4xbuI0zGTn8X9cmPNq5MS7OTlbHEimVVFBFRERE\nRK5DVq6Nqd/t5qP1R2jk58msf7ajRZ0qVscSKdVUUEVERERErlH8sfOMWRDPobOZ3N++PuO7B+Lm\n4mx1LJFSTwVVRERERKSQ8mx2pq88wNs/HaB6JVfmPxhN+8a+VscSKTNUUEVERERECuHA6XRGL0hg\n+/E0+rSszaSewXi7u1gdS6RMUUEVEREREfkbdrvJ3HWJvPL9HjwqOvPuoFbcHupvdSyRMkkFVURE\nRETkLxw/n8W4hQmsO5jCLYHVmdo3lOqV3KyOJVJmqaCKiIiIiPyBaZos3nqcSUt3YjNNXu4Tyj2R\nARiGYXU0kTJNBVVERERE5DdSMnKYuHgH3+88SWT9qrzeP5y61TysjiVSLqigioiIiIhcsmL3KcZ/\nvp0LWXk8dXsg/+rYEGcnjZqK3CgqqCIiIiJS7mXk5DPl6118tvkYgTUr8fEDUQT5V7Y6lki5o4Iq\nIiIiIuXapsOpjF0YT9K5LB6+uRGjb22CawVnq2OJlEsqqCIiIiJSLuXk23hj2T5mrT5EQFUPYh5q\nS2R9H6tjiZRrKqgiIiIiUu7sSr7AmJh49pxM596oACb2aI6Xq341FrGa/hWKiIiISLlhs5u8t/og\nby7bh7d7RWYPjeCWwBpWxxKRS1RQRURERKRcOJKSyZiYBOKOnOOO0JpM6RWKj2dFq2OJyG+ooIqI\niIhImWaaJv/bdIwp3+zC2cngzYFh9AqvjWHo9jFSBmScgdjZ0OZhcPO2Ok2RqaCKiIiISJl1+kI2\n4z/fxk97z9C+cTVe6xdGrSruVscSKbrTe2D9DNgWA7YcqB4Ize+2OlWRqaCKiIiISJn07fYTTFy8\nnYu5Nibd1Zz72tbHyUmjplKKmSYcWgXr34YDy6CCG4T/A9o+Cr5NrE5XLFRQRURERKRMScvKY9LS\nHSyJT6ZFHW/eGBBO4+peVscSuX75ubDj84Jiemo7ePpB54kQMQw8fa1OV6xUUEVERESkzFiz/yzj\nFiVwOj2H/+vahEc7N8bF2cnqWCLX52IqxM2BjbMg4yT4BUHPGRDaH1zcrE5XIlRQRURERKTUy8q1\n8cr3e5i7LpGGfp588Ug7wgKqWB1L5PqkHIQN70L8fMi7CA07Q6+3oVEXKOOTe6mgioiIiEiplnDs\nPKNj4jl0JpOh7erz1O2BuLk4Wx1L5NqYJhzdUDDx0Z5vwKkCtBgAbUZAzRCr090wKqgiIiIiUirl\n2ezMWHmAGT8doHolV+Y/GE37xmXrejwpB2z5sHsprJsByVvAvSp0HAtR/4JKNa1Od8OpoIqIiIhI\nqXPgdAZjYuLZlpRG75a1mdwzGG93F6tjiRRe9gXYMg82zoS0Y+DTCHq8DmH3QkVPq9NZRgVVRERE\nREoNu91k7rpEXvl+Dx4VnXlnUCvuCPW3OpZI4Z0/VlBK4z6C3HSo1x5ufwWa3g5OmtBLBVVERERE\nSoXj57MYtzCBdQdT6NzMj1f6tqB65bI5k6mUQcfjCk7j3bW04Ovg3gX3L63dytpcDkYFVUREREQc\nmmmaLN56nElLd2IzTV7uE8o9kQEYZXw2UykD7DbY+13BxEdH14NrZWjzCEQ/DFUCrE7nkFRQRURE\nRMRhpWbmMuGL7Xy/8yQR9aryxoBw6lbzsDqWyN/LzYT4T2HDO5B6CLzrQreXoOUQcKtsdTqHpoIq\nIiIiIg5pxe5TjP98O2lZuYzvHsjwmxri7KRRU3Fg6Sdh0yyInQ1Z56B2a+g3B4J6grOqV2HoVRIR\nERERh5KRk8+Ur3fx2eZjBNasxMcPRBHkr1EncWAnd8D6t2H7QrDnQ2APaDcKAqJBp6JfExVUERER\nEXEYmxNTGRMTT9K5LB6+uRGjb22CawVnq2OJ/JlpwoEVsH46HFoFLh4QcX/BNaY+Da1OV2qpoIqI\niIiI5XLybbyxbB+zVh+iTlV3Yh5qS2R9H6tjifxZXjZsjykYMT2zByr5Q5dJ0HooeOhntqhUUEVE\nRETEUruSLzAmJp49J9O5NyqAiT2a4+WqX1PFwWSehc0fwub3IfMM1AiF3u9BcB+oUNHqdGWG/uWL\niIiIiCVsdpP3Vh/kzWX78HavyOyhEdwSWMPqWCK/d2YfbHgbEj6D/Gxochu0HQkNbtL1pSVABVVE\nREREbrgjKZmMjUkg9sg5bg+pyYu9Q/Hx1CiUOAjThMRfYN0M2P8DOLtC2D3QZgRUD7Q6XZmmgioi\nIiIiN4xpmvxv0zGmfLMLZyeDNweG0Su8NoZGosQR2PJgxxewfgac3AYevtDpaYh4ALz8rE5XLqig\nioiIiMgNcTo9m6c+387KPadp16ga0/qHUauKu9WxRAruWRr3EWx8D9KTwbcp3PUWtBgILvoZvZFU\nUEVERESkxH27/QQTF2/nYq6NSXc157629XFy0qipWCz1MGycCVs+hrzMgutK73oLGncFJyer05VL\nKqgiIiIiUmLSsvKY/OVOFm89Tmhtb94cGEbj6pWsjiXl3dGNBafx7vkaDCcI6QdtHwX/FlYnK/dU\nUEVERESkRKzZf5ZxixI4nZ7D412aMPKWxrg4a1RKLGLLLyik62dA0mZw84b2j0PUcKhcy+p0cokK\nqoiIiIgUq6xcG698v4e56xJp6OfJF4+0IyygitWxpLzKSYetn8CGd+D8UahaH25/DcL/Aa5eVqeT\nP1BBFREREZFik3DsPKNj4jl0JpOh7eozvnsg7hWdrY4l5VFaUsGkR3EfQU4aBLSBbi9BszvAST+T\njkoFVURERESKLM9mZ8bKA8z46QDVK7nyyQPRdGjia3UsKY+S4wtO4925GEw7NL8b2o6EOhFWJ5NC\nUEEVERERkSI5cDqDMTHxbEtKo3fL2kzuGYy3u4vVsaQ8sdth/w+wbgYcWQMVK0HUQxD9EFStZ3U6\nuQYqqCIiIiJyXex2k4/WJzL1uz24V3TmnUGtuCPU3+pYUp7kXoSE/xVcX5pyACrXgdumQKt/FkyC\nJKWOCqqIiIiIXLPk81mMW5TA2gMpdG7mxyt9W1C9spvVsaS8SD8Fm9+HzR9CVirUagl9Pyw4nddZ\no/elmQqqiIiIiBSaaZos3nqcSV/uxGY3eblPKPdEBmAYhtXRpDw4tQs2vA3bYsCWB81uL7i+tF47\n0M9gmVCkgmoYRhXgAyAEMIFhwF5gAVAfSAQGmKZ5rkgpRURERMRyqZm5TFy8ne92nCSiXlVeHxBG\nvWqeVseSss404eBKWP82HFwBFdyh5RBoMwJ8G1udTopZUUdQ3wK+N02zn2EYFQEPYAKwwjTNqYZh\nPAU8BYwv4nFERERExEIr95ziyUXbScvKZXz3QIbf1BBnJ41YSQnKz4HtCwuK6eld4FUDbnkGIh4A\nDx+r00kJue6CahiGN3ATMBTANM1cINcwjLuBTpdW+whYhQqqiIiISKmUmZPPlG928b9NxwisWYl5\nw6JoXquy1bGkLLuYCrEfwqb3IeMUVA+Gu9+B0H5QwdXqdFLCijKC2gA4A8wxDCMMiAMeB2qYpnni\n0jongRpFiygiIiIiVticmMrYmASOnbvIQzc3ZMytTXGt4Gx1LCmrzh4omI03/lPIz4JGXaD3TGjY\nWdeXliNFKagVgFbAKNM0NxqG8RYFp/NeZpqmaRiGeaWNDcMYDgwHqFu3bhFiiIiIiEhxysm38eay\n/by3+iB1qrqzYHhbohrolEopAaYJR9YWnMa797uCGXhbDIA2j0KN5lanEwsUpaAmAUmmaW689PUi\nCgrqKcMw/E3TPGEYhj9w+kobm6Y5C5gFEBERccUSKyIiIiI31u4TFxi9IJ49J9O5NyqAiT2a4+Wq\nGz9IMbPlwa6lsG46nIgHdx+4aRxE/Qu8qludTix03f/bmKZ50jCMY4ZhNDNNcy/QBdh16c99wNRL\nfy8tlqQiIiIiUmJsdpNZqw/xxrK9eLtX5MP7IugSpCu1pJhlp0HcR7DxPbiQBNUaw51vQot7oKKH\n1enEART147BRwPxLM/geAu4HnIAYwzAeAI4AA4p4DBEREREpQUdTLjImJp7YI+foHlyTF3uHUM1L\nk9FIMTp3BDbOhC3zIDcD6neEHq9Dk9vAycnqdOJAilRQTdOMByKu8K0uRdmviIiIiJQ80zT5bPMx\n/v31LpwNgzcGhNG7ZW0MTUgjxSUptuA03t1fguEEwX2g7aNQK9zqZOKgdEGBiIiISDl0Oj2bpz7f\nzso9p2nXqBqv9Q+jdhV3q2NJWWC3wZ5vCiY+OrYBXL2h7UiIfhi8a1udThycCqqIiIhIOfPd9hNM\nWLydi7k2nruzOUPb1cfJSaOmUkQ5GRA/v+BWMecSoUpd6D4VWg4G10pWp5NSQgVVREREpJxIy8rj\n+S938sXW44TW9ubNgWE0rq7iIEV0IRk2zYLY2QWTINWJhK7PQ+Cd4Ky6IddGPzEiIiIi5cDaA2d5\nYmECp9NzeLxLE0be0hgXZ01OI0VwYlvBabw7FoFpLyik7UZBQJTVyaQUU0EVERERKcOy82xM/W4P\nc9cl0tDXk88faUd4QBWrY0lpZbfDgWWwfgYcXg0unhD5YMH1pT4NrE4nZYAKqoiIiEgZlXDsPGNi\n4jl4JpOh7eozvnsg7hWdrY4lpVFeFmxbUDBienYfVKpVcBpv66Hgrg88pPiooIqIiIiUMXk2O2//\ndIDpKw/g5+XKxw9E0bGJn9WxpDTKOAObPyj4c/Es1GwBfd6H5r2gQkWr00kZpIIqIiIiUoYcOJ3B\n2Jh4EpLS6BVei+d7huDt4WJ1LCltzuwtOI03YQHYcqBp94JbxdTvALpPrpQgFVQRERGRMsBuN5m3\nPpGXv9uDe0Vn3v5HK3q08Lc6lpQmpgmHf4Z1MwquM63gBuH/gLaPgm8Tq9NJOaGCKiIiIlLKJZ/P\nYtyiBNYeSKFzMz9e6duC6pXdrI4lpUV+Luz4vOD60lPbwdMPOk+EiGHg6Wt1OilnVFBFRERESinT\nNFkSf5znlu7EZjd5qXco90YFYOgUTCmMi6kQNwc2zoKMk+AXCD2nQ+gAcNEHHGINFVQRERGRUig1\nM5dnlmzn2+0naV2vKm8MCKNeNU+rY0lpkHIQNrwL8fMh7yI07Ax3vw2Nu+j6UrGcCqqIiIhIKbNy\nzynGf76d8xdzebJ7Mx66qRHOTioW8jdME45uKJj4aM834FQBQvsXXF9aM8TqdCKXqaCKiIiIlBKZ\nOflM+WY3/9t0lGY1KjH3/kiCa3lbHUscmS0fdi8tuL70eBy4VYGOYyBqOFSqaXU6kT9RQRUREREp\nBWITUxkTk8Cxcxd56KaGjLmtKa4VnK2OJY4q+wJs/Rg2zIS0o+DTEO6YVjArb0WdCi6OSwVVRERE\nxIHl5Nv4z/L9vPfzQWpXdWfB8LZENfCxOpY4qvPHYONM2DIPci5A3XZw+9SC+5g66QMNcXwqqCIi\nIiIOaveJC4xeEM+ek+ncExnAM3c2x8tVv77JFRzfUnB96c4lBV8H9yq4vrR2a2tziVwj/Q8nIiIi\n4mBsdpP3fznEGz/uo7J7BT74ZwRdm9ewOpY4GrsN9n0P62bA0XXgWhnaPALRD0OVAKvTiVwXFVQR\nERERB3I05SJjF8azOfEc3YNr8mLvEKp5uVodSxxJbibEfwob3oHUQ+BdF7q9BC2HgFtlq9OJBexZ\nWRgVK2I4l/7TuFVQRURERByAaZos2HyMf3+9CyfD4PX+YfRpVRtD96WUX6WfhE2zIHY2ZJ0rOH23\n3xwI6gnO+rW+vLGlpZH+00+kL19O5pq11H1/Fh6RkVbHKjL9JIuIiIhY7HR6Nk9/vp0Ve07TtmE1\npg0Io3YVd6tjiaM4uaPgNjHbF4I9HwJ7QNuRULcN6AOMciXv1GnSVywnY/lyMjdthvx8KtSoQZU+\nfXCuVs3qeMVCBVVERETEQt9tP8GExdu5mGvjuTubM7RdfZycVDrKPdOEAytg/XQ4tApcPCDi/oLr\nS6s1sjqd3EC5iYmkL19O+rLlZCUkAFCxfn2q3X8/lW7tiltICIaTk8Upi48KqoiIiIgF0rLyeP7L\nnXyx9Tihtb15c2AYjatXsjqWWC0vG7bHFIyYntkDXjWhy3PQ+n7w0O2FygPTNMnZvZsLy5aRsXw5\nOfsPAOAWHIzf/z1Opa5dqdioUZk9/V8FVUREROQGW3vgLOMWJnAqPYfHujRh1C2NcXEuOyMgch0y\nUyD2w4JrTDPPQI0Q6DUTQvpChYpWp5MSZtpsZG3ZcnmkNC85GZyc8GjdmhoTnqZSly641K5tdcwb\nQgVVRERE5AbJzrPxyvd7mLM2kYa+nnz+SDvCA6pYHUusdHZ/wWhpwv8gPxua3FZw/9IGN+v60jLO\nnpvLxfXrC0rpipXYUlMxXFzwbN8e30dH4NW5MxV8yt+ouQqqiIiIyA2wLek8oxfEc/BMJve1rcdT\ntwfhXrH03xJCroNpQuIaWD+j4D6mzq4QNhDaPArVA61OJyXIlpFJ5uqfSV++nIyfV2PPzMTJ0xOv\nm2+m0q1d8ex4E85enlbHtJQKqoiIiEgJyrPZeeeng0xfuR9fL1c+fiCKjk38rI4lVrDlwc7FBcX0\nRAJ4VIObn4LIB8FLPxNlVX5qKhkrV5K+bDmZ69dj5ubi7OND5TvuoNKtXfFo0wanijqN+1cqqCIi\nIiIl5OCZDMYsiCchKY1e4bV4vmcI3h4uVseSGy3rPMTNhY3vQXoy+DaFu96CFgPBRbcTKovyjh8n\nfcUK0pct52JcHNjtuNSuTdV776XSrV1xb9kSw7loZ1Dk2fPYemorq5NWs/r4aqZ2nErzas2L6RlY\nRwVVREREpJjZ7Sbz1icy9fs9uLk48/Y/WtGjhb/VseRGO5cIG96FLR9DXiY0uKmgmDbuCmXotiBS\nMPNu7sGDpC9bRvqy5WTv2gWAa5Mm+D78EJVuvRXXwMAiz7x7Nussa46vYXXSatYnrycjL4MKThWI\nqBFBvj2/OJ6K5VRQRURERIpR8vksnly0jTUHztKpmR+v9m1B9cpuVseSG+nYJlg3HfZ8DYYThPQr\nmPjIv4XVyaQYmXY72du3X555NzcxEQD38HCqj3ui4HYw9eoV6Rh2087ulN0Fo6RJq9mZshMTEz93\nP26rfxs31b6JNrXa4OlSdq5bVUEVERERKQamabI0Pplnl+4g32byYu8Q/hFVt8zeq1D+wG6D3V8V\nXF+atBncvKH9/7N339Fx3eeB9793CurMoAwwgzJo7ARYQBIsAIkhRQKQbMsqtiVLjiXFki0rltxk\nO3G8zr6btutNe7PHjtYlTryJN7GVxIljx44BkCIBVgiUWESwk+jAoANTMPXe/eOCQ1LNFNugPJ9z\ndEiKF8PfJQnwPvO0z8OmZ8FWkOjTidtEi0QItLfjbWrGu3s3UY8HTCbSN20i+6knsezchdnpuKVf\nwx/xc6j/EPt697G/bz8j0yMoKKzOWc1nKj+D2+VmZfbKefu1RQJUIYQQQohbNO4P81/+7SS/ODnI\nhpIs/vyRtZTmzJ+MhngXIS+8/kO9lHeiC7JK4X1/ApW/AcmWRJ9O3Abq9DT+Awf0oHTvXtTJSZSU\nFCy127DWfRHLjh0YMzJu6dfonOyM95Ie9Rwlqkaxmq3UFNbgdrnZWrAVe6r9Nt3R7CYBqhBCCCHE\nLXjlzBC//S8nmAiE+cq9y3lu+2KMhvmZ2RDXmOyDtu9A+w8gNAlFW6Dhj2DFB8Ag64PmutjUFL69\ne/E2NePbvx9tehqDzYb1nnv0dTBbt2JIvfkBV+FYmPbBdlr6WmjtbaXb2w3A4ozFPLHyCWpdtVQ6\nKjEbFt5QNQlQhRBCCCFugj8U5Y/+4zT/2NbNcqeVH3xiIxUFt5ZFEXNA/zE49Fdw6iegqVD+IFS/\nAK6qRJ9M3KLI0BC+mcm7/rY2iEYxORxkPvwQ1ro60jZuRDHffMA4FBiitbdVH3A0cIjp6DRJhiQ2\n5W/i4+Ufp7awFpfVdRvvaG6SAFUIIYQQ4j1q7xzjxZeP0zMe4NPuRXyxfhkpZsmazVuqCucb9f7S\nzlZIsui9pZufg6xbG4IjEivc1RUfcjR9/DhoGkklJdh/8yms9fWkrF6NcpMTl2NqjDdG36ClV8+S\nnh47DUBeeh4fXPRB3C43m/I3kWqSVUPXkgBVCCGEEOIGhaIx/rL5PN/Zd5GCzFR+/Gw1m8qyE30s\ncaeEA3DiR3DoJRg9D7ZCqP9D2PCUPgRJzDmaphE6c0bvJ21qInT+PAAp5eXkfu6z+uTdJUtuegDR\nVHiKg30HaeltYX/ffsZD4xgUA5W5lXx+/edxu9wszVw6bwcc3Q4SoAohhBBC3IAzg1N84UfHODPo\n5aNVRfzeB8uxJMuj1LzkG4K278Grfw3TY5BfCR/+vl7Oa1x4PYFznRaLMf3663pQ2txMpK8PDAbS\n1q/H+btfxbKrjiRX4c29tqZxceIiLX36GphjQ8eIaTEykjPYVrgNd6GbrYVbyUiWNzRulHxVFUII\nIYR4FzFV469bL/HnjeewpZr46yerqCt3JvpY4k4YOq2X8Z54GWIRWP4+vb+0pAYk4zWnqOEwgcOH\n9aB0zx5io6MoZjNpNdXYn/s01p07MdlvbipuMBqkbbAtXrrb7+8HYHnWcp5e9TRul5vVOasxyrCs\nmyIBqhBCCCHEO+gZC/Cll4/T1jnGvRVO/vvDq7FbkhN9LHE7aRpcegUOfgsu7gZTKqx7ArZ8BnKW\nJPp04j1Q/X58ra365N19+1B9PgxpaVh2bMdaV0e6243RcnOrfwZ8A/E1MG0DbQRjQVJNqWzO38wz\nq5/B7XKTl553m+9oYZIAVQghhBDiTTRN4+X2Hv7gZx0YFIU/f2QtH1pfKH1j80k0BCf/WZ/IO3QK\nLE7Y+XWoegbSpK94roiOj+Pbs0efvHvwIFo4jDErC+t99+pBaXU1huT3/qZSVI1yfPi4HpT2tnBh\n4s0RGgkAACAASURBVAIAhZZCHl76MG6Xm415G0k2yhtWt5sEqEIIIYQQ1xj2hvjdn5yg+fQQ1Yvs\n/Okja3BlpSX6WOJ2CYxB+/f1HlOfBxzl8OBLsPojYJJgYy6I9Pfjbd6Nt7mZQHs7qCqmgnyyHn8M\na10dqevXoxjfe3nteHCc/X37ae1t5UD/AabCU5gUE+uc6/jShi/hdrkpyyiTN6ruMAlQhRBCCCFm\n/OcbA3ztX9/AF4rye/eX84maUgwGeRidF0YvwuGX4PX/C9FpWLwLHvrfsHin9JfOAaGLF+OTd4On\nTgGQvHQJ9k8/i7WujpTy8vccOGqaxtnxs/Es6cmRk6iaSnZKNjuKduB2uakpqMGaZL0TtyTegQSo\nQgghhFjwpoIR/ttPT/GT1/tYXZjBXzy6lqVOeSid8zQNug7qZbxnf6FP4F3zKGx5HpzliT6deBea\nphE8eTI+eTd8+TIAKWvXkPulF7HW1ZFcVvaeXzcQCXB44LA+4KivlaHAEADl9nKeXfMs7kI3FTkV\nGJSb230qbp0EqEIIIYRY0A5eGOHL/3QcjzfE53Yu4bO7lmI2ysPpnBaLQMdP9Ym8/a9Daja4vwIb\nPwlWmcA8W2nRKIH2dj0o3b2b6OAgGI2kb95E1hMfx7prF2bne//z65nqia+BeXXwVSJqhHRzOtX5\n1bhdbrYVbiM3LfcO3JG4GRKgCiGEEGJBCkZi/M//PMPfHuhkUU46//xcNeuKsxJ9LHErgpPw2t/B\n4W/DVC/Yl8AH/gLWPg5J0kc8G6nBIP6DB/E2NuF75RVik5MoKSmkb9uK9Qufx7pjB8bMzPf0mhE1\nwuue19nXu4+W3hY6pzoBKLWV8tiKx3C73GxwbMAsO21nJQlQhRBCCLHgnOyd5IsvH+PCkI+nqkv4\n6vtWkpokOwvnrPEuOPIdPTgNe6G0Fj7wZ7D0XjBINny2iU1N4du3T18Hs38/WiCAwWbT18HU12PZ\nuhVD2nt7Q2FkeoT9fftp6W3hUP8hfBEfZoOZKmcVH13+UdwuN8W24jt0R+J2kgBVCCGEEAtGNKby\nV69c5Jt7zpNjSebvnt6Ee5mU9s1ZvUfh0Df1cl7FABUfgurPQMG6RJ9MvEl0eBjv7j14m5vxHzkC\nkQim3FwyHnxAXwezaROK+cYzmqqm0jHaER9wdGpUH5zkSHVwb+m91Lpqqc6vJs0smfO5RgJUIYQQ\nQiwIF4d9vPjycY73TPBgZQF/8MAqMtKkxG/OUWP6wKOD34Kew5CcAdUvwOZPQ4Yr0acT1wj39MQn\n704fOwaahrmkmOwnn9DXwaxdi/IeMty+sI9DA4f0AUe9rYwGR1FQWJ27mhcqX8DtcrMie4WsgZnj\nJEAVQgghxLymqhp/f7iL//HL06SYjXzrY+u4f01Boo8l3quwX18Rc/glGL8MmcVw3zdg3cchWSYu\nzwaaphE6ezY+eTd09iwAyStXkvPC81jr60leuvSGA0hN0+ic6owHpEeHjhJVo1iTrGwt2Irb5WZr\n4VayU7Lv5G2Ju0wCVCGEEELMWwOT03zln06w/8IIO5bn8j8/vAanLSXRxxLvxdQAtH0H2v8WghPg\n2gh1/w1W3A9GeZRNNE1VmT52LB6URnp6QFFI3bAex1d/B2tdHUmuG89sh2Nh2gfb41N3e7w9ACzJ\nXMIT5U/gLnRT6ajEZJA/+/lK/mSFEEIIMe9omsZPj/Xzez99g2hM448fXsXHNhVL6d9cMnhS3196\n8p9Bi+kBac1noWhTok+24GnhMP4jbXibmvDu2UNsZATMZtKrt2D/1Cex7tyJKSfnhl/P4/fQ2tdK\nS28LhwcOMx2dJtmYzKa8TTxZ/iS1rloKLYV38I7EbCIBqhBCCCHmlXF/mK//2xv8x8kB1hdn8heP\nVlKak57oY4kboapwoVnfX3p5H5jTYeMzsPk5yC5L9OkWNNXvx9e6H29zM759+1C9XpS0NCxuN9b6\nOizbt2O0WG7otWJqjJMjJ/XS3b5WzoydASA/PZ8HFj+A2+VmY95GUk2pd/KWxCwlAaoQQggh5o1X\nzg7x2/98golAmK/cu5xPuxdhMsqakVkvEoQTP4JDL8HIWbAWQN3vw4anIFV20yZKdHwc3yt79cm7\nBw6ghUIYs7KwNtTrk3drajAkJ9/Qa02GJjnYf5CW3hYO9B1gPDSOUTGyNnctX1j/BWpdtSzNvPH+\nVDF/3XKAqiiKEWgH+jRNu19RlGzgx0Ap0Ak8qmna+K3+OkIIIYQQ78QfivLHvzjNPxzpZrnTyg8+\nsZGKgoxEH0v8Or5haP8+tH0PAiOQtxoe/i5UPAympESfbkGKDA7ibd6Nt6mJQHs7xGKY8vPJfPRR\nrHV1pG1Yj2L69SGEpmlcmLgQXwNzfPg4MS1GZnImWwu34i7UBxxlJMvnqbje7cigfh44DdhmfvxV\nYLemad9QFOWrMz/+ndvw6wghhBBCvMXRrjFefPk43WMBnnUv4sX6ZaSYjYk+lng3w2f1/tLjP4JY\nCJbdB9XPQ2ktSAbtrgtduhQfchQ8eRKApMWL9X7SunpSKspvKLMZjAZpG2yLB6UD/gEAlmct5+lV\nT+N2uVmdsxqjQT4/xTu7pQBVURQX8AHgj4EXZ/73g8COme//H2AvEqAKIYQQ4jYLR1X+/+ZzfGff\nRQoyU/nRp7aweZE90ccS70TT9L7SQ38F5xvBlAKVH4Mtn4HcZYk+3YKiaRrBN07hbdaD0vDFiwCk\nrFlD7osvYq2rI3nRjfX89vv64wFp22AboViIVFMqm/M386k1n6K2sJa89Lw7eTtinrnVDOpfAr8N\nXLt8yqlp2sDM9wcB59t9oKIozwLPAhQXF9/iMYQQQgixkJwZnOKLPz7O6YEpPlpVxNfvX4k1xZzo\nY4m3Ew3DqZ/og48GT0J6Luz4mj78KP3GJ72KW6NFowTaj+pB6e7dRAcGwGgkbeNGsj72ONZduzDn\n/fpAMqpGOTZ0jJY+fTfphYkLALgsLj689MO4XW6q8qpINt5Yb6oQb3bTAaqiKPcDQ5qmHVUUZcfb\nXaNpmqYoivYOP/dd4LsAVVVVb3uNEEIIIcS1YqrGX7de4s8bz2FLNfG9J6uoL3/b98JFok2P67tL\n274L3gHIXQEPfBNWPwpm2UV7N6ihEP4DB/XJu3v2EJuYQElOJn3bNqyf+xyWHdsxZf36IVTjwXH2\n9+3XBxz1H8Ab9mJSTKx3rufLVV+m1lVLma1MBhyJ2+JWMqhbgQcURXk/kALYFEX5IeBRFCVf07QB\nRVHygaHbcVAhhBBCLGw9YwG+9PJx2jrHaCh38j8+tBq7RbI0s87YJTj8v+H1H0IkAIvugQe+BUt2\nSX/pXRDzevHta8Hb1ISvtRUtEMBgtWLZsQNrXR2W2m0Y0tLe9TU0TePs+Fn29eyjpa+Fk8Mn0dDI\nTslmZ9FO3C431QXVWJOs7/o6QtyMmw5QNU37XeB3AWYyqF/WNO3jiqL8KfAU8I2Zb396G84phBBC\niAVK0zRebu/hD37WgUFR+LNH1vLh9YWSrZlNNA16jsDBb8KZ/wCDCVY/og8+yluV6NPNe9GREby7\n9+jrYA4fhkgEY24OGR/8INb6etI3bURJevepyIFIgMMDh+O7SYcCeo6pwl7Bc2ufw+1yU24vx6DI\n2iZxZ92JPajfAF5WFOUZoAt49A78GkIIIYRYAIa9IX73JydoPj1E9SI7f/rIGlxZ7579EXdRLAqn\n/10ffNTXDimZUPsibHoWrDIY504K9/bGJ+9Ov/YaaBrm4mKyn3gCa10dqZVrUQzvHkx2T3XHBxy1\ne9qJqBHSzenUFNRQW1hLrauWnFTpExZ3120JUDVN24s+rRdN00aBXbfjdYUQQgix8GiaxvkhH42n\nBvmbA534QlF+7/5yPlFTisEgWdNZITgFr/89HP42THZD9iJ4/5/pU3mT0hN9unlJ0zRC587jbWrC\n29xM6MwZAJJXrCDn+eex1teRvGzZu1YWRGIRXht6LR6Udk51AlBqK+XxFY/jdrlZ71iP2SgDx0Ti\n3IkMqhBCCCHEexJTNV7rHqfx1CBNHR46RwMAbCrL5o8fWsVSp/S6zQoTPXDk2/Da30FoCopr4H3f\n0PeYym7L205TVaaPHY+vg4l0d4OikLpuHY7f+R2sdbtIKip619cYmR6htbeV1r5WDvYfxB/xYzaY\n2Zi3kcdWPIa70E2R7d1fQ4i7SQJUIYQQQiREMBKj9fwITR2D7D49xKg/jNmoULM4h0/WLqK+3InT\nJtNeZ4W+1/Qy3lP/qv+44iG9v7RwQ2LPNQ9p4TD+tlfxNjfh272H6PAwmM2kb9mC/ZlnsO68B1Nu\n7jt+vKqpdIx2xLOkp0ZPAeBIdXBf6X24XW625G8hzSyl8mJ2kgBVCCGEEHfNuD/M7jNDNHUM0nJu\nhOlIDGuKiXuWO2iocLJ9Wa7sM50tVBXO/VIPTLsOQJIVtvwWbP40ZMoO+9tJDQTw7d+Pt6kZ3969\nqF4vSloaltpaffLuju0Yre9cReANeznUf4iW3hb29+1nNDiKgsKa3DV8dt1ncbvcLM9aLoPFxJwg\nAaoQQggh7qiesQCNHR6aOgZ5tXOcmKqRZ0vhIxtcNFQ42VxmJ8kkk0FnjXAAjv1ffVXM2EXIKIJ7\n/zusewJSbIk+3bwRm5jA+8peffLu/v1ooRDGjAysdXX65N2aagwpb19BoGkal6cu09rbSktvC695\nXiOqRbEmWdlasBW3y83Wwq1kp2Tf5bsS4tZJgCqEEEKI20rTNE71T9HY4aHx1CBnBr0ALHda+cyO\nxdSXO1ldmCHZnNnG64G270L792F6HArWw0f+BlY+CEZ5ZLwdIh5PvJ800PYqxGKY8vLIfOQRrHV1\npFVtQDG9/e91KBaifbA9Xrrb6+sFYEnmEp6seJLawloqHZWYDPJnJeY2+RsshBBCiFsWiam0XR6j\nqcNDU4eHvolpDApUlWTz9Q+spL7cSYldprvOSp5TehnvyX+CWARWfACqX4DiLSBvItyy0OXL8XUw\nwRMnAEhatEjvJ62vI2XVqnd8s2bQP0hrn54lPTJwhOnoNMnGZDblbeKpiqdwu9wUWAru5u0IccdJ\ngCqEEEKIm+ILRWk5N0zjqUH2nBliKhgl2WSgdmkun69byq4VDuyW5EQfU7wdTYOLu+Hgt+DSK2BO\ngw2/CZufA/viRJ9uTtM0jeCpDrzN+jqY8IWLAKSsWkXuF7+or4NZtOhtPzamxjg5cjKeJT07fhaA\n/PR8Hlj8AG6Xm415G0k1pd61+xGzm6ZpTI1M47k8RdHKbFKtSYk+0i2TAFUIIYQQN2zIG2T36SEa\nTw1y4OIo4ahKVpqZhoo86sud1C7NIS1JHi9mrWgITrysZ0yHT4MlD3b9V9jwCUiTfsWbpcViBI4e\njZfvRvsHwGgkraqKrI8+hrVuF+b8/Lf92MnQJAf6DtDS18KBvgNMhCYwKkbW5q7lC+u/gNvlZknm\nEimJFwAE/RGGOqfwdE7huax/G/RFALj3U6tYssGR4BPeOvkXRAghhBDv6uKwj6aZftLXeybQNCjK\nTuWJLSXUlzupKsnCZJQhR7Oaf1TvLW37HviHwLkKHvo2rPowmOZ+xiUR1FAI/6FDeJua8O15hdj4\nOEpSEulbt2J9/gUsO+/BlJX1lo/TNI3zE+dp6W2htbeVY8PHUDWVzORMthVuw+1yU1NQQ0ZyRgLu\nSswmsajKSK9vJhCdZKjTy4RH3xGNAtn56ZStycFZZsNZZiM7f360UUiAKoQQQojrqKrGsd4JGk/p\nk3cvDvsBWF2YwRfrltFQ4WS50yoZnblg5LyeLT3+jxANwpJ6qHkByrZLf+lNiPl8+Pbt0yfv7mtB\nDQQwWCxYduzQ18HUbsOQ/tYgYTo6TdtAmx6U9rUy4B8AYEX2Cp5Z9Qxul5vVOasxGox3+5bELKGX\n6gbxdE7qAenlKUZ6fMSiKgBptiScZTZWVOfhLLXhKLGRlDo/Q7n5eVdCCCGEeE9C0RgHL47SeMpD\n82kPw94QJoPClkV2nqwupa7cSWGm9L3NCZoGnfv1wPTcL8GYDGs/ClueB8eKRJ9uzomOjuLds0ef\nvHvwEFokgjEnB9v992OtryN982aUpLdmoft8ffFe0lcHXyUUC5FqSmVL/haeXfMstYW1ONOdCbgj\nMRuEApHrynSHOqeY9uqluiazgdwSK6vvceEs1bOjlqzkBfOmoASoQgghxAI1GYjwytkhmjo87D07\nhD8cIz3JyI7lDhoqnOxY5iAjzZzoY4obFYvAqX+FQ9+CgeOQZoftX4WNz4Bl7vel3U3h3r74kKPp\n114HVcXscpH18Y9jra8jde1aFOP12c6IGuHY0LH4btKLk/pwpCJrER9Z9hHchW6q8qpIMkpJ9UIT\ni6qM9vniwajn8tR1pbpZeemUrM6JB6P2gnQMC7htQgJUIYQQYgHpn5iOr4I5fGmUqKqRa03mgcpC\nGiqc1Cy2k2ySMsM5ZXoCjv4AjnwHvP2Qsww++L9gzUfBLFnvG6FpGqHz5+NDjkIdpwFIXr6cnN/6\nLX3y7vLlb8lgjQXH2N+3n5beFg72HcQb8WJSTGxwbuDhpQ/jdrkptZUumMyX0P8ueUeD8TJdT+ck\nw91XS3VTbUk4S20s35Kn947O41LdmyW/G0IIIcQ8pmkaZz1eGk95aOwY5I2+KQAW56bzydpFNFQ4\nqXRlYjDIA/ScM94Jh78Nr/89hH1Q5oYP/qXeZ2pYuNmXG6WpKsETJ/A2NzPV1ESkqxsUhdTKShxf\n+QrW+jqSiouv/xhN48zYGb10t6+Fk8Mn0dCwp9jZVbILt8tNdX41liRLgu5K3G2hQIShTu/V3tG3\nK9XdUYizLGPBlereLAlQhRBCiHkmGlNp7xrXJ+92DNIzNo2iwLqiTL76vhXUlztZnCsP0HNWz6tw\n6Jtw+megGGDVR6D6M5C/NtEnm/W0SITAq68y1dSEb/ceokNDYDKRvnkz9k88jXXXTky5udd9TCAS\n4NDAIVp7W2ntbWVoegiAVfZV/Nba38LtcrPSvhKDIm8KzHexmMpo7zuU6gJZeWmUrLLrwWipjezC\ndIwLuFT3ZkmAKoQQQswD0+EYLeeHaerwsPu0h/FAhCSjga1L7HxmxxJ2rXTgsKYk+pjiZqkxOPNz\nOPgt6G2DlAzY+nnY9CzYChJ9ullNnZ7Gt38/vuZmvHv3oU5OoqSmYqmtxVpfh2X7dow223Uf0z3V\nHR9w1O5pJ6JGsJgtVBdU43a52Va4jZzUnATdkbgb4qW6VwYZXZ5iuMdLLDJTqms14yzLYPlmvVTX\nUWojWUp1bwv5XRRCCCHmqFFfiN1nhmg85WH/hWGCERVbioldK53UlztxL8vFkiz/1M9pIR+8/kM4\n/BJMdEFWKbzvT6DyNyBZsuDvJDY5iW/vXqaamvDvP4AWDGLMyMB6zz365N2tWzGkXH3DJhKLcHTo\naHw3aedUJwBlGWV8bMXHcLvcrHOsw2yUoWHzVWg6ytA1U3U9lyfjpbpGswFHsZVV2wv1QUalNqz2\nFCnVvUPkXy0hhBBiDuka9eulu6c8tHeNoWpQkJHCYxuLqS93sqksG7OUlM19k33Q9h1o/wGEJqFo\nCzT8Eaz4AMiuzLcV8Qzh3d2Mr7kZf9urEI1icjrJ/PCHsdbXkVZVhWK6+ug7Mj0Sn7h7aOAQ/ogf\ns8HMxryNPLbiMdyFbopsRQm8I3GnxGIqY31+PJev9o2OewKg6T+flZdGSYVdH2JUliGluneZBKhC\nCCHELKZpGif7Jmk8pU/ePevxArAiz8oLO5fSUO6kosAm7+TPFwPH9TLeUz8BTYWVD0DNZ8FVleiT\nzUrhzk598m5TM9PHjwOQVFaG/ROfwFpfR8qqVSgzA6NUTeWN4ZO09Omlux2jHQA40hy8r+x9uAvd\nbM7fTJo5LWH3I24/TdPwjgWv7hu9PMVwt5fotaW6pTaWbXLiLM3AUWolWdZrJZQEqEIIIcQsE46q\nHLk8SuMpD82nPQxMBjEosKksm9+7v5yGcidF2fIQPW+oKpxv1PeXdrZCkkXvLd38HGSVJPp0s4qm\naYROn9aHHDU3Ezp/AYCUigpyv/B5rPX1JC9eHL/eG/ZysP8gLb0t7O/bz1hwDAWFNblr+Oy6z7Ld\ntZ1lWcvkDZ55JDwdxdM1dc2alymmp8KAXqqbW2Slwl0Y3zkqpbqzjwSoQgghxCzgDUbYd26YxlMe\nXjk7hDcYJcVsYPuyXL7UsJydKxxkpycl+pjidopMw/F/hEMvweh5sBVC/R/C+ichNTPRp5s1tFiM\n6ddei2dKI/39YDCQVlWF82tfw1q3C3OBPihK0zQuTVyKr4F53fM6US2KNcnKtoJt1Lpq2Va4jayU\nrATflbgd1JjKaJ9f7xmd6R8dH/THS3UznWkUl2fHg1G7yyKlunOABKhCCCFEgnimgjR16KW7By+O\nEIlp2NOTeN+qPBrK89i2NIcUs/Qbzju+IWj7HrR/HwKjkF8JH/4+lD8IMoQHADUcJnDokB6U7t5D\nbGwMJSmJ9Joacp7/DJZ77sGUnQ1AKBZif9/++NTdPl8fAEsyl/BkxZO4XW7W5q7FZJDH3rlM0zR8\n46GZzOgkns4phruuluqmWMw4y2wsrXLoU3VLbKSky+fTXCSfqUIIIcRdomkaF4d9/Gqmn/RYzwQA\nJfY0frOmlIaKPNYXZ2E0SLnZvDR0Gg79FZx4GWJhWP4+qH4BSmpASgyJ+fz4W/bhbW7Gt68F1e/H\nkJ6OZft2ffJurRujJR2AQf8gLWdfprW3lSODR5iOTpNiTGFT/iY+UfEJal21FFhk/c5cFp6OMtQ1\ndd2al8CVUl2TgdxiCxW1hTODjKRUdz6RAFUIIYS4g2Kqxuvd4/rk3Q4Pl0f8AKx1ZfDlhmU0VOSx\n1GGRB6v5StPg0l69v/RCM5hSYd3HYctnIGdJok+XcNGxMXx79uBtasZ/6BBaOIwxOxvb+9+vT97d\nsgVDUhIxNcaJkRO0nNOzpOfGzwFQkF7AA4sfwO1ysylvEykm2fU7F6kxldF+/zUrXt5aqlu0Mjse\njNoLLRhNUqo7X0mAKoQQQtxmwUiMAxdGaOrQhxyN+MKYjQpbFtl5elsZ9Sud5GXIg/S8Fg3BG/+i\nZ0w9b0C6A3Z+HTY8Den2RJ8uoSJ9fXh378bb1Ezg6FFQVcyFhWQ9/jjW+jpS161DMRqZDE3yy94m\nWnpbONB/gMnQJEbFSKWjki9u+CLuQjeLMxfLmztzzHWlujP7Roe7vUTDM6W66deU6pbacJRKqe5C\nIwGqEEIIcRtMBMLsOTNE4ykPLeeHCYRjWJJN7FieS0NFHjuW52JLkYeseS8wBu1/o/eY+gbBUQ4P\nvgSrPwKm5ESfLiE0TSN88SLepia8Tc0EO/T1LslLl5Lz3HNY6+tIXrECgHPj52jt+Ftaels4Pnwc\nVVPJSs7CXejG7XJTXVBNRnJGIm9HvEfhYJShLu91O0cDk3qprsGkkFtkpXxbgZ4dLbVhy0mVNx0W\nOAlQhRBCiJvUOx7QS3dPeWjrHCOmajhtyXxofSH15XlsWZRNskmGHC0Ioxfh8Etw7B8gEoDFu+Ch\nl2DxzgXZX6qpKsGTJ+OTd8OdnQCkVlbi+MqXsdbVkVRSwnR0msMDR2g5/E+09rUy6B8EYGX2Sj65\n+pO4XW5W2VdhNMjn0VygxlTGBvzXrXgZG7haqpvhSMW1IgtnaQbOMhs5LinVvVWxaJSJwX5Gerop\nKl9FWsbcnwAuAaoQQghxgzRNo2NgKh6UdgxMAbDUYeG57YtoKM9jdWEGBhlytDBoGnQfgoPfgrO/\n0CfwrnkUtjwPzvJEn+6u0yIRAu3teJua8e7eTdTjAZOJ9E2byH7qSSw7d2F2Oujz9dHY20JL8zdo\nG2gjrIZJNaVSnV/Nc2ueo9ZViyPNkejbETfANx68Lhgd6vYSDcUAvVTXUWpj8XpHPDsqpbo3T43F\nmPAMMNrTzUhvF6M93Yz2djPW34caiwLwwJe+xtJNNQk+6a2TAFUIIYR4F9GYSlvnGI0zk3f7JqZR\nFNhQnMXX3r+C+vI8ynLSE31McTfFotDxb/rgo/7XITUb3F+GjZ8CqzPRp7ur1Olp/AcO6EHp3r2o\nk5MoKSlYamux1tdh2b4d1ZrGsaFjtPb8kJZDLVycvAhAsbWYR5c/Sq2rlipnFUlG2fM7m4WDUYa7\nvNdM1Z3E/+ZS3Zp8HDM7RzNypVT3ZqhqjMkhDyM9V4PQ0Z4uxgb6iEUi8esyHE7srmLK1m8kx1WM\nfea/+UACVCGEEOJNAuEoLeeGaTzlYc/ZISYCEZJMBtxLc/jcriXsXOEk17ow+wkXtOAkvPZ3cOQ7\nMNkD9iXwgb+AtY9DUlqiT3fXxKam8O3di7epGd/+/WjT0xgyMrDu2KGvg9m6lQllmn19+2k59occ\n7DuIN+LFZDCxwbmBDy39EG6Xm9KM0kTfingHqqox1u/Hc3mSoc6ZUt1+P9qVUt3cVAqXZ81kRjP0\nUl2zlOq+F5qqMjk8xGhvFyPxQLSbsb4eopFw/DprTi45rmJK1q7H7iomp6gEe2ER5pT5O2hPAlQh\nhBACGPaG2H1az5K2XhghHFXJSDWza6WDhvI83MtySEuSfzYXpIluOPxtPTgNe6FkG7z/T2HpvWBY\nGA/lkaEhfR1MYxP+tjaIRjE5HGQ+/BDW+npSN2zgjPcC/97bQuuev+XkyEk0NOwpdupK6nC73GzJ\n34IlyZLoWxFvwzcewtM5GS/XvbZUNzndhLPUxqLKXJxlGXqprkVKdW+Upml4R4YZ6enSs6K9M8Fo\nXw/RUCh+ncWeQ46rmKKK1diLislxlWB3FZGUunDe/LpC0a68FZJAVVVVWnt7e6KPIYQQYoG5POKn\n8dQgTR0ejnaPo2ngykqlvtxJQ3keG0uzMBkXRgAi3kbvUb2Mt+On+o9XfQiqn4eCdYk9110SHuui\nsQAAIABJREFU7uqKDzmaPn4cNI2kkhKsDfVY6+qIrVjEkcE2WvpaaO1tZXh6GIBV9lW4XfrU3ZX2\nlRgU+RyaTcLBKMPd3ut2jvon9EDJYFTIKbLGe0alVPfGaZqGd3QkXpI7ciUQ7e0hEpyOX5eela1n\nQl3FeiBaVILdVUxy2vxvFVEU5aimaVW/7jp5K1gIIcSCoaoaJ/om40Hp+SEfABUFNj6/aykN5Xms\nzLfKw9hCpsbg7C/1wLT7ECRn6EHp5k9DhivRp7ujNE0jdOaM3k/a3Ezo3DkAUsrLyf3cZ7HW1THg\nMPOrvlZaer9F+4l2omoUi9lCTUENbpebrYVbyUnNSfCdiCtUVWM8PlV38i2lurbcVAqWZuoBaZmN\nXJdVSnV/DU3T8I+P6QFoz5Xy3C5Ge3sITwfi16VlZJJTVMyqHXV6f+hMVjTFIlUEv45kUIUQQsxr\noWiMQxdHaerQy3eHvCGMBoXNZdk0lDupK3fiylp4JVTiTcJ+fUXM4Zdg7BJkFsOWz8C6j0OyNdGn\nu2O0WIzpY8fiQWmktxcMBtLWr8daX0fKPds5bhqgpbeF1r5Wuqa6ACjLKMNd6GZ70XYqHZWYDVLy\nORv4J0IzmVG9XHeoy0vkSqluml6q67gmO5pqkcFU70TTNAKTE1fLcnu6Z7KiXYT8/vh1qVYb9qJi\n7K4ScopK4pnRVKstgaefnSSDKoQQYsGaCkZ45cwQTR0e9p4dxheKkpZkZPuyXBoqnNyz3EFmmjyY\nCWBqANq+C+1/A8EJcG2EXf8frLgfjPPzMUkNhwkcPqwHpXv2EBsdRTGbSa+pIee5TxOqXsuBwEla\nels41PoSgWiAJEMSG/M28viKx3G73BRZixJ9GwteJBRjuHuKwctTDM2U6/rGrynVdVlYUZ0fL9fN\ncEip7jsJTE0y0t01kwntjg8tCvq88WtSLFbsrmJW1LhnJuaWkFNUPC/2js428/MrrxBCiAVnYHKa\n5g4PjR0eDl8aJRLTyLEkcf+afBoqnNQsziHFbEz0McVsMXgSDv0VnPxn0GJ6QFr9AhRvTvTJ7gjV\n78fX2qpP3t23D9Xnw5CWhmXHdtJ37aK7wk7zeDstvS9zuvn3AXCkOXj/ovfjLnSzOX8zaWapNEiU\neKlu59Wdo2P9fjRVr4S05aSQvyQznhnNKbJgkq93bzHtnbouE3rl+9NTk/FrktPSsbuKWbq5ZiYb\nqmdG0zIyJcC/SyRAFUIIMSdpmsY5j4+mjkEaOzyc6NUfMBblpPP0tjIayp1UFmVhNMgDhZihqnBx\nNxz8JlzeB+Z02PgMbH4OsssSfbrbLjo+jm/PK3ibmvAfPIgWDmPMzsZ6372Y7tnKa0UxWocOsb/v\nTxjbN4ZBMbAmZw2fW/c53C43y7KWyQN5gvgnQ/GJup7OSb1UN3i1VNdRaqNsTU48O5pqlYqQawV9\nPkZ6r9kjOrPKJTA5Eb8mKTUVu6uYxRs2k1NUHO8TtWTZ5e99gkmAKoQQYs6IqRpHu8bjQWnXqD6Q\norIok9++bzkN5XksccgACvEmkSCc+LGeMR05C9YCqPt92PAUpGYl+nS3VWRgIN5PGmhvB1XFXFBA\n5mOP4a0uZ3/2CC0D+znW9zWivVFsSTa2Fm7F7XKzrWAbmSlSrni3RcIxhru81/WOxkt1DQo5RRZW\nbM6L945mOtJQ5I03AEIB/3UluVcm6PrGx+LXmJNTsLuKKKusum5qrtWeI4HoLCUBqhBCiFktGInR\nen6ExlOD7DkzxKg/TJLRQPViO8+6F1G30onTNn8Xlotb4B+BV/8a2r4HgRHIWw0PfxcqHgbT/Mk4\nhS5ejAelwTfeACB56RIyP/UMlysdvJLSSWv/Pvq6/wG6YWnWUp6qeAq3y82a3DWYDPI4eLdoqsbY\noD5Vd6hTL9Ud7XtTqe7iDH3fqJTqxoWD0zOB6NWs6EhvN77Rkfg1pqRk7K4iildX6mtcZgJRW04u\nygLZVzxfyFckIYQQs864P8zuM0M0nhqk5fwwwYiKNcXEzhUO6sudbF+WizVFpoaKdzB8Tl8Tc/xH\nEAvB0nuh5gUorYV5kDHRNI3gyZPxoDR8+TIAKWvXkPq5Zzm2MoVm9RRHBv6RYHeQFGMKm/M38/Sq\np6ktrCXfkp/gO1g44qW6M72jQ11T8VLdpFQTzlIrG+4r0afrltpIs82fN05uRiQYZLSv52owOpMV\nnRoeil9jNJvJLiyiaOWqmbJcvUc0I9chgeg8IQGqEEKIWaF7NEBjh76f9NXOMVQN8mwpPFpVREN5\nHpvKskkyycOHeAeaBpdb9DLe878CUwpUPg5bnofcZYk+3S3TolEC7e16ULp7N9HBQTCZSN1YRfjB\n7RxcHKVp+ijnx/8GuqHQUshDSx7C7XKzMW8jKSapMrjTIuEYw93e63pHfWNXS3XtLgvLN+fF+0YX\ncqluJBxirK9X3yM6U5Y72tvN5PAQV5a0Gk0msgtcFCxbyeqd987sES0mw5mHwSBZ5flM9qAKIYRI\nCE3TONU/ReMpvZ/0zKA+zn9FnpX6cicN5XmsKrRJj5B4d9EwnPqJnjEdPAnpubDxU/rwo/ScRJ/u\nlqjBIP6DB/E2NuF75RVik5MoKSkkV2+me30Bza5xXpl8lcnQJEbFyDrHOtwuN26Xm0UZi+Rz5w7S\nVI3xwUC8Z/TNpbpWe0o8EHWWZZBbZMGUtPCCqmg4zFh/bzwTqveKdjHp8aBpKgAGo4ms/AI9E3ql\nNLeomExnPgbjwvs9m89kD6oQQohZJxJTabs8RuMpPVPaPxnEoEBVaTZf/8BK6sudlNjTE31MMRdM\nj8PRH8CR74B3AHJXwAPfhNWPgnnuZgtjU1P49u3T18Hs348WCGCw2VBr1nN6lY2f5/ZydPIQqqaS\nPZXNdtd2al211BTUYEuyJfr481ZgKozn8tVgdKhzivCVUt0UI45SG+vvLdZ7RxdgqW4sGmG8vy+e\nDb0ytGhicCAeiCoGA1n5hThKFrFy2474HtHMvAKMJglJxFXyt0EIIcQd5QtF2Xd2mKYOfcjRVDBK\nitlA7dJcvli/jJ0rHNgtyYk+ppgrxi7B4W/D6z+EiB8W7YAHvgVLds3Z/tLo8DDe3XvwNjfjP3IE\nIhGMuTn4d1Xx6nIDP7GcYyC0H4CVhpV8avWncLvcVNgrMEqp420XvVKqe2Xn6OUpvGNB4Gqp7rJN\neqmuo9RGlnPhlOrGolEmBvvjmdAre0QnBvtRY3rArigGMvPysbuKWV69LZ4ZzSooxGiS2QHi15MA\nVQghxG035A3S3DFEU8cgBy6MEo6pZKWZaajIo6HcSe3SXFIXYLmbuEmaBj1H9DLe0z8HgwlWPwLV\nz0PeqkSf7qaEe3r0ftKmJqaPHQNNQykqwPOBKvYuDvLz5DOEtIOkmlKpcdbwnMvNtsJtONIciT76\nvKKpGuOewHWZ0dFeH+qVUt1svVR3zU4XzlIbucXWBVGqq8ZiTHgG9AD0mj7R8YF+1FhUv0hRyHTm\nYXeVsHRTtT6wyFVMdoELU9LCyiCL20sCVCGEELfFhSEfTR0eGjsGOdYzgaZBcXYaT1SX0FDuZENJ\nFiajDDkS70E4oA88Ovgt6GuHlEyofVHvMbXNrUm0mqYROns2Pnk3dPYsALGlJVz80Hr+o2iEQym9\noAxRbC3mEddHqXXVUuWsIskoD/u3S2AqPJMZnZyZquslPK0HXFdKddc1FOv9o2UZ875UV1VjTHoG\nZwLQq3tEx/p7iUWj8esyHE7srmIWbdhEzszk3OxCF+YkqX4Rt58EqEIIIW6Kqmq83jMRD0ovDfsB\nWF2YwYt1y6ivcLLcaZVBLeLG+Edh8MTMfydh4ASMngdNhexF8P4/g8qPQdLc6VHWVJXpY8fiQWmk\npwcUhUB5CSc+spJ/ze/jsqUPk8HDBucGvlL4MdwuN6UZpYk++rwQDccY7vHpwehMua53VC/VVQwK\n9sJ0lm504iy14izNICtv/pbqaqrK5PAQo70z/aEzWdHxvl6ikXD8OluuA7urmJK16+N7RO2FRZhT\n5m5ft5h7JEAVQghxw4KRGIcujtLY4aH5tIdhbwiTQWHLIju/WVNK3UonBZmpiT6mmM00DcY79SD0\n2mDU23/1GpsL8lZDxUPg2gSL74E50muphcP4j7ThbWrCu2cPsZERNLOJsYpCDm4p4t/zB5hM7yUn\nNYfawnv5nMtNdUE16ea5E3jPRpqqMTEUuG7n6LWlupbsZJylGaze4cJZppfqmudhqa6mqkyNDL9l\nj+hoXw/RUCh+ncWeQ46rmOKKNfr6lqIS7IVFJKWmJfD0QugkQBVCCPGuJgMRXjk7RGPHIPvODuMP\nx0hPMrJjuYOGCic7ljvISJXBF+JtRMMwfOZqIHrlv9CU/vOKEXKWQVmtHpDmrYa8NZCWndhzv0eq\n34+vdT/e5mZ8+/aher2oqcn0rMql+Z4MWop8BJP7WZWzit9wPYzb5WZl9koMipS836xpb/iaYHSS\noS4voYBekmpOMeIosVHZUDyz5sVGesb8KkXVNA3v6MjVQPTK0KLeHiKhYPw6S1Y29qIS1uy6D7ur\nmJwivU80OU3eEBGzlwSoQggh3qJ/Yjpeunvk0hhRVSPXmsyD6wqpL3dSs9hOsmn+ZR/ELQhOwuAb\n1wSjJ2DoDKgR/efNaeBcBWsevRqMOsrBPDcz7tHxcXyv7NUn7x44gBYKEbGlcqbCyn8WBzlWEiU5\n1UdNwVb+y8yAI3uqPdHHnpOikRgjPb6Zibp6ue7UyPWluks2OGb2jmaQmZeGYZ6U6mqahm98NN4f\nOnJNIBqeDsSvS8vIJKeomFX31OtluUXF5LhKSLFYEnh6IW6OBKhCCCHQNI0zg14aT3loOj3IG316\nhmtxbjqfci+iodzJWlfmvHnoE7dA02Cq/5oS3RN6ie5E19Vr0nP1TGhN3dWsaPaiOVOm+04ig4N4\nm3fjbWoi0N4OsRiB7HSOrk+meVGUs64wpVmZuF0P8FsuN5WOSswGqS54L+KluteseLmuVDcrGWeZ\njVXua0p1k+f23yvQvwYHJidmsqFdV4cW9XUT8vvj16XaMshxFVPuvkffIzoTjKZaZQeumD8kQBVC\niAUqGlNp7xqPB6U9Y9MoCqwvzuKr71tBfbmTxbny7vuCFovC6IXrhxcNnoTA6NVrshdDwTrY8JQe\niOatAaszcWe+zUKXLsWHHAVPngRgLD+d/dVGDiyBvgKVjQVVPFToxu1y47K6EnziuWXaF44HolfW\nvMRLdZONOEqtVNZfmao7P0p19UD0Sib0Sla0m6DPG78mxWLF7ipmRY17pjS3BHtRCWm2jASeXIi7\n46YDVEVRioC/A5yABnxX07T/pShKNvBjoBToBB7VNG381o8qhBDiVk2HY7ScH6bxlIc9ZzyMByIk\nmQxsW5LD8zuWsGulk1zr3H8AFDch7AdPBwwevxqIek5BdKafzZikl+Su+MBMILoanBWQbE3suW8z\nTdMIvnEKb7O+ozR86RIAvUWp7NthoG2ZglqUidvl5kWXm015m0gzy2CZG3Fdqe5M72i8VFeB7EIL\nizc49L7RUhtZ+elzumpj2jul7xGNDyzSe0WnvVPxa5LT07G7Sli2eSv2mf7QnKIS0jIyZQK6WLAU\nTdNu7gMVJR/I1zTtNUVRrMBR4CHgN4ExTdO+oSjKV4EsTdN+591eq6qqSmtvb7+pcwghhHh3o74Q\nu08P0djhofX8MKGoii3FxK6VThrKnbiX5ZKeLAU1C4pv+K1Z0ZHz6O83o+8bzVsN+Wuv9ovmLAPj\n/CxX1aJRAkdfw9vUxFRzE7FBD6pB4VyJiQNLYxxdZqRocSVul5vawlqWZS2T4OHX0DSNyaHp+L5R\nT+cUI70+1Ng1pbqlNhxlNvLKbOQW2+ZsqW7Q52Okt+vqHtGZVS6ByYn4NUmpqXpvqKtEH1RUpJfn\npmdly98lsWAoinJU07SqX3fdTT+RaJo2AAzMfN+rKMppoBB4ENgxc9n/AfYC7xqgCiGEuL06R/w0\ndXho6vDQ3jWGqkFhZiqPbyqmodzJxrJszEaZIDrvqSqMX37rShff4NVrMor1AHTVh6/2i2a49JTW\nPKaGQvgPHMTb3MTk7maY9BIxKxwrU2jbYOB8RQaVS2q5x+Xm6wVbyUzJTPSRZ7V4qW7nFEMz315X\nqltipbKuCGdphl6qmzn3KjVCAf/VktwrfaK93fjHx+LXmFNSsbuKKFtXNdMfqu8StdpzJBAV4gbd\nlrfMFUUpBdYBRwDnTPAKMIheAiyEEOIO0jSNE72T8cm75zw+AFbm2/jszqXUlzupKLDJA9J8Fg3B\n0Ok3rXR5A8IzfW2KEXJXwKIdkL/mamY0NSuRp76rYl4vvn0tTDb9Ct++FpRgiOkUhfbFcGSXAf/6\nZVQv2sEzLjerc1ZjMkhlwduJRVSGe73X9Y5ODU8DM6W6BRYWr3fEV7zMtVLd8HSA0d6e67KiI73d\n+EZH4teYkpOxFxZRsroyXpabU1SiB6IGefNPiFtxy195FUWxAP8CfEHTtKlrH340TdMURXnbGmJF\nUZ4FngUoLi6+1WMIIcSCE46qHL40Gs+UDk4FMRoUNpZm8V/vL6e+3ElRtvTGzUvT429a6XJS3zeq\n6hkrkiz6SpfKx68GorkrwZyS2HMnQHRkBO+ePYz8538QbjuKIRpjwqLQthKOrUjBtqWGraXb+WOX\nm7z0vEQfd9aJl+p2TsUn6470elGj+uNdeqY+VbdiW0F8qm5SytwI7CPBIKN9PdfsEtWzot6R4fg1\nJnMS2YVFFJWvvmaPaAkZuQ4JRIW4Q266BxVAURQz8HPgV5qm/cXM/zsL7NA0bWCmT3WvpmnL3+11\npAdVCCFujDcYYe/ZYZo6PLxyZghvKEqq2Yh7WQ4N5XnsXOEgKz0p0ccUt4umwWTv9SW6gydgovvq\nNZa8mX7RNVdLdLPKYAE/PId7e5ls/BWeX/4MwxtnUTQYzIS25QqX1zoorq7HXbydjXkbSTbOvVLT\nOynoi8QHGF0JSkN+/Y0PU7IRR7E1PlHXWZqBJWv2//5FwiHGenvimdDRHn167uTwkP45BhhNJrIL\nXPGSXHuRnhXNcDgxzPH1SELMFne8B1XRU6XfB05fCU5n/DvwFPCNmW9/erO/hhBCCPBMBWdKdz0c\nujhCJKZhT0/i/avzqS93sm1pDilmeYCa82JRGDl3fSA6eFLPlgKggH0JFFZB1dNXg1GLI6HHng00\nTSN07jzD//kzRn/1C5Iv9QPQ44BXtxnx1VRQXnUfjxRtpyyjTErdZ8QiKiO9Pjydk/Fy3cnrSnXT\nWVyZi7MsY06U6kbDYcb6e2cGFV3JinYzMTQYD0QNRhPZBYXkLV5GxY46clwl2IuKyXTmYzDK11Eh\nZoNbmeK7DWgFTgLqzP/+Gnof6stAMdCFvmZm7G1fZIZkUIUQ4ipN07gw5KNxJig93qNPgiy1p9FQ\nkUd9uZP1xVkYZ/GDovg1Qj59hcu1k3Q9HRAL6T9vStFXulybFXVWQFJ6Ys89i2iqyvSx43T9/GWm\nd79CqmcSFTjrgjcqLJh3bGXduvuoKajBlmRL9HETTtM0Joenr1nx8qZS3YykeCDqLLWRWzJ7S3Vj\n0Qhj/X3xTOiVPaITgwNomv5IajAaycwrmBlUNLNH1FVCZl4+RtPsvC8h5rsbzaDeUonv7SIBqhBi\noYupGq93j9M40096ecQPwFpXBg0VeTSUO1nisEjmZy7yemYyotfsFx29SHylS2qWHoDmr7m6X9S+\nFIzyEP1mWjjM2KFWOn/2Y5T9r5I6ESRqgJOlCj3rCsiqa2DLqvtYlbMKg7JwS5wBgv5IPBD1XJ5i\nqHOKoD8CgCnJgKPEFh9i5CyzYcmaff3JsWiUicH+mQBUz4aO9HQxPtiPpuqBqGIwXBeI2l3F5LiK\nySooxGian2uRhJir7niJrxBCiFsTjMQ4cGGExlMemk97GPWHMRsVqhfn8PS2MupXOsnLmH0PjeId\nqCqMXbo+KzpwAvxDV6/JLNED0DUfvTq8yFY471e63Ao1EKCr6af0/eInWNpOkzwdw2CGk0tMTH5o\nDUUND1K/rJ7ctNxEHzVhYtGZUt3LU/Fy3ckhvVQXBbLz0ymrzIkHpNn56Rhm0ZopNRZjfLBfL83t\nudonOj7QjxqbGfylKGQ687C7Sli6uSa+RzSrwIXJLIGoEPOJBKhCCHEXTQTC7DkzROMpD/vODTMd\niWFNNrFjhYOGcifbl+diS5GHrVkvEoShjjcNL3oDInrmG4NJn5q7pO5qma5zFaTKLs13EvP5mbxw\nmoGzR5k8f5pwVxfGXg8ZPROYoxrmVDhebkVzb2J5wyM8VlxNknHhDQTTNI2pkenrVryM9PiIRfWM\nYlpGEs5SGytr8nGWZeCYRaW6qhpj0jM4E4DO9Ij2djPe30ssejUQzXA4sbuKWbxhU3xoUfb/a+/O\nYytL0/u+f99z7r6TvOTlvi9F1trL9PSsPdMz1TOWHI8hx7HsyJJjx4ocC5EDwYYcB1n+819BHMAJ\nIDhCFMSJICAxIhhOXD0jybIRLdMzPT3Vxdq579vdePd7zps/zuG9l0v1ShZZrOcDXNztkDzsOsXm\nr97nfZ6+fry+i9+QSQjx+V2Mn1hCCHGJLe8VG6Ng/mxhD8vWpGJ+/tJrfbwz082box34PBdnNUMc\nUdw7EkTvwvZD0Jbzvi/qBNBX/3rLSJcr4JFfpo+yq1Xy84/ZePBj9h7fozw/h7G8TnAjSzTnlJ8a\nQBzYicNO0s/S13oJf+Mtbt3+D/li++i5nv95KBdqbLWMeNlcyFHeb5bqdg5Guf7N/sbqaKTNf+5b\nAbRtk93aPNQxd2dlifTqCvVatXFcrLOLjv5Bhm++2pgj2t7bjzcglSNCvMwkoAohxCnTWjO7nuPO\nPafJ0f31HACTqQi/8tYo78x0c70vfqG7Yb6UtHbGt7SG0fWfQm6leUy01wmgV362GUYTwy/1SJej\ntGVRWlli7cF77D76kOL8U1haJbCeJrZXwXC33iaATAh2kl7Wp+Po/h4CIyO0TVylZ/IV3ugcJ+gJ\nnuv38rxZdZvd1f1Dq6OZzaLz5kGp7o0kXW4Y7eg931JdbdvkdraPzRHdW12hXq00jot2dNIxMMjg\ntZvNvaJ9A/iCMqdZCHGcBFQhhDgFNcvmh/N7jSZHq5kSSsHrQ238o5+Z5vZMiuGkdGC9MKyaswp6\ndL5oOeu8rwynUdHgm4c76YaT53veF4TWmsrWJhv3f8TWow8ozj3BWlrBv7ZLfLuIx11cjgEeH2x1\neNgZjGJ9eQTf8BCJ8Rm6r7zC9Z5pIr7IuX4v58Up1S2zuZBlaz7P5kKW7aWWUt2Yj9RIjCtf6iY1\nHKNrKIYveD6/tmmtye9ut+wPdZsWrSxTq5Qbx0Xa2ukYGOLGt7/rNCtymxb5Q/KzTwjxyUlAFUKI\nz6hQqfNHj7Z5d3aTHzzYIluq4fcYfG0iya99a4K3p7tIRqTM89yVc8dHumzdB8stNfQEnREuV3+u\n2Um3awZ8srpTy2bYePA+Ww9/Qv7pQ+qLS3hXd4ht7ROoOEuhUcBvwla7wVYqwtqNMczhQWJjV0hd\nucXY0A1eC8je20qxdqhMd2shRynvlup6DTqHolz/Rl9j1Mt5lOpqrdlP77oB1B3fsrzI7uoS1VKp\ncVw40UZH/yDX3r7tzBHtd4JoIPJy/mODEOJ0SUAVQohPYTtf4Qf3ndLdf/dkh2rdJhHy8q3pLt6Z\n6ebrk0lCPvnRei60hvzG8ZEue3PNY0IdTgB98++0jHQZB8M8v/M+Z1apxNajD9h48D65pw+oLi5g\nrmwR3cgTKThLoSEgoGA7rsikQmx9eRBzsJ/w6CRdUzfpH7/FjXDXue99vCgsy2a30VXXCaWtpbpt\n3WGGrrd01e0NYz7HUl2tNYVMurES2lwVXaJSLDSOC8biJPsHmfn623T0DzXKc4NRmSsrhDg78luU\nEEJ8jLntfd6ddULpj5fSaA39bUF+4YtD3J5J8YXhNjwXaGTDS8G2nFmirauiG3ehsN08pm3ECaC3\n/lozjEZ7XsqRLnatxu78A9bvv0fmySzl+XmM1U3C61kSGWcVL+De9iKQ7gyyd6sbY6CP4OgYnVM3\n6Jt8lelE/0s/X/Qop/y13LJvNMv28j5WzSnVDcacrrpTb3aTGnFKdf3PsVS3mM0054g29oouUS7s\nN44JRGMk+we58pW36BgYdIPoEKFY/LmdpxBCHJCAKoQQR9i25oOVTCOUPtlyfpG72hvj731rktsz\nKaZ7orJa9LxUi05JbmsY3bwHNXdFyvBC1zRMfOfwSJfAy7XKo7Ums/yUtQc/Yu/Rh5Tmn8LyGqH1\nDPHdCh4bvEAnsB+A3U4/GxPtrA/0EBgZpX3iGn1XXmOyawzzJV5R/jiVYo2thXxj3uhmS6mu6TXo\nGoxy7a2+xupotD3wXH5WFHPZw3NEV5wgWsrnGsf4w2E6+oeYfPOrThB1R7iE4gn5eSaEuDAkoAoh\nBFCpW/zx013uzG7y/dlNtvIVTEPx5mg7v/DFQb49k6K/TfYknrnC7uGmRRt3YecRaGc1Cn/cCaCv\n/Y1mF93klNOJ5yWR315jdfaH7Dy6S3H+CfbSCoG1PRLbJfw1Z0xLEqh4nA65O30xtr84jm9omMTE\nDL3TrzHWN43vJfpv9llZls3eaoHN+WYYTW8UG++3dYcYutbh7BsdjtHed/aluuX9fXbc8LnrBtGd\n5SWK2UzjGF8wRMfAIONfeJOO/qHGqmi4rV2CqBDiwpOAKoR4aWVLNf7w4RZ3Zjf5Nw+32a/UCflM\nvjHVye2ZFN+c6iIRkl/iz4TWkF44Pl80t9o8JtbvBNCZ77WMdBl6KUp0y/kMy/d/yPbDn7D/9DHW\n4hK+9V3imwXCJac5UQcQN2C3zSSfipK5NoB3aIjY+BW6p15hePQmt6TR0yfWKNV194zU7HPuAAAg\nAElEQVRuLeTYWso3S3WjXlIjcSbfcEt1h8+2VLdSLDRLcxuroksU0nuNY7yBIB39A4y88jrJfndF\ndGCISHuHBFEhxAtLAqoQ4qWyni3xfbd094+f7lK3NcmIn3/vZg/vzHTzpbEOAl4pbzxV9SpsPzge\nRitu6aEyITkJQ19pKdG9DuGO8z3vM1YtF1l99GM2H75P7slD6ouLeFa2iW7uk8g7zYna3NtezCCb\nCrP6xjDm0CDRsQm6pm4xMvk610OyT/CzqJTqbLV01d1cyFHKOZ2dTa9B50CUa1/vIzUSIzUcI9px\nNqW61VKR3ZXlQ6uiO8uL7O/tNo7x+P109A0yfOMVp2PuwCDJ/iGiyU4JokKIS0cCqhDiUtNa82hz\nnzv3Nnj3/iY/XXHmXI4mw/ytr43wzkw3rwwkMAz5Je9UlLOw8WFLGP0pbD0A29mjhzfk7A+9/peb\nYbRrBrzB8z3vM2JZddbn7rJ2/z2yT+5TWVjAXNkkspGjPV3H0BDHueVDinRXkO3rvewO9hMeHSc5\ncYP+6S8wnUid97fyQrMtm93Vgrs66pTrpjeL4CxGO6W6M+10uftGO/ojp16qWyuXnfDproTuLjvd\nc/M7zcZeHq+P9r4BBq7eaMwRTQ4MEUt2oQxpTiWEeDlIQBVCXDqWrfnRYpo79za4M7vJ0p6zZ+yV\nwQT/4LtTvDPTzXiXzOv7XLSG3NrhILpx1ynbPRDudLrnfvnbbonuDWgfvXQjXWzbZmvtMauzPyT9\n+B7l+XnU8jqhjQztu1V8dWdWaBQo+SCdDJAd7SQ30EtwdMxpTjT9Ole6hmU17BRorcnvlRtlupsL\nObYX89RbS3WHY0y+kSI1HKdrOIo/5D21r1+rlNlbXWmG0WWne252a7NxjOn10t7bT9/UDMlvDzVW\nReNdKYxL9vdDCCE+LQmoQohLoVS1+LePt3l3dpMfPNhir1DFZxp8ebyDX3lrjG9Pd9EVC5z3ab6Y\nrDrsPjk+X7TYLEGkfQx6bsGrv9gy0qX7/M75lGmt2d1dYWX2z9h9fJfS3FP00hqB9T3at8uEKs6s\n0BBQN2A36aPYHWfltW4CI6MkJq7Se+U1pgavYMhK2KmqlupsLuZaxry0lOp6DDoHI1z9mluqO3J6\npbr1apW9tZXGSuhBB93M1obzDziAYXpo7+2je2ySq9/4Nsl+Z49oItWNYUoQFUKIk0hAFUK8sPYK\nVX5wf5N3Zzf5o8fblGs20YCHt6908c5MN29NdRLxy4+5T6VagM3ZIyNdZqFect43fU5J7tTPQM9N\nd7/oVfBHz/e8T0k2v83y/ffYfvQTCk+fYC2v4F/dJbFVJF7Q+IFewAYybR7yqSgbV4bxDw8TG79C\nz5VX6Rm9gcfnP+fv5HKyLZvdtUJz3+h8jvRGoVGqm0iFGJxpb4x46eiLYHo+3z8I1Gs10uurjZXQ\ng8ZFmY0NtNtd2jBN2nr66BoZY/pr3yQ5MEhH/xCJ7h5Mj/wMEkKIT0N+agohXihLu0XuzDqlu+8t\n7GFr6IkH+CuvD3B7ppsvjrbjPeMxD5fG/vbxkS67T5ojXQIJJ4C+/jeb+0WTk2CeXjnkeSiU8yw9\n/hGbD99n/8kj6otLeFd3iG3t056xMYGDtd9cxCCXirD32ij5oSGi41Okpm7RO/Uq/qCUiZ8VbWvK\nhRr7mQrZrZKzb3Qhx/ZSnnrVuT4DES+pkRgTr3c5XXWHYgTCn/3atOp1J4i2hNDd5SXSG2to2/ma\nyjBIdPeSHBhm6stfb8wRbevpxfS82H8vhBDiopCAKoS40LTWfLia4103lD7YyANwpTvKr35znNsz\n3Vzri8nevY9i25CeP95FN7/ePCY+6ATQa3+pOdIlPvDCjnQp18ssz33AxsMfk33ygNriIubKFtGN\nHMk9C48NKZxbya/IpEIUrvRTGhwgMjZJ59RN+qdfJxi/3J2Ez0O1XKeYrbKfqVBovWUPHlcpZCvY\nlm58jOkxSA5EmPlqr9tVN04s+dlKdW3LIr2x1ijJPdgnml5fxbac7slKGSS6u+noH2Tii19pzBFt\n6+3H45UgKoQQZ0kCqhDiwqlZNn86t8ed2Q2+P7vJWraMoeD14Xb+y5+d5p2ZbgY7ZL7jieoV2Lp/\nJIx+CFUn2KNM6LwCI281V0W7r0Ow7XzP+zOo2TVWVh+w/uDHpB99SGVhAbW6QXg9S+dOjUANkji3\nmgfSnUHKgynWv9pHaHSc5MR1+qa/QCTVJ//AcQosy6aYrR4Pm4eeV6iWrWMf6w2YhON+wgk/PRNx\nIgk/obifSMJPtCPwmUp1bdsis7FxbI5oem0Fq153DlKKeFeKjv5Bxl57g46BIZIDQ7T19uGVMm0h\nhDgXElCFEBfCfqXOv3m4zZ3ZDf7gwRa5cp2A1+DrE53857cn+dZ0ivaw77xP82IppY+MdLnrzBu1\n3V++fRFnpMvNn2+G0c5p8L44zaIs22Jtd561+z9ymhPNz8HyGqH1DO3bFWKl5qxQS0G23Uexp42d\nW70ERkZon7hO78zrJAbGZEzHZ6S1U257NHDuZyoUM859IVullK829oIeMExFKO4jkvDT3hNmYLqd\ncMIJouG4r/HYF/jsv45o2ya7tXmoY+7OyhJ7q8tYtVrjuFhniuTAICO3XnNHuAzR3teP1//i/H0Q\nQoiXgQRUIcS52cqV+f79Le7MbvD/Pdmlatm0h31852o3t2dSfG2ik6BPOl2iNWRXjqyK/hQyS81j\nIt1OAJ38TnOkS9sIvAChTGvNRnaVlUc/ZvfxTyk8fYK9vEJgbY+2rTIdeU0MiLnHZ+MeCt1xcl8a\nozI8TGJihp7p1+gYmcbwy6rXp1GrWIdKbJtlty0rn9kKdl0f+9hg1OsGTT9dQ7FDgfPg9WDEizql\nGcPatsntbLn7Q5tzRPdWV6hXK43joh2ddAwMMnjtJsmDINo/gC9wOWftCiHEZSMBVQjxXD3Z2ufO\n7Abvzm7y/lIGgMH2EL/4pSHeudrNa0NtmKf0C+0LyarDzqPj80VLafcABR3j0Pe607zoIIxGus71\ntD+O1pqd4jYrcx+w9fAn7D99jLW4jHdth8RWgc60JqLhoO1QMWSQT0Up3epna2iI2NgU3VdepWvi\nBmZEmhN9HMuyKeWq7iqnu98ze3TPZ5VqqX7sYz1+k0jCTzjho2cs3gibzfDpIxzzY3pP9x8/auUy\nhUyaQjZD0b0vZNLkd7adMt2VZWqVcuP4SHsHHf2D3Lz9XTr63Vmi/YP4Q1L+L4QQLzIJqEKIM2Xb\nmveXM41QOrddAOBGf5xfvz3JO1e7mUxFXs49gJV92Lx3fKSL5a4GeQLOSJfpv+CW6N5wRrr4wud7\n3h8hU86wtPQhmw/fJ/f0IbWFRbyr20Q383Tt2QTqMOgeW/Uqsl1hauND7Aw5zYlSU6/QPfUK3vb2\nc/0+LiqtNZVC/ZmB8+Bx8aRyW8Mptw0n/LT1hOmfbifslt+GEs5+z3Dcjy94er8a1KtVim7QbAbP\nNIVMM4Qe3NfKpeOfQCnCiTY6+ga49vZtZ45o/yAdA4MEwvIPFUIIcRlJQBVCnLpyzeKPn+66oXSL\nnf0KHkPxpbEO/saXh/n2dIrexEtWbpffPL4quvuURooItjkB9Iu/7Nx3X4eOCTAv3o/pQq3A4voD\nNh7+mMzj+1QWFzBXNols5OjcrRMpQ797rGVANhmk0ttL5s0+wqPjJCdv0jP9Kv7u3pfzHyaeoVY9\nXG5bSFebIbSl6ZBVt499bCDibaxydg5EDgXOg5XP0yq3teo1itlsS/BMU8wcDaHOfaVYOPFzBCJR\nwok2QvEE3eOThBMJQvG2xmvhhPM4GI1hmFLmL4QQL5OL95uPEOKFlC3W+P2Hm7w7u8kfPtymWLUI\n+0y+caWLd2ZSfGOqi3jwJRjPYNuwN3c4iG7chf3N5jGJISeA3vgrzS66sb4LNdKlXC+zuPuU9Ufv\ns/f4HpX5OVheJ7SRIblTo30fenBuALk2H8WeDgrX+7BHRmmfuEbvldcIDQ6jPC/3/2psy6aYqx3r\nZtvc91mlmK1QKZ5QbuszCLthMzUSd0tvjzQZin/+clvbtijlchQy6UPltcWD1U73vpDNUM7nTvwc\n/lC4ES47B4cJ33jlUOBs3sdlZqgQQohnerl/axBCfC6rmRLv3nPmk/7p/B6WremK+vmLr/TxzkyK\nL4114Pdc4tWPWhm2Zo+PdKm5q0aGx+maO/atZhfd1DUIJs73vF01q8ZydpGVJz9h9/GHlOaeoJfX\nCK7v0b5doTMLKe3MCgUoRJzmRLUvdJMdGSUx7jQnio5MYARevk6oWmsqxXojbO5nKhTdwNkaQEu5\nKvpIua0yVCNgtqVC9E+1OXs7j6x6+gLmZ15l1rZNaT/vBM5GyDy+ylnIZijlcmh9fGXW6w80wmV7\nbz/909caq5utwTOUSMhYFiGEEKdCAqoQ4hPTWvNgI8+de5vcmd3g3pqzkjLeFeE/+foot2dS3OxP\nYFzGJkfFveZqaGOky0PQ7kxHX9QJoK/8QstIlyvgOd9f2i3bYnV/leXFu+w8/IDC0ydYyyv4V3dJ\nbJfoTms6Leh0j6/4DfLdMayrQ+SGhomNX6H7yqskxqcxY7GP/FqXSb1qHSqrfdaeT6t2Qrlt2NsI\nm8n+yJHOts7rwajvM/09cfagFlpWN9PNUtuWlc5i1gme2j5+fqbX64TMeBuxrhQ9E1cIJdoIH13p\nTCSk860QQojnTgKqEOIj1S2bHy6keXfWCaUr6RJKwauDbfzDP3eF2zMpRjsvUbMSrZ3xLYdWRe9C\ndrl5TLTXCaBXfrZZopsYPreRLra22Spusbg2y9bDD8g/eUh9cQnv6jaxrQLde5r2Khy0HaqbinxX\nmNrwMPtvDREdn6Rr8hYdk9cwk8lLvS/UtnWju+2h/Z5HmgydWG7rNRpBMzUS5+gsz0jCTyjuw+P9\ndFUDWmtq5ZIbMpuBsxk8Dx47wdOqHz83wzQbITPS3k7XyKgbNtsIJxKE407gDCfa8AVDl/rPWAgh\nxItNAqoQ4phitc4fPdrhzuwGv/9gi0yxhs9j8NXxJL/6zXG+NZ2iM3oJyvmsmrMKenS+aDnrvK8M\np1HRwBfhjb/tluheh0jnR3/eM6C1Zre8y+L2YzYevk/26QOqC4uYK5vENvKk9mzixeasUFvBfkeQ\nSm8f5dcH8IxN0Dl1k47JG/h6elCXrPFMo9y2ZdXzpD2fxWeU24ZiTtCMdwbpm0ic0GTIhy/o+VTB\nrlYpHyqt/ajg2TrHs3FeyiAUjzeCZ0f/YMvq5uEVz0A4gnoBZt4KIYQQH0cCqhACgJ39Cr9/f4s7\nsxv828c7VOo28aCXb13p4vZMiq9PdhL2v8A/Mso5d6TLXdj4wLnfug9W1XnfE3RGuFz9ueZIl64Z\n8D3fmYqZcobF9BzrTz5wmxPNY6xsEN7I0bVbpyMHoy3HF+I+yj1dWDN9lEfG6Ji8TufUTfyDQxg+\n33M997NSr1nPDJyF7MGszwr1E8pt/WEP4bgTNtv7Im7o9B0qu/005bb1Wu144Mxk3NEph0NotXTy\n2JRgNEY4niCUaKM31eOETTdwtgbPQDSKYVyuf0gQQgghPs4L/NumEOLzWtgpNEp331tMozX0JYL8\n1TcGeWcmxRdG2vGaL9iqjNaQ3zg+0mVvrnlMqMMd6fIr0HPTHekyDs8pDOxX91nMLbA6f5fdR3cp\nzc+hltcJrqdJ7tRIZWDIhiH3+HLQQ7EngX6lm/LIGG0TV+mauklweAwzcnFnon4c29aU8tVnBs6D\nfZ+VwvGSVtPb0t12KEr4ZrJln2dzv6fH9/F/pla9zn4me2xkyrExKtk0lcIzxqaEI41wmRqdaIbN\nI8EzGItjvuRdjYUQQoiPIv+XFOIlYtuau6tZdz7pJo829wGY6Ynxn709wTtXU8z0xF6c/Wm25cwS\nPTrSpbDdPKZtxAmgt/5ac75otOfMR7qU6iWWckusrN5n5+FPKcw/wV5aJbC2S8d2he40DNRgwD2+\n5jUopGLYkykqwyMEJqZJTb1CaGwcM5F4cf5McMptq6X6oVXPw6Gz2iy3tQ/X2yrFoXLb3vFEy2pn\ns8utP/TR5bYHY1P21o6X1h4tsS09Y2yKLxhqzOdMDgwxeP3W4TmdbvAMxRN4vDI2RQghhDgNElCF\nuOSqdZs/mdvlzuwG35/dYiNXxjQUbwy381/9+UFuz6QYaH++ZayfSa0Em7OHw+jmPagVnfcNL3RN\nw8R3Wka6XIVA/MxOqWpVWcmvsLT5iO3HPyX39CH24jLetR3atkr07EFvGXrd420D9jsj1Pv7qH9l\nEGP8Cl1Tt4iMTeJJpV6IPYT1mkUxe7TJ0NFV0Ar16gnltiFPI2y294SOjVSJJPwEo16MZ6zaa9um\nXNhnf2+NzbmP2tOZfubYFI/PT7jNCZVtPX30T191Gwm5TYTcpkKheAKv/+UbnSOEEEKcNwmoQlxC\n+XKNP3y4zZ3ZTf7wwRb5Sp2g1+StyU5uz6R4+0oXbeELvD+xsHu4adHGXdh5BAeBwx93Auirv9QM\no8kp8Jz+91S366ztr7G4+5TNp3fJPr5PfXEJz+oW8c0C3WlNKt+cFQpQaAtS7RuAWwMwNkXnlZtE\nRyfx9fejLuhKm7Y1xXz1hPDZuuezSrlQO/axpsdorG52DkUZTiQb+z4PXg/F/XhPKLd1mhsVKGYz\n7K19dDOhYjaDbVknfH1Po5w2muyke3zyUIlt64qnNxB8oVajhRBCiJeNBFQhLomNbJl372/y7uwm\nf/x0h5ql6Qj7+JnrPbxzNcVXxpMEPuX4izOnNaQXjs8Xza02j4n1OwF05nstI12GTrVE19Y2m4VN\nFjJzrM99SObJLJXFBczlTaKbebp3bTqzkGypRi1HfFR6Uqg3+rBGJ0hO3SAxMYNvcBAjeHFmR2qt\nqZatEwLn4aZDxWwV+4Ry22DMRzjuJ9oRpHssQSThI9QIn87tpHLbqjs2pZhZZ3Puo4OnVTseeg3T\nJBRPNMJl59CIEzJb53S69/5QWEKnEEIIcUlIQBXiBaW15snWPndmN7kzu8kHyxkAhjtC/EdfGeGd\nmRSvDLZhfsLupGeuXoXtB8fni1bc/X/KhOQkDH2lpUT3OoQ7TuXLa63ZKe2wkJ1ndfk+6Sf3KM3N\nYaysE9rIktq16E7DdEs/nprfpNTTDtd7sEfGSExco33iKv7hYcxE4lTO6/OwavaJMzz3MxWK2eZ+\nz3rl+KqjP+Rxg6aPtqm2Q11tD8puQ7HD5ba1aqXRQKiQTZNeO6GZkPu4Xjl5bEowFmuEy/be/ubq\n5pHgGYxEX4iSZyGEEEKcLgmoQrxALFvz/lLaCaX3NljYdfZf3hxI8Pe/M8U7MynGuyLnv5pUzsLG\nh4c76W49ANtdKfOGIHUNrv/lZhjtmgHv51t51FqTqWRYzC2yvPGQnUcfUpp/gl5aI7i+R+dOnZ40\nTLVkJ8tUlFIx7JEeeHuE0PgMHZPX8A+P4unqPJf/ltrWlPZrh1Y9m02Gqo1QWt7/mHLbgSjD193A\n2eZr6W7rx+t3VtOtes2d1ZmhkFljfzfN1tzRpkJpCpkM1VLxxPMNRmONcNkzPvXMlc5gLCZjU4QQ\nQgjxkSSgCnHBlWsW/+7xDu/ObvL9+5vsFqp4TcWXxpL8x18b5fZMilTsnJq5aA25tZYSXXe+aHqh\neUy40+me+6VvNeeLto9+rpEu+WqepdwSizuP2X78IYW5R1hLK/jWdknuVOndg/ECjB+cpoJiRwSr\nrwvzi8P4x6+QnLxBYHQUb08P6jmO/aiW6s/santwO6ncFgWhqBM8o+0Bukdix1Y9Iwk//rAHbdsU\nc1m3xDZNIZshvZpmdTZz6LViJk25sH/iefrDYcJxp3FQ1/BYSwOhZjOhUCJBKJaQsSlCCCGEODXy\nW4UQF1C6UOX3H2xxZ3aDP3q0Q6lmEfV7+MaVLt6ZSfHWVCexwHNutmNbsPP4cBDduAvF3eYx7WPQ\ncwte/cWWkS7dn+nLFWtFlvPLLKTn2Jz7kPzTh9QXlpwOudtlevc0Q1kYafmYcixArX8Az7VBPKOT\nJKduEBoZwzs4iOH3f77v/2NYdafctpitsp8+0lwo29zzWTuh3NYX9BCOO+Gz76Dc1g2coYSPSMJP\nIOKhWtyncLCqmVmjkM2w1drN1g2epXzO+ceDI7yBIOGEs5rZ0T/A4LUbJ5fYxhJ4fBe4iZYQQggh\nLi0JqEJcEMt7Rd6d3eTO7AY/XEhj2ZruWIB//7V+bs+keHO0A5/nOe3JqxadES6HRrrMQr3kvG/6\nnJLcqZ+BnpvNkS7+6Kf7MlaV5fwyi9kF1hbvkX36gNrCIubKJvGtIj17mp4MDLZkumrQS7U3hfFq\nP56xSZKT1wmNjOMbHsKMfrqv/0k0ym0PdbNtWfV0Xy/lT2j041FOWW3cT0dfhMGr7YfDZ9yH6alS\nK+cpZDLOHk43ZK6tpVvCaJpiLou2nzE2xR2LkujuoXdq+oQS24MOtjI2RQghhBAXmwRUIc6J1pp7\nazk3lG5yf91pFjSZivB33hrj9kyK631xjLNuclTYgfUPDjcv2n3SHOkSSDgB9PW/2TLSZRLMT7aC\nW7NrzpiW3CIraw9IP56lOj+PWt0kupGje0/Tk4aeavNjLI9BuacdNdWHd3SMjsnrRMYm8Q0PY7a3\nn9q+0Gq5/pGzPPcPym2t4+W2waiPcNxZ3ewajjldbeNO6PQFLJQqUa/mG3s7i9k0hb0MO/Npt6FQ\nhmImg23Vj52XYXrckJkg2t5B9+i4O6szcSx4+oIyNkUIIYQQl4cEVCGeg2K1zvxOgYWdIgu7Bea2\nC/zJ3C6rmRJKwReG2vlHPzPN7ZkUw8nw2ZyEbUN6/vhIl/x685j4oBNAr/5cM4zGBz52pItlW2wU\nN5zmRNtP2Xv8IcX5p6jldULrGVJ7Nr178Eqp5XQUlLviMNCD/+ujxCdmiI1dwT88jKen53N1cLUs\nm2Jr4GwZrdLa4bZWPqHcNmA29nX2TRx0t/XhD4FhlIAidn2fUi7b2MeZXcuwPut2sc1kqNeqxz6v\nMgxnNqcbNJMDwycGznCiDX9YxqYIIYQQ4uUkAVWIU1KuWSztFZnbLrCwW2Bhp+CE0t0Cm7nDIze6\non5u9Cf4tW9N8PZ0F8nIKe+PrFdg6/6RkS4fQjXvvK9M6LwCI2+1jHS5BqH2Z35KrTVbxS2W8kss\n7s2x8/Qe+3OP0UurBNbTpHYtetKaG7kj/13awtj9KfyvjhCZmCY+Po1/eBhffz/qU+5z1FpTdstt\n99Pufs9M5Vj5bWm/BkcWPQ3TLbdN+GjvDTMw3U4gYuDxVTBUEXQRq75PpZBrBM/t+QyL7rzOWqV8\n/ISUIhSLO8Ez0UZbTy+hhFNO2wycznsyNkUIIYQQ4uNJQBXiU6jWbZbTxUb4PAigCztF1rKlQ31p\nOsI+hpNhvjreyUgyxEgywnAyxHBHmLD/FP/qlTLHV0W3H4Dtlo76Ik74vPnzzTDaOQ3e4/sRtdbs\nlfecEJqZZ2PxPvtPH2ItruBb23HGtOxprmTAbPleq2E/9f4evG8OEhy/Qtv4DP6REXyDgxjhT7Yi\nXKtYh+Z4Hl35LGQqFHIV7Prx5j/BqLex6pkcCOHzVzE9ZZQqom1nxbNSzFHMZSlm0qytOY2FKsXC\niecSiEQbJbbd45PuHk9ndfMgjIYTbQSjMQxTxqYIIYQQQpwWCahCHFG3bFYzJbckt8DCbrERRlcz\nJayW8R+xgIeRzghfGG5jONnPSDLMSDLMUEeYePCUu+xqDdmVI2H0p5BZah4T6XYC6MQ7zZEubSNw\nZOUuW8mytP2YxdwC66uPyD69T21hCe/KNh07FbrTmuE9mGrZHln3mdR6uzBvDBAamyIxPkNgZATf\n8DCetrZnnnaj3PZo2Dyy6lk9odzW63fKbUNxL8lBg16fwjCrKIrYdgGrtk+1mKOUzzj7O+fSlPfz\nJ56HPxRurG52Do82Vzlbx6fEE4TicUzPc+6QLIQQQgghAFD6hFEEz9vrr7+u33vvvfM+DfESsW3N\neq7Mwk6BuYMgulNgfrfA8l6RWktTnLDPZNgNniPJMMMd4cbztpD3bPYKWnXYeXQ4iG7chVLaPUBB\nx7gTRg9WRbtvQKSr8SmKtSKLuUUW84usbD0h8+Q+lfl5zJVN2rZKTofcNERaKldtU1FNtaEG+wiP\nTtA2cZXgyBi+4SE8XV2HSlS11pQLtWcGzoJbflvKV4+X2xqKYNxLMGzhD1YxfRVMswTaWe2su8Gz\nnHf3eeayJ49N8QfckNmystkInq2ltjI2RQghhBDiPCmlfqS1fv1jj5OAKi4rrTVb+UpjJXR+t8C8\nuz90cbdIpd4c2RHwGk7wdMPnaNK5H06G6Iz4z7ZhTWW/ZaSLG0g3Z8Fy9616As5Il0YYveE890co\n18ss55dZyi2xtPeUvacPKM0/QS1vENvad0LoHrTvH/mSyRgM9BIcGaVt4iqh0TF8w8N4+/pQHg+1\nqkUhfUKJbba19LaKVT889kRrTSBi4w9W8QecMlvDKKJ1yQme1X0qxSylXJZiLnPy2BSvr7Gq+VHB\nM5RI4AsEz+pPRQghhBBCnCIJqOKloLVmt1A91JBoYafI3E6Bxd0CxWqzbNRnGgx2OHtAR5KhQ6ui\nqWjgbMa51MpQ3IXijnNf2G0+333ijnR5SmOJMdjmBNDu6435orW2YVaLm85qaHqencUHFOYew/Ia\n4fUcPXua7rSmKwtG677QWBDd341/ZJTE+BXCo5N4BoeoJ1KUysbhUSoH+z7dzrfVUrO21/kZUcX0\nVAiEqnh9leb+Tl3Equ1Tq+SpFLKU81ms+sljU5qltM1Otsf3dSbwBUPSwVYIIYQQ4pKRgCoulWyx\nxtzOPgu7BeZ3iu7eUCeU5svNQGQaioG2oFOK21KSO5IM05sIYn6eEGrbUM64Acb7oYoAAA3BSURB\nVHPXmR/aCJ97R567YbR2chMelAHxfjeM3sDqvsZ6LMWiXWYxt8jmyiPycw+xl1YJrqXp3rPdIAre\nlq2a9YAXqz+Fd3CI4Og1jJ5xavFuqoE2ihXj2GzPYku5rdY1tF1AUcIXrOD1VTDMMooi2i5Qr+1T\nK+cp72exThqbogxC8XijYVDrSqdz3+xgGwhHJHQKIYQQQrzEJKCKF85+pX64O65blruwUyBdrDWO\nUwr6EsFD4fMgkPa3BfGan3CUx0etbjYC6F7zeXEP9PFGPgB4QxBKOmNawkkIdWAHOygGo+T8EfK+\nADmPj7zpIW8Y5HWdne1l8nMPqS0u4V/dpWvPapTkhlryYM3np9A/jNU7jtk9jk70UfUnKKsQxRJO\nuW22ilWz0boO2gmY2i7i8ZXxeCsYZgmli9hWgXp1n2opR7168tiUYDR2ZDZn4lj32nA8QSAaxTCk\ng60QQgghhPh4ElDFhaO1plh1ZoW2hk8nkBbZ2T88K7QnHmhpSOSU5o52hhloD+H3HAlGp726GWxH\nh9ophjvIB2Pk/DHy/hB5X5C86WG/pimWa1TKVarFMvVCASufRxcK6EIRo1DCLFUJljXBKgQrEKpo\nQhUIViFUAX/NoOaNUvHHKfsTlJI9VNv7seM91P1tVHSQYkVRKdXc0FlEayd4GkbJ3d9ZaszvrFfy\n1KulE7+lQDjSCJfHgmfra7G4jE0RQgghhBCn7pMGVBkzIz6Tat0mU6ySKdVIF6qkizWyJec+XayS\nde/TxVrjcaZUo3qkqU4y4mc0GebtK51OEHUD6XDcJFjLuIFy2wmU+V3Y/OSrmxooKUXeFyEfbnNW\nMr0RCpFhSsFxyjVFtaqpV23qpRp2uQqlKqpYwSxW8JSKBCsFghVNyA2ZwZqPeN2P7Qlgmf7GrW4G\nsMwOLLPXee4JUPcFqftCWJEgVluQnCdI2vRjKR8WJjWrjm2X0LoAbvjEymPmtgA3eNb2qVdPDtK+\nYIhAYx9n7zODZyiewOOVsSlCCCGEEOLik4B6gWitqRTrFA4a1ri3/bRzX6/ZeH0GHr+Jx2fi9Zl4\n/QYe38Fz9z2viddv4vEZ7v2Rx16jsR/QsjXZUo2MGyYzxSqZg5BZOiFkuscUqs8odQW8piIR8tEe\nNEkFbYbidTq76nT463R4qvT5S/T6iiSNPP5qprm6+ahlxbO6jwbKSpE3DHJasV832be9lFSYsg5S\ntf3U6gb1Whd2tRMqNqpiYZQtPGULT9nGX/Phr/vxWQE8th+PChAx/QQ9rcHycNCseX3UPF6smId9\nw0PWUNgYWGjQdaCO1jX3ce3QY7T7niqiVA6FczxWDV2ro+0qtl0Dfbx7LYDH7ycQdvZvhuLdh1c3\nW+d1JhJ4ff7TvgSFEEIIIYQ4V2cWUJVS3wX+CWAC/0xr/Y/P6mu9CKy63RjN0QierSHUvbdqx4NL\nMOolnPDj8ZpUijVqFctZ9ata1KoWdv3Tl2nXFdSUpoqmBtSVxsZCKwtUHVQdU9UIeOqMeGqEPDWC\nnhphT4VwsEwoUiZsFgkbRUKqQJA8fnIoK4NdzVKrFijvVqnZiqptULMVNdugZin2LYMP6wa1mkHd\n8mLXPdh1E1X1QT2KUe/ArPkwbR8ey4/H9oMKuAHSR830UvP4qJse6qaJZZrUDRPLNKgbCjuksEOg\nlX1yeKQOuubs1yQPes997eB9Gyyc2ydken14fH68fj/eQMC590fc15znHr8fr8953+Pz4w+H3f2c\nbvhMtMnYFCGEEEII8VI7k4CqlDKBfwrcBlaAHyqlfk9rPXsWX+88aa2pluqHwqYTOA8H0VJL99QD\nhkcRjPnwx3yEuoPExmKYYRMV9EDIxPIbWH6DqtaUazb7lTqZQoVCIU+5UKBSyFEr72OV8lAqEdBV\nwlaFEBWCdg2ftvDZGo8NXgxMDAzbRGkPaA/a9mBrL1p7sfFjax8aPzYH9wG08qGViY2moC0K2ICN\n1s492O5qoI2T6DRaWxh2FWVXMdybsqsou4aha1gKbANspZzHSqM9Ntq0cILkQXhsfZyFg/B44h8E\ncHy6ifPf2fTi8fkPh0h/GG/Ajy8QwBcMOKHSdzxENoKlv+X9I4HT4/OhjE/YmEkIIYQQQgjxTGe1\ngvoG8ERrPQeglPod4HvACxlQ//l/8xuU8zWsmhe77sW2fdi2D2350QRAmzgJ6SCBatBllHZGeChd\nQNlFlC4693YRQxdRdhVrQ1NCUdYaNCian8p5rEBrFIqohphWKO2+bisUzecK5XyoUmilsJX7GOdx\nvfW1g8ccOVY5wfHgmFN38CndnKkMD4bHh+nx4fG2hEhfrLkSGQjgC/rxh0L4Q26gdINiI1AePPb7\nnY8/CJwSHoUQQgghhHhhnFVA7QOWW56vAF88o6915rYeLGLr/Cl+RhOIwmfNTVqjcMat4N47N4Uy\nDJShUIaJMk0M08AwTQzTg+Hx4PV48Hi8GF4fHq+zsujxHqwKBjC8PkyPp/kxpoFhejBNs+XzmBiG\nidE4zmwco0zTPfbk40zTg8fnw+N3wqOMKRFCCCGEEEIcOLcmSUqpXwZ+GWBwcPC8TuMTGf3Cq9hW\nCX/IwB/y4PcH8Pp9mB4/ps+P6Q1geP2YviCmz4fHXRE0vV53ZdCH6XXCmBMiFUoZoEApp2GRclOm\nMprPnZsBhrtSajhhU53FyqYQQgghhBBCnLOzCqirwEDL8373tQat9W8CvwnOHNQzOo9T8b1f//vn\nfQpCCCGEEEIIcemd1ea8HwITSqkRpZQP+Hng987oawkhhBBCCCGEuATOZAVVa11XSv0q8K9xNlz+\nltb63ll8LSGEEEIIIYQQl8OZ7UHVWv8r4F+d1ecXQgghhBBCCHG5yPwNIYQQQgghhBAXggRUIYQQ\nQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAXggRU\nIYQQQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAXggRUIYQQQgghhBAX\nggRUIYQQQgghhBAXgtJan/c5oJTaBhbP8EskgZ0z/PxCfBZyXYqLSK5LcdHINSkuIrkuxUV00a/L\nIa1158cddCEC6llTSr2ntX79vM9DiFZyXYqLSK5LcdHINSkuIrkuxUV0Wa5LKfEVQgghhBBCCHEh\nSEAVQgghhBBCCHEhvCwB9TfP+wSEOIFcl+IikutSXDRyTYqLSK5LcRFdiuvypdiDKoQQQgghhBDi\n4ntZVlCFEEIIIYQQQlxwlz6gKqW+q5R6qJR6opT6jfM+H3F5KaV+Sym1pZT6sOW1dqXUu0qpx+59\nW8t7/9C9Lh8qpb7T8vprSqm77nv/g1JKPe/vRVweSqkBpdQfKKVmlVL3lFK/5r4u16Y4F0qpgFLq\nz5RSH7jX5H/rvi7XpDh3SilTKfW+Uupfus/luhTnSim14F5PP1FKvee+dqmvy0sdUJVSJvBPgT8H\nzAB/VSk1c75nJS6x/wX47pHXfgP4gdZ6AviB+xz3Ovx54Kr7Mf+je70C/E/A3wYm3NvRzynEp1EH\nfl1rPQO8Cfxd9/qTa1Oclwrwttb6JnAL+K5S6k3kmhQXw68B91uey3UpLoJvaq1vtYyQudTX5aUO\nqMAbwBOt9ZzWugr8DvC9cz4ncUlprf8I2Dvy8veA33Yf/zbwF1te/x2tdUVrPQ88Ad5QSvUAMa31\nn2hng/j/2vIxQnxqWut1rfWP3cd5nF+8+pBrU5wT7dh3n3rdm0auSXHOlFL9wM8C/6zlZbkuxUV0\nqa/Lyx5Q+4Dllucr7mtCPC8prfW6+3gDSLmPn3Vt9rmPj74uxOemlBoGXgH+FLk2xTlyyyh/AmwB\n72qt5ZoUF8F/D/wDwG55Ta5Lcd408H2l1I+UUr/svnapr0vPeZ+AEC8LrbVWSknbbHEulFIR4P8E\n/p7WOte69USuTfG8aa0t4JZSKgH8C6XUtSPvyzUpniul1J8HtrTWP1JKfeOkY+S6FOfkq1rrVaVU\nF/CuUupB65uX8bq87Cuoq8BAy/N+9zUhnpdNt6wC937Lff1Z1+aq+/jo60J8ZkopL044/eda6//L\nfVmuTXHutNYZ4A9w9kLJNSnO01eAv6CUWsDZEva2Uup/Q65Lcc601qvu/RbwL3C2MF7q6/KyB9Qf\nAhNKqRGllA9n0/DvnfM5iZfL7wG/5D7+JeD/bnn955VSfqXUCM5m9T9zyzVySqk33e5qv9jyMUJ8\nau519D8D97XW/13LW3JtinOhlOp0V05RSgWB28AD5JoU50hr/Q+11v1a62Gc3xd/X2v9C8h1Kc6R\nUiqslIoePAbeAT7kkl+Xl7rEV2tdV0r9KvCvARP4La31vXM+LXFJKaX+D+AbQFIptQL818A/Bn5X\nKfW3gEXgPwDQWt9TSv0uMIvTZfXvuiVvAP8pTkfgIPD/uDchPquvAH8duOvu+QP4L5BrU5yfHuC3\n3c6SBvC7Wut/qZT6Y+SaFBeP/KwU5ymFsw0CnNz2v2ut/1+l1A+5xNelcho5CSGEEEIIIYQQ5+uy\nl/gKIYQQQgghhHhBSEAVQgghhBBCCHEhSEAVQgghhBBCCHEhSEAVQgghhBBCCHEhSEAVQgghhBBC\nCHEhSEAVQgghhBBCCHEhSEAVQgghhBBCCHEhSEAVQgghhBBCCHEh/P8lqevtvifg2QAAAABJRU5E\nrkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "try:\n", " import matplotlib.pyplot as plt\n", @@ -684,19 +540,11 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* geometric mean of time improvement is 3.5\n" - ] - } - ], + "outputs": [], "source": [ "# compute geomerical mean for all sizes\n", "nb_builders = len(builders)\n", @@ -737,7 +585,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.13" + "version": "2.7.11" } }, "nbformat": 4, diff --git a/examples/mp/jupyter/green_truck.ipynb b/examples/mp/jupyter/green_truck.ipynb index fe8b9f6..434c16f 100644 --- a/examples/mp/jupyter/green_truck.ipynb +++ b/examples/mp/jupyter/green_truck.ipynb @@ -13,7 +13,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + ">This notebook is part of the [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -792,7 +792,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com.\n" diff --git a/examples/mp/jupyter/incremental_modeling.ipynb b/examples/mp/jupyter/incremental_modeling.ipynb index ac86dd9..2828cd0 100644 --- a/examples/mp/jupyter/incremental_modeling.ipynb +++ b/examples/mp/jupyter/incremental_modeling.ipynb @@ -21,7 +21,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n", + ">This notebook is part of the **[Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)**\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -665,7 +665,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n" diff --git a/examples/mp/jupyter/lagrangian_relaxation.ipynb b/examples/mp/jupyter/lagrangian_relaxation.ipynb index 19a0609..e210da9 100644 --- a/examples/mp/jupyter/lagrangian_relaxation.ipynb +++ b/examples/mp/jupyter/lagrangian_relaxation.ipynb @@ -11,7 +11,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + ">This notebook is part of the [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -499,7 +499,7 @@ }, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* [Decision Optimization documentation](https://datascience.ibm.com/docs/content/DO/DOinDSX.html)\n", "* For help with DOcplex, or to report a defect, go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", diff --git a/examples/mp/jupyter/lifegame.ipynb b/examples/mp/jupyter/lifegame.ipynb index 38ee02d..4d7de0d 100644 --- a/examples/mp/jupyter/lifegame.ipynb +++ b/examples/mp/jupyter/lifegame.ipynb @@ -15,7 +15,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n", + ">This notebook is part of the **[Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)**\n", "\n", "This model is greater than the size allowed in trial mode of CPLEX.\n", ">It requires a **local installation of CPLEX Optimizers**. \n", @@ -469,7 +469,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n" diff --git a/examples/mp/jupyter/load_balancing.ipynb b/examples/mp/jupyter/load_balancing.ipynb index e4bed44..22d3d78 100644 --- a/examples/mp/jupyter/load_balancing.ipynb +++ b/examples/mp/jupyter/load_balancing.ipynb @@ -13,7 +13,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + ">This notebook is part of the [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -477,7 +477,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com.\n" diff --git a/examples/mp/jupyter/logical_cts.ipynb b/examples/mp/jupyter/logical_cts.ipynb index 2faac1e..199379c 100644 --- a/examples/mp/jupyter/logical_cts.ipynb +++ b/examples/mp/jupyter/logical_cts.ipynb @@ -15,7 +15,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n", + ">This notebook is part of the **[Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)**\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -453,7 +453,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n" diff --git a/examples/mp/jupyter/marketing_campaign.ipynb b/examples/mp/jupyter/marketing_campaign.ipynb index 7e7d7b6..9f438e1 100644 --- a/examples/mp/jupyter/marketing_campaign.ipynb +++ b/examples/mp/jupyter/marketing_campaign.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of the [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">Running the sample requires the installation of\n", " [CPLEX Optimization studio](https://www.ibm.com/products/ilog-cplex-optimization-studio)\n", @@ -497,7 +497,7 @@ }, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/mining_pandas.ipynb b/examples/mp/jupyter/mining_pandas.ipynb index 6b34290..7d313d0 100644 --- a/examples/mp/jupyter/mining_pandas.ipynb +++ b/examples/mp/jupyter/mining_pandas.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">Running the sample requires the installation of\n", " [CPLEX Optimization studio](https://www.ibm.com/products/ilog-cplex-optimization-studio)\n", @@ -930,7 +930,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/nurses_pandas-multi_objective.ipynb b/examples/mp/jupyter/nurses_pandas-multi_objective.ipynb new file mode 100644 index 0000000..875a574 --- /dev/null +++ b/examples/mp/jupyter/nurses_pandas-multi_objective.ipynb @@ -0,0 +1,1398 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# The Nurse Assignment Problem\n", + "\n", + "This tutorial includes everything you need to set up IBM Decision Optimization CPLEX Modeling for Python (DOcplex), build a Mathematical Programming model, and get its solution by solving the model on the cloud with IBM ILOG CPLEX Optimizer.\n", + "\n", + "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", + "\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", + "\n", + ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", + "\n", + "Discover us [here](https://developer.ibm.com/docloud)\n", + "\n", + "\n", + "Table of contents:\n", + "\n", + "- [Describe the business problem](#Describe-the-business-problem)\n", + "* [How decision optimization (prescriptive analytics) can help](#How--decision-optimization-can-help)\n", + "* [Use decision optimization](#Use-decision-optimization)\n", + " * [Step 1: Import the library](#Step-1:-Import-the-library)\n", + " - [Step 2: Model the data](#Step-2:-Model-the-data)\n", + " * [Step 3: Prepare the data](#Step-3:-Prepare-the-data)\n", + " - [Step 4: Set up the prescriptive model](#Step-4:-Set-up-the-prescriptive-model)\n", + " * [Define the decision variables](#Define-the-decision-variables)\n", + " * [Express the business constraints](#Express-the-business-constraints)\n", + " * [Express the objective](#Express-the-objective)\n", + " * [Solve with Decision Optimization](#Solve-with-Decision-Optimization)\n", + " * [Step 5: Investigate the solution and run an example analysis](#Step-5:-Investigate-the-solution-and-then-run-an-example-analysis)\n", + "* [Summary](#Summary)\n", + "\n", + "****" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Describe the business problem\n", + "\n", + "This notebook describes how to use CPLEX Modeling for Python together with *pandas* to\n", + "manage the assignment of nurses to shifts in a hospital.\n", + "\n", + "Nurses must be assigned to hospital shifts in accordance with various skill and staffing constraints.\n", + "\n", + "The goal of the model is to find an efficient balance between the different objectives:\n", + "\n", + "* minimize the overall cost of the plan and\n", + "* assign shifts as fairly as possible.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How decision optimization can help\n", + "\n", + "* Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes. \n", + "\n", + "* Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes. \n", + "\n", + "* Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage. \n", + "
\n", + "\n", + "With prescriptive analytics, you can: \n", + "\n", + "* Automate the complex decisions and trade-offs to better manage your limited resources.\n", + "* Take advantage of a future opportunity or mitigate a future risk.\n", + "* Proactively update recommendations based on changing events.\n", + "* Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Checking minimum requirements\n", + "This notebook uses some features of pandas that are available in version 0.17.1 or above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pip\n", + "REQUIRED_MINIMUM_PANDAS_VERSION = '0.17.1'\n", + "try:\n", + " import pandas as pd\n", + " assert pd.__version__ >= REQUIRED_MINIMUM_PANDAS_VERSION\n", + "except:\n", + " raise Exception(\"Version %s or above of Pandas is required to run this notebook\" % REQUIRED_MINIMUM_PANDAS_VERSION)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Use decision optimization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 1: Import the library\n", + "\n", + "Run the following code to import the Decision Optimization CPLEX Modeling library. The *DOcplex* library contains the two modeling packages, Mathematical Programming (docplex.mp) and Constraint Programming (docplex.cp)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import sys\n", + "try:\n", + " import docplex.mp\n", + "except:\n", + " raise Exception('Please install docplex. See https://pypi.org/project/docplex/')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "### Step 2: Model the data\n", + "\n", + "The input data consists of several tables:\n", + "\n", + "* The Departments table lists all departments in the scope of the assignment.\n", + "* The Skills table list all skills.\n", + "* The Shifts table lists all shifts to be staffed. A shift contains a department, a day in the week, plus the start and end times.\n", + "* The Nurses table lists all nurses, identified by their names.\n", + "* The NurseSkills table gives the skills of each nurse.\n", + "* The SkillRequirements table lists the minimum number of persons required for a given department and skill.\n", + "* The NurseVacations table lists days off for each nurse.\n", + "* The NurseAssociations table lists pairs of nurses who wish to work together.\n", + "* The NurseIncompatibilities table lists pairs of nurses who do not want to work together." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Loading data from Excel with pandas\n", + "\n", + "We load the data from an Excel file using *pandas*.\n", + "Each sheet is read into a separate *pandas* DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "CSS = \"\"\"\n", + "body {\n", + " margin: 0;\n", + " font-family: Helvetica;\n", + "}\n", + "table.dataframe {\n", + " border-collapse: collapse;\n", + " border: none;\n", + "}\n", + "table.dataframe tr {\n", + " border: none;\n", + "}\n", + "table.dataframe td, table.dataframe th {\n", + " margin: 0;\n", + " border: 1px solid white;\n", + " padding-left: 0.25em;\n", + " padding-right: 0.25em;\n", + "}\n", + "table.dataframe th:not(:empty) {\n", + " background-color: #fec;\n", + " text-align: left;\n", + " font-weight: normal;\n", + "}\n", + "table.dataframe tr:nth-child(2) th:empty {\n", + " border-left: none;\n", + " border-right: 1px dashed #888;\n", + "}\n", + "table.dataframe td {\n", + " border: 2px solid #ccf;\n", + " background-color: #f4f4ff;\n", + "}\n", + " table.dataframe thead th:first-child {\n", + " display: none;\n", + " }\n", + " table.dataframe tbody th {\n", + " display: none;\n", + " }\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from IPython.core.display import HTML\n", + "HTML(''.format(CSS))\n", + "\n", + "from IPython.display import display" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "try:\n", + " from StringIO import StringIO\n", + "except ImportError:\n", + " from io import StringIO" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "try:\n", + " from urllib2 import urlopen\n", + "except ImportError:\n", + " from urllib.request import urlopen" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# This notebook requires pandas to work\n", + "import pandas as pd\n", + "from pandas import DataFrame\n", + "\n", + "# Make sure that xlrd package, which is a pandas optional dependency, is installed\n", + "# This package is required for Excel I/O\n", + "try:\n", + " import xlrd\n", + "except:\n", + " if hasattr(sys, 'real_prefix'):\n", + " #we are in a virtual env.\n", + " !pip install xlrd \n", + " else:\n", + " !pip install --user xlrd \n", + "\n", + "# Use pandas to read the file, one tab for each table.\n", + "data_url = \"https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/mp/jupyter/nurses_data.xls?raw=true\"\n", + "nurse_xls_file = pd.ExcelFile(urlopen(data_url))\n", + "\n", + "df_skills = nurse_xls_file.parse('Skills')\n", + "df_depts = nurse_xls_file.parse('Departments')\n", + "df_shifts = nurse_xls_file.parse('Shifts')\n", + "# Rename df_shifts index\n", + "df_shifts.index.name = 'shiftId'\n", + "\n", + "# Index is column 0: name\n", + "df_nurses = nurse_xls_file.parse('Nurses', header=0, index_col=0)\n", + "df_nurse_skilles = nurse_xls_file.parse('NurseSkills')\n", + "df_vacations = nurse_xls_file.parse('NurseVacations')\n", + "df_associations = nurse_xls_file.parse('NurseAssociations')\n", + "df_incompatibilities = nurse_xls_file.parse('NurseIncompatibilities')\n", + "\n", + "# Display the nurses dataframe\n", + "print(\"#nurses = {}\".format(len(df_nurses)))\n", + "print(\"#shifts = {}\".format(len(df_shifts)))\n", + "print(\"#vacations = {}\".format(len(df_vacations)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, we introduce some extra global data:\n", + "\n", + "* The maximum work time for each nurse.\n", + "* The maximum and minimum number of shifts worked by a nurse in a week." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# maximum work time (in hours)\n", + "max_work_time = 40\n", + "\n", + "# maximum number of shifts worked in a week.\n", + "max_nb_shifts = 5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Shifts are stored in a separate DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "df_shifts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 3: Prepare the data\n", + "\n", + "We need to precompute additional data for shifts. \n", + "For each shift, we need the start time and end time expressed in hours, counting from the beginning of the week: Monday 8am is converted to 8, Tuesday 8am is converted to 24+8 = 32, and so on.\n", + "\n", + "#### Sub-step #1\n", + "We start by adding an extra column `dow` (day of week) which converts the string \"day\" into an integer in 0..6 (Monday is 0, Sunday is 6)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "days = [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\"]\n", + "day_of_weeks = dict(zip(days, range(7)))\n", + "\n", + "# utility to convert a day string e.g. \"Monday\" to an integer in 0..6\n", + "def day_to_day_of_week(day):\n", + " return day_of_weeks[day.strip().lower()]\n", + "\n", + "# for each day name, we normalize it by stripping whitespace and converting it to lowercase\n", + "# \" Monday\" -> \"monday\"\n", + "df_shifts[\"dow\"] = df_shifts.day.apply(day_to_day_of_week)\n", + "df_shifts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sub-step #2 : Compute the absolute start time of each shift.\n", + "\n", + "Computing the start time in the week is easy: just add `24*dow` to column `start_time`. The result is stored in a new column `wstart`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "df_shifts[\"wstart\"] = df_shifts.start_time + 24 * df_shifts.dow" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sub-Step #3 : Compute the absolute end time of each shift.\n", + "\n", + "Computing the absolute end time is a little more complicated as certain shifts span across midnight. For example, Shift #3 starts on Monday at 18:00 and ends Tuesday at 2:00 AM. The absolute end time of Shift #3 is 26, not 2.\n", + "The general rule for computing absolute end time is:\n", + "\n", + "`abs_end_time = end_time + 24 * dow + (start_time>= end_time ? 24 : 0)`\n", + "\n", + "Again, we use *pandas* to add a new calculated column `wend`. This is done by using the *pandas* `apply` method with an anonymous `lambda` function over rows. The `raw=True` parameter prevents the creation of a *pandas* Series for each row, which improves the performance significantly on large data sets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# an auxiliary function to calculate absolute end time of a shift\n", + "def calculate_absolute_endtime(start, end, dow):\n", + " return 24*dow + end + (24 if start>=end else 0)\n", + "\n", + "# store the results in a new column\n", + "df_shifts[\"wend\"] = df_shifts.apply(lambda row: calculate_absolute_endtime(\n", + " row.start_time, row.end_time, row.dow), axis=1, raw=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sub-step #4 : Compute the duration of each shift.\n", + "\n", + "Computing the duration of each shift is now a straightforward difference of columns. The result is stored in column `duration`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "df_shifts[\"duration\"] = df_shifts.wend - df_shifts.wstart" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sub-step #5 : Compute the minimum demand for each shift.\n", + "\n", + "Minimum demand is the product of duration (in hours) by the minimum required number of nurses. Thus, in number of \n", + "nurse-hours, this demand is stored in another new column `min_demand`.\n", + "\n", + "Finally, we display the updated shifts DataFrame with all calculated columns." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# also compute minimum demand in nurse-hours\n", + "df_shifts[\"min_demand\"] = df_shifts.min_req * df_shifts.duration\n", + "\n", + "# finally check the modified shifts dataframe\n", + "df_shifts" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 4: Set up the prescriptive model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from docplex.mp.environment import Environment\n", + "env = Environment()\n", + "env.print_information()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create the DOcplex model\n", + "The model contains all the business constraints and defines the objective.\n", + "\n", + "We now use CPLEX Modeling for Python to build a Mixed Integer Programming (MIP) model for this problem." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from docplex.mp.model import Model\n", + "mdl = Model(name=\"nurses\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Define the decision variables\n", + "\n", + "For each (nurse, shift) pair, we create one binary variable that is equal to 1 when the nurse is assigned to the shift.\n", + "\n", + "We use the `binary_var_matrix` method of class `Model`, as each binary variable is indexed by _two_ objects: one nurse and one shift." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# first global collections to iterate upon\n", + "all_nurses = df_nurses.index.values\n", + "all_shifts = df_shifts.index.values\n", + "\n", + "# the assignment variables.\n", + "assigned = mdl.binary_var_matrix(keys1=all_nurses, keys2=all_shifts, name=\"assign_%s_%s\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Express the business constraints\n", + "\n", + "##### Overlapping shifts\n", + "\n", + "Some shifts overlap in time, and thus cannot be assigned to the same nurse.\n", + "To check whether two shifts overlap in time, we start by ordering all shifts with respect to their *wstart* and *duration* properties. Then, for each shift, we iterate over the subsequent shifts in this ordered list to easily compute the subset of overlapping shifts.\n", + "\n", + "We use *pandas* operations to implement this algorithm. But first, we organize all decision variables in a DataFrame.\n", + "\n", + "For convenience, we also organize the decision variables in a pivot table with *nurses* as row index and *shifts* as columns. The *pandas* *unstack* operation does this." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Organize decision variables in a DataFrame\n", + "df_assigned = DataFrame({'assigned': assigned})\n", + "df_assigned.index.names=['all_nurses', 'all_shifts']\n", + "\n", + "# Re-organize the Data Frame as a pivot table with nurses as row index and shifts as columns:\n", + "df_assigned_pivot = df_assigned.unstack(level='all_shifts')\n", + "\n", + "# Create a pivot using nurses and shifts index as dimensions\n", + "#df_assigned_pivot = df_assigned.reset_index().pivot(index='all_nurses', columns='all_shifts', values='assigned')\n", + "\n", + "# Display first rows of the pivot table\n", + "df_assigned_pivot.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We create a DataFrame representing a list of shifts sorted by *\"wstart\"* and *\"duration\"*.\n", + "This sorted list will be used to easily detect overlapping shifts.\n", + "\n", + "Note that indices are reset after sorting so that the DataFrame can be indexed with respect to\n", + "the index in the sorted list and not the original unsorted list. This is the purpose of the *reset_index()*\n", + "operation which also adds a new column named *\"shiftId\"* with the original index." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create a Data Frame representing a list of shifts sorted by wstart and duration.\n", + "# One keeps only the three relevant columns: 'shiftId', 'wstart' and 'wend' in the resulting Data Frame \n", + "df_sorted_shifts = df_shifts.sort_values(['wstart','duration']).reset_index()[['shiftId', 'wstart', 'wend']]\n", + "\n", + "# Display the first rows of the newly created Data Frame\n", + "df_sorted_shifts.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we state that for any pair of shifts that overlap in time, a nurse can be assigned to only one of the two." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "number_of_incompatible_shift_constraints = 0\n", + "for shift in df_sorted_shifts.itertuples():\n", + " # Iterate over following shifts\n", + " # 'shift[0]' contains the index of the current shift in the df_sorted_shifts Data Frame\n", + " for shift_2 in df_sorted_shifts.iloc[shift[0] + 1:].itertuples():\n", + " if (shift_2.wstart < shift.wend):\n", + " # Iterate over all nurses to force incompatible assignment for the current pair of overlapping shifts\n", + " for nurse_assignments in df_assigned_pivot.iloc[:, [shift.shiftId, shift_2.shiftId]].itertuples():\n", + " # this is actually a logical OR\n", + " mdl.add_constraint(nurse_assignments[1] + nurse_assignments[2] <= 1)\n", + " number_of_incompatible_shift_constraints += 1\n", + " else:\n", + " # No need to test overlap with following shifts\n", + " break\n", + "print(\"#incompatible shift constraints: {}\".format(number_of_incompatible_shift_constraints))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Vacations\n", + "\n", + "When the nurse is on vacation, he cannot be assigned to any shift starting that day.\n", + "\n", + "We use the *pandas* *merge* operation to create a join between the *\"df_vacations\"*, *\"df_shifts\"*, and *\"df_assigned\"* DataFrames. Each row of the resulting DataFrame contains the assignment decision variable corresponding to the matching (nurse, shift) pair." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Add 'day of week' column to vacations Data Frame\n", + "df_vacations['dow'] = df_vacations.day.apply(day_to_day_of_week)\n", + "\n", + "# Join 'df_vacations', 'df_shifts' and 'df_assigned' Data Frames to create the list of 'forbidden' assigments.\n", + "# The 'reset_index()' function is invoked to move 'shiftId' index as a column in 'df_shifts' Data Frame, and\n", + "# to move the index pair ('all_nurses', 'all_shifts') as columns in 'df_assigned' Data Frame.\n", + "# 'reset_index()' is invoked so that a join can be performed between Data Frame, based on column names.\n", + "df_assigned_reindexed = df_assigned.reset_index()\n", + "df_vacation_forbidden_assignments = df_vacations.merge(df_shifts.reset_index()[['dow', 'shiftId']]).merge(\n", + " df_assigned_reindexed, left_on=['nurse', 'shiftId'], right_on=['all_nurses', 'all_shifts'])\n", + "\n", + "# Here are the first few rows of the resulting Data Frames joins\n", + "df_vacation_forbidden_assignments.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "for forbidden_assignment in df_vacation_forbidden_assignments.itertuples():\n", + " # to forbid an assignment just set the variable to zero.\n", + " mdl.add_constraint(forbidden_assignment.assigned == 0)\n", + "print(\"# vacation forbids: {} assignments\".format(len(df_vacation_forbidden_assignments)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Associations\n", + "\n", + "Some pairs of nurses get along particularly well, so we wish to assign them together as a team. In other words, for every such couple and for each shift, both assignment variables should always be equal.\n", + "Either both nurses work the shift, or both do not.\n", + "\n", + "In the same way we modeled *vacations*, we use the *pandas* merge operation to create a DataFrame for which each row contains the pair of nurse-shift assignment decision variables matching each association." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Join 'df_assignment' Data Frame twice, based on associations to get corresponding decision variables pairs for all shifts\n", + "# The 'suffixes' parameter in the second merge indicates our preference for updating the name of columns that occur both\n", + "# in the first and second argument Data Frames (in our case, these columns are 'all_nurses' and 'assigned').\n", + "df_preferred_assign = df_associations.merge(\n", + " df_assigned_reindexed, left_on='nurse1', right_on='all_nurses').merge(\n", + " df_assigned_reindexed, left_on=['nurse2', 'all_shifts'], right_on=['all_nurses', 'all_shifts'], suffixes=('_1','_2'))\n", + "\n", + "# Here are the first few rows of the resulting Data Frames joins\n", + "df_preferred_assign.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The associations constraint can now easily be formulated by iterating on the rows of the *\"df_preferred_assign\"* DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "for preferred_assign in df_preferred_assign.itertuples():\n", + " mdl.add_constraint(preferred_assign.assigned_1 == preferred_assign.assigned_2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Incompatibilities\n", + "\n", + "Similarly, certain pairs of nurses do not get along well, and we want to avoid having them together on a shift.\n", + "In other terms, for each shift, both nurses of an incompatible pair cannot be assigned together to the sift. Again, we state a logical OR between the two assignments: at most one nurse from the pair can work the shift.\n", + "\n", + "We first create a DataFrame whose rows contain pairs of invalid assignment decision variables, using the same *pandas* `merge` operations as in the previous step." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Join assignment Data Frame twice, based on incompatibilities Data Frame to get corresponding decision variables pairs\n", + "# for all shifts\n", + "df_incompatible_assign = df_incompatibilities.merge(\n", + " df_assigned_reindexed, left_on='nurse1', right_on='all_nurses').merge(\n", + " df_assigned_reindexed, left_on=['nurse2', 'all_shifts'], right_on=['all_nurses', 'all_shifts'], suffixes=('_1','_2'))\n", + "\n", + "# Here are the first few rows of the resulting Data Frames joins\n", + "df_incompatible_assign.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The incompatibilities constraint can now easily be formulated, by iterating on the rows of the *\"df_incompatible_assign\"* DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "for incompatible_assign in df_incompatible_assign.itertuples():\n", + " mdl.add_constraint(incompatible_assign.assigned_1 + incompatible_assign.assigned_2 <= 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Constraints on work time\n", + "\n", + "Regulations force constraints on the total work time over a week;\n", + "and we compute this total work time in a new variable. We store the variable in an extra column in the nurse DataFrame.\n", + "\n", + "The variable is declared as _continuous_ though it contains only integer values. This is done to avoid adding unnecessary integer variables for the _branch and bound_ algorithm. \n", + "These variables are not true decision variables; they are used to express work constraints.\n", + "\n", + "From a *pandas* perspective, we apply a function over the rows of the nurse DataFrame to create this variable and store it into a new column of the DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# auxiliary function to create worktime variable from a row\n", + "def make_var(row, varname_fmt):\n", + " return mdl.continuous_var(name=varname_fmt % row.name, lb=0)\n", + "\n", + "# apply the function over nurse rows and store result in a new column\n", + "df_nurses[\"worktime\"] = df_nurses.apply(lambda r: make_var(r, \"worktime_%s\"), axis=1)\n", + "\n", + "# display nurse dataframe\n", + "df_nurses" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "###### Define total work time\n", + "\n", + "Work time variables must be constrained to be equal to the sum of hours actually worked.\n", + "\n", + "We use the *pandas* *groupby* operation to collect all assignment decision variables for each nurse in a separate series. Then, we iterate over nurses to post a constraint calculating the actual worktime for each nurse as the dot product of the series of nurse-shift assignments with the series of shift durations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Use pandas' groupby operation to enforce constraint calculating worktime for each nurse as the sum of all assigned\n", + "# shifts times the duration of each shift\n", + "for nurse, nurse_assignments in df_assigned.groupby(level='all_nurses'):\n", + " mdl.add_constraint(df_nurses.worktime[nurse] == mdl.dot(nurse_assignments.assigned, df_shifts.duration))\n", + " \n", + "# print model information and check we now have 32 extra continuous variables\n", + "mdl.print_information()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "###### Maximum work time\n", + "\n", + "For each nurse, we add a constraint to enforce the maximum work time for a week.\n", + "Again we use the `apply` method, this time with an anonymous lambda function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# we use pandas' apply() method to set an upper bound on all worktime variables.\n", + "def set_max_work_time(v):\n", + " v.ub = max_work_time\n", + " # Optionally: return a string for fancy display of the constraint in the Output cell\n", + " return str(v) + ' <= ' + str(v.ub)\n", + "\n", + "df_nurses[\"worktime\"].apply(convert_dtype=False, func=set_max_work_time)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Minimum requirement for shifts\n", + "\n", + "Each shift requires a minimum number of nurses. \n", + "For each shift, the sum over all nurses of assignments to this shift\n", + "must be greater than the minimum requirement.\n", + "\n", + "The *pandas* *groupby* operation is invoked to collect all assignment decision variables for each shift in a separate series. Then, we iterate over shifts to post the constraint enforcing the minimum number of nurse assignments for each shift." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Use pandas' groupby operation to enforce minimum requirement constraint for each shift\n", + "for shift, shift_nurses in df_assigned.groupby(level='all_shifts'):\n", + " mdl.add_constraint(mdl.sum(shift_nurses.assigned) >= df_shifts.min_req[shift])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Express the objective\n", + "\n", + "The objective mixes different (and contradictory) KPIs. \n", + "\n", + "The first KPI is the total salary cost, computed as the sum of work times over all nurses, weighted by pay rate.\n", + "\n", + "We compute this KPI as an expression from the variables we previously defined by using the panda summation over the DOcplex objects." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# again leverage pandas to create a series of expressions: costs of each nurse\n", + "total_salary_series = df_nurses.worktime * df_nurses.pay_rate\n", + "\n", + "# compute global salary cost using pandas sum()\n", + "# Note that the result is a DOcplex expression: DOcplex if fully compatible with pandas\n", + "total_salary_cost = total_salary_series.sum()\n", + "mdl.add_kpi(total_salary_cost, \"Total salary cost\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Minimizing salary cost\n", + "\n", + "In a preliminary version of the model, we minimize the total salary cost. This is accomplished\n", + "using the `Model.minimize()` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "mdl.minimize(total_salary_cost)\n", + "mdl.print_information()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Solve with Decision Optimization\n", + "\n", + "Now we have everything we need to solve the model, using `Model.solve()`. The following cell solves using your local CPLEX (if any, and provided you have added it to your `PYTHONPATH` variable). \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Set Cplex mipgap to 1e-5 to enforce precision to be of the order of a unit (objective value magnitude is ~1e+5).\n", + "mdl.parameters.mip.tolerances.mipgap = 1e-5\n", + "\n", + "s = mdl.solve(log_output=True)\n", + "assert s, \"solve failed\"\n", + "mdl.report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step 6: Investigate the solution and then run an example analysis\n", + "\n", + "We take advantage of *pandas* to analyze the results. First we store the solution values of the assignment variables into a new *pandas* Series.\n", + "\n", + "Calling `solution_value` on a DOcplex variable returns its value in the solution (provided the model has been successfully solved)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create a pandas Series containing actual shift assignment decision variables value\n", + "s_assigned = df_assigned.assigned.apply(lambda v: v.solution_value)\n", + "\n", + "# Create a pivot table by (nurses, shifts), using pandas' \"unstack\" method to transform the 'all_shifts' row index\n", + "# into columns\n", + "df_res = s_assigned.unstack(level='all_shifts')\n", + "\n", + "# Display the first few rows of the resulting pivot table\n", + "df_res.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Analyzing how worktime is distributed\n", + "\n", + "Let's analyze how worktime is distributed among nurses. \n", + "\n", + "First, we compute the global average work time as the total minimum requirement in hours, divided by number of nurses." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "s_demand = df_shifts.min_req * df_shifts.duration\n", + "total_demand = s_demand.sum()\n", + "avg_worktime = total_demand / float(len(all_nurses))\n", + "print(\"* theoretical average work time is {0:g} h\".format(avg_worktime))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's analyze the series of deviations to the average, stored in a *pandas* Series." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# a pandas series of worktimes solution values\n", + "s_worktime = df_nurses.worktime.apply(lambda v: v.solution_value)\n", + "\n", + "# returns a new series computed as deviation from average\n", + "s_to_mean = s_worktime - avg_worktime\n", + "\n", + "# take the absolute value\n", + "s_abs_to_mean = s_to_mean.apply(abs)\n", + "\n", + "\n", + "total_to_mean = s_abs_to_mean.sum()\n", + "print(\"* the sum of absolute deviations from mean is {}\".format(total_to_mean))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To see how work time is distributed among nurses, print a histogram of work time values.\n", + "Note that, as all time data are integers, work times in the solution can take only integer values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "# we can also plot as a histogram the distribution of worktimes\n", + "s_worktime.plot.hist(color='LightBlue')\n", + "plt.xlabel(\"worktime\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### How shifts are distributed\n", + "\n", + "Let's now analyze the solution from the _number of shifts_ perspective.\n", + "How many shifts does each nurse work? Are these shifts fairly distributed amongst nurses?\n", + "\n", + "We compute a new column in our result DataFrame for the number of shifts worked,\n", + "by summing rows (the *\"axis=1\"* argument in the *sum()* call indicates to *pandas* that each sum is performed by row instead of column):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# a pandas series of #shifts worked\n", + "df_worked = df_res[all_shifts].sum(axis=1)\n", + "df_res[\"worked\"] = df_worked\n", + "\n", + "df_worked.plot.hist(color=\"gold\", xlim=(0,10))\n", + "plt.ylabel(\"#shifts worked\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We see that one nurse works significantly fewer shifts than others do. What is the average number of shifts worked by a nurse? This is equal to the total demand divided by the number of nurses.\n", + "\n", + "Of course, this yields a fractional number of shifts that is not practical, but nonetheless will help us quantify\n", + "the _fairness_ in shift distribution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "avg_worked = df_shifts[\"min_req\"].sum() / float(len(all_nurses))\n", + "print(\"-- expected avg #shifts worked is {}\".format(avg_worked))\n", + "\n", + "worked_to_avg = df_res[\"worked\"] - avg_worked\n", + "total_to_mean = worked_to_avg.apply(abs).sum()\n", + "print(\"-- total absolute deviation to mean #shifts is {}\".format(total_to_mean))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Introducing a fairness goal\n", + "\n", + "As the above diagram suggests, the distribution of shifts could be improved.\n", + "We implement this by adding one extra objective, _fairness_, which balances\n", + "the shifts assigned over nurses.\n", + "\n", + "Note that we can edit the model, that is add (or remove) constraints, even after it has been solved. \n", + "\n", + "### Step #1 : Introduce three new variables per nurse to model the \n", + "number of shifts worked and positive and negative deviations to the average." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# add two extra variables per nurse: deviations above and below average\n", + "df_nurses[\"worked\"] = df_nurses.apply(lambda r: make_var(r, \"worked%s\"), axis=1)\n", + "df_nurses[\"overworked\"] = df_nurses.apply(lambda r: make_var(r, \"overw_%s\"), axis=1)\n", + "df_nurses[\"underworked\"] = df_nurses.apply(lambda r: make_var(r, \"underw_%s\"), axis=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step #2 : Post the constraint that links these variables together." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Use the pandas groupby operation to enforce the constraint calculating number of worked shifts for each nurse\n", + "for nurse, nurse_assignments in df_assigned.groupby(level='all_nurses'):\n", + " # nb of worked shifts is sum of assigned shifts\n", + " mdl.add_constraint(df_nurses.worked[nurse] == mdl.sum(nurse_assignments.assigned))\n", + "\n", + "for nurse in df_nurses.itertuples():\n", + " # nb worked is average + over - under\n", + " mdl.add_constraint(nurse.worked == avg_worked + nurse.overworked - nurse.underworked)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step #3 : Define KPIs to measure the result after solve." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# finally, define kpis for over and under average quantities\n", + "total_overw = mdl.sum(df_nurses[\"overworked\"])\n", + "mdl.add_kpi(total_overw, \"Total over-worked\")\n", + "total_underw = mdl.sum(df_nurses[\"underworked\"])\n", + "mdl.add_kpi(total_underw, \"Total under-worked\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, let's modify the objective by adding the sum of `over_worked and under_worked` to the previous objective.\n", + "\n", + "**Note:** The definitions of `over_worked` and `under_worked` as described above are not sufficient to give them an unambiguous value. However, as all these variables are minimized, CPLEX ensures that these variables take the minimum possible values in the solution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "mdl.minimize(total_salary_cost + total_overw + total_underw) # incorporate over_worked and under_worked in objective" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our modified model is ready to solve.\n", + "\n", + "The `log_output=True` parameter tells CPLEX to print the log on the standard output." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sol2 = mdl.solve(log_output=True) # solve again and get a new solution\n", + "assert sol2, \"Solve failed\"\n", + "mdl.report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Step #4 : Alternative solve: multi-objective\n", + "Instead of aggregating all objectives into a single goal, one may prioritize goals.\n", + "For instance, one may first minimize cost, and then optimize fairness.\n", + "This is a 2 steps optimization which may be configured by exploiting the multi-objective API of docplex as follows:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, redefine the optimization problem as a multi-objective minimization.\n", + "Objectives are grouped into sub-problems with respect to the list of priorities that is provided. The number of items in the prioriries list must be the same as the number of objectives.\n", + "\n", + "Sub-problems are solved one after the other in the order of decreasing priorities.\n", + "\n", + "Objectives with same priorities are blended into an aggregated goal, where each objective is weighted according to the values provided in the _weights_ list. If no list of weights is provided, all objectives have unitary weight." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from docplex.mp.constants import ObjectiveSense\n", + "\n", + "mdl.set_multi_objective(ObjectiveSense.Minimize, [total_salary_cost, total_overw, total_underw], priorities=[1, 0, 0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For multi-objectives probles, solve is performed in the same way:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "sol3 = mdl.solve(log_output=True) # solve the multi-objective problem\n", + "assert sol3, \"Solve failed\"\n", + "mdl.report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this example, one gets the same solution when blending all the objectives together (Step #3) or when decomposing the problems into two sub-problems, setting higher priority for cost minimization." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, if one wants to optimize fairness first, and then cost, multi-objective solve returns a different solution:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "mdl.set_multi_objective(ObjectiveSense.Minimize, [total_overw, total_underw, total_salary_cost], priorities=[1, 1, 0])\n", + "\n", + "sol4 = mdl.solve(log_output=True) # solve the multi-objective problem\n", + "assert sol4, \"Solve failed\"\n", + "mdl.report()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "You learned how to set up and use IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model and solve it with IBM Decision Optimization on Cloud.\n", + "\n", + "You also learned how to setup your problems if different objective are considered for evaluating solutions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## References\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", + "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", + "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", + "* Contact us at dofeedback@wwpdl.vnet.ibm.com." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Copyright © 2017 IBM. IPLA licensed Sample Materials." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.11" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/mp/jupyter/nurses_pandas.ipynb b/examples/mp/jupyter/nurses_pandas.ipynb index bde359d..568b60b 100644 --- a/examples/mp/jupyter/nurses_pandas.ipynb +++ b/examples/mp/jupyter/nurses_pandas.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -1396,7 +1396,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." @@ -1426,7 +1426,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.13" + "version": "2.7.11" } }, "nbformat": 4, diff --git a/examples/mp/jupyter/nurses_scheduling.ipynb b/examples/mp/jupyter/nurses_scheduling.ipynb index 13e8e43..a6c09c5 100644 --- a/examples/mp/jupyter/nurses_scheduling.ipynb +++ b/examples/mp/jupyter/nurses_scheduling.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -940,7 +940,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/oil_blending.ipynb b/examples/mp/jupyter/oil_blending.ipynb index 9d39e20..52763e1 100644 --- a/examples/mp/jupyter/oil_blending.ipynb +++ b/examples/mp/jupyter/oil_blending.ipynb @@ -11,7 +11,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">Running the sample requires the installation of\n", " [CPLEX Optimization studio](https://www.ibm.com/products/ilog-cplex-optimization-studio)\n", @@ -717,7 +717,7 @@ }, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/pasta_production.ipynb b/examples/mp/jupyter/pasta_production.ipynb index dbfd187..43c8a21 100644 --- a/examples/mp/jupyter/pasta_production.ipynb +++ b/examples/mp/jupyter/pasta_production.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -328,7 +328,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/jupyter/sktrans/transformers.ipynb b/examples/mp/jupyter/sktrans/transformers.ipynb index 32550cf..6b49485 100644 --- a/examples/mp/jupyter/sktrans/transformers.ipynb +++ b/examples/mp/jupyter/sktrans/transformers.ipynb @@ -43,8 +43,10 @@ }, { "cell_type": "code", - "execution_count": 1, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "try:\n", @@ -76,8 +78,10 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# the baseline diet data as Python lists of tuples.\n", @@ -118,18 +122,11 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "#foods=9\n", - "#nutrients=7\n" - ] - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "nb_foods = len(FOODS)\n", "nb_nutrients = len(NUTRIENTS)\n", @@ -167,17 +164,11 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The food-nutrient matrix has shape: (9L, 7L)\n" - ] - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "mat_fn = np.matrix([FOOD_NUTRIENTS[f][1:] for f in range(nb_foods)])\n", "print('The food-nutrient matrix has shape: {0}'.format(mat_fn.shape))" @@ -195,8 +186,10 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "nutrient_mins = [NUTRIENTS[n][1] for n in range(nb_nutrients)]\n", @@ -215,8 +208,10 @@ }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# step 1. add two lines for nutrient mins, maxs\n", @@ -226,28 +221,21 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(7L, 11L)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "mat_nf.shape" ] }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "np_costs = np.array(food_costs)" @@ -271,102 +259,11 @@ }, { "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
namevalue
5Chocolate Chip Cookies10.000000
1Spaghetti W/ Sauce2.155172
6Lowfat Milk1.831167
8Hotdog0.929698
0Roasted Chicken0.000000
2Tomato,Red,Ripe,Raw0.000000
3Apple,Raw,W/Skin0.000000
4Grapes0.000000
7Raisin Brn0.000000
\n", - "
" - ], - "text/plain": [ - " name value\n", - "5 Chocolate Chip Cookies 10.000000\n", - "1 Spaghetti W/ Sauce 2.155172\n", - "6 Lowfat Milk 1.831167\n", - "8 Hotdog 0.929698\n", - "0 Roasted Chicken 0.000000\n", - "2 Tomato,Red,Ripe,Raw 0.000000\n", - "3 Apple,Raw,W/Skin 0.000000\n", - "4 Grapes 0.000000\n", - "7 Raisin Brn 0.000000" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "from docplex.mp.sktrans.transformers import *\n", "\n", @@ -398,146 +295,11 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
foodRoasted ChickenSpaghetti W/ SauceTomato,Red,Ripe,RawApple,Raw,W/SkinGrapesChocolate Chip CookiesLowfat MilkRaisin BrnHotdogminmax
Calories277.4358.225.881.415.178.1121.2115.1242.120002500
Calcium21.980.26.29.73.46.2296.712.923.58001600
Iron1.82.30.60.20.10.40.116.82.31030
Vit_A77.43055.2766.373.124.0101.8500.21250.20.0500050000
Dietary_Fiber0.011.61.43.70.20.00.04.00.025100
\n", - "
" - ], - "text/plain": [ - "food Roasted Chicken Spaghetti W/ Sauce Tomato,Red,Ripe,Raw \\\n", - "Calories 277.4 358.2 25.8 \n", - "Calcium 21.9 80.2 6.2 \n", - "Iron 1.8 2.3 0.6 \n", - "Vit_A 77.4 3055.2 766.3 \n", - "Dietary_Fiber 0.0 11.6 1.4 \n", - "\n", - "food Apple,Raw,W/Skin Grapes Chocolate Chip Cookies Lowfat Milk \\\n", - "Calories 81.4 15.1 78.1 121.2 \n", - "Calcium 9.7 3.4 6.2 296.7 \n", - "Iron 0.2 0.1 0.4 0.1 \n", - "Vit_A 73.1 24.0 101.8 500.2 \n", - "Dietary_Fiber 3.7 0.2 0.0 0.0 \n", - "\n", - "food Raisin Brn Hotdog min max \n", - "Calories 115.1 242.1 2000 2500 \n", - "Calcium 12.9 23.5 800 1600 \n", - "Iron 16.8 2.3 10 30 \n", - "Vit_A 1250.2 0.0 5000 50000 \n", - "Dietary_Fiber 4.0 0.0 25 100 " - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "# convert raw data to dataframes\n", "df_foods = DataFrame(FOODS, columns=[\"food\", \"cost\", \"min\", \"max\"])\n", @@ -559,26 +321,11 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "food\n", - "Roasted Chicken 0.84\n", - "Spaghetti W/ Sauce 0.78\n", - "Tomato,Red,Ripe,Raw 0.27\n", - "Apple,Raw,W/Skin 0.24\n", - "Grapes 0.32\n", - "Name: cost, dtype: float64" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "# the cost vector\n", "scY = df_foods['cost'].copy()\n", @@ -595,102 +342,11 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
namevalue
5Chocolate Chip Cookies10.000000
1Spaghetti W/ Sauce2.155172
6Lowfat Milk1.831167
8Hotdog0.929698
0Roasted Chicken0.000000
2Tomato,Red,Ripe,Raw0.000000
3Apple,Raw,W/Skin0.000000
4Grapes0.000000
7Raisin Brn0.000000
\n", - "
" - ], - "text/plain": [ - " name value\n", - "5 Chocolate Chip Cookies 10.000000\n", - "1 Spaghetti W/ Sauce 2.155172\n", - "6 Lowfat Milk 1.831167\n", - "8 Hotdog 0.929698\n", - "0 Roasted Chicken 0.000000\n", - "2 Tomato,Red,Ripe,Raw 0.000000\n", - "3 Apple,Raw,W/Skin 0.000000\n", - "4 Grapes 0.000000\n", - "7 Raisin Brn 0.000000" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "df_diet = CplexRangeTransformer().transform(scX, scY, ubs=df_foods['max']).sort_values(by='value', ascending=False)\n", "df_diet\n" @@ -698,8 +354,10 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "%matplotlib inline\n", @@ -708,20 +366,11 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\neHjKarWWLTv0TuD3CxbvIaDaxfB7gSellGnABPC+VabxGSFENTAItEopF4/lI6XMklISBz2iAAAV\nZUlEQVR+a+HvGCAPuB14bAMv+S2NV5yvMaOjo/9eXl7+X7fffvuEybR0XSYwMJDjx4/T2NhIX1+f\nR84vpaShoWHN1lOL0Wq1JCUlcfr0abZv305LSwvnz5+nvb39ukj0WIuNivPU1BQNDQ0UFBQwODjI\nnj17yMvLIy4u7rqIaJFS8oEPfIAXX3yR973vfQwMDPCOd7zD+dy9995LfHy8tbOzcwyIAKKXDVEB\nfFQI8WUgY5UMwc5FQlsF7FplOg63RhQQKIT40KLnzi7b95yU0ialbHQxp5uea//J8sLIyMhXKysr\nv37rrbeOL+935+fnx4kTJ+jr66O1tVVxn2lPTw8RERHrLmGqUqmIiYkhOzub3NxcNBoNVVVVlJSU\n0NnZydzcnKLzVAJ3xdnRraW1tZXz58/T3NxMeHg4p0+f5tChQ4SHh183MeBWq5XKykoAvvjFLzpT\nsp988kkAvvvd7/Lzn//cZLVab5FSJgM67O4GJ1LKQuAU0A88J4T4OxenWuwPsgJr+o2llGbgtYVx\nHSxf5V485vXxhl5HeB3z1wl6vf7xiIgIw9ve9rav/ulPfwpb3D5Jo9GQnZ1NXV0dly9fXlGXd6OY\nzWY6OjqcroqN4uPjw65du9i1axezs7PodDpqamqc/fmio6OJiIi45lbmtm3bVl1kNZvNjIyMoNPp\nlvQ5zM3NVaxtltLMz89TWVnJzp07efnll3n22WcJCAjgu9/9LnfccQfvfOc7efTRR2fm5ub+V0pZ\nIIT4C2BFoLcQIhHok1I+I4TwBY4Az29mbsJ+9ToJXN7MODczXnG+jtDr9f8dFhY2n5eX983f//73\nYZGRkc7nVCoVhw4doquri5KSErKysvD3v9qazNq0trayZ88eRf2lgYGB7Nmzhz179mC1WhkdHWVw\ncJCGhgbUajVhYWHOfoEBAQFbaoGq1WqklFitVmZmZpiYmGB8fJzJyUlUKhWRkZEkJiZy+PDh68Yy\nXo2xsTFqampcFufPzMwkMTGRnJycqYmJifcCXxdC1AGVQLOL4c4ADwghzMAM4MpydpfPCCHuBrRA\nLfD9TYx1U+PNELwOCQgIeHdkZORzv/nNbyJd9RzU6/XU1taSkZHB9u3bN3SOmZkZLl26RH5+/pYJ\n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\nYDCkIf8Peu6c5OzC9H4AAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", @@ -744,20 +393,11 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nYBiC/D8M5jZ7F6YDYwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "plot_radar_chart(labels=np_diet['name'], stats=np_diet['value'], color='g')" ] @@ -810,8 +450,10 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "# N is the size \n", @@ -836,8 +478,10 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": false + }, "outputs": [], "source": [ "try:\n", @@ -858,8 +502,10 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "costs = [0] * N\n", @@ -877,102 +523,11 @@ }, { "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
value
01.0
12.0
23.0
34.0
45.0
56.0
67.0
78.0
89.0
910.0
1011.0
\n", - "
" - ], - "text/plain": [ - " value\n", - "0 1.0\n", - "1 2.0\n", - "2 3.0\n", - "3 4.0\n", - "4 5.0\n", - "5 6.0\n", - "6 7.0\n", - "7 8.0\n", - "8 9.0\n", - "9 10.0\n", - "10 11.0" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], "source": [ "from docplex.mp.sktrans.transformers import *\n", "res = CplexTransformer().transform(spm, costs, ubs=2*N, lbs=1)\n", @@ -982,16 +537,18 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { - "display_name": "dev44_27", + "display_name": "Python 2", "language": "python", - "name": "dev44_27" + "name": "python2" }, "language_info": { "codemirror_mode": { @@ -1003,7 +560,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.13" + "version": "2.7.11" } }, "nbformat": 4, diff --git a/examples/mp/jupyter/sparktrans/SparkML_transformers.ipynb b/examples/mp/jupyter/sparktrans/SparkML_transformers.ipynb index a2884f8..6effa92 100644 --- a/examples/mp/jupyter/sparktrans/SparkML_transformers.ipynb +++ b/examples/mp/jupyter/sparktrans/SparkML_transformers.ipynb @@ -2,24 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from IPython.core.display import display, HTML\n", "display(HTML(\"\"))" @@ -70,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": true }, @@ -101,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": true }, @@ -145,20 +132,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "#foods=9\n", - "#nutrients=7\n" - ] - } - ], + "outputs": [], "source": [ "nb_foods = len(FOODS)\n", "nb_nutrients = len(NUTRIENTS)\n", @@ -177,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, @@ -218,19 +196,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The food-nutrient matrix has shape: (9L, 7L)\n" - ] - } - ], + "outputs": [], "source": [ "mat_fn = np.matrix([FOOD_NUTRIENTS[f][1:] for f in range(nb_foods)])\n", "print('The food-nutrient matrix has shape: {0}'.format(mat_fn.shape))" @@ -246,7 +216,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": true }, @@ -268,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": true }, @@ -281,22 +251,11 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(7L, 11L)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mat_nf.shape" ] @@ -314,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": true }, @@ -338,61 +297,22 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "root\n", - " |-- Roasted Chicken: double (nullable = true)\n", - " |-- Spaghetti W/ Sauce: double (nullable = true)\n", - " |-- Tomato,Red,Ripe,Raw: double (nullable = true)\n", - " |-- Apple,Raw,W/Skin: double (nullable = true)\n", - " |-- Grapes: double (nullable = true)\n", - " |-- Chocolate Chip Cookies: double (nullable = true)\n", - " |-- Lowfat Milk: double (nullable = true)\n", - " |-- Raisin Brn: double (nullable = true)\n", - " |-- Hotdog: double (nullable = true)\n", - " |-- min: double (nullable = true)\n", - " |-- max: double (nullable = true)\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_df.printSchema()" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "|Roasted Chicken|Spaghetti W/ Sauce|Tomato,Red,Ripe,Raw|Apple,Raw,W/Skin|Grapes|Chocolate Chip Cookies|Lowfat Milk|Raisin Brn|Hotdog| min| max|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "| 277.4| 358.2| 25.8| 81.4| 15.1| 78.1| 121.2| 115.1| 242.1|2000.0| 2500.0|\n", - "| 21.9| 80.2| 6.2| 9.7| 3.4| 6.2| 296.7| 12.9| 23.5| 800.0| 1600.0|\n", - "| 1.8| 2.3| 0.6| 0.2| 0.1| 0.4| 0.1| 16.8| 2.3| 10.0| 30.0|\n", - "| 77.4| 3055.2| 766.3| 73.1| 24.0| 101.8| 500.2| 1250.2| 0.0|5000.0|50000.0|\n", - "| 0.0| 11.6| 1.4| 3.7| 0.2| 0.0| 0.0| 4.0| 0.0| 25.0| 100.0|\n", - "| 0.0| 58.3| 5.7| 21.0| 4.1| 9.3| 11.7| 27.9| 18.0| 0.0| 300.0|\n", - "| 42.2| 8.2| 1.0| 0.3| 0.2| 0.9| 8.1| 4.0| 10.4| 50.0| 100.0|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_df.show()" ] @@ -416,32 +336,11 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+--------------------+------------------+\n", - "| name| value|\n", - "+--------------------+------------------+\n", - "|Chocolate Chip Co...| 10.0|\n", - "| Spaghetti W/ Sauce|2.1551724137931036|\n", - "| Lowfat Milk|1.8311671008899093|\n", - "| Hotdog|0.9296975991385928|\n", - "| Apple,Raw,W/Skin| 0.0|\n", - "| Raisin Brn| 0.0|\n", - "| Roasted Chicken| 0.0|\n", - "| Tomato,Red,Ripe,Raw| 0.0|\n", - "| Grapes| 0.0|\n", - "+--------------------+------------------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from docplex.mp.sparktrans.transformers import CplexRangeTransformer\n", "from pyspark.ml import Pipeline\n", @@ -468,30 +367,11 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "|Roasted Chicken|Spaghetti W/ Sauce|Tomato,Red,Ripe,Raw|Apple,Raw,W/Skin|Grapes|Chocolate Chip Cookies|Lowfat Milk|Raisin Brn|Hotdog| max|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "| 277.4| 358.2| 25.8| 81.4| 15.1| 78.1| 121.2| 115.1| 242.1| 2500.0|\n", - "| 21.9| 80.2| 6.2| 9.7| 3.4| 6.2| 296.7| 12.9| 23.5| 1600.0|\n", - "| 1.8| 2.3| 0.6| 0.2| 0.1| 0.4| 0.1| 16.8| 2.3| 30.0|\n", - "| 77.4| 3055.2| 766.3| 73.1| 24.0| 101.8| 500.2| 1250.2| 0.0|50000.0|\n", - "| 0.0| 11.6| 1.4| 3.7| 0.2| 0.0| 0.0| 4.0| 0.0| 100.0|\n", - "| 0.0| 58.3| 5.7| 21.0| 4.1| 9.3| 11.7| 27.9| 18.0| 300.0|\n", - "| 42.2| 8.2| 1.0| 0.3| 0.2| 0.9| 8.1| 4.0| 10.4| 100.0|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_LP_df = food_nutrients_df.select([item for item in food_nutrients_df.columns if item not in ['min']])\n", "food_nutrients_LP_df.show()" @@ -499,33 +379,11 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-- all numbers will be cast to float\n", - "+--------------------+------------------+\n", - "| name| value|\n", - "+--------------------+------------------+\n", - "| Tomato,Red,Ripe,Raw| 10.0|\n", - "| Grapes| 10.0|\n", - "| Apple,Raw,W/Skin| 9.619047619047619|\n", - "| Roasted Chicken|2.0169262017603247|\n", - "| Spaghetti W/ Sauce| 0.0|\n", - "| Hotdog| 0.0|\n", - "| Lowfat Milk| 0.0|\n", - "|Chocolate Chip Co...| 0.0|\n", - "| Raisin Brn| 0.0|\n", - "+--------------------+------------------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from docplex.mp.sparktrans.transformers import CplexTransformer\n", "\n", @@ -541,22 +399,11 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWAAAAEKCAYAAAAsDo9wAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAIABJREFUeJzsnXl4HNWV9t8jtVq7uiX1pn2xrMWW\nLMuyZUm2bAyZkIQlJnEIBr4ESEKAQAgEmGQy4wGGTAjrEGASIMM2AQxJZoCQMATwLsnaZW3WLmuX\nWvvWknqp8/3R1Y1WW5K7W7Jdv+epR923qu691eo+devcc99DzAwJCQkJCdfjttodkJCQkLhUkQyw\nhISExCohGWAJCQmJVUIywBISEhKrhGSAJSQkJFYJyQBLSEhIrBKSAZZwKEQUTETl4tZDRJ0z3sud\n0N4WIvrKMs/5EhGNiH2qJaLHV9DuCSLavEh5HRGdIqJCIto0Y98nROS/3LYWaOOxGZ9rDRFdf751\nSqwOkgGWcCjMPMDMm5l5M4DfAXjW9p6ZjU5ocguAZRlgkcNiH7cA+CYRbXdgn77NzKkAXgHwa1sh\nM1/JzGMOauNJsf/fAPAKEbk7qF4JFyIZYAmXQUQPEVGVuN0jlsWJ718lomoiepOIriSiPCKqJ6Kt\n4nGZRJRPRGVElEtE64nIG8ABADeJo8F9RKQiog+JqEKsI/lsfWJmA4BTAMLEdvyI6HVx9FpGRNeI\n5T5E9Eex3oMAvJZwyfm2esU6OohIKV5zNRH9NxFVEtF74rWAiLYR0VEiKiGij4lIe47+1wIwAVCI\n599BREXiCPyPRORNRDIiahb3q4hIIKJs8X0+EUUv4VoknIBkgCVcAhFlALgJQAaALAB3zXg8TwDw\nFIAUAJsA7GPmbAA/B/Az8ZjTAHYycxqAfwPwGDNPAngUwFviCPtP4r4CZt4E4GEAr5+jX0EAYgGc\nEIsOAPg/Zs4AcDmAp4nIC8DdAIbEen8NIG0Jl/0VAO8vsm8DgBeZOQXAFIAfEpEngOcAfJOZ0wH8\nQbyes/V/G4AqZh4Ui/7IzNvEEXgTgFuY2QygmYgSAOwEUAIgRzT6GmY+s4RrkXACstXugMQlQw6A\nP4sjThDR+7Aag78DaGTmGrG8BsBn4jmVsBphAFACeJOI1p2jnZ0ArgIAZv67OJr1ZeaJOcftIaIK\nAIkA/o2Z9WL5lwF8lYhsht8LQCSAXQCeEOstI6Lqs/ThXSLyBUCwujgWooWZT4qv/wDgdgBHAGwE\n8BkRAYA7gI5Fzn+QiO4CEAPgH2aUbyKiR2H9vPwBfCSWHxevIQnArwDcBqBA3CRWCWkELOEq6Cz7\npme8Fma8F/DFIOGXAD5h5mQAe7G4C2BuO4u1e1gczW4C8GMiSplx/N4ZfutIZq4X9y1VOOXbsI6q\n/wjg+UWOmVsXi21XzGg7hZm/usj5TzJzPKxPFW+Ko2cAeBPAneLI+jF88Tkdh/UmuBVWo6yC1SAf\nW+I1STgByQBLuIpjAK4TfZJ+AL4Oq1FYKgoAneLrW2aUj8E60pvZzk2ANdoBQAczTxBRFhG9OrdS\n0Yf6BICHxKJPAPzYtp+IbK6GmfWmwjpStR3zFhHNGumKE47/BGAXEcUvcD0xovsAAPbD6gKpARAm\numtARHIi2ii+vpeI7lig/+/B+qRws1jkC6CHiDwA3Djj0HwAuwEYxb5VAvgBlvc/kHAwkgGWcAnM\nXAjgHQBFAE4C+C0zVy6jil8DeJKIcueUHwKQKk6Y7YPVh5stuhceBXCreFwUgMlF6v5PAFcQUSSA\nRwD4iJNj1bD6kQHgBQDBYr33ASiecf4mAD0LXLMBwLMAfrpAm9UAfiDW5wvgZWaeBrAPwDNEdApA\nGQBbdEYSgIFF+v8ogJ+S1W9xAEAhgE9hNei2vkwC6AKQJxYdB+Az8xgJ10OSHKXEpQARPQvgFZuv\n2YH1BsJ6M7lhGefEAfiTGEa21HP+CuDr4oSaxEWCZIAlJFzMSgywxMWJZIAlJCQkVgnJBywhISGx\nSkgGWEJCQmKVkAywhISExCohGWAJCQmJVUIywCuAiK4jIiaixPOo43UxbnWpxz9MsyUI96+07UXq\nLyNRXlEUb5kgoptn7C+xLTYgIg8iKhFf/0IUlqkQ+7ZdLD9DRKoF2smbWyYhcakiaUGsDNvKpRvw\nRaC+K3iWmZ8iovUASojoT8xsclDdeQCyAZQDSAVQJ77/g6hrEAurahhg1VvII6IsAFcD2MLM06LB\nPavmryiyc96Iiw4UsC4mkImbh/iXAJjFzST+NQIYZGaLI9qXkHAEkgFeJuIy2h0A9gD4EMDDRHQZ\nrKuRBmBV9joG4C5mFohoHMBL4vFDAG5g5r45daYDeAaAH4B+WBWsuhfrAzM3EJEBQCAAPRH9AFYx\nFzmARgD/D1Y9hQYA62A1VIMALmPmY0R0HMCtzNw4o9pcAF+DdVVYNqxavreI+zIAlM4wXl8B8DGA\nEAD94gouMHP/Ap+XN4D/hVWI5xUiGmdmP/Eze1i83mRYFbpsI+5gse5QACGBgYExvr6+64go0mw2\n6wD4RkVFyRQKBfz8/NjDw4PkcjlkMhk8PDwIACwWC5tMJphMJjaZTDQ1NcUDAwNu4eHhJovFYpTJ\nZHoi6piammoZGBhoFAShC0A3rKvFeiRDLeEKJAO8fPbCKldYT0SDMzQAMmCVGGwF8H+wCmX/CdZl\npqXM/FMiOgDgX2GVNgRgfZyHVbDl68zcR0TfhlV45rbFOiC22TBDwet/mPkVcd9jAL7HzM8TUb3Y\npxh8IUFYACB8jvEFrCPgx8TX2bAuyd1P1gwO2bAaaBt7xP1uAA6I7XwG4F1mPjrjOD8ABwG8ycxv\nLnApabCqj4W7ubm9EBgYWOvp6anQ6XQUERFBUVFR8piYGJ+wsDCPkJAQ2DYfH5/FPpolYTKZ0Nvb\nG93d3Z3R3d2Nrq4u4cyZM4bW1tap9vZ2oaOjA6GhocMymay0s7Pz74IgFAM4La1Ck3A0kgFePvsB\n/If4+qD4/q8ACpnZJnr9DqyP6X+CVdHrXfH4PwD4nzn1JcA6Avx0hgThYqPf+8TRbixmZ4FIFg2v\nElaj94lYbpMgjIFVgvAHAI7CqscwC2Y+I4q/6GCVaKwTj9sOqwF+Xry2UFgf5W2ykumwqmztgVWG\n8WfM/LpY7QcAnmDmt0SXQRQAd51O93xwcPBXxsbGvDIyMj7ctWuXb1lZme/XvvY13d133w1n4+Hh\ngfDwcISHh9uK3GD93PxsBWNjY5r3338/vqGh4ZtlZWXDlZWVCA0NHXZ3dy/p6en5zGw2FwOocaAL\nSOISRDLAy4CIgmEV6U4mIobVWDKAv2FhecGFmFtOAKqZOWsJXbD5gL8BURuXmadgFR3fy8yniOgW\nAJeJxx8HcAesj/IHADwo7ltMgjAfVjGYbmZmIjoJq7slA1YBHQD4Kr4w8BAf1Y8AOEJElQC+iy9E\n0AsA/CAsLGyfTqfLWr9+PZ08edLzv/7rv+6enp7Gq6++io8++kgDAHfffTf8/Oz2b9Xx9/dHQkIC\nrrvuOg8/Pz81AIyNjanLy8vXFxYWfuPYsWMjZWVlFB4e3jQwMPD61NTUB2dzG0lILIRkgJfHPlgf\np39oKyCio7COdjOIKAZWF8S3AbwsHuImnncQVnnAE5hNHQA1EWUxc77okohn5moiuhsAmPmFmScw\n8/8Q0XdhNXYvwSrH2C2eexO+kG0sgFUftpmZp4ioHMAPYZ04s2WpuJuZvyMenwur0tfr4vt8AE/C\n6hMdFsu+AuBfxPMTAAjM3CDu2wygz9fX9y43N7eQ8PDwbyiVSv/Y2Fj5n/70J7i7u8PPzw9XXXUV\njhw5cs4P+2wIggCz2WzfBEEAM9s3IoKbmxuICDKZzL7ZypaCwWCAr6+v/b2/vz9ycnKQk5Mj/+lP\nf6oGgIaGBtX//u//bn7nnXceDQkJGTEaje8NDg6+C6CSpXX+EudAMsDLYz+AuRl0/wzgTliN1eOw\nptU5BuvEEwBMANgohm2NwGqc7TCzUQxH+w0RKWD9n/wHrHKFiZjte53JowDeJqJXYDWIBbAa/0qI\n+rhiZEI7vhi9HhevwSYDGYnZEo25sMon5ovnd5M12WMeAIiv14sauoD1kf15ItISkZ+np6fv+vXr\nJ7/73e/e+Oyzz8pLSkqCg4ODcdttt+HnP/85nnjiiUUuZTZmsxnj4+MwGAz2bXJyEtPT0xAEAWJf\n5hnWmcbVZogFQYDFYrEbaovFYj9fLpfDy8sLPj4+9s3Pzw9yuRwWi2VJxnr9+vV46KGHPB966CH1\n4OCg+m9/+9vP3nrrrdvLyspMYWFhh7q6ut4EcMRJCUklLnAkMR4HIM7oP8DMVy+wb5yZV/RsTUQf\nAfiGs368RPQkgP9m5oolHr8TwM3MfAcRRapUqrvd3d1v2rJli/zmm28O/upXv0qBgYFLbp+ZMT4+\njpGREQwPD2N0dBTT09OQyWTw8/ObZRi9vb3h6ekJd3fHJP8VBAFGoxFTU1OzDP34+Dimp60JOSwW\nC9atWweFQgGFQrGsto1GI44dO4Z33313+OOPPzYx8/Gurq4nYJ0rkH50EgAkA+wQnGWA1xpE5OHm\n5naVVqv9uVqtjr3vvvsCr7/+evelRiWYzWYMDg5icHAQAwMDMJlM8PPzsxu4gIAAeHp6LtlF4Eya\nm5sxMTEBPz8/jIyMYGRkBEQEpVKJ4OBgBAUFwdvbe0l1CYKAo0eP4umnnx4oLi4eNRgML46Njb3K\nzENOvgyJNY5kgCXOCRFpVCrVfTKZ7JbrrrvO55577glISko653nMjKGhIfT19aGvrw8Wi8VuvIKC\nguDltZTM7qtDVVUVtFot1Gq1vcxsNmNoaMh+AzEajQgODoZarYZKpYJMdm6P3sDAAF577bXp//zP\n/xybmpo63t3d/fBSn0AkLj4kAyyxKES0OSQk5GFfX98dDz30kOLmm2/2ONeoz2KxQK/Xo6enB8PD\nw1AqldBoNFCpVPD09DzruWuJvLw8pKenn7XPFosFAwMD9huMl5cXdDoddDrdOW8uzIxDhw7h0Ucf\n7a+vr+/q7+9/2Gw2fygtALm0kAywxDyIKDskJOTFhISEiAMHDgRfdtllZ3ULCIIAvV6Pzs5OjI6O\nQqPRICQkBIGBgWvCnbASDh8+jD179izrnPHxcfT29qK7uxtEhPDwcISEhEAuP+vqbDQ2NuLJJ58c\n+eCDD8YnJiYeGR8ff1UyxJcGkgGWsENEG3U63W83bNiw8fnnnw/asGHDWY8fGRlBW1sb+vv7oVar\nERYWBqVSecEaXRvT09MoLi7Gjh07VlyHwWBAV1cXurq64OXlhaioKKjVari5La5/NTQ0hEceeWT0\n4MGDg0NDQ/cbjcb3pQm7ixvJAEuAiCJ1Ot1zISEhOS+++GJwVtbia0LMZjM6OzvR2toKLy8vREZG\nQqPRnNWwXGj09fWhp6cHKSkpDqlv5o1Kp9MhOjr6rBN4nZ2deOihh4Y///zzzt7e3juZWUodf5Ei\nGeBLGCJSaTSaf1coFNc9++yzQV/72tfcFhu9GgwGtLS0QK/XIzQ0FFFRUWt6Eu18aGpqgkwmQ1RU\nlEPrtVgs6OrqwpkzZ+Dl5YXY2FgEBwcvenxtbS3uvffewYqKirqenp47pMm6iw/JAF+CEJGvVqs9\nIJfLv/fYY48F3HzzzR6LjWBHR0fR0NAAg8GA2NhYhISEXFSj3YUoKytDdHQ0lhPTvFyGhobQ1NSE\nqakprFu3DjqdblHXTWFhIX70ox8NdHR0nOzp6bmHmVuc1jEJlyIZ4EsIIiI/P78b/f39n7rrrruC\nLr/8cnl29sLyvMPDw6irqwMzIy4uDsHBwRe8b3epHDt2DNnZ2UsKKztfJiYm0NjYiKGhIcTFxSEs\nLGzBz5mZ8cknn/C99947ODw8/K5er/+pqAMicQEjGeBLBCLSarXat3ft2rXl5ZdfViqVShQUFNiN\nq42RkRHU1taCmZGYmAilUrmKvXY9zIyjR4/isssuc2m7U1NTaGhowODgINavX4+QkJAFDbEgCHj2\n2Wcnn3jiiV69Xv9tZi50aUclHIpkgC9yiIh8fX33KxSKZ1966SXV1VdfbfcfjI+Po7S0FDk5OZic\nnMTp06cxPT2NxMREBAUFrWa3V43x8XHU1NQgIyNjVdqfnJxEfX09RkdHkZSUBJVqXlYnAEBDQwOu\nv/76wa6urrf1ev0DNlF8iQsLyQBfxBCRRqvVvpOTk7Pl5ZdfVi7k06ysrMT4+DiMRiMSExOh0Wgu\nGVfDQnR1dWF0dBSJiStO9+cQbDcCZsbGjRsXlOq0WCx49tlnJ5988skecTQ8T+dZYm0jGeCLFD8/\nv/1KpfLZ3/72t6prrrlmnooMM6OzsxP19fUwmUzYs2fPORcMXArU1dXB398foaGhq90VANaly9XV\n1VCpVIiPj1/QLy2Nhi9cJAN8kUFEGo1G81ZOTs7WV155ZcFR79jYGCorK+Hr64ukpCR0d3djfHwc\nGzduXIUery0KCwuxYcOGNSUOz8xoaWlBa2srEhMTERISMu8Yi8WCZ555ZvKpp56SRsMXEJIBvoiQ\ny+WXq1Sqt3/3u9+prr322nmjXkEQ0NjYiO7ubmzatMkeZsXMOH78OLZs2bKmDM9qcOTIEezevXtN\numGmp6dRVVUFZkZKSsqCOhX19fW4/vrrBzs7O1/s7+//V2kl3drm4g7ovEQgIgoODr4/KSnpj6Wl\npdqFjO/IyAhOnDgBZkZOTs6sGFciwsaNG1FdXe3Sfq81lirCvlp4enoiPT0d4eHhyMvLQ0dHx7xj\n4uPjUVRUFLR37957NRrNX8Ss1BJrFMkAX+AQkVyj0bz9pS996UBhYWGQTqebtZ+Z0djYiFOnTmHz\n5s1ISEhYcCFFcHAw3N3dodfr5+27VBgbG4O/v/9qd+Oc6HQ67Ny5E3q9HsXFxTAaZ+v1e3h44JVX\nXgl45JFHvqRWq0uJKGyVuipxDiQXxAUMEanVavXfH3jggfgHH3zQZ+7IbXJyEqWlpQgMDERiYuI5\nV7AZDAYUFhZi165da3a1my2ThclkgslkgtFohNFotKcamoubmxs8PDwgl8tn/V1oMqutrQ0mkwnr\n1q1z9mU4jK6uLtTV1SE5OXmWdrGN48eP87e//e3e7u7uvcxcsApdlDgLkgG+QCGiTVqt9m+vv/56\nyFe+8pV51rK3txc1NTVISUlZNJZ0IWpra+Hh4bGqRkgQBIyNjWFiYgLj4+OYmJjAxMQEzGazPZfb\nUgyqrS6bwZ751+Zu8PHxga+vL3x9faHX6xEWFrbgJJcr+OUvf4m3334b7u7ucHNzw0svvYTt27ef\n8zzbjdYWKTH3RtzW1oYrr7xyoL29/cmJiYn/x8zJS+0TEe0FUM/MNeL7WwD8nZm7xPe/B/CMbb9Y\n9nUAtzLzXvH9zwF8j5njxPfXAPgBM187Y38bM781ow4tgP8CEAHAA8AZZv7aUvt9oSAZ4AsQf3//\nb2k0mv/8+OOPVfHx8bP2CYKA2tpajIyMYMuWLcsWQTebzTh+/Diys7NdIqDOzDAYDBgeHsbQ0BCG\nhoZgsVjg7+8PPz8/+Pn52Q2kh4eHQ9u2WCwwGAx2A9/Y2AgvLy8wMxQKBQIDAxEYGAh/f3+nPxHk\n5+fj/vvvx5EjR+Dp6Yn+/n4YjcYlh8MxM2prazE0NLSgkPzExASuuuqq0ePHj5sFQdAsVW+YiF4H\n8BEz/0l8fwTW9FvFZzlHDaCKmbXi+w8BhAP4CjPriehXAIaZ+dfi/sMArmfmvhl1vASghpmfE99v\nuijFiGam8pa2tb0BILVa/XhOTs7g0NAQz2V6eppzc3O5traWBUGYt3+ptLe3c3l5+YrPPxdGo5E7\nOzu5tLSUDx06xCdPnuTa2lru7e1lo9HotHbPxaFDh5iZ2WKx8ODgIDc1NXFJSYm9j83NzTwxMeGU\ntv/85z/z1VdfveC+qKgofuihh3jbtm28bds2bmhoYGbmDz/8kDMyMnjz5s18xRVXcE9PD/f29vKn\nn37K+/fv57S0NL799ts5MjKS+/r6uLm5mYOCgiyenp69AE4D+DsAb7Z+t9YB+D8AJbBmz04EkA1g\nEEALgHIA/whgHECd+N4bwBEAW3n+d7UeQJz4ugTALwDsFd8fBZAjvg4AkLvA+R8C+OYC5X4APgdQ\nCmt276+L5dGwGn3bcQ8AeFh8HQfgMwCnxPPWieUPAigCUAHgkbltuWJbdaMibUv8RwHuGo3mT3fc\ncceo2WzmuYyMjPDhw4e5u7t73r7lIggCHz9+nEdGRs67LhtjY2NcX1/PJ06c4KNHj3JNTQ0PDAyc\n143CkUxNTfGJEycW3T82NsZNTU2cl5fHhw8f5srKSu7v73dY/8fGxjg1NZXXr1/Pd955Jx85csS+\nLyoqih977DFmZn7jjTf4qquuYmbmwcFBe/uvvPIK33///czM/MADD/A777zDbW1t/PHHHzMA7uvr\n45aWFnZ3d+cnn3zSpFarGwB8AGuWa4hGbb34ejuAQ+Lr1wHs4y++h7MM7lkM8OsAvgMgAcBBAFcA\neAKADMAQAC/xuG8AeHSB868EMAzgsGi8Q8VyGYAA8bUKQCMAOocBLgBwnfjaC4APgC8DeFk81w3A\nRwB2ze2Hs7dVNyzStoR/EiDTaDQf/eIXvxhb6Aff09PDhw8f5tHR0Xn7VsrQ0BDn5uael4GZnp7m\n5uZmPn78OOfl5XFraytPTk46rI+ORK/Xc0VFxZKONZlM3NPTYx/B19TU8NjY2Hn3wWw28+HDh/nA\ngQOs1Wr5tddeY2arAW5qamJm69NDUFAQMzNXVFTwP/zDP3BycjLHx8fzlVdeyczMqamp3NDQwAUF\nBVxdXc1BQUF2AxwXF8fMzJ999pnF19d3EMCvxVHlpDiqtW2nmc/LAP8AwO8A3ArgXgD+4sh3G4CT\nM457GUDW3PPFfUEAbgTw3wB6Aahh9Qe/II5ay8V+6xYzwGK7HQvU/RSAMzOutxFWP7VLf9vO19uT\nOC+ISK5Wq/92zz33ZP3zP//zvPzvLS0t6OrqQnZ2tkOXEiuVSnh7e6O7u3tZy3KZGT09PWhvb8fk\n5CTCwsKwdevWNS/ePjo6ioCAgCUdK5PJoNVqodVqYTab0dPTg6qqKphMJoSFhSEiImJF/mp3d3dc\ndtlluOyyy5CSkoI33ngDt9xyCwDMmlizvb7nnntw//3349prr8WRI0fw8MMPA7D+D9zd3bFt2zbU\n1NTg9ttvhyAIAGD3DV9xxRVu3/nOd5RvvPHGDw0Gw5uw+mQ3L7vTi5MH4B4A7gBeYeYxIvICcBmA\n3BnHZQC4c6EKmHkQwNsA3iaijwDsgtWgqgGkM7OJiM7AOqo1Y3ZYre0Lt1hQNwH4FTO/tPxLcxxr\nM9ZIAgBARJ4ajebTf/zHf8yea3yZGdXV1RgYGEBmZqZTdBySkpJQX1+/aIjXTMxmM5qbm3H06FH0\n9/cjMTERu3fvRlxc3Jo3vsDyDPBMZDIZwsPDkZmZiW3btkEQBJw4cQJVVVUwGAxLrqeurg4NDQ32\n9+Xl5bMycrz77rv2v7aUUSMjIwgLs4b4vvHGG/Zjd+7ciffeew9EhM7OTpw6dQo1NTXz/o+xsbF0\n4403KrRa7ScAuojoW4B1YQ8RpYqHjcFq9LDI+8WoARAKIAdAme2yANwBq3EGEW0EUMsLTAgS0eVE\n5CO+9ofVR90GQAFALxrfPQBsH1IvAA0RBRORJ4CrAYCZRwF0iNEcICJPsd5PANxGRH5ieRgRaZZw\nXQ5FGgGvUcSR799/8YtfZPz4xz+eZcGYGadOnYK7uzvS09OdtnLLy8sLYWFhaGpqwtxoCxuTk5No\nbm6GXq9HREQEduzY4fBoBVfgiEUYXl5eiIuLQ2xsLHp6elBaWgpPT0+sW7funPKe4+PjuOeeezA8\nPAyZTIa4uDi8/PLL9v3T09PYvn07BEHAO++8AwB4+OGH8a1vfQthYWHIzMxES4s1Uca//uu/Yv/+\n/Xj33Xexe/dulJeXIzY2FnV1dfD19Z3VblhYGD7++OOwL3/5y+79/f0/IqJ/hvUx/yCsk1YHAbxC\nRD8GsA9Wl8TviGgSwKLJA5mZiagAgIKZTWJxPoDbIRpgAF+FdeJvIdIBvEBEtpHt75m5iIhaAPyF\niIphNei1YnsmInoUVn9vi61c5P8BeEncbwLwLWb+OxElAcgXfz/jAG4G4NqVSK72eUjbuTcAMrVa\n/fdf//rX86bcLRYLFxYWnnekw1Kx+SUNBsOs8snJSS4vL+ejR49ye3s7WywWp/fFWQiCwIcPH3ZK\n3QMDA1xYWMi5ubk8ODi4ojqioqK4r69vycdPTU2xyWRiZua8vDxOTU1lZquf+/DhwwtGchQUFLBG\no2kDEMau+55/CiDEVe2txW3VOyBtc/4hgLtarf7okUceGec5mM1mPnnyJDc2Ns7d5VS6u7u5pKSE\nma2TQNXV1Xz48GHu7OxcM1EM58PY2BgXFBQ4tY3h4WHOz8/ngoKCZU+WLtcA19fX8+bNm3nTpk28\ndetWLiwstO8bHBzkw4cP8/j4vK8XHzt2TNBoNC0AtLwGfguXwiYtxFhDkFVL8uCtt976tccff3yW\nLJnFYkFxcTHUajViY2Nd2i9mRn5+Pvz8/DAwMIDY2FhERESs2eXKy8WVIuwDAwM4ffo0fH19kZiY\neNb09M5ieHgY5eXl2LZt2zyXxOeffy7s37+/pa+vbxszD7m8c5cYkgFeQ6hUqn+55pprHnj11VcD\nZvp1BUFAUVHRqhhfANDr9aisrIQgCNizZ49LklW6EleLsDMzent7UVtbi4iICMTExLj8ZmYzwhkZ\nGfDxmR1c8/7775t/+MMflur1+h3MbHZpxy4xLo4hzEWAj4/P1bGxsfe9/PLLs4wvM9vX+bva+E5P\nT6OkpAQtLS3Izs6GVqtFd3e3S/vgClYaAbFSiAg6nQ45OTkwmUw4ceIEhoZcO9hUKpVITU1FYWEh\npqZmJ1feu3ev7K677krWaDSrGqJ1KSAZ4DUAESWq1erX/va3vwXOjCBgtkY7+Pn5uVQch5nR2tqK\nvLw8hIaGYvv27fD29kZiYiKFX7ohAAAgAElEQVQaGxthNl9cg6KJiYl5j+KuwN3dHYmJiUhLS0NN\nTQ0qKythMpnOfaKDCAwMRHJyMgoLC+dJWh44cMBn+/bt3wgKCrrLZR26BJEM8CpDRIEajeaTv/71\nr6q5qmW1tbVwc3NDQkKCy/ozNTWFkydPYmRkBDt37pylDCaXyxEdHT0rXvVCZy2IsPv7+yM7OxsB\nAQHIzc3F4OCgy9pWqVRYv349ioqKZsUJWywWPPDAA0qdTvdrmUy2w2UdusSQDPAqQkQytVr9fy+9\n9FJocvJshcDW1laMjY0hJSXFZcZBr9cjPz8fsbGx2LRp04LxvFFRUdDr9ctaZLCWGRsbWxNpmIgI\nUVFR9tVr9fX1cNX8TEhICMLCwlBWVgZmxuTkJPLy8hATE4NPPvnET6vV/pmIIl3SmUsMyQCvIhqN\n5nd33nnnxr17986a1dLr9Whra8OWLVtcYnwFQUB1dTWampqQlZUFrVa76LFubm7YsGHDRZO+aHR0\nFAqFYrW7YcfX1xfZ2dkwm83Iz8/H5OSkS9qNjo6Gt7c3ysrKcPLkSWzcuBERERGIiIjAH//4R41a\nrf7UtjJNwnFIBniVCAwMvGP79u3ffPjhh2c5H8fHx1FTU4OMjAyXRBtMTk4iNzcXnp6eyMzMXNKy\nYbVaDUEQ0N/f7/T+OZvR0dE1l4bIdpNbv349Tp486bI0UQqFAj09PYiIiEBwcLC9PDs7mx5//PFo\njUbzP7RWE+ZdoEgGeBWQyWTZoaGhvzx48KBy5vfZZDKhuLgYaWlpLhFDHxoawsmTJ7FhwwbExcUt\na7SdnJyMmpoalz0mOwtXR0AsB7VajezsbNTX19uXGTsDZquYe0dHB/bs2YOurq55fujbbrtNvm/f\nvmy1Wv3vTuvIJYgUB+xiiChAq9WeLioqCo2IiLCXMzMKCwsRHh5uF1hxJp2dnWhsbMS2bdvmxYEu\nlZqaGvj4+CA6OtqxnVsEZobRaMTExAQMBoM9H5wtzZBN8csGEc3LB+ft7Q1fX194e3uDiHD48GHs\n2bPHJf1fKRaLBeXl5fDw8EBycrJDY4YtFgvKysrg5eWFjRs3gohgMBhQUFCArKysWU9EZrMZWVlZ\ng8XFxdcwc95ZqpVYIpIBdjFarfbdxx9/fO+tt946S76svr4eJpMJGzdudGr7zIy6ujoMDw8jPT39\nvIRzbDGsO3fudLgAjyAIGBkZsacpGh8fBzNDLpfD19cXPj4+8PT0nGVg5xomZp6XvHNqagrj4+OY\nnJyEIAiYnp5GbGysPf3QWhUSYmY0NDRgYGAAW7dudUg/p6amUFRUhIiIiHk30b6+PtTX1yMrK2vW\n59rS0oLMzMw2vV6fyMyucVBfxEgG2IXI5fIrd+zY8c6hQ4cCZz7u9/f3o66ubt6X3dEIgjBrJOUI\nd15bWxtGR0cxN4pjuTAzhoeHodfrodfrYbFYnJ6XTa/Xo6OjA1qtFkNDQxgeHobZbEZQUBC0Wi2C\ng4PX3Kq/rq4uNDQ0YPv27ecl8zkyMoLS0tJFsykD1hWCgiAgKSlpVvlvfvObqV/+8pf/3dvbe/uK\nOyABQDLALoOIFFqttqa0tDR05pLX6elp5OXlITMz06m6AIIgoKSkBAEBAQ6NK2ZmnDhxAps3b172\nZJYgCNDr9ejs7LRHI2i1WqjVaqfoG8+lqakJMplslu6uIAgYGBiAXq9HX18fPD09ERISgtDQUJf0\naSn09/ejqqrKvkBmuXR3d6Ourg5bt249awieTQMkLi4OGs0XUrmCICArK2uwsLDwWmbOXbQCiXMi\nGWAXodPp3nviiSf2fuc737E/O9r8vtHR0WcN/TpfbEI+wcHBiIuLc3j9g4ODqK+vR2Zm5jmPtY10\nOzo60N/fD5VKhfDwcCiVSpcvhigrK0N0dDQCAwMXPcZgMKCzsxNdXV3w9vZGREQEtFrtqgsRDQ4O\noqKiYkEth8VgZjQ2NqKvrw9bt25d0g1lamoK+fn587JknzlzBpmZmW29vb1JzHxxBIWvAu62NCYS\nzkMul39l69atDzz99NN+M41Ma2srLBaLU5cZWywWFBUVQaPROK0db29v9Pb2wt3dfdERlSAI6Ojo\nwKlTpzA+Po7Q0FBs2LABOp3OPiHmahoaGhAXF3dWY+rh4YHg4GBER0fDz88PPT09qKmpgdFohL+/\n/6q5KLy9vaFUKlFSUgKVSnVOYyoIAk6dOgWz2Yz09PQl91smk8Hb2xv19fUIDQ21/5+USiW8vLw8\nS0pKwh588MG/nPcFXaJII2AnQ0QKnU5XU1paGjpzWe/4+DiKi4uxc+dOp/2IBUFAQUEBQkNDZz1m\nO4PJyUkUFBRg165dswyayWRCS0sLOjs7odPpEBMTsyZSFDEzjh49issuu2zZ51osFnR0dKClpQWB\ngYGIjY1dtVhimy83IyNjUT2L6elpFBcXQ6fTITY2dkU3u/LycgQGBs76HjEzsrOzB4uKir5uNptP\nrPgiLmGkOGAno9Vqf//EE0+oZxpfm8jOpk2bnGZ8bSpqWq3W6cYXsI7IQkJC7PGqZrMZDQ0NOHHi\nBDw8PJCTk4OkpKQ1YXwBq2thpeF37u7uiIqKwu7du6HT6VBRUYGysrJVWZ6tUCiQlpaGoqIiTE9P\nz9s/Ojpq9+OuW7duxU8aycnJaGlpmbUyj4hw8ODBIJVK9Za0Sm5lSC4IJ+Ll5fXVrVu3/vSpp56a\n53pwc3NzmmFktibslMvli+ZycwaBgYH2x9yqqiq75GFQUNCq+0znMjAwAMAqRrNSiAh+fn52cfqK\nigqMj49DoVC41DXh5eUFHx8fVFRUICwszP5Z6/V6VFRUYMuWLbNWtq0ENzc3+Pj4oK6uDmFhYbNc\nET4+Pl7FxcXhDz744IfnfTGXGGvrV3ERQUQypVL52zfffDNopvGdnJzEmTNnnJp9oampCUajcV74\nkLMZGRmBxWJBZ2cndu7ciXXr1sHd3d2lfVgqjlwBR0TQarXYtWsXlEol8vLycObMGZeuEtRoNIiJ\niUFRUREEQUBzczMaGhqQlZXlsOvUaDTw8PBAV1fXrPI777zTU6fTXUtErpPtu0iQDLCT8Pf3//5N\nN90UPDfLQlVVFTZs2OC0EVJ7ezv6+/uxefNml01sGY1GnDp1CrW1tcjMzISHh8eaV0tzhgYEESE8\nPBw5OTkYHx9Hbm4uRkdHHdrG2QgPD4darcahQ4cwNDSEzMxMhy9pT05Oti8askFEeOGFF1Q6ne63\nDm3sEkAywE6AiLx9fX0P/Mu//MuskACbqMrMmEpHMjw8jObmZmzdutVlj/w9PT3Izc1FcHAwsrKy\n4O/vj+TkZFRVVa1pnYiJiQmnyVDKZDIkJycjOTnZfmOau0zaGRiNRvT19UEul0OhUDjl6UMul9tT\n3M8kJycH8fHxm4gow+GNXsRIBtgJBAUFPXjvvfcqlUqlvUwQBNTU1Jz3irHFMBqNKC8vX1aI0flg\nsVhQWVmJ1tZWZGdnIzw83D7iVigU8PX1XbPpi1wlwq5UKrFz504QEfLz8536VDA+Po68vDxER0dj\n586d6OnpcZpaXWRkJIaGhuaN7l944YVgrVb7kqSYtnQkA+xgiEjp4+Pzo5/85Cezlii1tLQgJCTE\nKavdbBEPiYmJLhEXHxsbQ25uLnx9fZGRkbHgY25SUhLq6upmZVlYK7hShJ2IkJCQgMTERBQUFMzz\nnzqC/v5+FBUVIS0tDSEhIXBzc0N6ejoqKyudoidMREhOTp6nCZ2SkoLs7OwoNze3Lzu80YsUyQA7\nGI1G828HDhxQzgy3MhqNaGtrc9pCiLq6OigUCuh0OqfUP5Oenh6UlJQgNTX1rDGlnp6eiIiIQGNj\no9P7tFxWQ4IyODgYO3bsQHt7u0NlPFtbW3H69GlkZWXNEpb39vZGSkoKSkpKnOL+CAwMhFwun6dV\n/PTTTweq1eoXiEiyLUtA+pAcCBGF+vn53bCQ0tm6deuc4hrQ6/UYHBx0alQF8MUy1ubmZmRnZy8p\ni0RsbCy6u7tdltVhqayWBrBcLkdGhtVFWlRUdF7JTZkZVVVV6OvrQ3Z29oLx1SqVCjqdDjU1NStu\n52wkJSXh9OnTs24mMTExuPbaazVEdJiI9ERUZdtHREFE9CkRNYh/F18DfokgGWAHotPpnnnqqaeC\nZhrayclJDAwMYKb2r6MwmUyorq52euoim4ra+Pg4MjMzlyxK4+bmhqSkJKcZgJWymiLsRIQNGzYg\nJCQEeXl5K7o5mUwmFBYWQiaTIT09/ayTbevWrcPo6Kg97tmR+Pj4QKVSob29fVb5Y489FqBUKpMA\nXD3nlJ8B+JyZ1wP4XHx/SSMZYAdBRPFqtfqKvXv3zvpM6+vrER8f7xQDWVVVhfXr1zt1dZlNS8Lf\n3x+pqanLjq7QarUwGo0uzfR7Lqanp12SceRsREREYOPGjSgoKMDExMSSzzMYDMjLy0NYWBgSExPP\n+b0iImzevBmVlZXnNeJejLi4ODQ3N89yc2g0Gtx5550+vr6+cw3w1wG8Ib5+A8Beh3foAuOiMcBE\npCWit4momYhKiCifiK5zVfshISHPPvfcc6qZPwiDwYCRkRGn+GZ7enpgMpmcmj3DbDajsLAQWq12\n2SmLZmKbsFkLYWnT09OQy+WrmobeRnBwMNLS0lBYWIixsbFzHj84OIiCggKkpKQgPDx8ye3YspY4\n40nE09MTWq123ij4Zz/7ma+3t/cdAGZ+0Fpm7gYA8a9z4jEvIC4KAyyGvbwP4BgzxzJzOoAbAITP\nOc4p8VlEFBoQEJAxV9jFWaNfo9GI06dPIzU11WmGxGQyoaCgAOHh4eedcsjf3x9KpXLej3Q1WGs5\n4BQKBdLT01FcXHzWRRvt7e2oqqpCZmYmgoKClt1OVFQUJiYm0NfXdz7dXZB169ahpaVl1ijY398f\ne/fu9QGwdj7sNcjakvtfOZcDMDLz72wFzNwK4HkiugXAVQC8APgS0bUAPgAQCMADwD8z8wdEFA3g\n/wAUAEgDUA/gO8xsIKJ0AM8A8APQD+AWZu4moh8DuMPNzU2tUCiCZxrDqakpjIyMIDU11eEXW1NT\ng/j4eKc9RlssFrtOsaNG2AkJCcjNzUVISMh5pdMxGo0YHh7GxMSEfTMajYuGu7m5ucHDwwPe3t7w\n8/PD2NgYfH19wcxrYhQMAAEBAdi2bRuKioqwbdu2WSFytoSZo6OjyM7OXvFErs0VUVBQgJycHIcu\n0pDL5VCr1ejq6po1Mv/e977n+9prr3kQEbH18aeXiELE304IANeke17DXBRylKIhjGHm+xbYdwuA\nxwBsYuZBcRTsw8yjRKQCcBLAegBRAFoA7GTmXCJ6FUANgOcAHAXwdWbuI6JvA7iSmW8joi4AiSEh\nIQ1lZWWamaLq1dXVCAgIcPjk2/DwMGpqapCVleUUA8LMKC4uhkqlQkxMjEPrPnPmDAwGAzZs2LDk\nc6ampuzZKcbGxuDh4QGFQgE/Pz/4+vrC19cXcrkc7u7uC34egiDAaDTCYDBgYmLCngXDZDLB29sb\nwcHB0Gq18Pf3X3WDPDIygrKyMmRmZsLLywtmsxllZWXw8fHBhg0bHNK/xsZGCILgcJGmqakpuxyp\nrZ9nzpxBcnKyZWJiYrf4m3oSwAAzP05EPwMQxMwPObQjFxgXywh4FkT0IoCdAIwAXgTwKTPbZoEI\nwL8T0S4AAoAwADbL2T4jxcofAPwY1lFxMoBPxS+WOwDbEq8KIjqcnp6umKnFajKZoNfrHS6GY1M5\nS0lJcZrxrayshL+/v8ONL2B9DD527BgmJiYW1a4FrJEjHR0d6O7uhru7OzQaDeLi4hAQELDs63Zz\nc4OXlxe8vLwQFBRkSyoJd3d3TE1Noa+vD3V1dRgfH4dKpUJERAQUCsWqGGOFQoHk5GQUFhYiLS0N\n5eXliIqKQmRkpMPaiI2NxbFjxxAREeHQRUFeXl5QKBTQ6/XQarXYv38/jhw5gqmpKXci+pyIfgTg\ncQDvEdH3ALQB+JbDOnCBcrEY4GoA37S9YeYfiaPbYrFo5jTzTQDUANKZ2UREZ2B1TwDA3McBhtVg\nVzNz1gLtXqVUKltDQkI809PTUV1dDZlMhvb2drtEoSPp6uqCn5+f03yYTU1NEATBoTnjZmILwaqu\nrrbHw9pgZvT29qKlpQUWiwXh4eHLCnlbCswMQRDsj/He3t6IjIxEZGSkPT9dQ0MDJiYm7OWuznih\nUqkQEhKCo0ePIjMz87zkMhfCzc0NiYmJOH36NLZs2TJv/7PPPovf//73ICKkpKTgtddeW3KUTWxs\nLGpqaqDVavHOO+/Yyzds2DB2+vTpj5l5AMAVjrqWi4GLYhIOwCEAXkR054yyxQSiFQD0ovHdA6vr\nwUYkEdkM7X4AJwDUAVDbyonIg4g2iit9rkxPT/d88cUXMTw8bE+d3tbW5tBRC2CNSKivr3fagou+\nvj709vZi06ZNTh392TLw2iaDBEHAmTNncPToUfT29iIlJQU7d+5EdHS0w5NgGgyGRUd9bm5u0Ol0\n2LZtG3bs2AFBEHD8+HFUV1cvKHTuLLq6utDV1YWoqKh5q8wchVarxfT0NIaGhmaVd3Z24je/+Q2K\ni4tRVVUFi8WCgwcPLrnegIAACIKA8fHxWeX33XefMjg4+M5FTrukuSgMsOjg3wtgNxG1EFEhrHGG\n/7jA4W8B2EpExbCOhmtn7DsN4LtEVAEgCMBvmdkIYB+AXxPRKQDlALIBuLu7u7/e0NCgSktLw333\n3QelUom+vj4olUqHG4/m5mZERkY6ZeJtcnISVVVVSE9Pd4mK2saNG1FdXY329nYcO3YMU1NTyM7O\nRmpqqlM1GmyZl8+Fh4cH4uLisHv3bgQEBCA/Px+1tbWzJBgdDTOjrq7OLm6UnJyM0dFRp2hHEJH9\nfzB3DshsNmNychJmsxkGgwFz5VTPRUxMjD0rio39+/fLZDLZbdLy5AVgZmmzfgmjAVQt43jf8PBw\nvcVi4ZkUFBTw8PAwOxKTycSHDh1is9ns0HqZmc1mMx87doz7+/sdXvdiDA8P8yeffMLHjx/nqakp\nl7VbW1vLnZ2dyz7PYrFwc3MzHzp0iNvb21kQBIf2y2w2c3FxMVdUVPDM79P09DQfPnyYx8bGHNqe\njeLiYtbr9bPK/uM//oN9fX1ZpVLxjTfeuOw6BUFY8Lt60003DQL4Eq+B3/pa2qQ70grx8fHZv3fv\nXsXU1JS9bHp6GlNTU0saZS2HlpYWREZGOkXfta6uDiEhIeedsmYpmM1mVFdXo7KyEtu2bYPJZHLp\nZNdKRdjd3NwQExODHTt2YGBgACdPnlzW6rWzYUv7HhQUhJSUlFlPIHK5HGlpaSgtLXWKoE58fDzq\n6+vt74eGhvDBBx+gpaUFXV1dmJiYwB/+8Idl1UlE0Ol086RIf/KTnwSGhYX93CEdv4iQDLAIM59h\n5iWL9SqVyh/fdNNN8vLycuTm5qK1tRWtra0ODzszm83o6OhwSv64wcFBDA0NOU2lbSajo6PIzc2F\nj48PduzYgcDAQMTFxc0T9nYm5yvCLpfLkZqaivj4eBQVFaGjo+O8+jM6OoqTJ08iPj5+0agThUIB\nrVaLhoaG82prIfz9/SGXy+06EZ999hliYmKgVqvh4eGBb3zjG8jLy1t2vZGRkWhra5tVlp6eDk9P\nz01EJC3MmIFkgFcAEQX6+/vrMjMzkZ2djS1btmB6ehr19fXQ6/Xo6elx2IiltbUV4eHhDp+Nt1gs\nqKiocEnqojNnzqCsrAxpaWmIiYmxtxceHo7h4WGXpO2xWCwgIodcq01asqenB2VlZSvSPO7p6UFp\naSnS09PPmSFl/fr10Ov1GBkZWWmXF2XmKDgyMhInT56EwWAAM+Pzzz9fUSilbaHL3AzK+/bt8yKi\nKx3W+YsAyQCvAHd3969ef/319kBWb29v6HQ6qNVqJCQkoK+vD0ePHkVFRQWGhoZsPuNlIwgC2tra\nznsp8EKcPn0aUVFRZ43HPV8EQUBFRQUGBgawc+fOeeFzZ5sMcjRjY2MOzQHn4eGB9PR0BAYGIj8/\nHzNdUWeD2Srr2dTUhOzs7CX1yc3NDampqSgvL1/0xj48PIx9+/YhMTERSUlJyM/PX1J/FAoF3Nzc\nMDw8jO3bt2Pfvn3YsmULUlJSIAgCbr/99iXVM5ewsDB0dnbOKvvWt77lFxYWduuKKrxIuShWwrma\niIiIT//yl798afPmzfay2tpa+Pv725fuCoKAvr4+tLe3Y3x8HKGhoQgPD4ePz2LRcfPp7OzE8PAw\nNm7c6ND+j46OoqKiAjt27HDa6NdsNqOoqAjBwcFYv379WdspLS1FaGioUwXl29raYDQaERcX5/C6\n+/r67LKgZ4vRtt2QAGDTpk3Ljjipra2Fh4fHgi6j7373u8jJycH3v/99+8q/mSmxzkZ/fz/a29uR\nlpa2rP6cjenpaRQWFiInJ8deJggCwsPD9d3d3WHM7HhptgsQaQS8TIjIQxCE1JkaD8yMnp4ezFyK\n7ObmBq1Wi61bt2LHjh3w9PREWVmZ3V+8lJCm1tZWh49+ma2r6TZu3OhUIZ+TJ08iIiJiSWJESUlJ\nTk9c6UwRHrVajfT0dJSWlmJ4eHjBY4xGI/Lz81cs6wlYpR/b2trmxSWPjo7i2LFj+N73vgfA6qte\nqvEFrC6VkZERh4bZeXp6QiaTzZqsdHNzw549e2QAFlrUdEkiGeDlk/PlL39ZNtOojI2NwcfHZ1E/\nrYeHB6KiorBjxw6kpaVhenoaubm5KC4uXtRfbAtmd7SLoLe3F56enggMdE4yAqPRiJMnTyI2NnbJ\nkone3t4IDQ1Fc3OzU/oEOF8Fzd/fH9u2bUN5efm8BQ5jY2PIy8vDunXrsG7duhXf+GQyGeLj41Fb\nWzurvLm5GWq1GrfeeivS0tLw/e9/f1lRGkSEiIgIh6vVhYaGzouGuPHGG4N0Ot3NDm3oAkYywMsk\nJCTkOzfccMMs69XT04OQkJAlne/j44P4+Hjs3r0bcXFxdn9xZWUlhoeH7b5QZ4x+BUFAbW3tssRw\nloNNRS0uLm7ZAfzr1q1De3v7kn2py8UVIuy2JKXl5eV2fV+9Xo+SkhJs2bLFIS6W0NBQjI+Pz5q4\nNJvNKC0txZ133omysjL4+vri8ccfX1a9NgPsSJekVqtFb2/vrLLLL78czPw1hzVygSMZ4GVARCQI\nwj/M1f3t7e2d5X5YYl1QKpVISUnB7t27oVar0djYiKNHj6K2thY9PT0O94m2t7dDq9U6JYOGIAgo\nLi5GRETEkm9GM3F3d0dCQsK80Z0jMBqNLhNh9/Hxsev71tfXo76+HllZWQ4bfRMREhMTZ4XvhYeH\nIzw8HNu3bwcA7Nu3D6WlpcuqVy6Xw8/Pz6GZS7y8vOxqdDa8vb2RmJjoSUTOERy5wJAM8PLYsGnT\nJo+ZI6np6WkQ0XktPbbpENj8xdPT07BYLMjPz1+yv/hcMDNaWloQGxt73nUtRE1NDZRK5XnFK4eE\nhGBiYmJRP+pKcbUIu00qs6mpCRkZGQ4feQcHB8NoNNpH2TqdDhEREXaj/Pnnn6/oKScqKsrhboiF\nRsE333xzkEKh2OfQhi5QJAO8DIKCgr590003zUpH0NfXZxeYcQQeHh4wm83IyMiY5y/u7e1d8URV\nZ2cn1Gq1Ux7DOzs7YTAYzltjloickr7IlQbYlklEqVQiMTHRaSF2c1exPf/887jpppuwadMmlJeX\n45/+6Z+WXWdwcDAGBwcdOhmqVqvnZeG45ppr3H19ffc7rJELGMkALwNPT899V1111az1wI42wBaL\nxS4aM9NfvG7dOuj1+gX9xeeCmdHU1OSUFW9jY2NoaGhAWlqaQx7xbWLrjhShWekS5OUyMTGBvLw8\nREVFIT4+HtHR0WDmeavC5mKxWJCWloarr56bw3JxVCoVJicn7ZNtmzdvRnFxMSoqKvD++++vaJKV\niBAcHOzQDMpKpRIjIyOzvqtarRYBAQFqInLsmv0LEMkALxEicpfJZKqZ+qzMjOHh4WWF/JwLm0Gf\nacyICIGBgQv6i+vr68+Z2ry/vx8BAQEO9/3a0tVv3rz5vNIMzSUxMRH19fXLyuIrCAKmp6cxMTGB\n8fFxTE1N2c93xQi4v78fhYWFSE1NtU9AEhE2bdqElpaWs0YlPPfcc8tecUZEiI2NxZkzZ86n2/MI\nCQmZF7lwPhCRPRXUTHbs2OEBYL4g8SXGxSLI7goSk5NnS0VMTk7C29vboRKO3d3dZ/Wj2vzFOp0O\nJpMJXV1d9gmX8PBwhIaGzjOGZ86cccoChMbGRqjVaofegABrDGlkZCSampoWFIcXBAFDQ0Po6+vD\n0NAQpqam7LnfPDw8QEQwm80wmUwwm82YmJhATU0N1Go1VCqVQ28WgDVipa2tDZmZmfP0hmUymd0t\nkJ2dPe8poaOjA3/961/xi1/8As8888yy2tXpdKirq0NiYqLDhJpUKpXdbeKoSUuba2PmTTAnJ0f5\n3nvvZQE47JBGLlAkA7xEiGjL7t27Zw2jBgcHV5ShdjEEQcDw8DBmrrA7G7b44qioKBgMBrS3tyM3\nNxd+fn6IiIiAWq2G0WjE5OSkw+N+x8fH0d3dPWulkyOJiYnBsWPHEBkZCW9vbzAzhoaG0NbWhqGh\nIQQFBUGtViMqKgpeXl6LGouJiQlUVFQgNDQUfX19aGhogFwuR2RkJHQ63XndPJkZNTU1MBgMyMrK\nWjQOPCgoCAqFYsHQwp/85Cd44oknlpSWfi62m3F3d/ey0tSfq06lUmn/jB1BUFAQmpqaZl371q1b\nSalU7gHw7w5p5AJFMsBLJDQ09Evbtm2bNYM1MDDgsKzBgDUp40rzkfn4+CAhIQHx8fEYHh5Ge3s7\nampqIJPJoFKpHDqiAaxJR5OTk50m4O7m5oakpCRUVVUhKioK9fX18PLyQlRUFFJTU5d8LaOjo1Aq\nlVCpVFCpVEhKSsLY2Hu6GH0AACAASURBVBja2tpQV1eH6OjoFUl9ms1mlJSUICAgAFu3bj1nfxIS\nEnDixAmEhYXZR+AfffQRNBoN0tPTceTIkWW1byMqKgplZWUOM8AAoNFo0NfX5zADHBAQME9wKSEh\nASaTyTnpXS4gJB/wEhEEIWNuDq2RkRGHjiwHBgbOOweYzV+8adMm7N69G9PT0xgbG8OxY8fQ0NBw\nTn/xUtDr9XB3d3e6hrCvry/6+/vR1NSEzZs3Y+vWrfP84+diIf+vv78/Nm7ciJ07d8JoNOL48ePz\nQqXOhsFgQF5eHsLCwpCUlLSk/tg0HGbG7+bm5uLDDz9EdHQ0brjhBhw6dAg337y8RWI2bRFH/F9t\nBAcHo7+/32H1ubm5QS6Xz1pkI5PJEBgY6Hmpy1NKBngJiBNwQTN9nYIggJkdKpLe39/v0CSMBoMB\nfn5+2L59O7KzsyGXy1FaWorc3Fy0tbWtKL6Y2Zo6x9EZn+e20dTUhJKSEmzatAkmk2nFS7LPNgHn\n4eGBhIQEZGZmorW1FSUlJef8TAYHB1FQUIDk5ORljzojIiIwMDBgN5a/+tWv0NHRgTNnzuDgwYO4\n/PLLly2ADlhXxzkyasTLywsmk2lFMpuLYYuGmElmZqYMgOMUgC5AJAO8NOI3bNgwa5jj6NAmm37q\nctTSzkVXV5d9Rn6uHsXk5CRyc3NRUlKyrPjivr4++0IDZ2B7tDcYDNi5cyfCwsIQFBR0zlCuxZiY\nmDhnX728vJCRkQGtVou8vLwvkkq+9RYQHQ24uQHR0Rh4/nlUVlZi+/btK3o8JyLExcWhsbFxBVey\nOI6OXACAwMBAhy6IWcgA5+TkKAMCAi5pYR7JAC8BIkrftWvXLGtr89c6CkfXB2DR5cw2f/Hu3bsR\nGxuL3t5eHD16FFVVVfNiNufS0NCA9evXO7SfNmyKYRqNBikpKfani4SEBDQ3Ny97xG4TYV+qnzo8\nPNweTzv+8svA7bcDra0AM9DaCuVDD2FHaysGBgawZ88eJCUlYePGjXjuueeW3KfQ0FAMDAzMUzS7\n7LLL8NFHHy3r+mzYwgsdqaOhUqkc6oZQKBTzDPDWrVtJoVBc7rBGLkCkSbglEBIScsX27dtnBdGO\njo46VKthYGDAoT7VqakpuLu7n3WJtM1fHBgYCEEQoNfrUV9fb8+GGx4ePiusamRkBDKZzCmZi20q\nagkJCfN0NTw8PBATE4P6+vplaSOvRIRdoVBg+/btoBtuAAyGWfvcp6aAAwcgy8/H008/jS1b/j97\nbx7fVnXn/b+PLO+OdzvxFmdx4tjxkjh24uxQKIEyQPswU5hCh9ICpaXLtCW0nbbMTFva39AOzVAg\nUNryFAgFwkBZygM0zeI4q5d4t+N4t+VF8m5JXrSc3x+yFNmW96ssoPfrpRfK1dU5R8L63HO/axZD\nQ0Ns2rSJT3/603NK/xVCsGLFClpaWhS9kC1btoyuri7FWldFRETQ3NysyFhgs+dPjoVOSUnBZDK5\nz5Z1FeDZAc8BKeWWyQ44vV6vqAlC6R3wfB169pCmnJwctm3bhre3N8XFxZw8eZKWlhbMZjNNTU3T\n9i5bDPYqaq7E105iYiI9PT0XzQNzYKEJGP6+vvhO55RraSEmJgb738OSJUtISUmZ0v1hJuzdIpRM\nUY6MjFQ0g83Pz2/KLn0x2NtBOZu61Go1oaGhvkII96cpXqF4BHgOCCHCJkc7jIyMKFpXQWlBX4xD\nz9vbmxUrVrB9+3YyMzMZHh7m+PHjDtFQUjiklJSWlhIXFzdjRTkhBKmpqVRWVs557KGhofkLcGUl\nbN/OtHENy5dP+Ke93529Etlc8Pb2JiwsbEqNhMXg6hZ/sfj4+CgqwtPtggH3VIi6CvAI8CwIIbx8\nfX0nhDpYLBa8vLwUi6uVUmK1WhWNqOjr61MkQy0wMNARX2y/zT169KjDXrxYWltbHbflsxEZGYlK\npUKr1c5p7HntgI1G+MEPYMMGOH3a9TkBAfDYY45/6vV6br/9dvbt2zdvoY+Pj1c0ckEIgb+/P8ZJ\nZpPF4Cp+dzEEBQVNuYNJTEz0BeZfv/RjgkeAZyc6Ojp6wpbPaDQqGq0wF0/9fBgdHcXb21tRQe/o\n6GDVqlWO+OKIiAhqa2s5duzYguOLR0ZGaGhoIC0tbc4Xs/Xr11NdXT2nqI0536V8+CGkpsJ//Rc4\n15+49VZITEQKgTkuDn73O7jrLsBW9ez222/nrrvu4v/8n/8zp7U7Ex4ernjlMaXjd5UW4ICAgCkX\niMTExEBgftX7P0Z4nHCzE5OQkDDhQmWvAaEUSheLUdqebLVaGRoacoypUqmIiYkhJiaGsbEx2tvb\nKSoqQqVSOQqyT5eW60xFRQUpKSnzqs0QEBBAdHQ0TU1NM9Y2nlMR9s5O+Na34OBB2+f08UFlLx5+\nzz3wwgsgBGOjo5w8eZKdO3eixnbH8pWvfIWUlBS++93vznntztgrj/X29ioW+x0SEjLnu4O5EBwc\nrGixn4CAgCnhcvHx8V7h4eEeE4SHaYlJTEycEEqg9A54aGhI0ciCBdk+Z6C/v5+wsDCXYubj48OK\nFSvYsWMHmZmZGI1G8vPzKSoqQqvVTmsvHhwcZGxsbN6dRADWrFlDc3PzhE4Lrsaf/B188MEHJCcn\ns2b1aj747Gdh7Vo4eBDp44Pmlluw2u9CbroJfv97GP+8vr6+JCQkOMToxIkTvPTSSxw+fJgNGzaw\nYcMG3n///Xl/DnvKr1KEhIQoumNdsmTJvJyesxEQEDDlTikmJoaAgIBPrAB7dsCzIISIWbly5QR1\nVLq4zcjIiKI1hQcHBxWNVpirQ8/ZXtzX10drayuVlZVER0cTHx8/YVdeU1PDunULKwWgVqtZs2YN\nNTU1ZGRkuDxnsgBbLBYeeughjj71FHGPPorq7bcBMG3cSOkXv8iGfftQ9/VBTg688QZM2sGvWLGC\n48ePOy42SjgiIyIiqK+vX/Q4dnx9fRV1mqnVakWz4fz8/FwKsBAiQbFJrjI8AjwLERERa2JjYyfc\nKYyNjSkaATEyMqJord6FxL/ORE9PDwkJc/+NCCEIDw8nPDwcq9VKV1cX58+fZ3h4mLi4OEdLncUU\ne4mLi6OpqWla883g4CDLnSIWCo8d45dWKwm33AIWC0N+fry7eTPx3/gG2/7jP1C3tEBSErz/vs3Z\nNgm1Wu1I+V0+KRJiofj4+GCxWBxOXaXGVLoBqVKFnFQq1ZQLV0xMDCaTyeOE8+AaPz+/lZObTCr9\nB660ACsdUTEyMrJgm7fdXrx582ZHycaCggJGR0dpbW2dV9F1Z4QQrF+/noqKCpe70QlmmPffJ+3z\nn+fzTU1gtSJvvJEX7r2XtwID2fHEE6irqiA6Gv72N5hhp798+fIFp0RPR3Bw8IJKUU5HUFDQvFrS\nz4aPj8+Mpp6F4Pz/y9/fHyGEcg6VqwyPAM9O/OQW66Ojo4tqwjkZKaViZR3NZrPi4qvUxcZuL/b1\n9SU7O3vO9uLpCAsLw8/Pj87OzosHDxxAJiayY/du1CtW2EwKN99MYE8PLYGBWB9/nLIHH2TA25tv\nVFWhOn0agoLgo49sdR9mwF58X8nKY0pHGvj5+Smakqz0eGq1espF19vb21tcipbVVyAeAZ4Fs9m8\ndHLKsZK3jFarVdE6ve4wZyjp0BsZGUGtVhMSEuKoR7Fy5Uo6Ojo4evQolZWV8xKk1NRU+p5+GpmY\naHOaffGLiJYWhJSg0UBhIXh50XTzzdyflMTpNWsIFIIdeXnsbm4Gb294913IzJzTfK6aTC6GJUuW\nXNEC7O/vr+gFx9501pnw8HAJKNsx4CrBI8CzoFKp/FztdpUSTZPJpGiLHKUFWOmIj8lNTO324szM\nTHbv3k14eDg1NTUcO3aMurq6WcXE73//l3X//d8Iu2nA1S46JITQr3yF8s5OvLRaVnz0EdeWlCCF\ngJdfhmuumfP6lY5cCAwMVFTglBZMpU0QarV6SlGl8aYGyhVWuYrwOOFmQaVSufXWSMndNCgvwCMj\nI4o69AYHB6eN+JgcX6zRaCgsLMTLy4v4+Pip8cUHDsA996CaxVMv+/o4p1LxPw88wO9/8AM29fYC\nIPbtg89/fl7rX7JkiaI2W1eRAYtByUgILy8v7r33XiwWC93d3bz00kuLzq50NkHs27ePBx54AH9/\nfxUwJ5ueEOIa4GEp5ZQW0kKIzcCvgaWABPKBbwGPAHop5a9dvOeklHLbDPMdHZ+vcC7rmy+eHfAs\nuNs2pbTD7EoX9LlGaPj4+LBy5Up27NhBRkYGBoOB/Px8iouLbfbiAwds5SLnECY1EhnJViH4p+Bg\nntfrbbuO73/floQxT+y2eqUy2Ly8vBTNhlMydMzf359HH32UH//4x4SHh/P0008vekzn9e3btw+j\n0Wi/A1zUbaAQYilwEPi+lDIZSAE+AGb8Y5tJfC8FHgGeHbfvgJXsq6a0AF8JJpLAwEDWrVvH7t27\nWbFiBR0dHYx+5ztTykW6wioEft3d+N52G+zdC2NjcPfd8MtfLvQj4O/vr6idVUlUKpWisbteXl5Y\nLBa2bt3qqPgmpWTv3r2kpaWRnp7Oa6+9BthqY1x33XVkZWWRnp7O2+Ox1gaDgZtvvpnMzEx+//vf\nc/ToUZ588kna29u59tpr+fvf/x4CqIUQNwghTgkhioUQB4UQQQBCiBuFEDVCiHxgurzvh4A/SSlP\nja9RSinfkFLay9qlCiGOCiEahBCOK68QQu/0/BEhRLkQolQI8f85Dy6EUAkh/iSE+Pn4v6dba5MQ\n4j/Hj5cLIWYMdvcI8CxM3gEr3dxSacG80nfUsHD7uQDCa2rI/NWv8J3BDivHHxZfX4SUtofzCYGB\njiy3heDKkXSlYBdMJcczm838/e9/59ZbbwXgzTffpKSkhNLSUg4dOsTevXvp6OjAz8+Pt956i+Li\nYo4cOcL3vvc9pJR88MEHxMbGUlpayle/+lWysrL41re+RWxsLEeOHOHWW2/VAxHAj4HrpZRZQCHw\nXSGEH/A8cAuwk+ltxWlA0QwfZR2wB9gM/LsQYsKuQghxE/BZYIuUMhN43OllNXAAqJVS/lgIEelq\nrU7nd48f3w88PNP36xHgWZgsFkpHLSgtcFf6jnpB9PfDk0/aCuZs3w4HDkx7W2JVqSj6zndof/tt\nvEwm1+f9/veLWs7AwICikQsDAwOKmSFUKpViBXmGh4f5wQ9+wEcffURvby+f/vSnAcjPz+ef//mf\n8fLyYunSpezevZuCggKklPzbv/0bGRkZXH/99Wg0Grq6ukhPT+fQoUN8//vfp6GhYcpnPXv2bABw\nHZAKnBBClAD3AInYhLNRSnlB2uIU5980z8ZfpZSjUspuQIvNTuzM9cALUkojgJSy1+m154AKKaW9\nFF7uNGu18+b4f4uAFTMtyuOEu8xc6eGPl219UtrKQj7zjC012H7LHxwM110HYWHIAwcQTg4ni68v\nZV//Oprdu2mXklir1aUAS4uFvy6w/Q/YLkrnzp2jpKRkwWNM5q9//asi37U9lnqh7Y2c+dWvfkVS\nUhJSSm6//XZeeeUVwsLCSE9Px9fX1zHHrl27MBqNvP7662RkZLBnzx6EEDQ0NHDq1Cm8vb3Zt28f\nBoOBgYEBCgsLOX/+PN/97nc5ceIEQggfwAT8TUr5z85rEEJswHZDMxuVwCbg7Wled/ZMWpiqfWKG\neU4C1woh/ltKOTJ+7pS1upjL1TwT8AjwLExODnCVTrkY3GWzUwql1zcr/f3w4ouwfz/U1Fw8npYG\nn/kMbNkC3t6MSklfSAjBL7+Mf3c3lshIjHffzcju3QQzHlSqUoGLnaXw8uIf/mGKE33OFBcXk5SU\npFh89NGjR7lmHqFwMzE2NkZBQQHbt29f9FhBQUFcuHCBgYEBli9fzm233UZ9fT3vvvsuzz33HO+/\n/z69vb1kZ2dz5swZXnvtNerq6njggQc4cuQI3/72t2lsbMTHx4fw8HD8/Pz4y1/+wqFDh3jqqadI\nT0/nnXfeITs7u6+0tDQPeEYIkSSlrBNCBADxQA2wUgixWkpZD0wnek8BZ4UQf5VSngEQQtwNHJrj\nx/0IeFQI8YqU0iiECHfaBf8B2AUcFEJ8DjgNPD15rVLK2vl+xx4BngU5SW2FEIoKsDtsdkp61ZVe\nH7iwo9t3u/v320pD2ne7S5bA9dfDnj0QG4tFSjqBVqsVExB3zTXodu8mQAhWAaVSkp2Xh3jpJXy7\nu5E+PjA6OnUXfO+9i1q/0o5JJXGHT0GlUrFx40YyMzN59dVXufvuuzl16hSZmZkIIXj88cdZtmwZ\nd911F7fccgvZ2dls2LDBUWypvLycvXv3olKpuOGGG7jzzjsBeOCBB7jpppvo6+tbAnQDXwL+LISw\np17+WEpZK4R4APirEKIbW2hZ2uR1Sim7hBB3Ar8WQkQDViCPi+aAGZFSfjC+2y4UQowB7wP/5vT6\nE0KIEOAl4C5XawXmLcBCSTH5OLJ8+fKOlpaWCYZ/JXcser2e6upqcnJyFBmvubkZi8UyY63c+VBa\nWkpCQsKiCuc4c+bMGdLS0mwF6Pv74aWXbMJbXX3xJKfdrlSr6QFapaQfmwcmXgiWjAu4WUpOS0kA\nEHnsGMufeQaczBJWIWwC7OyIe/BB25wL5OjRo+zevVsx88yV/PfU0tKCyWRi9erVioxXUVHB0qVL\nJ8SCf+ELX+j+85//fJO7Ym2vZDw74Nlx6xXKHXGgSpYkVDpRYElQEKPHjhH46qsz7naHpKRVSrqk\nJAxIEIINTLVJq4UgW0qOACkvvzxBfAFUUmKNiiLv+efJaG4m/DvfgWefhS98AXbunPf67U5YpcRX\n6dodFotlTsXw5zOeu9c3nhl3ZYaVuBmPAM+C2Wx2uwArXXNVye64isW89vfDyy+z5re/xbvW6U7N\nabc7qlajATRWK97YRDcZ8JpF7BqAlPF4X1eodDq2Hz7M2R07WH/77YQePGgzQ1RUwDxjkvv7+xWv\njaFkdxWlm8VaLBZFxzObzVMEWK/XW4ErM7DazXgEeHaMrloQKRUP7O3trWiuvdLFWAICAhbePFJK\nOHPGdrv/+uswMoI3MBYcjM9118GePVhiYmx2XSkxSUmcEGwWAt85frcGKekGdlqtCG9vW6KFC7yf\nfJJtf/wj2muvxRwYiLq+HpYuhaEhW6fjxx5z9Hubicm1LBaLwWBQtNaG0oI+NjamaCq6yWSaIsAa\njUYAHa7f8fHGI8CzoFarOzs7O5OcO0zY89mVcMQoHealtAAHBwdz/vz5+b1pYOCibbeq6uLx9evh\n5ps5k5NDkrc3XUCflCwF1jvZdedDhZSkCoH4859di6+/vy3z7fRpRHk5S9999+Jr9lje5mZbWjPM\nKsI6nW5OHZznitL9AIeHhxXtB6h0/0NXDsyBgQEJKBdYfRXhScSYBSll6+QdoNIVopQM9VLapmz/\nrLM6a+273XvugWXL4JvftIlvUBB89rPw7LMM/eIXVG/bhsHbmwvYnGnXCEGqSrUg8dVKiQqIPHEC\nXnvNFnb2yCOOTsZy+XJ4/nlbN+PSUjh5cvriO0Yj/OhHM86n1+vx8vJS9JZcaQF2RzEmJcdzZQMe\nGxszT442+qTg2QHPgtFobJjcydVecUqpVvL2XatS49nTR5Vyxtjbibtc30y73c98htEtW9B4e6OR\nEm8pSRCC3VJyFlvu6ULvAKxSUi0lmxsbYd8+28HHH4fvfQ/+678oKy0lPj6eiIgI22tCwNattsfB\ng67LVs7S7aKlpUWxdkR2lG7IqtfrFfs7AveH3On1+gn1GD5peAR4Fnp7e+s1Go0Zp+9K6eaHSguw\nvci3UqFjERERdHd3X1yflHD27EXbrj1KIigIrr8eyw030BkXR5uUjAJxMNGuKwRLrFZ0QPQC19QM\nxPT34//zn18ssOPUIt7eacIhwM4sX24zO7g6Pg0mk4muri6Sk5MXuOKpjIyM4OPjo1jquJQSk8mk\naLcWUM5M5ipNvqOjA7Va/Ym0/4JHgOdCR1NTkwFwGNaULnqt9Hj2PmNKCXBkZCQNDQ0khobaCpjv\n3w+VlRdPSE1FfuYz9Obm0qpW0wcsHbfNTmdaSBaCYimJYv4/8DEpaR4bY/cvfwk9Pba2Q88/P6HA\nTnBwMG1tba4HeOwxm83XqZqaxc+P9q99jfhpnKv19fWsXLlS0ZCsnp4e1xeIBaK0A86Vw2wxuFpf\nR0cHVqtV2UZ7VxEeAZ6djubm5gkG34CAALq6uqY7f94EBQXR39+v2HjBwcELj1yYjJSEnD/Psv/4\nD+SxYwjn3e5112HYs4eW2Fg6gVBsoWOZzC6qgUIQLCVtwHx7ktdYrWQ/9xzi/Hmbvfntt6eEk83Y\na83uaPvRj2xmh+XLUT32GPqsLAoKCsjKypogPEajkc7OTnbt2jXPlc5MV1eX4g49JSMWlO6ubTQa\nXQqwwWBoUGySqwyPAM9OR2tr6wSDYUBAgOI7ViW77YaEhFDjXEdhIQwM2DpOPPMMorISR1vS1FRM\nN91E69ataNRqvLE509ZgS4qYD6lCkC8l0TDnsLNBKQl8/32CDh0CX19bP7eYqV3N7SUjpw0XvOuu\nCREPAlsF79bWVk6ePElOTg7+/v5IKSktLSUtLU3RKnNWq5WBgQHCwpRrhdbf37/ojhXOKO0gdNXe\nqq2tzdTf39+o2CRXGR4Bnp3u7u7uCb9gf39/jHMoBj5XlBZ0b29vLBbL/B1xUkJBgc3E8NprE2y7\n+uuuo+6GGxiNi7PZdYUgB/BbTF1dIUgBSqRkM7PvmqWUtJaUkPqHP9gO/PGPkJ097fl208584mwT\nEhIIDAzk9OnTbNiwgf7+fgICAoicoV39Quju7iYiIkLRMMSenh4SExNnP3GODA4O2vu1KYLRaJxy\nwWlqajICCt2uXX14BHgWpJTWuLi4CWmSKpUKq9WqWDKGEELxyIXw8HD6+vrmljQwOHjRtltR4Tgs\nU1PR33QTDbm59Hh7MwpsBUIV3AkuE4JeKTkvJetm+S67OzpIfvxxhNVqayn0hS/MeL7dDDHfRIfw\n8HC2bNnCqVOnABSr0+BMa2srzrHli8VqtTI2NqZoyNjg4KCjoI4SDA0NkZAw0eA0bt7zOOE8zEi3\nVquNiY6+6LO3p+gq5fRQOnIhMjKS7u7u6QVYSlvL9meembLbHbvuOlpvuIGWuDhCsZkYMoAqKTEK\ngXI3uTZShOCslDRLSeI0ImwxGAj4+c9RGwy21OVf/GLWce0CvGzZ/Bvums1mhBD4+flx4cIFkpOT\nFdutjo2Nodfrr2jzgzsiKlyFMlbbijDVKzbJVYZHgOeA1Wo9UVRUlH7TTTc5jtm74yolwCEhIQwM\nDCgaOlZXVzf1hcFBh23XebdrTU2l+6abqM3NRe3tTbwQ7GSiXTcRKJOSWIWz94QQZANnx2NzJ4jw\n0aPw0kuodDoCweZ0+/OfbUkXsxAcHLwgZ+ng4CBFRUXk5OQQFBREZWUlRUVFbNy4UZEoiNbWVhIS\nEhQ1P+h0OkXNJEpnwNmTg5w/8+joKHq93iilVM7+dpXhyYSbA52dnUdOnz494Y9kRi/7AoiIiFC0\niI6Pjw9CCFtast22++Uv2xxWX/86VFQgg4LQ33orpU8/Tf4vfsHQrl1k+/iQq1IRL8QUp1qQEKiA\nfjckLXmN14DoGDdHSClt4vv006DTXSwl2d9vc7zNgaCgoHm3kNdqtRQVFZGdnc2SJUsQQpCWlkZU\nVBQnT55cdJq31WqlpaVlyq34Yunq6sL5Dm2x2G3USqHX66cknFRUVODt7V2u2CRXIZ4d8NwoysvL\nGwIcW4KQkBAuXLig2AT2HbWSTT9jg4LQ//rX+L3+OpRf/Ds3paTQftNNNOXmEunjw0ohCJ7jnGuF\noFZKNruhVZGXycTmlhY6Ghvpampi6QcfIGylCi8yMmILH5tD4RznFvKzRTBIKamrq0Or1bJt27Yp\n6caJiYkEBgZy6tQpsrKyFlxvobW1lWXLlimaXWYwGPD29lbUXNDT06NoiNzAwMAUE0lhYaGlp6fn\n74pNchXiEeC50TBZbBeyu5oJIQSBgYEYDIbFpaZKCUVF8MwzrHz1VUfcrgwKou9Tn+LCnj14x8WR\nIAS7mH8SRLgQmKVkUMo5i7bLNfb0QFMTNDZCfb3teWcnKquVWf3u8wjZW7JkCXq9fsZwqsHBQUpL\nS4mIiGDr1q3TinVkZCQ5OTkUFRWxdu1aYlyEv82E1WqlsbGRbdu2zet9s9HR0THvtcxGf3+/okV9\n+vv7p9ji8/Ly+o1G4xnFJrkK8QjwHJBSyri4OK1Op4u2O7VUKhVeXl6K5srbHWcLEuChoYu23fHd\nrgB616+n64YbGNi6lXhfXzYx/3jdyaQIQaWU5DIHAR8dtQlmY+NFsW1pmZCF5kClgqQkyMiArCzk\n//wPwlX7+XnUY7CbilwJsNFopLa2lqGhITIyMuYkOEFBQWzbto3CwkL0ej1JSUlzvog1NjYSExOj\neKpwR0cHmzdvVmw8o9GIn5+fonHPAwMDU9K4CwoKrECpYpNchXgEeI5IKU8VFxen7dmzx3EsLCyM\nvr4+xWxvkZGR1NbWzu/Wr7DQFj726qsOUbMGBtJ13XW03XADMj6eYCBXwR9TmBD4SkkXthZBgG1X\nq9PZRLap6eKutqvLdeGb0FBbMfaNG2HDBsjMtLWdd3L89AYHE/bII6ic7K5Wf3/kz37GXF1hwcHB\nE2zrUkq6u7tpaWnBYDCwdu1aR2+zueLt7c2WLVsoLy/n3LlzZGZmzuqcGx0dpaWlRfFsuqGhIdRq\ntaIV2np6ehR16FmtVsxm84QLz9jYGENDQ8P2NvCfVDwCPEc6OjoOnz59+u49e/Y4FCI8PJze3l7F\nBNhuB57VZmnf7e7fD2VljsP6lBSab7wRMb7bzRECk5SckJJkBW3LDA+zvrmZpsZGohsbUTU02Ha1\nrhxUXl62XW1mFXhvZwAAIABJREFUpk1sMzNtO9zY2Am1GyZjNpspS0tj57PPovr3f4eWFqzx8XR+\n61vUJiTgd/o0UVFRhIWFsWTJkmnvQuydfVtbW9HpdPT39xMREcGqVasIDQ1d8HeiUqnIzMykoaGB\n06dPk52dPaMIVlVVsXbtWkVrSQA0NTUpaqsFm0MvKSlJsfFcmTMqKytRq9UV07zlE4NHgOfOFEdc\neHg4TU1Nik0ghCA8PJyenh7X8bvjtl3n3a4lKIj2a69lcM8eohMSSGWiWcBbCEKkpAeY957GarXt\nYO222oYG23OtFl9gSl2wiIiLu9qNG21Cm5JiSxmeJ3V1dSQmJqK+9lpbjWFsITux4w+j0YhWq6W1\ntZWhoSHMZluujEqlQgjhqK8shMBgMDAyMsKqVasICQlRNPxr1apVBAUFOZxzrkwdnZ2dmEwmYmNj\nXYywcCwWC93d3axfv17RMYeGhhS1//b29k6JqCgsLLT09vZ+oh1w4BHg+VBfWzux67Sfnx9jY2OK\nNi6MjY2lvb39ogAPDcErr9iE12m3O5CainbPHvy3bSPGx4eEGURlhRDUS0nkTMJjNNrEtanJJrQN\nDdDaOqXJJQDe3rB2LTIjg+aICEJ37iR0925bix8FMBqNdHV1sXOGppkBAQEud372DEW7EAPk5+ez\nYsUKt9W1jY6Oxt/fn6KiIlJSUljq9D2MjY1RXV3Ntm3bFO9+otFoiImJUdRWq9VqiY6OVnSt3d3d\npKenTzjmccDZ8AjwHBlPSe7QaDTRzvnxdjuwUjaziIgIKioqkIWFiGefte12DQYAzEFBdF57LZYb\nb2RpfDxr5vgjCQWGAaOUBFit0Nk5dVc7TUNLoqMhPf2irTYjA5KTwccHASwdHub06dNsDQlBqSTY\nqqoqUlJSFiQsrt5jzzJUMq7V1Rxbt251OOdWrVoFQHFxMevWrVPURgs2W3ZjY6OizjewOfSUNGlY\nrVaXta5PnTplBUoUm+gqxSPA80Cv17/yzjvvrP/a177m+N6io6OVy0IaGkL1yits2bcP4VTNrD81\nFf2ePQRv20b8fH7Iej00NSGamtjU0IBsarLZal21U/LxgXXrHBEIZGbahHeWWhL+/v6kpaVRVFQ0\nYwjXXOnp6cFisSiaVDBjcXYF8fX1ZevWrZSWllJWVoavry/BwcGKh4iBzawRGhqqeLaa0hXa+vr6\npozX3NzM8PBwq5TSoNhEVykeAZ4Hg4OD/3vgwIGHv/a1rzlUKTIykgsXLpCSkrLwgYuLL9p2DQYC\ngLGgIPquvRb1nj2EJyQQOtNu12KB9vaJcbXNzdDb6zhlQjmamBib0G7YcHFXu3YtLLAQUFRUFP39\n/ZSXl5ORkbHg21cpJZWVlWRlZS3o/dMxY3F2hVGpVGzYsIFz587R0NDApz71KcXnkFJy4cIFsmeo\nBLcQ7BsJJc0PWq12ij/j7bffNg0MDLyk2CRXMR4BngdSyvply5aNGAwGxy2Vt7c3Xl5e88+dHxqy\n1TR45hlbw8hxBlNSGLvxRiq2bmWnry9ek38Mg4MXQ70aGmzPNRqYnDEGtiLl69bZRDYri+7YWLqi\no1k/g211oSQlJVFaWkptbe2C2/a0tLQQERGhaI80uNgh5FLR29vL0NAQ6enpjggJJT+TVqtlyZIl\nirazB9vOdO3atYqOqdVqp0RUHDhwoN9gMLyl6ERXKR4BnidSyncPHTr09dtuu81xbNmyZXPvblBc\nDPv3I195BTEeyWAKDMRw7bX433gjweNJBsvGxtA2NxPT3HzRKdbcbKuF4IqEhIu22sxM22P1alsY\n2DgRUlJ1/DjOFxClEEKQmZnJ2bNnFxQaZTKZaGhoYMeOHYquC2wXSZPJpGia93QMDAxQXl7Oli1b\n8Pf3Jzg4mMLCQtavXz+30qCzIKWkpqZG8d3v8PAwo6OjilZUMxqN+Pj4THB+Dg4O0tLSYpBSumjK\n98nDI8DzRKvVHjhw4MAdt912m8OguGzZMsrLy6cXHb0eXnkFuX8/osTmdxCAISUF1Y034r9+PaEa\njS3M7OBBaGwkWaNBuGpVHxBgC+1yDvVKT4c5hA0JIUhNTaWiooItW7Ys5OPPOn52djYFBQVYrVaH\nI2ou1NbWsmrVKrdFKihdPtQV/f39lJSUkJ2d7ZgnJCSE3NxcCgoKMBgMi3ZwNTc3ExUVpfgF1B0d\nnzs7O6ekH3/44YfSYrG8qehEVzEeAZ4/Z44fP25xTpYIDAwk5K9/Rd5xB6K11ZYq+9hjtsyuZ55x\n7Hbtey9rUBBi7VoCTSb4wx9sZoVJCGAkNhavzEy8c3Iu7mpXrpxTKcbpiIyMpLGx0RFupDReXl6O\negkWi2VOqbp6vZ6enh5SU1MVX4+d4OBgBgYG3CbAPT09lJeXs3nz5immAT8/P7Zt28a5c+fQ6/Ws\nX79+QTtxk8lEY2Oj4ncJUkra29tnDPtbCB0dHVPs+QcOHOjR6XSvKjrRVYyQbigt+HEnPj7+nTfe\neOOW3Nxc24EDB7Ded9+ElFkpBGKu321QkE2snXe1aWl0jcfDZmRkKLp+o9FIQUEBO3fuVDSG1Bmr\n1UppaSkqlYr09PQZ5zlz5gxJSUlujVJoa2vDaDQqbuMEW4WzxsZGRx+56ZBSUltbS19fH5s2bZr3\nbr+8vJyQkBC37FS1Wq2if2fDw8MUFxezfft2xzGz2UxCQkJXZ2dnrJTSqthkVzGeHfAC0Gg0Lxw8\nePCa3NxcW8vYH/1ogvgCrsVXCNsONiNjYlxtYqLLtNzooCCqq6sZHR1VNI40ICCAmJgYR6cHd2CP\nBqirq+P06dNs2rTJ5WfQarV4eXm5PURsocXZZ8Jujx0cHGTbtm2ztpMSQpCcnIxGo3E0/pyrI623\nt5fBwUHS0tKUWPoE6uvrFb/It7e3T8n8O3XqFF5eXvke8b2IpyD7wvjbW2+9NQK2H6GcqTziQw/B\n88/DmTO2yIf6enjrLXj0Ubj1VlixYtqaCEIIVq1aRUOD8l27k5KS0Gq1DAwMKD62HSEEa9asYdWq\nVZw8eRLdpMpmVquV6upqt5oe7ChdPnR4eJiTJ08ihGDz5s3z6uUXFxdHRkYGZ86cmVMRfrPZTFlZ\nGRs2bFDcidjT04OPj4+i7efBtQC//vrrgxqN5v8qOtFVjkeAF4CUUj82Ntb0wQcfcOzYMcamS8FN\nTISnnoL77oPNm2EBjpP4+HhHLQElse9QS0pKHO1i3MWyZcvIzc2ltraWqqoqR52GpqYmli5dqng4\nlSuci7MvBiklGo2G06dPk5yczLp16xYkimFhYeTm5lJZWUlra+uM59bU1DgKwitNbW2t4maZwcFB\nfHx8JtzxSCl5++23x4BPfP0HZ2YVYCHEMiHEq0KIeiFElRDifSHEWiHENUKI99y1sLmML4TYIIT4\nzALGXjv+OeqEENVCiNeFEEuFEF8SQjw1zXveF0I4YnS0Wu1/v/nmm8M7duzA99e/tkUnOBMQwHvb\ntrFu3TrS0tLIzMzkxRdfnO9SUalUPP/885SXT+3cstjC3kuWLCEuLo4ap6w7d+Hv7+/oNHH8+HE0\nGg3Nzc2KVt2aDXtx9oViMBg4c+YMWq2W7du3Lzr70f6ddHR0UFVVhSt/jE6nY3BwUPGKZ2DLUlOp\nVIoW3gFbpEZiYuKEY3l5eVgslvxPcv83V8wowMJ2aX8LOCqlXC2lTAX+DVCm6sri2QDMS4CFEH7A\nX4H9UsokKWUKsB+YMUhTSvkZKaUjCNdkMr313nvvDUkpbe1xfvc7SExECoElPp5Dd9zBb3t6OHv2\nLBUVFeTl5bn8gc0F+63q5F3wyZMnFzSeM6tXr2ZwcJCODvd3BhdCsHr1arZs2UJVVRUqlYrh4Uv3\ne7TXhJgvJpOJqqoqCgsLSUpKYuPGjYoVVVer1eTk5ABQUFDgqOoGNjNHRUUFGzdudEv88mKSZqbD\nXqFtcoTNE0880dPe3v64opN9HJDjDRBdPYBPAXnTvHYNcBR4A6gBDnAxquI64BxQDvwR8B0/ngOc\nxFYF/yywBPADXhg/9xxwrdP4740/3zz+vnPj/00GfIAWQIetqMcdQOD4fAXj597mYt1fBl6c5jN9\nCXgT+AC4ADzu9FoTtoqOK8Y/759UKlVPbm6uNBgM0k5PT48sLCyUCQkJsq6uTrri0KFDcsOGDTIt\nLU3ee++9cmRkZMbjiYmJsqysTJaVlck9e/bI3/3ud1JKKQMDAx1jPv744zI7O1ump6fLRx99VEop\npV6vl5/5zGdkRkaGXL9+vXz11Vddrmd0dFQeOXJEDg0NuXxdaQYGBuTx48elTqeT+fn5sri4+JLM\n3dHRISsrK+d8/ujoqDx//rw8fPiwbGpqkhaLxY2rk7K5uVkeO3ZMGo1GabFYHN+RO+jp6ZGnTp1S\nfNyWlhZZVVU1Za6lS5c22vXB83DSnBlfhG8Bv5nmtWuAASAe2076FLBjXFBbgbXj570I/Ou4YDYA\nOePHg7FFYXwPeGH82LpxUfWbJMDBgHr8+fXA/8qLgvmU05p+Adw9/jwUqAUCJ637CeDb03ymL42v\nMWR8Dc1AgpwqwBLYDiRHRkYO/+pXv3L8sVmtVnn48GGZmJgoXTE8PCzj4+Pl+fPnpZRSfvGLX5S/\n+c1vpj0upU2AGxoa5HPPPSdffPFFx1h2Af7www/l/fffL61Wq7RYLPLmm2+Wx44dk2+88Ya87777\nHOf39/e7XJOUUvb19cmjR49Kk8k07TlKYLVa5YkTJ2RfX5/j352dnfLEiRPy9OnTUqvVSqvV6pa5\nDQbDnERnaGhIlpWVySNHjsj6+nppNpvdsh5XdHd3y8OHD8uzZ89OewFfLFarVebl5cnBwUHFx87L\ny5NGo3HCsSeeeGIkODh4r7wCBO9KeyzWCXdWStkmbWElJePilAw0SintxXP/BOwaP94hpSwAkFIO\nSinN2ET7pfFjNeOiN9krEAIcFEJUAL8BpqtAfQPwAyFECbbduR8w36DJv0spB6SUI0AVkOjinFYp\n5Qkp5XmLxdLx4YcfOl4QQhAbG8u1117rcvDz58+zcuVKh+PjnnvuIS8vb9rjdj772c8SHBzssujP\nRx99xEcffcTGjRvJysqipqaGCxcukJ6ezqFDh/j+97/P8ePHZ7T1hYaGsmrVKoqKitzqlOvs7MTf\n39+R8iqEYOnSpWwbt5e3tbVx9OhRqqurFa/f4O/vP63JY3R0lMbGRvLz8ykvLycyMpLdu3ezatUq\nxbtYzERERAQxMTHodDr8/JQq8DmRtrY2QkNDFY986Ovrw8/Pb0IstJSS3/72t0ODg4N/UHSyjwmz\nxc5UAv84w+vO1bot4+NNZ6wS2HaOro7Pxs+AI1LKzwkhVmAT1+nmuF1KeX6GsSqB3TO87uozTcbx\nOQYGBl6qq6v7N+fzkpKSyM7Opq6uboqTSUrXduDpjtvZvn077733Ht/4xjfo6emZEDcrpeSHP/wh\nX/3qV6e8r6ioiPfff58f/vCH3HDDDTz66KPTzpGQkMDw8DBlZWXz7pM2FywWC+fPn8eRwDKJkJAQ\nNm7ciNlsprOzk6qqKoaHhwkPDyc6OpqwsLBFxUMLIRx1IVQqFQMDA+h0OrRaLQAxMTFkZ2e7Tfjm\ngkajobe3l0996lOUlJSg1+tZu3atYv8vzGYzdXV1ExIklKK+vn5K+vnhw4cZGRk5LqXsneZtn2hm\n2wEfBnyFEPfbDwghcoQQMwlYDbBCCGFXni8Cx8aPxwohcsbHWSKEUAN5wF3jx9Zi27FOFtAQQDP+\n/EtOx4ew2ZHtfAh8c9x5iBBio4v1vQJsE0Lc7PSZbhRCpLs4dzqWCyG2Alit1rju7m6js3fdy8uL\nJUuWsH//fofTZ3BwkN/97nesW7eOpqYm6urqAHjppZfYvXv3tMft/PSnPyUiIoKDBw9SWVk5QbD3\n7NnDH//4R4eHX6PRoNVqaW9vJyAggLvvvpuHH36Y4uLiWT/YmjVrUKlUnD8/0zVsYdTX1xMXFzer\nwKnVauLj49myZQs7d+4kJiaGnp4eCgsLOXLkCAUFBVRXV9PS0kJPTw9DQ0OMjo46umHYH2NjYxgM\nBvr6+mhvb6e2tpbR0VHy8vLIz8+ntbWVwMBAxzxJSUmXVXy7u7upr68nJycHPz8/Nm/ezNjYGMXF\nxY7QvcVib/qqdGdme9unyQk1P/3pT7s7Ojr+Q9HJPkbMuAOWUkohxOeAfUKIHwAj2Gyh/wrETfOe\nESHEvdhMBmpsDrFnpZRjQog7gN8KIfyxNWm4HngGeFYIUQ6YgS9JKUcnXfEfB/4khPgutouCnSNc\nNDn8EttOeR9QNi7CTcA/TFrfsBDiH8Y/0z7ABJQB357pu5hENXCPEOI54IKXl9eTL7zwwt5vfvOb\nju3ZHXfcga+vryNI39vbm+9973v4+fnxwgsv8E//9E+YzWZycnJ48MEH8fX1dXncmX379vHlL3+Z\n8vJyEhISHMdvuOEGqqur2bp1K2BLOnj55Zepq6tj7969qFQqvL292b9//6wfTAhBeno6hYWF1NfX\ns3r16nl8LdMzMjKyoHoDXl5eREVFOSqJSSnR6/UYDAYMBgMajQaTycTY2Jij4pkdtVrtqMbl7+9P\nUFAQy5Ytw8/PT7HPpRS9vb1UVFSQm5vrSFG2p3E3NTVx6tSpRe/Oh4aG6O7udkvFOVd3e3V1ddTW\n1rZLKcumeZuHy22Evtoe2OzcFZOOha9YsUI72UteXl4uW1tbpdKYTCZ55MgRqdfrFR/bjsVikWfP\nnnU4BRdLUVGR7OjoUGSsxdDd3S1LSkou9zIm0N3dLY8cOTIhmmYyWq1WHj58eEZH6kxYLBaZl5fn\ncH4qidFolEePHp3iPL3//vv71Wr15+QV8Lu9Uh+eTDgFkFL2joyM/O2dd96Z4L1as2YNdXV1iju1\n1Go1GRkZlJSU2C8AiqNSqdi0aRNDQ0PU1NQsap6+vj5GR0cnNKu8XFzq4uyzodPpHOVBZ8oIjIqK\nIicnh3PnztHZ2Tnveerq6oiKilK03q+dCxcusGbNmgl26u7ubt55550hs9n8juITfozwCPA8kVI2\nSSmnVETp7Ox85OGHH+51ttX5+voSFRXllnY44eHhhIaG0tjYqPjYdlQqFVlZWYyMjNgahS5AhKW0\ntRlaaAlGpXEuzn65aW9vp7q6mtzc3DmVyQwKCmLbtm00NDRQV1c3588wODhIZ2enWyrBDQ8P09/f\nP6Xv3U9+8pPBoaGhH0kplTFef0zxCLBCSCk1Q0NDB1988cUJ6WpJSUk0NDS4JbRr3bp1tLa2Liq9\ndjbsnS68vb05e/bsvGtStLW1ERwcTHBwsJtWOH/sxdkvF1LaylI2NzezdevWeUV2+Pj4kJubi8Fg\nmFMdD6vVSklJCRs2bHBL6dHz589P2f02Nzfz1ltv6YxG48uKT/gxwyPACqLVan/06KOP9jv/uH19\nfYmJiXHLTtXLy4uMjAzOnTunmJfcFUII1q1bR1xcHCdPnsQ43kppNuwhT+vWrXPb2haCvUvy5cBi\nsXDu3DlGRkbYsmXLgjqAqFQqMjIyCA4O5tSpU4y56nI9TnV1NTExMW65AA4ODqLX66d0vXj44Yf7\nenp6vi09ZSdnxSPACiKl7DMajft/+9vfTtherV69mpaWlhl/KAslLCyM+Ph4l8V6lCY+Pp709HRH\nQZrZuHDhgltCnhbL5RJgo9HIqVOnCAsLIyMjY1E7UntdjaSkJE6ePOnSrt3e3o5er3dbwaOqqipS\nU1Mn7H4rKio4fvx4q9lsft8tk37M8AiwwvT29v7XE0880e9cZ1etVrN69Wpqa2tneOfCWbFiBRaL\nheZm9/c5DA8PZ+vWrdTX11NZWTntLbDRaESr1U6pinUlcDkEWKPRcPbsWVJTU1m5cqVi4y5dupSs\nrCyKioomXBSHhoaora0lKyvLLbZ3nU6HWq0mPDx8wvFvfvObvV1dXV+VV4KR/SrAI8AKY4vKMT72\n2GOPTTDMJiQk0NfX5xYPvN1O29zcTP90XZMVxM/Pj9zcXHx9fTlx4oRLG3RlZSWpqalua3m0GJQu\nzj4TZrOZc+fO0dHRwfbt26cIlhIEBwezdetWamtraWhowGw2U1xczMaNG93S5NRqtTp2v86cOHGC\nmpqaCinlacUn/Zhy5f06PgYMDg4+++KLL/Y6hwsJIUhLS6O8vNwtHni1Ws2mTZsoKSlhdHR09jcs\nEiEESUlJpKWlUVRURG1trWM33N3djdVqVaQNuztQqjj7bHR1dZGfn094ePiCesDNB19fX7Zu3Upf\nXx9Hjhxh5cqVitf5tdPQ0MCyZcsmhM1JKXnooYd6Ojs7H5zhrR4m4RFgNyClNPf39+/94Q9/OKHf\nT1hYGAEBAbS3t7tl3sDAQFJTUzl79uyEurLuJCwszJHddvz4cXp6eqiqqnJL7zIlWWxx9pkYHh6m\noKCA1tZWcnNzSUxMvCQheF5eXvj6+uLn5+fIEFSa4eFh2traptiV33vvPWtXV9cxKWW14pN+jPF0\nRXYTQgixdOnS6ry8vGTn+MuxsTFOnDjB9u3b3eacam1tRaPRsHnz5ktqAtDr9Zw9exaA3NzcS9Jq\naKHU1tYSEBBAfHy8YmOazWYaGxvRaDSkpKRc8sST+vp6+vv7ycrKoqOjg9raWrKzswkKClJkfCkl\nZ8+eZeXKlRMKrpvNZlJSUrrr6uqypJQz91fyMAHPDthNSCllV1fXPXfeeWev862uj48PycnJVFRU\nuG3uhIQEIiMj3Zop5wp7PGtycjIFBQVUVFRcEnPIQlDSEWe1WmlqauL48eOoVCp27tx5ycW3ra0N\nrVbr6J4RGxvLhg0bKCgooLu7W5E52tvb8fHxmdLt4uc//7lxYGDgDx7xnT8eAXYjUsozGo3mtd/8\n5jcTitDGxMRgNpsVb5PuzOrVq/Hx8aG6+tLdEZ4/f56kpCTi4uLYtWsXoaGhnDp1ylFW8kpCCQG2\nWCw0NTWRl5fHyMgIO3bsYPXq1Ze0fjCAVqulsbGRnJycCXc8oaGh5ObmUl1dvegImdHRUWpra1m/\nfmIp7vLycvbv36/R6XQ/WdQEn1A8Jgg3I4Twi46Ors7Pz1+xZs0ax/GRkRFOnTrlVlOElJLi4mKC\ngoIUrSnriqGhIUpKStixY8eEeaxWKxqNhsbGRoKCgli9erXbnEPzQUrJ0aNHpy2cPxMjIyM0NTXR\n0dFBbGwsK1asWFSd4sWg0+morKycMaPOHokREBAwJW53LkgpKSgoYPny5ROSLkwmE5mZmT3V1dXX\nSindH4j+McSzA3YzUsoRrVZ7xx133NHjbIrw8/MjOTmZ0tJSt5kJhBBkZWVhMBiorq52qzliunoP\nKpWKhIQEdu7cyfLly6mpqSE/P5+mpia3JKbMFSEEarV6zo4qq9VKZ2cnBQUFnDlzhoCAAHbt2kVy\ncvJlE9+uri6qqqocIYHToVaryc7OxsvLa0Hp5C0tLfj4+EzJePvZz35m0Ol0z3nEd+F4dsCXiOjo\n6KceeeSRLz/88MMTqq6cO3eOiIgIli+fb+ekuSOlpKysDJVKRVpamuI74a6uLtra2ti0adOczh8e\nHkaj0aDRaPD39yc+Pp6oqCi3hmm5orS0lPj4+ClFxO1YrVb6+vrQaDT09PQQGRlJQkICISEhl72w\nUEdHBxcuXGDLli3zugC0tbU5ir7PxUlqMBgoKChgx44dqNUXy4eXlZXx6U9/+rxWq02TttZiHhaA\nR4AvEeOmiKr8/PyVzqYIk8nEiRMn2LRpk+I9upyRUlJRUYHVaiUjI0MxAbFareTl5bFly5Y5VfSa\nzMDAABqNxpFZFR0dzdKlS1myZInbRc5en8M5M214eBidTkdXVxd6vZ6wsDBiYmKIioq6YpJKNBoN\nDQ0NE4q3z4fe3l5KS0vJzMycMTHEYrFw4sQJ0tPTCQsLcxw3mUxkZGT01NTUXCOldJ83+ROAR4Av\nIUKIzRs2bPh/hYWF4c6OmoGBAUpKSti+ffuEXYbSSCmpqalBr9ezceNGReaqr6/HbDaTnJy86LFG\nRkbo6upCq9Wi1+vx9fUlLCyM0NBQQkJC8Pf3V0yUpZR0dXXR3NxMeHg4/f39jjmjoqIu2UVgPkgp\naWhooLOzk82bNy/qjsFoNFJYWMjKlSsndFdxpqysjMDAwCndQ37yk58Ynn322X06ne7HC16AB8Aj\nwJec6Ojo3+7du/cre/funbBdbG5upre3lw0bNrj9R9/c3ExLSwvZ2dkL2rXaGR0d5eTJk+zatcst\nnv+RkRH6+vocKdz2SAo/Pz8CAgLw9fXF29vb0XZo8hqsVismk2lCyyKj0YjRaERKibe3N3q9ntTU\nVEJDQwkKCrqiBNcZq9VKeXm54w5Gie/bbDZTVFREcHAw69atm/DZ7SainJycCcc9pgdl8QjwJUYI\n4RsdHV19+PDhlc4hPVJKSkpKCAkJmdJZ1h10d3dTXl7Oxo0bF9wlobS0lMjISOLiXLYHdAtSSkZG\nRjAajYyNjTmEdWxsbEpqsb0Lsl2gvb29CQgIICAgwGFOOHLkCNdcc80VK7xgS94pLCwkKiqKpKQk\nRdcqpaSqqgqj0ei4KxoYGODcuXNs3759wi57eHiYjRs39pw/f363lLJSsUV8gvEI8GVACJGamJh4\nrKioKNLZAWSxWDh16hTr1q0jMjLS7eswGAwUFhayZs0aYmNj5/XegYEBKioq2LZt2xUtXrNx+vRp\nMjMzF3Un4E70ej2FhYUkJydP6TqhJPa7Int96ck+CSkln/vc5/rz8vJ+1Nvb+4zbFvIJ48rwKnzC\nkFJWabXar9x88829ziFBXl5eZGdnU15ejsFgcPs6AgMD2bZtG62trZSXl8+5qLvdoXeltBlaDEuW\nLLlsxdlno7W1lcLCQjZu3OhW8QVITEwkOTmZ48ePk5CQMMUh/NhjjxlOnjz5F4/4KotHgC8TRqPx\nnfr6+qcegYMYAAAZfklEQVS+/vWvT/j1+/n5sXHjRgoKCi5JnKy3tzebN28mMDCQEydOzKlMY0dH\nB4GBgW5p8HipuZzdMabDZDI56vtu3779kiSuSClpa2tj9erVtLW1TSgY9e6775qffPLJap1Od7/b\nF/IJw2OCuIwIIUR0dPS7//mf/3n9gw8+OCGYs7Ozk/r6enJzcy9Zaqvd9rdy5UqWL1/ucndrsVg4\nfvz4vHuZXakMDg5y4cKFOccwu5u+vj5KS0tZvXr1tNEJ7qCmpgaTyUR6ejomk4nCwkIiIiIwmUxc\nd911rV1dXRullD2XbEGfEDwCfJkRQvhHRUUVv/HGG8m7du2aoHiNjY10d3eTnZ19yW71zWYzFRUV\njI2NkZ6ePsU2Wltbi0qlclubm0uN1Wrl+PHj7N69+7Kuw2KxUFdX5yioo1QFs7nQ1NSEVqudEPFg\ntVo5ceIE//Iv/zLU1NS01eN0cw8eE8RlRko5rNPprr/zzju7JhdMWblyJcHBwZe0qplarWbDhg2s\nWLGCM2fO0NDQ4Jh7eHiY9vb2SxKlcalQqVRIKd1enH0muru7OX78OF5eXmzfvv2Siq9Go6G9vZ1N\nmzZNqeHxyCOP9Gq12n/xiK/78AjwFYCUUtPR0fHZPXv29Ex2vq1duxa1Wk1VVdUlLS0ZHR3Njh07\nGBkZIT8/n4GBAaqqqkhJSbliMsKUIigoyG3F2WdidHSU4uJi6urq2Lx5M0lJSZf0u+3q6qKhoYGc\nnJwpZq6HHnposK6u7mmDwfCXS7agTyAfr1/SVYyU8kxXV9cPbr/99n7naAR7KyOTyeT2gjqTUavV\npKamkpmZSXFxMT09PR8Lx9tkLrUjzmq10tjYyMmTJ1m2bBlbtmy55MXrtVotNTU1bNmyZUpG3bPP\nPjv6l7/8Jb+7u/vfL+miPoF4BPgKoq+v7/fFxcV/uOeeewadb4ntTTfHxsYuuQiDLVTLy8uLVatW\ncerUKYfD5uPCpRJge6RBXl4eo6Oj7Nixg9jY2EseyqfVaqmuriY3N3dKKdQ///nPpkcffbRKq9X+\no6ezsfvxCPAVhk6n2/vRRx8duP/++wed//6dRfhSmyPa2toICwsjKSmJXbt24evrS35+PvX19XOO\nHb6ScbcA2+tOHD9+nL6+PrZu3cq6desuefU3sJkdampqppSwDAoK4s033zR/+9vfPq/T6XYDdwgh\nnpppLCHEZ4UQqdO8tkII4SnUMwseAb7CkFJKnU730LvvvvvmN7/5zSFXImy1Wt1aR9gZs9lMXV2d\no9iOSqVi5cqV7Ny5E4vFQl5eHhcuXLiqd8T+/v5u6dhhL0afn5+PRqMhOzub9PT0yxa+19bWxoUL\nF1zWDzabzTz44IN1Op1uh5Ry9mBwG58FXAqwh7nhEeArkHER/vLBgwf/unfvXv1kEU5LS8Pf35+i\noiK3e+9ra2tZuXLllFtVtVrN2rVr2blzJ15eXpw4ceKSZfApzXyLs8+GyWSivr6eY8eO0d/fz6ZN\nm8jKyrqsTUobGxtpaWlxaXb46KOPrKOjo1Kn022XUg5Mfq8QIlEI8XchRNn4f5cLIbYBtwK/EkKU\nCCFWCyE2CSFKhRCngIec3u8nhHhBCFEuhDgnhLh2/HiAEOL18XFfE0KcEUJku/ebuMKQUnoeV+gD\nUEVHR7/6jW98Y9BqtcrJ1NfXy/z8fDk6OjrlNSXQ6/Xy6NGj0tXck7FarbK9vV3m5+fLM2fOyM7O\nTmmxWNyyLndQUlIie3p6FjVGf3+/LCsrk4cPH5Z1dXVybGxModUtHKvVKisrK+XZs2el2Wye8vq7\n775rjoqKqgUsQInTowV4Str+Dt8F7hl//mXgL+PP/y/wj/Li32sZsHv8+a+AivHn3wNeGH++bnxs\nP+Bh4Lnx42mAGciWbvxNXWmPy74Az2OW/0E2Ef7TfffdN+BK0Nrb2+XRo0elwWCY8tpiOXPmjNRq\ntfN+X19fn0OIysrKZF9f35xE/HLS0NAgGxsb5/0+o9Eoa2tr5dGjR+WZM2dke3v7FXPhMZvNsqCg\nQFZUVLj8/t944w1TVFRUNRAO6OXEv7svOQlwN+A9/twb6B5/7hBgIARocXp/hpMAvwV8yum14+Ov\n/wW41ul48SdNgN1X/duDIkgprUKIL7399ttPDw8P3/Xiiy8GO8eKxsTE4Ofnx5kzZ8jIyJi2vc58\n0el0AERFRc37vaGhoYSGhmK1WtFqtdTV1aHX64mJiWHp0qVXREufyQQHB6PRaOZ0rtFoRKvV0t7e\njtVqJT4+nq1bt7qtuepCGBkZobCwkLi4uAkdP+y88sorpn/913+t0el0O6WUA/P8/+HK+SCmOW5/\nbT7HPzF4BPgqQEophRAPffTRR8ZbbrnlKwcPHgx1tieGhYWRm5tLYWEh8fHxLn9w88FqtVJVVUV2\n9uLMcSqVimXLlrFs2TJMJhNdXV3U19czMDBAaGgoS5cuJSoq6ooQrpmqolmtVnp6etBqteh0Onx9\nfYmOjiYzM5PAwMBLvNLZ6evro6SkhLS0tCkXUCkl+/btG/7lL39ZrdPpdksp55KBchK4E3gJuAvI\nHz8+BCwZH7dfCDEghNghpcwfP89O3vi/Dwsh1gLLgfPj43weODIeTZG+0M98teKpBXGVERYW9tXY\n2NhffPDBB+GTi7VYLBZKSkrw8vIiPT19wUV8GhsbGRkZISUlRYklT0FKSX9/P11dXeh0OqxWKyEh\nIYSFhREWFnbZWgHZi7M7d+Lo7+/HZDIRHh5OdHQ0kZGRbm0btViam5tpamoiOzt7ysVhbGyMe++9\nd+DQoUOHtFrtXVLKUftrQgi9lDLI6d9fwmYO+IYQYgXwRyAS0AH3SilbhBDbgeeBUeAfgdDx84zA\nh9jME2lCCD/gWWATNjvvd6WUR4QQgcCfgLXAOWx24DullBeU/2auTDwCfBWiVqu3LV269M3XX389\nevv27ROUSkpJU1MTra2tZGVlzbuuwNjYGCdOnGDnzp2XTGgsFgsDAwMT2g/5+PgQFBREYGCg4xEQ\nEKDYmqxWK8PDwxgMBsejtbUVHx8fAgICHBeD0NDQq6Lqm9lspqysDICMjIwp35NWq+Wmm27qbW5u\nfrynp+dxeQX88IUQXthsyyNCiNXA34G1Ukr312G9QvAI8FWKECIhOjr6b4899tiK++67b4pC9Pf3\nU1JSQlJSEvHx8XMet7y8nNDQ0EtaCtEVY2Nj6PX6CQJpMBgcYXdqtXpCu6HphNlqtU5oW+QcahYQ\nEDBB4DUajcNkcjUxODjIuXPnWLFiBYmJiVNeLykp4dZbb9Vqtdp/GRkZ+fAyLNElQoglwBFsjj0B\nfF9K+f8u76ouLR4BvooRQgRER0e/efvtt2998skngyeLkMlkmrArmi3zamhoiJKSEnbs2HHFOcmc\nkVJisVgcojo2NobZ7Lo/pJeX15S+cNN9ttbWVkZGRlizZo07l68YUtq6JLe1/f/t3XtwU3d2B/Dv\nsWXLkh+yZXmFsDC2mxgSjEOgKSFjQrxM2t0tTIZQJg8YymamoWQDOwwmzZAJzZQ2S9LZJYFs251M\nCpuwxCWBbAqbSdM2BuIxJBDMYw3GLzBYWJb1sizrSrak0z/ulWuM8AMwkuXfZ+YO1/elnxjN0U+/\n+7vntOPhhx9GVlbWTcfs37+/f/369e02m+0vJtNP+4lCBOAJjojIYDD844wZM9YdOnQoJycn56Zj\nIk9ARbspE8HMOHHiBGbMmAG9Xj/ezY5L3d3daG5ujpvk7MORJAl1dXXQ6XSYOXNm1IrQW7Zs8e7e\nvfuszWb7S47ygIUQe/F7N0EYFWUs77X09PTv582b95svvvjCMHPmzBuOMZvNyM3NxdmzZ2GxWDBr\n1qybesOdnZ1Qq9WTNvgC8kyIWKSlHIvIGH9bWxtKS0ujFm/1er1Yvny5+8yZM/tsNtsGZp74CTsS\nlHgUOUH09vYevHz5csWiRYvadu3a5R/6iLJGo8H8+fORm5uLmpoadHR0RCa/IxwOo6GhYdxmPUwU\n8ZCcfTg9PT2ora2Fz+dDeXl51OBbU1PDs2fPtn/77bcbOzs7fyaCb3wTQxAJRhkXfreoqOjpqqoq\nfWFh4U3HBAIB1NfXD5Qd6ujoQDgcRklJyb1vcJw5deoUSkpKoo6nxkowGMSlS5fgdDpRWlqKaMNM\nPp8PlZWVngMHDjTbbLblzHzl3rdUGCsRgBMUEZUbjcbfvf7668aXXnpJHe3Gk8PhwPnz5+H3+1FR\nUTEhpluNt8bGRmi12jHNHBkvzAyLxYKmpiYUFRVh+vTpUW8g1tbWYuXKlfbu7u5/crlcO5k5Prvw\nwk1EAE5gkd5wcXHx01VVVfpoU5Tq6upARHC5XAPVkBOt5NBYWK1WOJ1OPPhgbLMs2u12XLx4ETqd\nDjNmzIj65ShJEiorK3s+/fTTJiWB+uUYNFW4AyIATwIqlarcYDDs27p16w/WrVs30Bt2u924cOEC\nFixYgGAwiKamJnR1deH++++HyWSK66lo48Xn8+H8+fOYP39+TF6/u7sbDQ0NAIBZs2bd8kGa2tpa\nrFq1yu52u990uVzvil7vxCQC8CSh9IbfKy4ufqqqqkpfUFCA2tpalJaWQqfTDRwnSRKamprgcrlQ\nUlKCKVOmTKpAzMw4cuQIKioq7unrejweNDQ0IBQKDTsVUJIkbN68ueeTTz5pVnq9rfe0ocJdJaah\nTRLM7APwgkqlWjh//vzfLlmyxLh69Wrt4OALyLMlysrKIEkSGhsb0djYiOLiYuTn50+KoYnBydnv\nRckgh8OB5ubmgZugt8pmFwwG8cEHH/Rt27bNLUnS206nc4fo9U58ogc8CRFRcmZm5pr09PRt69at\n01VWVmpvVa3B7/ejtbUVnZ2dmDZtGgoKCuIie9l4Onv2LKZNmzZuc6LD4TCsVitaW1uRlpaG++67\n75bVppkZBw4cCL3yyisur9e7r6ura6t4qCJxiAA8iRGROicnZ6NGo9m4ZcuW7BdffDH1Vr2+/v5+\nXLt2DVevXkV2djaKioowtPecKFpbW5GUlIRoU/juhN/vx9WrV2GxWJCXl4eioqJh01lWV1dj/fr1\nDrvd/lVnZ+cmZu64qw0SYk4EYAFElJWXl/f3Wq129VtvvZWzYsWK5FsNNzAzurq6cPnyZQQCAUyb\nNg1mszkmFX7Hi8PhgMViQVlZ2R1fK5KUvq2tDYFAAAUFBTCbzcNmdaurq8PLL7/saG1trbNarS+J\nHA6JSwRgYQARGadMmfLPOTk5P3nnnXf0Tz75JA13A87v96O9vR0WiwVarRb5+fkwGo23nYc4XvT1\n9eG7775DeXn5bZ3PzHC5XGhvb4fD4YDBYEBBQcGIvxhaWlqwceNG18mTJ1utVutaZv7+thogTBgi\nAAs3IaJik8n0blZW1qOvvvpq9nPPPaca7iENZobH44HFYkFnZycyMzMxZcoUGI3GCdszjiRnH+0M\nkEjVDKvVCrvdDp1OB7PZDIPBMOzNS2bGsWPHsG3bNkd9fX2nzWb7eSgU+p+79T6E+CYCsHBLRGTK\ny8urVKlUq9asWZO+YcOG9JFy5UaCcUdHB2w2G1QqFfLy8pCXlxeXteBu5fjx45gzZw40Gs0tj5Ek\naaBMUU9PD/R6PUwmE3Jzc0f8FeD3+7Fv377g9u3b3V6v90RHR8cbosc7+YgALIyIiNI0Gs1KnU73\n6kMPPZS9adMmw+LFi0c1LU2SJHR1daGrqwvd3d3IzMyEXq+HXq+HTqeL26lt9fX1MBgMMBqNAOQv\nlt7eXjidTjidTrjdbqjV6oEvl6ysrFF9uTQ0NGDnzp2ezz77TAoGgx/a7fZfMbN1vN+PEJ9EAI6B\nofW37vBaagB/gFyv6xfM/B+3OG4NgK+Y+XqUfXsgF0c0MnOPsu1dABsA5DGznYhqmfkxIlqSlJS0\nd+rUqX1z587V6fX61N27d4+qrcwMr9cLp9MJh8MBj8eD5ORk6HQ66HQ6ZGVlITMzM+Y118LhMFpa\nWuDxeKDRaNDd3Q2/3w+tVovc3NyBL4/RjnX7fD7s378/tGPHDqfdbm+1Wq3bw+HwH5i5f+SzhUQm\nAnAM3OUA/CiAt5h50QjHHQFQycynouzbA2AugLeZeS8RJQE4A0APYA4z2wcdWwjgMIBHVSrVrpSU\nlKeKi4uDzz//fMayZcs0M2fOHNMwQ39/PzweD9xuNzweD7xeL4LBINRqNdLT06HRaKDVaqHRaKBW\nq6FWq6FSqe5oKCMUCiEQCCAQCMDv98Pn8w0skiSBiJCSkoJAIIAHHngA2dnZSEtLG9Nr2Gw2HD58\nOLR3717nhQsX+kKh0D673b6Lma/ddsOFhCMCcAxEC8BENB1yRdk8KJVnAVgANAH4EwA6AE4ATzDz\nMSL6BsAmAPuUcy4DWA65/PdSABrI5cTXKtv3KNeTACxgZmnQa++BXCb8MWZeSkQ/BLACwI8hV8a1\nR9ocCcBKtds1AP4UwD8kJydvIaIXjEZjYOnSpSnPPPOMrry8/LZ6s8yMvr4+9Pb2QpKkgcAYCARu\nqusGyPXhkpKSQEQDQxqRvL7MjGAwiMGf8+TkZKSmpkKtViMtLQ1arXZg0Wg0ICKEQiHU1NRg0aJh\nv9duaPPFixdx8OBBqaqqyut0Ou2SJFW53e79AC7FQxFMIQ4xs1ju8QLAG2XbIQB/ray/AOD3yvqX\nAGYBWALgJIDXAKgBXFb2PwE5IEauox+0/hGApcr6EcjBNFp79kAuK34CQA7kUuOLAFwBYBjcZgCF\nAP6orK8B8B6AZQC+Uc5NA/Cj/Pz8j41GY8eSJUu6Pv7447Db7ebxEA6Hua+vjwOBAEuSxD6fj3t7\ne1mSJPb7/dzX18ehUOi2rl1dXT3suX19ffz111/z2rVr3Waz2WY2m4+mpqb+FPKwTcw/Z2KJ/0Xk\ngogfCwA8rax/BOBtZf0bAI8DKALwCwB/A+Ao5GAcTQURvQJAC3kIoR5ycB+NgwCeBTAfcs95NCog\n94L/nJk9yrYvAXxJRHT48OE5x48ffzY1NfXp9PR03bx582jhwoXZjzzyiKqsrGzMP+2HigwXjIeM\njAx4vV5kZWUhHA6jqakJp06d4pqamu7a2to+m80WTEpKOnr9+vUPARxhZv+4NERIWCIAx6/IT9Zv\nAPwtgKkAtgLYDLnXe2zoCUSUBuBfIPd0rxHRG5B7pKNVBeA0gN8yc3iU46ytAIoBlAC4YXyZmRlA\nnbL8HRGlNTc3l33++ed/ZjAYFgeDwTnp6enpc+fOpccff3wgKA839eteCIVCaGxsRHV1Ne/atct3\n+vRpn91u71epVE09PT3V3d3dtQBOM7Mjpg0VJjwRgONHLeTe50eQx3FrlO3fAvgQQCsz+4noDOTe\n6ZIo14gEWzsRZUAeVvhU2dYDIHO4BjDzVSJ6DcBYHgRoA1AJ4DMiWsHM9cNc3w/gO2V5D5C/NFpa\nWmYfOnRoICinpKRk5OTksNlspunTp6cUFhZqzWZzqslkgslkwtSpU5GZmXlbN+L8fj+sViuuX7+O\njo4OWCyWUFtbW++VK1f62tvbw11dXSRJUn9KSsolr9d71OVy1UAOtq4xv5ggjEAE4NjQElH7oL9/\nBXnK178T0Wb8/004MHOAiK5BHp8F5B7xcwDOD70oM7uJ6H1l3xXcOEyxB8C/EdFNN+GGXOM3Y30z\nzHyJiFYC+ISIljJzyxjO9SvtPAng1wBARHTt2rWsc+fOTQVgAmDS6XSFGRkZ9yUlJRWEQiETM2eq\nVKrU5ORkIiJSqVSsUqmQkpLCRIT+/n4KBoMIhUIUCoUQDoc5GAz2M7NPpVJ1AmiXJKnF4XC0sJzk\nJrJ0sUjzKNwjYhaEMOEp0+aSIXcoVJCrffcDCAIIioAqxCsRgAVBEGIkPp8DFQRBmAREABYEQYgR\nEYAFQRBiRARgQRCEGBEBWBAEIUZEABYSAhGFiOgMEf2RiA4RUfQywzeeUzvC/i9Gc51Bx79BRBal\nHQ1E9K/KFDlBiEp8OIREITHzHGYuhZw17mcjncDMj42w/yfM7B5jO3Yw8xwADwKYDTmp0Q2ISDwA\nJQAQAVhITMcB5AMAEWUQ0f8S0WkiOk9ET0UOIiKv8q+JiI4N6kEvVLZfISIDERUS0UUiep+I6ono\nKyIaKWFFKuRHw13KtY4Q0ZtEdBTAz4loDxHtJKJaImolor8ah/8HIc6JACwkFCJKBrAYwH8qm/wA\nljHzXMiZ234ZpdTz8wD+S+m5PgQ5Gf1Q9wP4NTPPAuCGnGM5mo1Kvo4OAI3MPPha2cy8iJl/qfxt\nAlAOOa/H9rG8TyExiAAsJAqNEvgckNNw/reynQC8SUTnICcZygdgHHLuSQA/VbLHzWalLNMQlwcF\n0+8h50WOJjIE8QMA6UT07KB9Q8tF/Z6Zw8x8IUqbhElABGAhUUhK4JsO+ed/ZAx4JeSKIfOU/Z0Y\nkqKTmY9BzrlsAfAREa2Ocv3AoPUQRkhkxXK9ty+V60b0DnPNiVEuWrirRAAWEgozd0POLFdJRCmQ\nSznZmLmfiCogB+gbKOWgbMz8PoAPINfHuyPKMMdjAEadGU6YfMTdWCHhMHMdEZ2FnF/5dwAOEdEp\nyGO7DVFOeQLAZiLqB+AFEK0HPFobiWgVgBQA5yAnyBeEqEQ2NEEQhBgRQxCCIAgxIgKwIAhCjIgA\nLAiCECMiAAuCIMSICMCCIAgxIgKwIAhCjIgALAiCECMiAAuCIMTI/wE8PeiKIv+4fwAAAABJRU5E\nrkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", @@ -580,22 +427,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\nB9UldBQ6CUwPAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "diet_max_cost = diet_max_cost_df.toPandas()\n", "plot_radar_chart(labels=diet_max_cost['name'], stats=diet_max_cost['value'], color='r')" diff --git a/examples/mp/jupyter/sparktrans/SparkML_transformers_pipeline.ipynb b/examples/mp/jupyter/sparktrans/SparkML_transformers_pipeline.ipynb index dc5df80..f027164 100644 --- a/examples/mp/jupyter/sparktrans/SparkML_transformers_pipeline.ipynb +++ b/examples/mp/jupyter/sparktrans/SparkML_transformers_pipeline.ipynb @@ -2,24 +2,11 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from IPython.core.display import display, HTML\n", "display(HTML(\"\"))" @@ -70,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": true }, @@ -101,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": true }, @@ -146,20 +133,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "#foods=9\n", - "#nutrients=7\n" - ] - } - ], + "outputs": [], "source": [ "nb_foods = len(FOODS)\n", "nb_nutrients = len(NUTRIENTS)\n", @@ -178,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, @@ -222,19 +200,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The food-nutrient matrix has shape: (9L, 7L)\n" - ] - } - ], + "outputs": [], "source": [ "mat_fn = np.matrix([FOOD_NUTRIENTS[f][1:] for f in range(nb_foods)])\n", "print('The food-nutrient matrix has shape: {0}'.format(mat_fn.shape))" @@ -250,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": true }, @@ -272,7 +242,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": true }, @@ -285,22 +255,11 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(7L, 11L)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mat_nf.shape" ] @@ -318,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": true }, @@ -342,61 +301,22 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "root\n", - " |-- Roasted Chicken: double (nullable = true)\n", - " |-- Spaghetti W/ Sauce: double (nullable = true)\n", - " |-- Tomato,Red,Ripe,Raw: double (nullable = true)\n", - " |-- Apple,Raw,W/Skin: double (nullable = true)\n", - " |-- Grapes: double (nullable = true)\n", - " |-- Chocolate Chip Cookies: double (nullable = true)\n", - " |-- Lowfat Milk: double (nullable = true)\n", - " |-- Raisin Brn: double (nullable = true)\n", - " |-- Hotdog: double (nullable = true)\n", - " |-- min: double (nullable = true)\n", - " |-- max: double (nullable = true)\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_df.printSchema()" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "|Roasted Chicken|Spaghetti W/ Sauce|Tomato,Red,Ripe,Raw|Apple,Raw,W/Skin|Grapes|Chocolate Chip Cookies|Lowfat Milk|Raisin Brn|Hotdog| min| max|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "| 277.4| 358.2| 25.8| 81.4| 15.1| 78.1| 121.2| 115.1| 242.1|2000.0| 2500.0|\n", - "| 21.9| 80.2| 6.2| 9.7| 3.4| 6.2| 296.7| 12.9| 23.5| 800.0| 1600.0|\n", - "| 1.8| 2.3| 0.6| 0.2| 0.1| 0.4| 0.1| 16.8| 2.3| 10.0| 30.0|\n", - "| NaN| 3055.2| 766.3| 73.1| 24.0| 101.8| 500.2| 1250.2| 0.0|5000.0|50000.0|\n", - "| 0.0| 11.6| 1.4| 3.7| 0.2| 0.0| 0.0| 4.0| 0.0| 25.0| 100.0|\n", - "| 0.0| 58.3| 5.7| 21.0| 4.1| 9.3| 11.7| 27.9| 18.0| 0.0| 300.0|\n", - "| 42.2| 8.2| 1.0| 0.3| 0.2| 0.9| 8.1| 4.0| 10.4| 50.0| 100.0|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_df.show()" ] @@ -429,32 +349,11 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+--------------------+------------------+\n", - "| name| value|\n", - "+--------------------+------------------+\n", - "|Chocolate Chip Co...| 10.0|\n", - "| Spaghetti W/ Sauce|2.1551724137931036|\n", - "| Lowfat Milk|1.8311671008899093|\n", - "| Hotdog|0.9296975991385928|\n", - "| Raisin Brn| 0.0|\n", - "| Tomato,Red,Ripe,Raw| 0.0|\n", - "| Apple,Raw,W/Skin| 0.0|\n", - "| Grapes| 0.0|\n", - "| Roasted Chicken| 0.0|\n", - "+--------------------+------------------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from docplex.mp.sparktrans.transformers import CplexRangeTransformer\n", "from pyspark.ml.feature import Imputer\n", @@ -489,30 +388,11 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+-----------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "| Roasted Chicken|Spaghetti W/ Sauce|Tomato,Red,Ripe,Raw|Apple,Raw,W/Skin|Grapes|Chocolate Chip Cookies|Lowfat Milk|Raisin Brn|Hotdog| min| max|\n", - "+-----------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "| 277.4| 358.2| 25.8| 81.4| 15.1| 78.1| 121.2| 115.1| 242.1|2000.0| 2500.0|\n", - "| 21.9| 80.2| 6.2| 9.7| 3.4| 6.2| 296.7| 12.9| 23.5| 800.0| 1600.0|\n", - "| 1.8| 2.3| 0.6| 0.2| 0.1| 0.4| 0.1| 16.8| 2.3| 10.0| 30.0|\n", - "|57.21666666666666| 3055.2| 766.3| 73.1| 24.0| 101.8| 500.2| 1250.2| 0.0|5000.0|50000.0|\n", - "| 0.0| 11.6| 1.4| 3.7| 0.2| 0.0| 0.0| 4.0| 0.0| 25.0| 100.0|\n", - "| 0.0| 58.3| 5.7| 21.0| 4.1| 9.3| 11.7| 27.9| 18.0| 0.0| 300.0|\n", - "| 42.2| 8.2| 1.0| 0.3| 0.2| 0.9| 8.1| 4.0| 10.4| 50.0| 100.0|\n", - "+-----------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+------+-------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "data_cleansing.fit(food_nutrients_df).transform(food_nutrients_df).show()" ] @@ -530,30 +410,11 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "|Roasted Chicken|Spaghetti W/ Sauce|Tomato,Red,Ripe,Raw|Apple,Raw,W/Skin|Grapes|Chocolate Chip Cookies|Lowfat Milk|Raisin Brn|Hotdog| max|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "| 277.4| 358.2| 25.8| 81.4| 15.1| 78.1| 121.2| 115.1| 242.1| 2500.0|\n", - "| 21.9| 80.2| 6.2| 9.7| 3.4| 6.2| 296.7| 12.9| 23.5| 1600.0|\n", - "| 1.8| 2.3| 0.6| 0.2| 0.1| 0.4| 0.1| 16.8| 2.3| 30.0|\n", - "| NaN| 3055.2| 766.3| 73.1| 24.0| 101.8| 500.2| 1250.2| 0.0|50000.0|\n", - "| 0.0| 11.6| 1.4| 3.7| 0.2| 0.0| 0.0| 4.0| 0.0| 100.0|\n", - "| 0.0| 58.3| 5.7| 21.0| 4.1| 9.3| 11.7| 27.9| 18.0| 300.0|\n", - "| 42.2| 8.2| 1.0| 0.3| 0.2| 0.9| 8.1| 4.0| 10.4| 100.0|\n", - "+---------------+------------------+-------------------+----------------+------+----------------------+-----------+----------+------+-------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "food_nutrients_LP_df = food_nutrients_df.select([item for item in food_nutrients_df.columns if item not in ['min']])\n", "food_nutrients_LP_df.show()" @@ -561,33 +422,11 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-- all numbers will be cast to float\n", - "+--------------------+------------------+\n", - "| name| value|\n", - "+--------------------+------------------+\n", - "| Tomato,Red,Ripe,Raw| 10.0|\n", - "| Grapes| 10.0|\n", - "| Apple,Raw,W/Skin| 9.619047619047619|\n", - "| Roasted Chicken|2.0169262017603247|\n", - "| Raisin Brn| 0.0|\n", - "| Lowfat Milk| 0.0|\n", - "| Hotdog| 0.0|\n", - "| Spaghetti W/ Sauce| 0.0|\n", - "|Chocolate Chip Co...| 0.0|\n", - "+--------------------+------------------+\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from docplex.mp.sparktrans.transformers import CplexTransformer\n", "\n", @@ -612,22 +451,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\nrkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", @@ -651,22 +479,11 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\nB9UldBQ6CUwPAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "diet_max_cost = diet_max_cost_df.toPandas()\n", "plot_radar_chart(labels=diet_max_cost['name'], stats=diet_max_cost['value'], color='r')" diff --git a/examples/mp/jupyter/sports_scheduling.ipynb b/examples/mp/jupyter/sports_scheduling.ipynb index 5fa3c5c..7a36eef 100644 --- a/examples/mp/jupyter/sports_scheduling.ipynb +++ b/examples/mp/jupyter/sports_scheduling.ipynb @@ -13,7 +13,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of the [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + ">This notebook is part of the [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "\n", ">Running the sample requires the installation of\n", " [CPLEX Optimization studio](https://www.ibm.com/products/ilog-cplex-optimization-studio)\n", @@ -726,7 +726,7 @@ }, "source": [ "#### References\n", - "* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [Decision Optimization CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com.\n" diff --git a/examples/mp/jupyter/tutorials/Beyond_Linear_Programming.ipynb b/examples/mp/jupyter/tutorials/Beyond_Linear_Programming.ipynb index 1dcfd2a..dc8a7b1 100644 --- a/examples/mp/jupyter/tutorials/Beyond_Linear_Programming.ipynb +++ b/examples/mp/jupyter/tutorials/Beyond_Linear_Programming.ipynb @@ -13,7 +13,7 @@ "After completing this unit, you should be able to describe what a network model is, and the benefits of using network models, explain the concepts of nonlinearity and convexity, describe what a piecewise linear function is, and describe the differences between Linear Programming (LP), Integer Programming (IP), Mixed-Integer Programming (MIP), and Quadratic Programming (QP). You should also be able to construct a simple MIP model. \n", "\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires a valid subscription to **Decision Optimization on Cloud** or a **local installation of CPLEX Optimizers**. \n", "\n", @@ -36,7 +36,7 @@ "source": [ "## Use IBM Decision Optimization CPLEX Modeling for Python\n", "\n", - "Let's use the [DOcplex](https://cdn.rawgit.com/IBMDecisionOptimization/docplex-doc/2.0.15/docs/index.html) Python library to write sample models in Python." + "Let's use the [DOcplex](http://ibmdecisionoptimization.github.io/docplex-doc/) Python library to write sample models in Python." ] }, { @@ -222,7 +222,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ @@ -529,6 +529,9 @@ }, "outputs": [], "source": [ + "# Display matplotlib plots in the notebook\n", + "%matplotlib inline\n", + "\n", "# create a new model to attach piecewise\n", "pm = Model(name='pwl')\n", "pwf1 = pm.piecewise_as_slopes([(0, 0), (0.4, 1000), (0.2, 3000)], lastslope=0.1)\n", @@ -1440,7 +1443,7 @@ " plt.title(title)\n", " plt.show()\n", " \n", - "display_pie( all_fracs.values(), all_fracs.keys(),title='Allocated Fractions')" + "display_pie( list(all_fracs.values()), list(all_fracs),title='Allocated Fractions')" ] }, { @@ -1536,7 +1539,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." @@ -1549,6 +1552,18 @@ "display_name": "Python 2", "language": "python", "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.11" } }, "nbformat": 4, diff --git a/examples/mp/jupyter/tutorials/Linear_Programming.ipynb b/examples/mp/jupyter/tutorials/Linear_Programming.ipynb index c366d50..5efbcb6 100644 --- a/examples/mp/jupyter/tutorials/Linear_Programming.ipynb +++ b/examples/mp/jupyter/tutorials/Linear_Programming.ipynb @@ -15,7 +15,7 @@ "You should also be able to describe some of the algorithms used to solve LPs, explain what presolve does, and recognize the elements of an LP in a basic DOcplex model.\n", "\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires a valid subscription to **Decision Optimization on Cloud** or a **local installation of CPLEX Optimizers**. \n", "\n", @@ -217,7 +217,7 @@ "\n", "### Using DOcplex to formulate the mathematical model in Python\n", "\n", - "Use the [DOcplex](https://cdn.rawgit.com/IBMDecisionOptimization/docplex-doc/2.0.15/docs/index.html) Python library to write the mathematical model in Python.\n", + "Use the [DOcplex](http://ibmdecisionoptimization.github.io/docplex-doc/) Python library to write the mathematical model in Python.\n", "This is done in four steps:\n", "\n", "- create a instance of docplex.mp.Model to hold all model objects\n", @@ -1159,7 +1159,7 @@ "metadata": {}, "source": [ "## References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." @@ -1169,21 +1169,21 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python [conda root]", + "display_name": "Python 2", "language": "python", - "name": "conda-root-py" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2" + "pygments_lexer": "ipython2", + "version": "2.7.11" } }, "nbformat": 4, diff --git a/examples/mp/jupyter/ucp_pandas.ipynb b/examples/mp/jupyter/ucp_pandas.ipynb index aec5eb6..c298f29 100644 --- a/examples/mp/jupyter/ucp_pandas.ipynb +++ b/examples/mp/jupyter/ucp_pandas.ipynb @@ -10,7 +10,7 @@ "\n", "When you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n", "\n", - ">This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n", + ">This notebook is part of [Prescriptive Analytics for Python](http://ibmdecisionoptimization.github.io/docplex-doc/).\n", "\n", ">It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n", "\n", @@ -1119,7 +1119,7 @@ "metadata": {}, "source": [ "#### References\n", - "* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n", + "* [CPLEX Modeling for Python documentation](http://ibmdecisionoptimization.github.io/docplex-doc/)\n", "* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n", "* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n", "* Contact us at dofeedback@wwpdl.vnet.ibm.com." diff --git a/examples/mp/modeling/nurses_multiobj.py b/examples/mp/modeling/nurses_multiobj.py new file mode 100644 index 0000000..e28df15 --- /dev/null +++ b/examples/mp/modeling/nurses_multiobj.py @@ -0,0 +1,530 @@ +# -------------------------------------------------------------------------- +# Source file provided under Apache License, Version 2.0, January 2004, +# http://www.apache.org/licenses/ +# (c) Copyright IBM Corp. 2015, 2018 +# -------------------------------------------------------------------------- + +from collections import namedtuple + +from docplex.mp.model import Model +from docplex.mp.constants import ObjectiveSense +from docplex.util.environment import get_environment + +# ---------------------------------------------------------------------------- +# Initialize the problem data +# ---------------------------------------------------------------------------- + +# utility to convert a weekday string to an index in 0..6 +_all_days = ["monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday"] + + +def day_to_day_week(day): + day_map = {day: d for d, day in enumerate(_all_days)} + return day_map[day.lower()] + + +TWorkRules = namedtuple("TWorkRules", ["work_time_max"]) +TVacation = namedtuple("TVacation", ["nurse", "day"]) +TNursePair = namedtuple("TNursePair", ["firstNurse", "secondNurse"]) +TSkillRequirement = namedtuple("TSkillRequirement", ["department", "skill", "required"]) + + +NURSES = [("Anne", 11, 1, 25), + ("Bethanie", 4, 5, 28), + ("Betsy", 2, 2, 17), + ("Cathy", 2, 2, 17), + ("Cecilia", 9, 5, 38), + ("Chris", 11, 4, 38), + ("Cindy", 5, 2, 21), + ("David", 1, 2, 15), + ("Debbie", 7, 2, 24), + ("Dee", 3, 3, 21), + ("Gloria", 8, 2, 25), + ("Isabelle", 3, 1, 16), + ("Jane", 3, 4, 23), + ("Janelle", 4, 3, 22), + ("Janice", 2, 2, 17), + ("Jemma", 2, 4, 22), + ("Joan", 5, 3, 24), + ("Joyce", 8, 3, 29), + ("Jude", 4, 3, 22), + ("Julie", 6, 2, 22), + ("Juliet", 7, 4, 31), + ("Kate", 5, 3, 24), + ("Nancy", 8, 4, 32), + ("Nathalie", 9, 5, 38), + ("Nicole", 0, 2, 14), + ("Patricia", 1, 1, 13), + ("Patrick", 6, 1, 19), + ("Roberta", 3, 5, 26), + ("Suzanne", 5, 1, 18), + ("Vickie", 7, 1, 20), + ("Wendie", 5, 2, 21), + ("Zoe", 8, 3, 29) + ] + +SHIFTS = [("Emergency", "monday", 2, 8, 3, 5), + ("Emergency", "monday", 8, 12, 4, 7), + ("Emergency", "monday", 12, 18, 2, 5), + ("Emergency", "monday", 18, 2, 3, 7), + ("Consultation", "monday", 8, 12, 10, 13), + ("Consultation", "monday", 12, 18, 8, 12), + ("Cardiac_Care", "monday", 8, 12, 10, 13), + ("Cardiac_Care", "monday", 12, 18, 8, 12), + ("Emergency", "tuesday", 8, 12, 4, 7), + ("Emergency", "tuesday", 12, 18, 2, 5), + ("Emergency", "tuesday", 18, 2, 3, 7), + ("Consultation", "tuesday", 8, 12, 10, 13), + ("Consultation", "tuesday", 12, 18, 8, 12), + ("Cardiac_Care", "tuesday", 8, 12, 4, 7), + ("Cardiac_Care", "tuesday", 12, 18, 2, 5), + ("Cardiac_Care", "tuesday", 18, 2, 3, 7), + ("Emergency", "wednesday", 2, 8, 3, 5), + ("Emergency", "wednesday", 8, 12, 4, 7), + ("Emergency", "wednesday", 12, 18, 2, 5), + ("Emergency", "wednesday", 18, 2, 3, 7), + ("Consultation", "wednesday", 8, 12, 10, 13), + ("Consultation", "wednesday", 12, 18, 8, 12), + ("Emergency", "thursday", 2, 8, 3, 5), + ("Emergency", "thursday", 8, 12, 4, 7), + ("Emergency", "thursday", 12, 18, 2, 5), + ("Emergency", "thursday", 18, 2, 3, 7), + ("Consultation", "thursday", 8, 12, 10, 13), + ("Consultation", "thursday", 12, 18, 8, 12), + ("Emergency", "friday", 2, 8, 3, 5), + ("Emergency", "friday", 8, 12, 4, 7), + ("Emergency", "friday", 12, 18, 2, 5), + ("Emergency", "friday", 18, 2, 3, 7), + ("Consultation", "friday", 8, 12, 10, 13), + ("Consultation", "friday", 12, 18, 8, 12), + ("Emergency", "saturday", 2, 12, 5, 7), + ("Emergency", "saturday", 12, 20, 7, 9), + ("Emergency", "saturday", 20, 2, 12, 12), + ("Emergency", "sunday", 2, 12, 5, 7), + ("Emergency", "sunday", 12, 20, 7, 9), + ("Emergency", "sunday", 20, 2, 12, 12), + ("Geriatrics", "sunday", 8, 10, 2, 5)] + +NURSE_SKILLS = {"Anne": ["Anaesthesiology", "Oncology", "Pediatrics"], + "Betsy": ["Cardiac_Care"], + "Cathy": ["Anaesthesiology"], + "Cecilia": ["Anaesthesiology", "Oncology", "Pediatrics"], + "Chris": ["Cardiac_Care", "Oncology", "Geriatrics"], + "Gloria": ["Pediatrics"], "Jemma": ["Cardiac_Care"], + "Joyce": ["Anaesthesiology", "Pediatrics"], + "Julie": ["Geriatrics"], "Juliet": ["Pediatrics"], + "Kate": ["Pediatrics"], "Nancy": ["Cardiac_Care"], + "Nathalie": ["Anaesthesiology", "Geriatrics"], + "Patrick": ["Oncology"], "Suzanne": ["Pediatrics"], + "Wendie": ["Geriatrics"], + "Zoe": ["Cardiac_Care"] + } + +VACATIONS = [("Anne", "friday"), + ("Anne", "sunday"), + ("Cathy", "thursday"), + ("Cathy", "tuesday"), + ("Joan", "thursday"), + ("Joan", "saturday"), + ("Juliet", "monday"), + ("Juliet", "tuesday"), + ("Juliet", "thursday"), + ("Nathalie", "sunday"), + ("Nathalie", "thursday"), + ("Isabelle", "monday"), + ("Isabelle", "thursday"), + ("Patricia", "saturday"), + ("Patricia", "wednesday"), + ("Nicole", "friday"), + ("Nicole", "wednesday"), + ("Jude", "tuesday"), + ("Jude", "friday"), + ("Debbie", "saturday"), + ("Debbie", "wednesday"), + ("Joyce", "sunday"), + ("Joyce", "thursday"), + ("Chris", "thursday"), + ("Chris", "tuesday"), + ("Cecilia", "friday"), + ("Cecilia", "wednesday"), + ("Patrick", "saturday"), + ("Patrick", "sunday"), + ("Cindy", "sunday"), + ("Dee", "tuesday"), + ("Dee", "friday"), + ("Jemma", "friday"), + ("Jemma", "wednesday"), + ("Bethanie", "wednesday"), + ("Bethanie", "tuesday"), + ("Betsy", "monday"), + ("Betsy", "thursday"), + ("David", "monday"), + ("Gloria", "monday"), + ("Jane", "saturday"), + ("Jane", "sunday"), + ("Janelle", "wednesday"), + ("Janelle", "friday"), + ("Julie", "sunday"), + ("Kate", "tuesday"), + ("Kate", "monday"), + ("Nancy", "sunday"), + ("Roberta", "friday"), + ("Roberta", "saturday"), + ("Janice", "tuesday"), + ("Janice", "friday"), + ("Suzanne", "monday"), + ("Vickie", "wednesday"), + ("Vickie", "friday"), + ("Wendie", "thursday"), + ("Wendie", "saturday"), + ("Zoe", "saturday"), + ("Zoe", "sunday")] + +NURSE_ASSOCIATIONS = [("Isabelle", "Dee"), + ("Anne", "Patrick")] + +NURSE_INCOMPATIBILITIES = [("Patricia", "Patrick"), + ("Janice", "Wendie"), + ("Suzanne", "Betsy"), + ("Janelle", "Jane"), + ("Gloria", "David"), + ("Dee", "Jemma"), + ("Bethanie", "Dee"), + ("Roberta", "Zoe"), + ("Nicole", "Patricia"), + ("Vickie", "Dee"), + ("Joan", "Anne") + ] + +SKILL_REQUIREMENTS = [("Emergency", "Cardiac_Care", 1)] + +DEFAULT_WORK_RULES = TWorkRules(40) + + +# ---------------------------------------------------------------------------- +# Prepare the data for modeling +# ---------------------------------------------------------------------------- +# subclass the namedtuple to refine the str() method as the nurse's name +class TNurse(namedtuple("TNurse1", ["name", "seniority", "qualification", "pay_rate"])): + def __str__(self): + return self.name + + +# specialized namedtuple to redefine its str() method +class TShift(namedtuple("TShift", + ["department", "day", "start_time", "end_time", "min_requirement", "max_requirement"])): + + def __str__(self): + # keep first two characters in department, uppercase + dept2 = self.department[0:4].upper() + # keep 3 days of weekday + dayname = self.day[0:3] + return '{}_{}_{:02d}'.format(dept2, dayname, self.start_time).replace(" ", "_") + + +class ShiftActivity(object): + @staticmethod + def to_abstime(day_index, time_of_day): + """ Convert a pair (day_index, time) into a number of hours since Monday 00:00 + + :param day_index: The index of the day from 1 to 7 (Monday is 1). + :param time_of_day: An integer number of hours. + + :return: + """ + time = 24 * (day_index - 1) + time += time_of_day + return time + + def __init__(self, weekday, start_time_of_day, end_time_of_day): + assert (start_time_of_day >= 0) + assert (start_time_of_day <= 24) + assert (end_time_of_day >= 0) + assert (end_time_of_day <= 24) + + self._weekday = weekday + self._start_time_of_day = start_time_of_day + self._end_time_of_day = end_time_of_day + # conversion to absolute time. + start_day_index = day_to_day_week(self._weekday) + self.start_time = self.to_abstime(start_day_index, start_time_of_day) + end_day_index = start_day_index if end_time_of_day > start_time_of_day else start_day_index + 1 + self.end_time = self.to_abstime(end_day_index, end_time_of_day) + assert self.end_time > self.start_time + + @property + def duration(self): + return self.end_time - self.start_time + + def overlaps(self, other_shift): + if not isinstance(other_shift, ShiftActivity): + return False + else: + return other_shift.end_time > self.start_time and other_shift.start_time < self.end_time + + +def solve(model, **kwargs): + # Here, we set the number of threads for CPLEX to 2 and set the time limit to 2mins. + model.parameters.threads = 2 + model.parameters.mip.tolerances.mipgap = 0.000001 + model.parameters.timelimit = 120 # nurse should not take more than that ! + sol = model.solve(log_output=True, **kwargs) + if sol is not None: + print("solution for a cost of {}".format(model.objective_value)) + print_information(model) + # print_solution(model) + return model.objective_value + else: + print("* model is infeasible") + return None + + +def load_data(model, shifts_, nurses_, nurse_skills, vacations_=None, + nurse_associations_=None, nurse_imcompatibilities_=None): + """ Usage: load_data(shifts, nurses, nurse_skills, vacations) """ + model.number_of_overlaps = 0 + model.work_rules = DEFAULT_WORK_RULES + model.shifts = [TShift(*shift_row) for shift_row in shifts_] + model.nurses = [TNurse(*nurse_row) for nurse_row in nurses_] + model.skill_requirements = SKILL_REQUIREMENTS + model.nurse_skills = nurse_skills + # transactional data + model.vacations = [TVacation(*vacation_row) for vacation_row in vacations_] if vacations_ else [] + model.nurse_associations = [TNursePair(*npr) for npr in nurse_associations_]\ + if nurse_associations_ else [] + model.nurse_incompatibilities = [TNursePair(*npr) for npr in nurse_imcompatibilities_]\ + if nurse_imcompatibilities_ else [] + + # computed + model.departments = set(sh.department for sh in model.shifts) + + + print('#nurses: {0}'.format(len(model.nurses))) + print('#shifts: {0}'.format(len(model.shifts))) + print('#vacations: {0}'.format(len(model.vacations))) + print("#associations=%d" % len(model.nurse_associations)) + print("#incompatibilities=%d" % len(model.nurse_incompatibilities)) + + +def setup_data(model): + """ compute internal data """ + # compute shift activities (start, end duration) and stor ethem in a dict indexed by shifts + model.shift_activities = {s: ShiftActivity(s.day, s.start_time, s.end_time) for s in model.shifts} + # map from nurse names to nurse tuples. + model.nurses_by_id = {n.name: n for n in model.nurses} + + +def setup_variables(model): + all_nurses, all_shifts = model.nurses, model.shifts + # one binary variable for each pair (nurse, shift) equal to 1 iff nurse n is assigned to shift s + model.nurse_assignment_vars = model.binary_var_matrix(all_nurses, all_shifts, 'NurseAssigned') + # for each nurse, allocate one variable for work time + model.nurse_work_time_vars = model.continuous_var_dict(all_nurses, lb=0, name='NurseWorkTime') + # and two variables for over_average and under-average work time + model.nurse_over_average_time_vars = model.continuous_var_dict(all_nurses, lb=0, + name='NurseOverAverageWorkTime') + model.nurse_under_average_time_vars = model.continuous_var_dict(all_nurses, lb=0, + name='NurseUnderAverageWorkTime') + # finally the global average work time + model.average_nurse_work_time = model.continuous_var(lb=0, name='AverageWorkTime') + + +def setup_constraints(model): + all_nurses = model.nurses + all_shifts = model.shifts + nurse_assigned = model.nurse_assignment_vars + nurse_work_time = model.nurse_work_time_vars + shift_activities = model.shift_activities + nurses_by_id = model.nurses_by_id + max_work_time = model.work_rules.work_time_max + + # define average + model.add_constraint( + len(all_nurses) * model.average_nurse_work_time == model.sum(nurse_work_time[n] for n in all_nurses), "average") + + # compute nurse work time , average and under, over + for n in all_nurses: + work_time_var = nurse_work_time[n] + model.add_constraint( + work_time_var == model.sum(nurse_assigned[n, s] * shift_activities[s].duration for s in all_shifts), + "work_time_{0!s}".format(n)) + + # relate over/under average worktime variables to the worktime variables + # the trick here is that variables have zero lower bound + # however, thse variables are not completely defined by this constraint, + # only their difference is. + # if these variables are part of the objective, CPLEX wil naturally minimize their value, + # as expected + model.add_constraint( + work_time_var == model.average_nurse_work_time + + model.nurse_over_average_time_vars[n] + - model.nurse_under_average_time_vars[n], + "average_work_time_{0!s}".format(n)) + + # state the maximum work time as a constraint, so that is can be relaxed, + # should the problem become infeasible. + model.add_constraint(work_time_var <= max_work_time, "max_time_{0!s}".format(n)) + + # vacations + v = 0 + for vac_nurse_id, vac_day in model.vacations: + vac_n = nurses_by_id[vac_nurse_id] + for shift in (s for s in all_shifts if s.day == vac_day): + v += 1 + model.add_constraint(nurse_assigned[vac_n, shift] == 0, + "medium_vacations_{0!s}_{1!s}_{2!s}".format(vac_n, vac_day, shift)) + #print('#vacation cts: {0}'.format(v)) + + # a nurse cannot be assigned overlapping shifts + # post only one constraint per couple(s1, s2) + number_of_overlaps = 0 + nb_shifts = len(all_shifts) + for i1 in range(nb_shifts): + for i2 in range(i1 + 1, nb_shifts): + s1 = all_shifts[i1] + s2 = all_shifts[i2] + if shift_activities[s1].overlaps(shift_activities[s2]): + number_of_overlaps += 1 + for n in all_nurses: + model.add_constraint(nurse_assigned[n, s1] + nurse_assigned[n, s2] <= 1, + "high_overlapping_{0!s}_{1!s}_{2!s}".format(s1, s2, n)) + #print('# overlapping cts: {0}'.format(number_of_overlaps)) + + for s in all_shifts: + demand_min = s.min_requirement + demand_max = s.max_requirement + total_assigned = model.sum(nurse_assigned[n, s] for n in model.nurses) + model.add_constraint(total_assigned >= demand_min, + "high_req_min_{0!s}_{1}".format(s, demand_min)) + model.add_constraint(total_assigned <= demand_max, + "medium_req_max_{0!s}_{1}".format(s, demand_max)) + + for (dept, skill, required) in model.skill_requirements: + if required > 0: + for dsh in (s for s in all_shifts if dept == s.department): + model.add_constraint(model.sum(nurse_assigned[skilled_nurse, dsh] for skilled_nurse in + (n for n in all_nurses if + n.name in model.nurse_skills.keys() and skill in model.nurse_skills[ + n.name])) >= required, + "high_required_{0!s}_{1!s}_{2!s}_{3!s}".format(dept, skill, required, dsh)) + + # nurse-nurse associations + # for each pair of associated nurses, their assignment variables are equal + # over all shifts. + c = 0 + for (nurse_id1, nurse_id2) in model.nurse_associations: + if nurse_id1 in nurses_by_id and nurse_id2 in nurses_by_id: + nurse1 = nurses_by_id[nurse_id1] + nurse2 = nurses_by_id[nurse_id2] + for s in all_shifts: + c += 1 + ctname = 'medium_ct_nurse_assoc_{0!s}_{1!s}_{2:d}'.format(nurse_id1, nurse_id2, c) + model.add_constraint(nurse_assigned[nurse1, s] == nurse_assigned[nurse2, s], ctname) + + # nurse-nurse incompatibilities + # for each pair of incompatible nurses, the sum of assigned variables is less than one + # in other terms, both nurses can never be assigned to the same shift + c = 0 + for (nurse_id1, nurse_id2) in model.nurse_incompatibilities: + if nurse_id1 in nurses_by_id and nurse_id2 in nurses_by_id: + nurse1 = nurses_by_id[nurse_id1] + nurse2 = nurses_by_id[nurse_id2] + for s in all_shifts: + c += 1 + ctname = 'medium_ct_nurse_incompat_{0!s}_{1!s}_{2:d}'.format(nurse_id1, nurse_id2, c) + model.add_constraint(nurse_assigned[nurse1, s] + nurse_assigned[nurse2, s] <= 1, ctname) + + model.total_number_of_assignments = model.sum(nurse_assigned[n, s] for n in all_nurses for s in all_shifts) + model.nurse_costs = [model.nurse_assignment_vars[n, s] * n.pay_rate * model.shift_activities[s].duration for n in + model.nurses + for s in model.shifts] + model.total_salary_cost = model.sum(model.nurse_costs) + + +def setup_objective(model): + model.add_kpi(model.total_salary_cost, "Total salary cost") + model.add_kpi(model.total_number_of_assignments, "Total number of assignments") + model.add_kpi(model.average_nurse_work_time, "average work time") + + total_over_average_worktime = model.sum(model.nurse_over_average_time_vars[n] for n in model.nurses) + total_under_average_worktime = model.sum(model.nurse_under_average_time_vars[n] for n in model.nurses) + model.add_kpi(total_over_average_worktime, "Total over-average worktime") + model.add_kpi(total_under_average_worktime, "Total under-average worktime") + total_fairness = total_over_average_worktime + total_under_average_worktime + model.add_kpi(total_fairness, "Total fairness") + + model.set_multi_objective(ObjectiveSense.Minimize, [model.total_salary_cost, total_fairness, model.total_number_of_assignments], + priorities=[2, 3, 1]) + + +def print_information(model): + print("#shifts=%d" % len(model.shifts)) + print("#nurses=%d" % len(model.nurses)) + print("#vacations=%d" % len(model.vacations)) + print("#nurse skills=%d" % len(model.nurse_skills)) + print("#nurse associations=%d" % len(model.nurse_associations)) + print("#incompatibilities=%d" % len(model.nurse_incompatibilities)) + model.print_information() + model.report_kpis() + + +def print_solution(model): + print("*************************** Solution ***************************") + print("Allocation By Department:") + for d in model.departments: + print("\t{}: {}".format(d, sum( + model.nurse_assignment_vars[n, s].solution_value for n in model.nurses for s in model.shifts if + s.department == d))) + print("Cost By Department:") + for d in model.departments: + cost = sum( + model.nurse_assignment_vars[n, s].solution_value * n.pay_rate * model.shift_activities[s].duration for n in + model.nurses for s in model.shifts if s.department == d) + print("\t{}: {}".format(d, cost)) + print("Nurses Assignments") + for n in sorted(model.nurses): + total_hours = sum( + model.nurse_assignment_vars[n, s].solution_value * model.shift_activities[s].duration for s in model.shifts) + print("\t{}: total hours:{}".format(n.name, total_hours)) + for s in model.shifts: + if model.nurse_assignment_vars[n, s].solution_value == 1: + print("\t\t{}: {} {}-{}".format(s.day, s.department, s.start_time, s.end_time)) + + +# ---------------------------------------------------------------------------- +# Build the model +# ---------------------------------------------------------------------------- + +def build(context=None, **kwargs): + mdl = Model("Nurses", context=context, **kwargs) + load_data(mdl, SHIFTS, NURSES, NURSE_SKILLS, VACATIONS, NURSE_ASSOCIATIONS, + NURSE_INCOMPATIBILITIES) + setup_data(mdl) + setup_variables(mdl) + setup_constraints(mdl) + setup_objective(mdl) + return mdl + + +# ---------------------------------------------------------------------------- +# Solve the model and display the result +# ---------------------------------------------------------------------------- + +if __name__ == '__main__': + # Build model + model = build() + + # Solve the model and print solution + solve(model) + + print(model.get_solve_details()) + + # Save the CPLEX solution as "solution.json" program output + with get_environment().get_output_stream("solution.json") as fp: + model.solution.export(fp, "json") diff --git a/examples/mp/modeling/sport_scheduling.py b/examples/mp/modeling/sport_scheduling.py index 7e7e437..792d998 100644 --- a/examples/mp/modeling/sport_scheduling.py +++ b/examples/mp/modeling/sport_scheduling.py @@ -13,7 +13,7 @@ # ---------------------------------------------------------------------------- # Initialize the problem data # ---------------------------------------------------------------------------- -nbs = (8, 1, 1) +nbs = (8, 3, 2) team_div1 = {"Baltimore Ravens", "Cincinnati Bengals", "Cleveland Browns", "Pittsburgh Steelers", "Houston Texans", "Indianapolis Colts", @@ -35,9 +35,9 @@ # ---------------------------------------------------------------------------- # Build the model # ---------------------------------------------------------------------------- -def build_sports(context=None): +def build_sports(**kwargs): print("* building sport scheduling model instance") - mdl = Model('sportSchedCPLEX', context=context) + mdl = Model('sportSchedCPLEX', **kwargs) nb_teams_in_division, nb_intra_divisional, nb_inter_divisional = nbs assert len(team_div1) == len(team_div2) diff --git a/examples/mp/zeppelin/chicago_coffee_shops.json b/examples/mp/zeppelin/chicago_coffee_shops.json new file mode 100644 index 0000000..d1bcdfe --- /dev/null +++ b/examples/mp/zeppelin/chicago_coffee_shops.json @@ -0,0 +1 @@ +{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "C:\\Users\\AURELIEFolacci\\python\\workspace\\docplex\\docplex\\src\\samples\\examples\\delivery\\jupyter\\chicago_coffee_shops", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Finding optimal locations of new stores\n\nThis tutorial includes everything you need to set up IBM Decision Optimization CPLEX Modeling for Python (DOcplex), build a Mathematical Programming model, and get its solution by solving the model on the cloud with IBM ILOG CPLEX Optimizer.\n\nWhen you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n\n>This notebook is part of [Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html).\n\n>It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n\nDiscover us [here](https://developer.ibm.com/docloud)\n\n\nTable of contents:\n\n- Describe the business problem\n* How decision optimization (prescriptive analytics) can help\n* Use decision optimization\n * Step 1: Import the library\n - Step 2: Model the data\n * Step 3: Prepare the data\n - Step 4: Set up the prescriptive model\n * Define the decision variables\n * Express the business constraints\n * Express the objective\n * Solve with Decision Optimization\n * Step 5: Investigate the solution and run an example analysis\n* Summary\n\n****", "apps": [], "results": {"msg": [{"data": "

Finding optimal locations of new stores

\n

\n

This tutorial includes everything you need to set up IBM Decision Optimization CPLEX Modeling for Python (DOcplex), build a Mathematical Programming model, and get its solution by solving the model on the cloud with IBM ILOG CPLEX Optimizer.

\n

\n

When you finish this tutorial, you'll have a foundational knowledge of Prescriptive Analytics.

\n

\n
\n

This notebook is part of Prescriptive Analytics for Python.

\n
\n

\n
\n

It requires an installation of CPLEX Optimizers

\n
\n

\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n
    \n
  • Describe the business problem
  • \n
\n
    \n
  • How decision optimization (prescriptive analytics) can help
  • \n
\n
    \n
  • Use decision optimization
  • \n
\n
*  Step 1: Import the library\n
\n
-  Step 2: Model the data\n
\n
*  Step 3: Prepare the data\n
\n
-  Step 4: Set up the prescriptive model\n
\n
    * Define the decision variables\n
\n
    * Express the business constraints\n
\n
    * Express the objective\n
\n
    * Solve with Decision Optimization\n
\n
*  Step 5: Investigate the solution and run an example analysis\n
\n
    \n
  • Summary
  • \n
\n

\n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Describe the business problem\n\n* A fictional Coffee Company plans to open N shops in the near future and needs to determine where they should be located knowing the following:\n * Most of the customers of this coffee brewer enjoy reading and borrowing books, so the goal is to locate those shops in such a way that all the city public libraries are within minimal walking distance.\n* We use [Chicago open data](https://data.cityofchicago.org) for this example.\n* We implement a [K-Median model](https://en.wikipedia.org/wiki/K-medians_clustering) to get the optimal location of our future shops.", "apps": [], "results": {"msg": [{"data": "

Describe the business problem

\n

\n
    \n
  • A fictional Coffee Company plans to open N shops in the near future and needs to determine where they should be located knowing the following:
  • \n
\n
* Most of the customers of this coffee brewer enjoy reading and borrowing books, so the goal is to locate those shops in such a way that all the city public libraries are within minimal walking distance.\n
\n\n
    \n
  • We implement a K-Median model to get the optimal location of our future shops.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## How decision optimization can help\n\n* Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes. \n\n* Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes. \n\n* Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage. \n
\n\nWith prescriptive analytics, you can: \n\n* Automate the complex decisions and trade-offs to better manage your limited resources.\n* Take advantage of a future opportunity or mitigate a future risk.\n* Proactively update recommendations based on changing events.\n* Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.", "apps": [], "results": {"msg": [{"data": "

How decision optimization can help

\n

\n
    \n
  • Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage.
  • \n
\n


\n

\n

With prescriptive analytics, you can:

\n

\n
    \n
  • Automate the complex decisions and trade-offs to better manage your limited resources.
  • \n
\n
    \n
  • Take advantage of a future opportunity or mitigate a future risk.
  • \n
\n
    \n
  • Proactively update recommendations based on changing events.
  • \n
\n
    \n
  • Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use decision optimization", "apps": [], "results": {"msg": [{"data": "

Use decision optimization

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 1: Import the library\n\nRun the following code to import the Decision Optimization CPLEX Modeling library. The *DOcplex* library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.", "apps": [], "results": {"msg": [{"data": "

Step 1: Import the library

\n

\n

Run the following code to import the Decision Optimization CPLEX Modeling library. The DOcplex library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport sys\ntry:\n import docplex.mp\nexcept:\n raise Exception('Please install docplex. See https://pypi.org/project/docplex/') ", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nNote that the more global package docplex contains another subpackage docplex.cp that is dedicated to Constraint Programming, another branch of optimization.", "apps": [], "results": {"msg": [{"data": "

Note that the more global package docplex contains another subpackage docplex.cp that is dedicated to Constraint Programming, another branch of optimization.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 2: Model the data\n\n- The data for this problem is quite simple: it is composed of the list of public libraries and their geographical locations.\n- The data is acquired from [Chicago open data](https://data.cityofchicago.org) as a JSON file, which is in the following format:\n\ndata\" : [ [ 1, \"13BFA4C7-78CE-4D83-B53D-B57C60B701CF\", 1, 1441918880, \"885709\", 1441918880, \"885709\", null, \"Albany Park\", \"M, W: 10AM-6PM; TU, TH: 12PM-8PM; F, SA: 9AM-5PM; SU: Closed\", \"Yes\", \"Yes \", \"3401 W. Foster Avenue\", \"CHICAGO\", \"IL\", \"60625\", \"(773) 539-5450\", [ \"http://www.chipublib.org/locations/1/\", null ], [ null, \"41.975456\", \"-87.71409\", null, false ] ]\n\nThis code snippet represents library \"**3401 W. Foster Avenue**\" located at **41.975456, -87.71409**\n", "apps": [], "results": {"msg": [{"data": "

Step 2: Model the data

\n

\n
    \n
  • The data for this problem is quite simple: it is composed of the list of public libraries and their geographical locations.
  • \n
\n
    \n
  • The data is acquired from Chicago open data as a JSON file, which is in the following format:
  • \n
\n

\n

data\" : [ [ 1, \"13BFA4C7-78CE-4D83-B53D-B57C60B701CF\", 1, 1441918880, \"885709\", 1441918880, \"885709\", null, \"Albany Park\", \"M, W: 10AM-6PM; TU, TH: 12PM-8PM; F, SA: 9AM-5PM; SU: Closed\", \"Yes\", \"Yes \", \"3401 W. Foster Avenue\", \"CHICAGO\", \"IL\", \"60625\", \"(773) 539-5450\", [ \"http://www.chipublib.org/locations/1/\", null ], [ null, \"41.975456\", \"-87.71409\", null, false ] ]

\n

\n

This code snippet represents library \"3401 W. Foster Avenue\" located at 41.975456, -87.71409

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nDisclaimer:\nThis site provides applications using data that has been modified for use from its original source, www.cityofchicago.org, the official website of the City of Chicago. The City of Chicago makes no claims as to the content, accuracy, timeliness, or completeness of any of the data provided at this site. The data provided at this site is subject to change at any time. It is understood that the data provided at this site is being used at one\u2019s own risk.", "apps": [], "results": {"msg": [{"data": "

Disclaimer:

\n

This site provides applications using data that has been modified for use from its original source, www.cityofchicago.org, the official website of the City of Chicago. The City of Chicago makes no claims as to the content, accuracy, timeliness, or completeness of any of the data provided at this site. The data provided at this site is subject to change at any time. It is understood that the data provided at this site is being used at one\u2019s own risk.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 3: Prepare the data\nWe need to collect the list of public libraries locations and keep their names, latitudes, and longitudes.", "apps": [], "results": {"msg": [{"data": "

Step 3: Prepare the data

\n

We need to collect the list of public libraries locations and keep their names, latitudes, and longitudes.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# Store longitude, latitude and street crossing name of each public library location.\nclass XPoint(object):\n def __init__(self, x, y):\n self.x = x\n self.y = y\n def __str__(self):\n return \"P(%g_%g)\" % (self.x, self.y)\n\nclass NamedPoint(XPoint):\n def __init__(self, name, x, y):\n XPoint.__init__(self, x, y)\n self.name = name\n def __str__(self):\n return self.name", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Define how to compute the earth distance between 2 points\nTo easily compute distance between 2 points, we use the Python package [geopy](https://pypi.python.org/pypi/geopy)", "apps": [], "results": {"msg": [{"data": "

Define how to compute the earth distance between 2 points

\n

To easily compute distance between 2 points, we use the Python package geopy

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport pip._internal\ntry:\n import geopy.distance\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n pip._internal.main(['install', 'geopy'])\n else:\n pip._internal.main(['install', '--user', 'geopy']) ", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# Simple distance computation between 2 locations.\nfrom geopy.distance import great_circle\n \ndef get_distance(p1, p2):\n return great_circle((p1.y, p1.x), (p2.y, p2.x)).miles", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Declare the list of libraries\nParse the JSON file to get the list of libraries and store them as Python elements.", "apps": [], "results": {"msg": [{"data": "

Declare the list of libraries

\n

Parse the JSON file to get the list of libraries and store them as Python elements.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_libraries_from_url(url, name_pos, lat_long_pos):\n import requests\n import json\n r = requests.get(url)\n myjson = json.loads(r.text, parse_constant='utf-8')\n myjson = myjson['data']\n libraries = []\n k = 1\n for location in myjson:\n uname = location[name_pos]\n try:\n latitude = float(location[lat_long_pos][1])\n longitude = float(location[lat_long_pos][2])\n except TypeError:\n latitude = longitude = None\n try:\n name = str(uname)\n except:\n name = \"???\"\n name = \"P_%s_%d\" % (name, k)\n if latitude and longitude:\n cp = NamedPoint(name, longitude, latitude)\n libraries.append(cp)\n k += 1\n return libraries", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nlibraries = build_libraries_from_url('https://data.cityofchicago.org/api/views/x8fc-8rcq/rows.json?accessType=DOWNLOAD',\n name_pos=12,\n lat_long_pos=18)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nprint(\"There are %d public libraries in Chicago\" % (len(libraries)))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Define number of shops to open\nCreate a constant that indicates how many coffee shops we would like to open.", "apps": [], "results": {"msg": [{"data": "

Define number of shops to open

\n

Create a constant that indicates how many coffee shops we would like to open.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nnb_shops = 5\nprint(\"We would like to open %d coffee shops\" % nb_shops)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Validate the data by displaying them\nWe will use the [folium](https://folium.readthedocs.org/en/latest/quickstart.html#getting-started) library to display a map with markers.", "apps": [], "results": {"msg": [{"data": "

Validate the data by displaying them

\n

We will use the folium library to display a map with markers.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport pip._internal\ntry:\n import folium\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n pip._internal.main(['install', 'folium'])\n else:\n pip._internal.main(['install', '--user', 'folium'])", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport folium\nmap_osm = folium.Map(location=[41.878, -87.629], zoom_start=11)\nfor library in libraries:\n lt = library.y\n lg = library.x\n folium.Marker([lt, lg]).add_to(map_osm)\nmap_osm", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nAfter running the above code, the data is displayed but it is impossible to determine where to ideally open the coffee shops by just looking at the map.\n\nLet's set up DOcplex to write and solve an optimization model that will help us determine where to locate the coffee shops in an optimal way.", "apps": [], "results": {"msg": [{"data": "

After running the above code, the data is displayed but it is impossible to determine where to ideally open the coffee shops by just looking at the map.

\n

\n

Let's set up DOcplex to write and solve an optimization model that will help us determine where to locate the coffee shops in an optimal way.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 4: Set up the prescriptive model", "apps": [], "results": {"msg": [{"data": "

Step 4: Set up the prescriptive model

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.environment import Environment\nenv = Environment()\nenv.print_information()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Create the DOcplex model\nThe model contains all the business constraints and defines the objective.", "apps": [], "results": {"msg": [{"data": "

Create the DOcplex model

\n

The model contains all the business constraints and defines the objective.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.model import Model\n\nmdl = Model(\"coffee shops\")", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Define the decision variables", "apps": [], "results": {"msg": [{"data": "

Define the decision variables

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nBIGNUM = 999999999\n\n# Ensure unique points\nlibraries = set(libraries)\n# For simplicity, let's consider that coffee shops candidate locations are the same as libraries locations.\n# That is: any library location can also be selected as a coffee shop.\ncoffeeshop_locations = libraries\n\n# Decision vars\n# Binary vars indicating which coffee shop locations will be actually selected\ncoffeeshop_vars = mdl.binary_var_dict(coffeeshop_locations, name=\"is_coffeeshop\")\n#\n# Binary vars representing the \"assigned\" libraries for each coffee shop\nlink_vars = mdl.binary_var_matrix(coffeeshop_locations, libraries, \"link\")", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Express the business constraints\nFirst constraint: if the distance is suspect, it needs to be excluded from the problem.", "apps": [], "results": {"msg": [{"data": "

Express the business constraints

\n

First constraint: if the distance is suspect, it needs to be excluded from the problem.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfor c_loc in coffeeshop_locations:\n for b in libraries:\n if get_distance(c_loc, b) >= BIGNUM:\n mdl.add_constraint(link_vars[c_loc, b] == 0, \"ct_forbid_{0!s}_{1!s}\".format(c_loc, b))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nSecond constraint: each library must be linked to a coffee shop that is open.", "apps": [], "results": {"msg": [{"data": "

Second constraint: each library must be linked to a coffee shop that is open.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nmdl.add_constraints(link_vars[c_loc, b] <= coffeeshop_vars[c_loc]\n for b in libraries\n for c_loc in coffeeshop_locations)\nmdl.print_information()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nThird constraint: each library is linked to exactly one coffee shop.", "apps": [], "results": {"msg": [{"data": "

Third constraint: each library is linked to exactly one coffee shop.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nmdl.add_constraints(mdl.sum(link_vars[c_loc, b] for c_loc in coffeeshop_locations) == 1\n for b in libraries)\nmdl.print_information()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nFourth constraint: there is a fixed number of coffee shops to open.", "apps": [], "results": {"msg": [{"data": "

Fourth constraint: there is a fixed number of coffee shops to open.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# Total nb of open coffee shops\nmdl.add_constraint(mdl.sum(coffeeshop_vars[c_loc] for c_loc in coffeeshop_locations) == nb_shops)\n\n# Print model information\nmdl.print_information()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Express the objective\n\nThe objective is to minimize the total distance from libraries to coffee shops so that a book reader always gets to our coffee shop easily.\n", "apps": [], "results": {"msg": [{"data": "

Express the objective

\n

\n

The objective is to minimize the total distance from libraries to coffee shops so that a book reader always gets to our coffee shop easily.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# Minimize total distance from points to hubs\ntotal_distance = mdl.sum(link_vars[c_loc, b] * get_distance(c_loc, b) for c_loc in coffeeshop_locations for b in libraries)\nmdl.minimize(total_distance)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Solve with Decision Optimization\n\nSolve the model on the cloud. ", "apps": [], "results": {"msg": [{"data": "

Solve with Decision Optimization

\n

\n

Solve the model on the cloud.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nprint(\"# coffee shops locations = %d\" % len(coffeeshop_locations))\nprint(\"# coffee shops = %d\" % nb_shops)\n\nassert mdl.solve(), \"!!! Solve of the model fails\"", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 6: Investigate the solution and then run an example analysis\n\nThe solution can be analyzed by displaying the location of the coffee shops on a map.", "apps": [], "results": {"msg": [{"data": "

Step 6: Investigate the solution and then run an example analysis

\n

\n

The solution can be analyzed by displaying the location of the coffee shops on a map.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ntotal_distance = mdl.objective_value\nopen_coffeeshops = [c_loc for c_loc in coffeeshop_locations if coffeeshop_vars[c_loc].solution_value == 1]\nnot_coffeeshops = [c_loc for c_loc in coffeeshop_locations if c_loc not in open_coffeeshops]\nedges = [(c_loc, b) for b in libraries for c_loc in coffeeshop_locations if int(link_vars[c_loc, b]) == 1]\n\nprint(\"Total distance = %g\" % total_distance)\nprint(\"# coffee shops = {0}\".format(len(open_coffeeshops)))\nfor c in open_coffeeshops:\n print(\"new coffee shop: {0!s}\".format(c))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Displaying the solution\nCoffee shops are highlighted in red.", "apps": [], "results": {"msg": [{"data": "

Displaying the solution

\n

Coffee shops are highlighted in red.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport folium\nmap_osm = folium.Map(location=[41.878, -87.629], zoom_start=11)\nfor coffeeshop in open_coffeeshops:\n lt = coffeeshop.y\n lg = coffeeshop.x\n folium.Marker([lt, lg], icon=folium.Icon(color='red',icon='info-sign')).add_to(map_osm)\n \nfor b in libraries:\n if b not in open_coffeeshops:\n lt = b.y\n lg = b.x\n folium.Marker([lt, lg]).add_to(map_osm)\n \n\nfor (c, b) in edges:\n coordinates = [[c.y, c.x], [b.y, b.x]]\n map_osm.add_child(folium.PolyLine(coordinates, color='#FF0000', weight=5))\n\nmap_osm", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Summary\n\n\nYou learned how to set up and use IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model and solve it with IBM Decision Optimization on Cloud.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

\n

You learned how to set up and use IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model and solve it with IBM Decision Optimization on Cloud.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## References\n* [CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud).\n* Contact us at dofeedback@wwpdl.vnet.ibm.com.", "apps": [], "results": {"msg": [{"data": "

References

\n\n\n
    \n
  • Need help with DOcplex or to report a bug? Please go here.
  • \n
\n
    \n
  • Contact us at dofeedback@wwpdl.vnet.ibm.com.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nCopyright \u00a9 2017-2018 IBM. IPLA licensed Sample Materials.", "apps": [], "results": {"msg": [{"data": "

Copyright \u00a9 2017-2018 IBM. IPLA licensed Sample Materials.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}]} \ No newline at end of file diff --git a/examples/mp/zeppelin/efficient.json b/examples/mp/zeppelin/efficient.json new file mode 100644 index 0000000..a831f24 --- /dev/null +++ b/examples/mp/zeppelin/efficient.json @@ -0,0 +1 @@ +{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "C:\\Users\\AURELIEFolacci\\python\\workspace\\docplex\\docplex\\src\\samples\\examples\\delivery\\jupyter\\efficient", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Writing efficient DOcplex code\n\nIn this notebook, we show how to improve efficiency of DOcplex models using five simple rules.", "apps": [], "results": {"msg": [{"data": "

Writing efficient DOcplex code

\n

\n

In this notebook, we show how to improve efficiency of DOcplex models using five simple rules.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## A simple timing tool\n\nTo measure performance we need a simple timing tool. For this purpose, we chose to implement a Python context manager object (see https://docs.python.org/3/reference/datamodel.html#context-managers) for details.\n\nThis object stores the start time when entering a block and reports time spent when exiting the block. Python's `with` statement avoids cluttering code with intrusive prints.", "apps": [], "results": {"msg": [{"data": "

A simple timing tool

\n

\n

To measure performance we need a simple timing tool. For this purpose, we chose to implement a Python context manager object (see https://docs.python.org/3/reference/datamodel.html#context-managers) for details.

\n

\n

This object stores the start time when entering a block and reports time spent when exiting the block. Python's with statement avoids cluttering code with intrusive prints.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport time\nimport math\n\nclass ContextTimer(object):\n def __init__(self, msg):\n self.msg = msg\n self.start = 0\n \n def __enter__(self):\n self.start = time.time()\n return self # return value is value of with ()\n \n def __exit__(self, *args):\n elapsed = time.time() - self.start\n self.msecs = math.ceil(1000* elapsed)\n print('<-- {0}, time: {1:.0f} ms'.format(self.msg, self.msecs)) \n \n# try our timer on computing fibonacci numbers\n\ndef fib(n):\n return 1 if n <= 2 else fib(n-1) + fib(n-2)\n\n# timing fibonacci(30)\nwith ContextTimer(\"fibonacci 30\"):\n n = 30\n f = fib(n)\n print(\"fibonacci({0}) = {1}\".format(n, f))\n ", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## The benchmark model\n\nTo compare various implementations, we need a simple, scalable benchmark model. The model has no real business meaning, but is simple to grasp\nand can be scaled by changing one `size` parameter.\nNote that we'll be comparing only the _build_ time of the model, not the _solve_ time.\n\nNote that the model has _n_ constraints, all with expressions of size _N_, so we expect the underlying matrix _size_ to grow as $O(N^2)$.", "apps": [], "results": {"msg": [{"data": "

The benchmark model

\n

\n

To compare various implementations, we need a simple, scalable benchmark model. The model has no real business meaning, but is simple to grasp

\n

and can be scaled by changing one size parameter.

\n

Note that we'll be comparing only the build time of the model, not the solve time.

\n

\n

Note that the model has n constraints, all with expressions of size N, so we expect the underlying matrix size to grow as $O(N^2)$.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Description\n\nLet $N$ be an integer (the size of the problem).\n\n$$\nminimize \\sum_{k=0}^{k=N-1} (k+1) * y_{k}\\\\\ns.t.\\\\\n\\forall\\ \\ m\\ in \\{0..N-1\\}\\ \\ \\sum_{l=0}^{l=N-1} (y_{l} * (l+ (l+m) \\%3) \\ge l\\\\\ny_{k} = 0, 1\n$$", "apps": [], "results": {"msg": [{"data": "

Description

\n

\n

Let $N$ be an integer (the size of the problem).

\n

\n

$$

\n

minimize \\sum{k=0}^{k=N-1} (k+1) * y{k}\\

\n

s.t.\\

\n

\\forall\\ \\ m\\ in {0..N-1}\\ \\ \\sum{l=0}^{l=N-1} (y{l} * (l+ (l+m) \\%3) \\ge l\\

\n

y_{k} = 0, 1

\n

$$

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## A beginners's implementation of the model\n\nIn this section we show a Python/Docplex beginner's implementation of this model.\n", "apps": [], "results": {"msg": [{"data": "

A beginners's implementation of the model

\n

\n

In this section we show a Python/Docplex beginner's implementation of this model.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.model import Model\n\ndef build_bench_model1(size=10):\n m = Model(name=\"bench1\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_dict(rsize, name=\"y\")\n # create constraints\n k = {(i,j) : (i + (i+j) %3) for i in rsize for j in rsize}\n for i in rsize:\n m.add(m.sum(ys[i] * k[i,j] for j in rsize) >= i, \"ct_%d\" %i)\n # for minimize, create a list of coefficients\n rsize1 = [i+1 for i in rsize]\n m.minimize(m.sum(ys[k] * rsize[k] for k in rsize))\n return m", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nLets run our context timer with N=1000; we expect a model with 1000 variables and 1000 constraints:", "apps": [], "results": {"msg": [{"data": "

Lets run our context timer with N=1000; we expect a model with 1000 variables and 1000 constraints:

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nwith ContextTimer(\"bench1_size_1000\"):\n m11k = build_bench_model1(1000)\n m11k.print_information()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nAs expected the model has 1000 variables and 1000 constraints and the build time is significant.\nFor N=3000, we can expect an increase in buid time by a factor of 9:", "apps": [], "results": {"msg": [{"data": "

As expected the model has 1000 variables and 1000 constraints and the build time is significant.

\n

For N=3000, we can expect an increase in buid time by a factor of 9:

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nN=3000\nwith ContextTimer(\"bench1 size={0}\".format(N)):\n build_bench_model1(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n# Seven tips to improve DOcplex code efficiency", "apps": [], "results": {"msg": [{"data": "

Seven tips to improve DOcplex code efficiency

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use scalar product\n\nWhen building large expressions, scalar product (`Model.scal_prod()`) is \nan efficient way to combine a sequence of variables (or expressions)\nand a sequence of coefficients.\nTry using `scalar_prod` instead of using `for` loops in expressions.", "apps": [], "results": {"msg": [{"data": "

Use scalar product

\n

\n

When building large expressions, scalar product (Model.scal_prod()) is

\n

an efficient way to combine a sequence of variables (or expressions)

\n

and a sequence of coefficients.

\n

Try using scalar_prod instead of using for loops in expressions.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model2(size=10):\n m = Model(name=\"bench2\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_dict(rsize, name=\"y\")\n # create constraints\n k = {(i,j) : (i + (i+j) %3) for i in rsize for j in rsize}\n for i in rsize:\n m.add(m.scal_prod([ys[i1] for i1 in rsize], [k[i,j] for j in rsize]) >= i, \"ct_%d\" % i)\n # for minimize, create a list of coefficients\n rsize1 = [i+1 for i in rsize]\n m.minimize(m.scal_prod([ys[k] for k in rsize], rsize1))\n return m\n\nwith ContextTimer(\"bench3 size={0}\".format(N)):\n build_bench_model2(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Use variable lists instead of dicts, if possible\n\nIn the previous examples, we had to create an auxiliary sequence from the variable dictionary to pass to `scal_prod`. Actually, a variable _list_ would be much simpler to use than the dictionary, so we replace the `var_dict` by a `var_list`", "apps": [], "results": {"msg": [{"data": "

Use variable lists instead of dicts, if possible

\n

\n

In the previous examples, we had to create an auxiliary sequence from the variable dictionary to pass to scal_prod. Actually, a variable list would be much simpler to use than the dictionary, so we replace the var_dict by a var_list

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model21(size=10):\n m = Model(name=\"bench2.1\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n k = {(i,j) : (i + (i+j) %3) for i in rsize for j in rsize}\n for i in rsize:\n m.add(m.scal_prod(ys, [k[i,j] for j in rsize]) >= i, \"ct_%d\" % i)\n # for minimize, create a list of coefficients\n rsize1 = [i+1 for i in rsize]\n m.minimize(m.scal_prod(ys, rsize1))\n return m\n\nwith ContextTimer(\"bench2.1 size={0}\".format(N)):\n build_bench_model21(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use batches of constraints\n\nAdding constraints to the model by batches using `Model.add_constraints()`\nis usually more efficient.\nTry grouping consttraints in lists or comprehensions (both work).\n\nIf the constraints are named, pass a second argument with the collection of constraint names.", "apps": [], "results": {"msg": [{"data": "

Use batches of constraints

\n

\n

Adding constraints to the model by batches using Model.add_constraints()

\n

is usually more efficient.

\n

Try grouping consttraints in lists or comprehensions (both work).

\n

\n

If the constraints are named, pass a second argument with the collection of constraint names.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model3(size=10):\n m = Model(name=\"bench3\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n k = {(i,j) : (i + (i+j) %3) for i in rsize for j in rsize}\n m.add_constraints((m.scal_prod(ys, [k[i,j] for j in rsize]) >= i for i in rsize),\n [\"ct_%d\" % i for i in rsize])\n # for minimize, create a list of coefficients\n rsize1 = [i+1 for i in rsize]\n m.minimize(m.scal_prod(ys, rsize1))\n return m\n\nwith ContextTimer(\"bench3 size={0}\".format(N)):\n build_bench_model3(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Avoid creating unnecessary containers\n\nThe previous version allocated one dictionary `k` for coefficients and an auxiliary list for the objective. We can simplify the code bys using comprehensions instead.", "apps": [], "results": {"msg": [{"data": "

Avoid creating unnecessary containers

\n

\n

The previous version allocated one dictionary k for coefficients and an auxiliary list for the objective. We can simplify the code bys using comprehensions instead.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model4(size=10):\n m = Model(name=\"bench4\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n m.add_constraints((m.scal_prod(ys, [(i+ (i+j)%3) for j in rsize]) >= i for i in rsize),\n (\"ct_%d\" % i for i in rsize))\n # for minimize, create a list of coefficients\n m.minimize(m.scal_prod(ys, (i+1 for i in rsize)))\n return m\n\nwith ContextTimer(\"bench4 size={0}\".format(N)):\n build_bench_model4(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Take control of name generation\n\nNaming variables and/or constraints is useful to generate readable LP files. However, generating lare numbers of strings may have a significant cost in Python, sepcially for large models. \n\nDOcplex provides a keyword `ignore_names` at model creation time, which may disable all names (variables and constraint names alike) that are set in the model. \n\nBy default, this flag is `False`, and names are enabled. By setting this flag to `True`, all names mentioned in the model are discarded (in particular, names are not used in LP generation).\n\nIn the next version we simply add the `ignore_names=True` keyword argument to the model constructor", "apps": [], "results": {"msg": [{"data": "

Take control of name generation

\n

\n

Naming variables and/or constraints is useful to generate readable LP files. However, generating lare numbers of strings may have a significant cost in Python, sepcially for large models.

\n

\n

DOcplex provides a keyword ignore_names at model creation time, which may disable all names (variables and constraint names alike) that are set in the model.

\n

\n

By default, this flag is False, and names are enabled. By setting this flag to True, all names mentioned in the model are discarded (in particular, names are not used in LP generation).

\n

\n

In the next version we simply add the ignore_names=True keyword argument to the model constructor

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model5(size=10):\n m = Model(name=\"bench5\", ignore_names=True)\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n m.add_constraints((m.scal_prod(ys, [(i+ (i+j)%3) for j in rsize]) >= i for i in rsize),\n (\"ct_%d\" % i for i in rsize))\n # for minimize, create a list of coefficients\n m.minimize(m.scal_prod(ys, (i+1 for i in rsize)))\n return m\n\nwith ContextTimer(\"bench6 size={0}\".format(N)):\n build_bench_model5(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Take control of argument checking\n\nDOcplex does a minimal checking on arguments. As this can be useful when writing the model to avoid errors, this checking has a runtime cost. When running a deployed model that has been thoroughly tested and tuned, you can remove all checks by adding the `checker=\"off\"` keyword argument to the model constructor.\n\nAgain, the next version is identical to the previous one , except that type-checking has been disabled.", "apps": [], "results": {"msg": [{"data": "

Take control of argument checking

\n

\n

DOcplex does a minimal checking on arguments. As this can be useful when writing the model to avoid errors, this checking has a runtime cost. When running a deployed model that has been thoroughly tested and tuned, you can remove all checks by adding the checker=\"off\" keyword argument to the model constructor.

\n

\n

Again, the next version is identical to the previous one , except that type-checking has been disabled.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef build_bench_model6(size=10):\n m = Model(name=\"bench6\", ignore_names=True, checker=\"off\")\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n m.add_constraints((m.scal_prod(ys, [(i+ (i+j)%3) for j in rsize]) >= i for i in rsize),\n (\"ct_%d\" % i for i in rsize))\n # for minimize, create a list of coefficients\n m.minimize(m.scal_prod(ys, (i+1 for i in rsize)))\n return m\n\nwith ContextTimer(\"bench6 size={0}\".format(N)):\n build_bench_model6(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use the \"advanced model\" class\n\nDOcplex contains and `AdvModel` class, which is a subclass of `Model`.\nThis class contains highly efficient methods for special cases, for examples, scalar prodicts with all different variables. \nBy default, `AdvModel` methods do not perform any checking on their arguments. For example, the `cal_prod_vars_all_different` method does not check that the variables are indeed all different. If this is not true, then errors or incorrect results may occur.\n\nStill, you can enable type-checking on AdvModel by specifying `checker=\"on\"` at construction time, and remove it later.\n\nThe benchmark model is a good fit for the `scal_prod_vars_all_different` method as all our scalar products involve the `ys` variables.\n\nAdvModel provides other specialized fast method, among them:\n\n - `sum_vars_all_different` to compute the sum of a sequence of all different variables.\n - `quad_matrix_sum` to compute a quadratic expression from a matrix $Q$ and a vector of variables $X$ as $X^{t}QX$\n - `vector_compare` to compute a sequence of linear constraint from two sequences of expressions\n", "apps": [], "results": {"msg": [{"data": "

Use the \"advanced model\" class

\n

\n

DOcplex contains and AdvModel class, which is a subclass of Model.

\n

This class contains highly efficient methods for special cases, for examples, scalar prodicts with all different variables.

\n

By default, AdvModel methods do not perform any checking on their arguments. For example, the cal_prod_vars_all_different method does not check that the variables are indeed all different. If this is not true, then errors or incorrect results may occur.

\n

\n

Still, you can enable type-checking on AdvModel by specifying checker=\"on\" at construction time, and remove it later.

\n

\n

The benchmark model is a good fit for the scal_prod_vars_all_different method as all our scalar products involve the ys variables.

\n

\n

AdvModel provides other specialized fast method, among them:

\n

\n
    \n
  • sum_vars_all_different to compute the sum of a sequence of all different variables.
  • \n
\n
    \n
  • quad_matrix_sum to compute a quadratic expression from a matrix $Q$ and a vector of variables $X$ as $X^{t}QX$
  • \n
\n
    \n
  • vector_compare to compute a sequence of linear constraint from two sequences of expressions
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.advmodel import AdvModel\n\ndef build_bench_model7(size=10):\n m = AdvModel(name=\"bench7\", ignore_names=True, checker='off')\n rsize = range(size)\n # create variables as a dictionary indexed by the range\n ys = m.binary_var_list(rsize, name=\"y\")\n # create constraints\n m.add_constraints((m.scal_prod_vars_all_different(ys, [(i+ (i+j)%3) for j in rsize]) >= i for i in rsize),\n (\"ct_%d\" % i for i in rsize))\n \n # for minimize, use comprehension\n m.minimize(m.scal_prod_vars_all_different(ys, (i+1 for i in rsize)))\n return m\n\nwith ContextTimer(\"bench7 size={0}\".format(N)):\n build_bench_model7(N)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n# Summary\n\nFrom version 1 to version 7 , model build time has decreased from 35s to 4s (on our platform). Result smay well differ on other platforms, but still, this demonstrates that the way the model is built can greatly influence the performance.\n\nHere is a list of tricks to try to improve model building time:\n\n - Use Model.scal_prod wherever possible\n - Add constraints in batches, not one by one\n - Leverage Python comprehensions to avoid unnecessary data structures\n - Try ignoring name generation (for large models)\n - Try disabling all argument checking\n - Eventually, look at specialized methods in the `AdvModel` class.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

From version 1 to version 7 , model build time has decreased from 35s to 4s (on our platform). Result smay well differ on other platforms, but still, this demonstrates that the way the model is built can greatly influence the performance.

\n

\n

Here is a list of tricks to try to improve model building time:

\n

\n
    \n
  • Use Model.scal_prod wherever possible
  • \n
\n
    \n
  • Add constraints in batches, not one by one
  • \n
\n
    \n
  • Leverage Python comprehensions to avoid unnecessary data structures
  • \n
\n
    \n
  • Try ignoring name generation (for large models)
  • \n
\n
    \n
  • Try disabling all argument checking
  • \n
\n
    \n
  • Eventually, look at specialized methods in the AdvModel class.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Plotting the trend\n\nIn this section we compute the times to build different model versions on various sizes, and\nplot the result on a graph.\nThis code requires the `matplotlib` library to run.\n\n**Note**: the next cell might take a significant time to run, as it\nruns a lot of (size, model_build_function) combinations...", "apps": [], "results": {"msg": [{"data": "

Plotting the trend

\n

\n

In this section we compute the times to build different model versions on various sizes, and

\n

plot the result on a graph.

\n

This code requires the matplotlib library to run.

\n

\n

Note: the next cell might take a significant time to run, as it

\n

runs a lot of (size, modelbuildfunction) combinations...

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# various sizes to sample performance\nsizes = [100, 300, 600, 1000, 3000, 5000]\n\n# a lits of tuples (fn, label) to build model and an explanatory label\nbuilders = [(build_bench_model1, \"initial\"), \n (build_bench_model2, \"scal_prod\"),\n (build_bench_model4, \"batch_cts\"),\n (build_bench_model5, \"ignore_names\"),\n (build_bench_model6, \"checker_off\"),\n (build_bench_model7, \"advmodel\")]\nprint(\"* start computing performance data\")\nres = {}\nprint(\"* start computing results...\")\nnb_runs = len(sizes) * len(builders)\nr = 0\nfor s in sizes:\n for b, (bf, _) in enumerate(builders):\n r +=1 \n with ContextTimer(\"[{2}/{3}] use {0} with size={1}\"\n .format(bf.__name__, s, r, nb_runs)) as tt:\n m = bf(s)\n m.end()\n elapsed = tt.msecs\n res[b, s] = tt.msecs\n\n\nprint(\"* end computing results\")\n# now we have a dict of (#builder, size) -> time", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ntry:\n import matplotlib.pyplot as plt\n except ImportError:\n print(\"try install matplotlib: pip install matplotlib\")\n raise\n\n\nlabels = [ bl for (_, bl) in builders]\nplt.figure(figsize=(16,7))\nfor b in range(len(builders)):\n bts = [res[b,s]/1000 for s in sizes]\n plt.plot(sizes, bts, label=labels[b])\n plt.legend()\n\nplt.show()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Average improvement\n\nIn the next cell, we compute the geometric mean of improvment between the first and last versions. Of course, results may differ depending on platform (and the model, too) but the idea is, applying the above rules may yield a significant improvement", "apps": [], "results": {"msg": [{"data": "

Average improvement

\n

\n

In the next cell, we compute the geometric mean of improvment between the first and last versions. Of course, results may differ depending on platform (and the model, too) but the idea is, applying the above rules may yield a significant improvement

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# compute geomerical mean for all sizes\nnb_builders = len(builders)\nratios = {}\nfor s in sizes:\n initial = res[0, s]\n final = res[nb_builders-1, s]\n r = (initial/final)\n ratios[s] = r\n\nimport math\nrgm = math.exp(sum(math.log(r) for r in ratios.values()) / float(nb_builders))\nprint(\"* geometric mean of time improvement is {0:.1f}\".format(rgm))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}]} \ No newline at end of file diff --git a/examples/mp/zeppelin/lifegame.json b/examples/mp/zeppelin/lifegame.json new file mode 100644 index 0000000..47dd4b8 --- /dev/null +++ b/examples/mp/zeppelin/lifegame.json @@ -0,0 +1 @@ +{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "C:\\Users\\AURELIEFolacci\\python\\workspace\\docplex\\docplex\\src\\samples\\examples\\delivery\\jupyter\\lifegame", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Using logical constraints: Conway's Game of Life\n\nThis tutorial includes everything you need to set up decision optimization engines, build a mathematical programming model, leveraging logical constraints.\n\n\nWhen you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n\n>This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n\nThis model is greater than the size allowed in trial mode of CPLEX.\n>It requires a **local installation of CPLEX Optimizers**. \n\nDiscover us [here](https://developer.ibm.com/docloud)\n\n\nTable of contents:\n\n- Describe the business problem\n* How decision optimization (prescriptive analytics) can help\n* Use decision optimization\n * Step 1: Import the library\n * Step 2: Set up the prescriptive model\n * Step 3: Solve the problem with default CPLEX algorithm\n* Summary\n****", "apps": [], "results": {"msg": [{"data": "

Using logical constraints: Conway's Game of Life

\n

\n

This tutorial includes everything you need to set up decision optimization engines, build a mathematical programming model, leveraging logical constraints.

\n

\n

\n

When you finish this tutorial, you'll have a foundational knowledge of Prescriptive Analytics.

\n

\n
\n

This notebook is part of the Prescriptive Analytics for Python

\n
\n

\n

This model is greater than the size allowed in trial mode of CPLEX.

\n
\n

It requires a local installation of CPLEX Optimizers.

\n
\n

\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n
    \n
  • Describe the business problem
  • \n
\n
    \n
  • How decision optimization (prescriptive analytics) can help
  • \n
\n
    \n
  • Use decision optimization
  • \n
\n
*  Step 1: Import the library\n
\n
*  Step 2: Set up the prescriptive model\n
\n
*  Step 3: Solve the problem with default CPLEX algorithm\n
\n
    \n
  • Summary
  • \n
\n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nThis example is demonstrating **Life Game from Robert Bosch and Michael Trick, CP 2001, CPAIOR 2002.** using CPLEX\n\nThe original paper can be found [here](http://repository.cmu.edu/tepper/507)\nIt is based on [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) and is a basic integer program with birth constraints.\n\nTo begin the game, the player places checkers on some of the cells of the board, creating an initial pattern.\nA cell with a checker in it is living and those without are dead.\nThe pattern is then modified by applying the following rules over ad over abain.\n* If a cell has exactly two living neighbors, then its state remain the same in the new pattern (if living, it remains living, if dead it remains dead).\n* If a cell has exactly three living neightbors, then it is living in the next pattern. This is a birth condition.\n* If a cell has fewer than 2 or more than 3 living neighbors, then it is dead in the next pattern. These are the death by isolation and death by overcrowding conditions reespectively.\n", "apps": [], "results": {"msg": [{"data": "

This example is demonstrating Life Game from Robert Bosch and Michael Trick, CP 2001, CPAIOR 2002. using CPLEX

\n

\n

The original paper can be found here

\n

It is based on Conway's Game of Life and is a basic integer program with birth constraints.

\n

\n

To begin the game, the player places checkers on some of the cells of the board, creating an initial pattern.

\n

A cell with a checker in it is living and those without are dead.

\n

The pattern is then modified by applying the following rules over ad over abain.

\n
    \n
  • If a cell has exactly two living neighbors, then its state remain the same in the new pattern (if living, it remains living, if dead it remains dead).
  • \n
\n
    \n
  • If a cell has exactly three living neightbors, then it is living in the next pattern. This is a birth condition.
  • \n
\n
    \n
  • If a cell has fewer than 2 or more than 3 living neighbors, then it is dead in the next pattern. These are the death by isolation and death by overcrowding conditions reespectively.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## How decision optimization can help\n\n* Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes. \n\n* Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes. \n\n* Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage. \n
\n\nWith prescriptive analytics, you can: \n\n* Automate the complex decisions and trade-offs to better manage your limited resources.\n* Take advantage of a future opportunity or mitigate a future risk.\n* Proactively update recommendations based on changing events.\n* Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.\n\n", "apps": [], "results": {"msg": [{"data": "

How decision optimization can help

\n

\n
    \n
  • Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage.
  • \n
\n


\n

\n

With prescriptive analytics, you can:

\n

\n
    \n
  • Automate the complex decisions and trade-offs to better manage your limited resources.
  • \n
\n
    \n
  • Take advantage of a future opportunity or mitigate a future risk.
  • \n
\n
    \n
  • Proactively update recommendations based on changing events.
  • \n
\n
    \n
  • Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.
  • \n
\n

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use decision optimization", "apps": [], "results": {"msg": [{"data": "

Use decision optimization

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 1: Import the library\n\nRun the following code to import Decision Optimization CPLEX Modeling library. The *DOcplex* library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.", "apps": [], "results": {"msg": [{"data": "

Step 1: Import the library

\n

\n

Run the following code to import Decision Optimization CPLEX Modeling library. The DOcplex library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\niimport sys\ntry:\n import docplex.mp\nexcept:\n raise Exception('Please install docplex. See https://pypi.org/project/docplex/')", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nA restart of the kernel might be needed if you updated docplex.", "apps": [], "results": {"msg": [{"data": "

A restart of the kernel might be needed if you updated docplex.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 2: Set up the prescriptive model", "apps": [], "results": {"msg": [{"data": "

Step 2: Set up the prescriptive model

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.model import Model\nimport math\n\nfrom collections import namedtuple\n\nTdv = namedtuple('Tdv', ['dx', 'dy'])\n\nneighbors = [Tdv(i, j) for i in (-1, 0, 1) for j in (-1, 0, 1) if i or j]\n\nassert len(neighbors) == 8", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nn = 6", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nassert Model.supports_logical_constraints(), \"This model requires logical constraints cplex.version must be 12.80 or higher\"\n", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nlm = Model(name='game_of_life_{0}'.format(n))\nborder = range(0, n + 2)\ninside = range(1, n + 1)\n\n# one binary var per cell\nlife = lm.binary_var_matrix(border, border, name=lambda rc: 'life_%d_%d' % rc)\n\n# store sum of alive neighbors for interior cells\nsum_of_neighbors = {(i, j): lm.sum(life[i + n.dx, j + n.dy] for n in neighbors) for i in inside for j in inside}\n\n# all borderline cells are dead\nfor j in border:\n life[0, j].ub = 0\n life[j, 0].ub = 0\n life[j, n + 1].ub = 0\n life[n + 1, j].ub = 0\n", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nThe sum of alive neighbors for an alive cell is greater than 2", "apps": [], "results": {"msg": [{"data": "

The sum of alive neighbors for an alive cell is greater than 2

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfor i in inside:\n for j in inside:\n lm.add(2 * life[i, j] <= sum_of_neighbors[i, j])", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nThe sum of alive neighbors for an alive cell is less than 3", "apps": [], "results": {"msg": [{"data": "

The sum of alive neighbors for an alive cell is less than 3

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfor i in inside:\n for j in inside:\n lm.add(5 * life[i, j] + sum_of_neighbors[i, j] <= 8)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nFor a dead cell, the sum of alive neighbors cannot be 3", "apps": [], "results": {"msg": [{"data": "

For a dead cell, the sum of alive neighbors cannot be 3

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfor i in inside:\n for j in inside:\n ct3 = sum_of_neighbors[i, j] == 3\n lm.add(ct3 <= life[i, j]) # use logical cts here", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nSatisfy the 'no 3 alive neighbors for extreme rows, columns", "apps": [], "results": {"msg": [{"data": "

Satisfy the 'no 3 alive neighbors for extreme rows, columns

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfor i in border:\n if i < n:\n for d in [1, n]:\n lm.add(life[i, d] + life[i + 1, d] + life[i + 2, d] <= 2)\n lm.add(life[d, i] + life[d, i + 1] + life[d, i + 2] <= 2)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nSymmetry breaking", "apps": [], "results": {"msg": [{"data": "

Symmetry breaking

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nn2 = int(math.ceil(n/2))\nhalf1 = range(1, n2 + 1)\nhalf2 = range(n2 + 1, n)\n\n# there are more alive cells in left side\nlm.add(lm.sum(life[i1, j1] for i1 in half1 for j1 in inside) >= lm.sum(life[i2, j2] for i2 in half2 for j2 in inside))\n\n# there are more alive cells in upper side\nlm.add(lm.sum(life[i1, j1] for i1 in inside for j1 in half1) >= lm.sum(life[i2, j2] for i2 in inside for j2 in half2))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nSetting up the objective: find maximum number of alive cells", "apps": [], "results": {"msg": [{"data": "

Setting up the objective: find maximum number of alive cells

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nlm.maximize(lm.sum(life))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# add a dummy kpi\nnlines = lm.sum( (lm.sum(life[i,j] for j in inside) >= 1) for i in inside)\nlm.add_kpi(nlines, 'nlines')\n\n# parameters: branch up, use heusristics, emphasis on opt, threads free\nlm.parameters.mip.strategy.branch = 1\nlm.parameters.mip.strategy.heuristicfreq = 10\nlm.parameters.emphasis.mip = 2\nlm.parameters.threads = 0", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\n# store data items as fields\nlm.size = n\nlm.life = life\n", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nborder3 = range(1, lm.size-1, 3)\nlife_vars = lm.life\nvvmap = {}\nfor i in border3:\n for j in border3:\n vvmap[life_vars[i, j]] = 1\n vvmap[life_vars[i+1, j]] = 1\n vvmap[life_vars[i, j+1]] = 1\n vvmap[life_vars[i+1, j+1]] = 1\n\nini_s = lm.new_solution(var_value_dict=vvmap)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nassert ini_s.check(), 'error in initial solution'", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nlm.add_mip_start(ini_s)", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 3: Solve the problem with default CPLEX algorithm", "apps": [], "results": {"msg": [{"data": "

Step 3: Solve the problem with default CPLEX algorithm

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nassert lm.solve(log_output=True), \"!!! Solve of the model fails\"\nlm.report()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\ndef lifegame_solution_to_matrix(mdl):\n rr = range(0, mdl.size+2)\n life_vars = mdl.life\n array2 = [[life_vars[i, j].solution_value for j in rr] for i in rr]\n return array2", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nprint(lifegame_solution_to_matrix(lm))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Summary\n\n\nYou learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model with logical constraints.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

\n

You learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model with logical constraints.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### References\n* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n", "apps": [], "results": {"msg": [{"data": "

References

\n\n\n
    \n
  • Need help with DOcplex or to report a bug? Please go here
  • \n
\n
    \n
  • Contact us at dofeedback@wwpdl.vnet.ibm.com\"
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nCopyright \u00a9 2017-2018 IBM. Sample Materials.", "apps": [], "results": {"msg": [{"data": "

Copyright \u00a9 2017-2018 IBM. Sample Materials.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}]} \ No newline at end of file diff --git a/examples/mp/zeppelin/logical_cts.json b/examples/mp/zeppelin/logical_cts.json new file mode 100644 index 0000000..92b3237 --- /dev/null +++ b/examples/mp/zeppelin/logical_cts.json @@ -0,0 +1 @@ +{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "C:\\Users\\AURELIEFolacci\\python\\workspace\\docplex\\docplex\\src\\samples\\examples\\delivery\\jupyter\\logical_cts", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Use logical constraints with decision optimization\n\nThis tutorial includes everything you need to set up decision optimization engines, build a mathematical programming model, leveraging logical constraints.\n\n\nWhen you finish this tutorial, you'll have a foundational knowledge of _Prescriptive Analytics_.\n\n>This notebook is part of the **[Prescriptive Analytics for Python](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)**\n\n>It requires an [installation of CPLEX Optimizers](http://ibmdecisionoptimization.github.io/docplex-doc/getting_started.html)\n\nDiscover us [here](https://developer.ibm.com/docloud)\n\n\nTable of contents:\n\n- Describe the business problem\n* How decision optimization (prescriptive analytics) can help\n* Use decision optimization\n * Step 1: Import the library\n * Step 2: Learn about constraint truth values\n * Step 3: Learn about equivalence constraints\n* Summary\n****", "apps": [], "results": {"msg": [{"data": "

Use logical constraints with decision optimization

\n

\n

This tutorial includes everything you need to set up decision optimization engines, build a mathematical programming model, leveraging logical constraints.

\n

\n

\n

When you finish this tutorial, you'll have a foundational knowledge of Prescriptive Analytics.

\n

\n
\n

This notebook is part of the Prescriptive Analytics for Python

\n
\n

\n
\n

It requires an installation of CPLEX Optimizers

\n
\n

\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n
    \n
  • Describe the business problem
  • \n
\n
    \n
  • How decision optimization (prescriptive analytics) can help
  • \n
\n
    \n
  • Use decision optimization
  • \n
\n
*  Step 1: Import the library\n
\n
*  Step 2: Learn about constraint truth values\n
\n
*  Step 3: Learn about equivalence constraints\n
\n
    \n
  • Summary
  • \n
\n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nLogical constraints let you use the _truth value_ of constraints inside the model. The truth value of a constraint \nis true when it is satisfied and false when not. Adding a constraint to a model ensures that it is always satisfied. \nHowever, with logical constraints, one can use the truth value of a constraint _inside_ the model, allowing to choose dynamically whether a constraint is to be satisfied (or not).", "apps": [], "results": {"msg": [{"data": "

Logical constraints let you use the truth value of constraints inside the model. The truth value of a constraint

\n

is true when it is satisfied and false when not. Adding a constraint to a model ensures that it is always satisfied.

\n

However, with logical constraints, one can use the truth value of a constraint inside the model, allowing to choose dynamically whether a constraint is to be satisfied (or not).

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## How decision optimization can help\n\n* Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes. \n\n* Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes. \n\n* Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage. \n
\n\nWith prescriptive analytics, you can: \n\n* Automate the complex decisions and trade-offs to better manage your limited resources.\n* Take advantage of a future opportunity or mitigate a future risk.\n* Proactively update recommendations based on changing events.\n* Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.\n\n", "apps": [], "results": {"msg": [{"data": "

How decision optimization can help

\n

\n
    \n
  • Prescriptive analytics (decision optimization) technology recommends actions that are based on desired outcomes. It takes into account specific scenarios, resources, and knowledge of past and current events. With this insight, your organization can make better decisions and have greater control of business outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics is the next step on the path to insight-based actions. It creates value through synergy with predictive analytics, which analyzes data to predict future outcomes.
  • \n
\n

\n
    \n
  • Prescriptive analytics takes that insight to the next level by suggesting the optimal way to handle that future situation. Organizations that can act fast in dynamic conditions and make superior decisions in uncertain environments gain a strong competitive advantage.
  • \n
\n


\n

\n

With prescriptive analytics, you can:

\n

\n
    \n
  • Automate the complex decisions and trade-offs to better manage your limited resources.
  • \n
\n
    \n
  • Take advantage of a future opportunity or mitigate a future risk.
  • \n
\n
    \n
  • Proactively update recommendations based on changing events.
  • \n
\n
    \n
  • Meet operational goals, increase customer loyalty, prevent threats and fraud, and optimize business processes.
  • \n
\n

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Use decision optimization", "apps": [], "results": {"msg": [{"data": "

Use decision optimization

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 1: Import the library\n\nRun the following code to import Decision Optimization CPLEX Modeling library. The *DOcplex* library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.", "apps": [], "results": {"msg": [{"data": "

Step 1: Import the library

\n

\n

Run the following code to import Decision Optimization CPLEX Modeling library. The DOcplex library contains the two modeling packages, Mathematical Programming and Constraint Programming, referred to earlier.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nimport sys\ntry:\n import docplex.mp\nexcept:\n raise Exception('Please install docplex. See https://pypi.org/project/docplex/')", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nA restart of the kernel might be needed.", "apps": [], "results": {"msg": [{"data": "

A restart of the kernel might be needed.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 2: Learn about constraint truth values\n\nAny discrete linear constraint can be associated to a binary variable that holds the truth value of the constraint. \nBut first, let's explain what a discrete constraint is", "apps": [], "results": {"msg": [{"data": "

Step 2: Learn about constraint truth values

\n

\n

Any discrete linear constraint can be associated to a binary variable that holds the truth value of the constraint.

\n

But first, let's explain what a discrete constraint is

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Discrete linear constraint\n\nA discrete linear constraint is built from discrete coefficients and discrete variables, taht is variables with type `integer` or `binary`. For example, assuming x and y are integer variables:\n\n - `2x+3y == 1` is discrete\n - `x+y = 3.14` is not (because of 3.14)\n - `1.1 x + 2.2 y <= 3` is not because of the non-integer coefficients 1.1 and 2.2", "apps": [], "results": {"msg": [{"data": "

Discrete linear constraint

\n

\n

A discrete linear constraint is built from discrete coefficients and discrete variables, taht is variables with type integer or binary. For example, assuming x and y are integer variables:

\n

\n
    \n
  • 2x+3y == 1 is discrete
  • \n
\n
    \n
  • x+y = 3.14 is not (because of 3.14)
  • \n
\n
    \n
  • 1.1 x + 2.2 y <= 3 is not because of the non-integer coefficients 1.1 and 2.2
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### The truth value of an added constraint is always 1\n\nThe truth value of a constraint is accessed by the `status_var` property. This varianle is aplain Docplex decision variable that can be used anywhere a variable can. However, the value of the truth value variable and the constraint are linked, both ways:\n\n - a constraint is satisfied if and only if its truth value variable equals 1\n - a constraint is _not_ satisfied if and only if its truth value variable equals 0.\n\nIn this toy model,we show that the truth value of a constraint which has been added to a model is always equal to 1.", "apps": [], "results": {"msg": [{"data": "

The truth value of an added constraint is always 1

\n

\n

The truth value of a constraint is accessed by the status_var property. This varianle is aplain Docplex decision variable that can be used anywhere a variable can. However, the value of the truth value variable and the constraint are linked, both ways:

\n

\n
    \n
  • a constraint is satisfied if and only if its truth value variable equals 1
  • \n
\n
    \n
  • a constraint is not satisfied if and only if its truth value variable equals 0.
  • \n
\n

\n

In this toy model,we show that the truth value of a constraint which has been added to a model is always equal to 1.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nfrom docplex.mp.model import Model\n\nm1 = Model()\nx = m1.integer_var(name='ix')\ny = m1.integer_var(name='iy')\nct = m1.add(x + y <= 3)\nct_truth = ct.status_var\nm1.maximize(x+y)\nassert m1.solve()\nprint('the truth value of [{0!s}] is {1}'.format(ct, ct_truth.solution_value))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### The truth value of a constraint not added to a model is undefined\n\nA constraint that is not added to a model, has no effect. Its truth value is undefined: it can be either 1 or 0.\n\nIn the following example, both `x` and `y` are set to their upper bound, so that the constraint is not satisfied; hence the truth value is 0.", "apps": [], "results": {"msg": [{"data": "

The truth value of a constraint not added to a model is undefined

\n

\n

A constraint that is not added to a model, has no effect. Its truth value is undefined: it can be either 1 or 0.

\n

\n

In the following example, both x and y are set to their upper bound, so that the constraint is not satisfied; hence the truth value is 0.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm2 = Model()\nx = m2.integer_var(name='ix', ub=4)\ny = m2.integer_var(name='iy', ub=4)\nct = (x + y <= 3)\nct_truth = ct.status_var # not m2.add() here!\nm2.maximize(x+y)\nassert m2.solve()\nm2.print_solution()\nprint('the truth value of [{0!s}] is {1}'.format(ct, ct_truth.solution_value))", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Using constraint truth values in modeling\n\nA constraint's truth value is actually a plain DOcplex decision variable, and as such, can be used with comparison operators and arithmetic operators.\nLet's experiment again with a toy model: in this model,\nwe state that the truth value of `y == 4` is less than the truth value of `x ==3`.\nAs we maximize y, y has value 4 in the optimal solution (it is the upper bound), and consequently the constraint `ct_y4` is satisfied. From the inequality between truth values,\nit follows that the truth value of `ct_x2` equals 1 and x is equal to 2.\n\nUsing the constraints in the inequality has silently converted each constraint into its truth value.", "apps": [], "results": {"msg": [{"data": "

Using constraint truth values in modeling

\n

\n

A constraint's truth value is actually a plain DOcplex decision variable, and as such, can be used with comparison operators and arithmetic operators.

\n

Let's experiment again with a toy model: in this model,

\n

we state that the truth value of y == 4 is less than the truth value of x ==3.

\n

As we maximize y, y has value 4 in the optimal solution (it is the upper bound), and consequently the constraint ct_y4 is satisfied. From the inequality between truth values,

\n

it follows that the truth value of ct_x2 equals 1 and x is equal to 2.

\n

\n

Using the constraints in the inequality has silently converted each constraint into its truth value.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm3 = Model()\nx = m3.integer_var(name='ix', ub=4)\ny = m3.integer_var(name='iy', ub=4)\nct_x2 = (x == 2)\nct_y4 = (y == 4)\nm3.add( ct_y4 <= ct_x2 )\nm3.maximize(y)\nassert m3.solve()\nm3.print_solution()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nConstraint truth values can be used with arithmetic operators, just as variables can. In th enext model, we express a more complex constraint:\n- either x is equal to 3, _or_ both y and z are equal to 5\n\nLet's see how we can express this easilty with truth values:", "apps": [], "results": {"msg": [{"data": "

Constraint truth values can be used with arithmetic operators, just as variables can. In th enext model, we express a more complex constraint:

\n
    \n
  • either x is equal to 3, or both y and z are equal to 5
  • \n
\n

\n

Let's see how we can express this easilty with truth values:

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm31 = Model(name='m31')\nx = m31.integer_var(name='ix', ub=4)\ny = m31.integer_var(name='iy', ub=10)\nz = m31.integer_var(name='iz', ub=10)\nct_x2 = (x == 3)\nct_y5 = (y == 5)\nct_z5 = (z == 5)\n#either ct-x2 is true or -both- ct_y5 and ct_z5 mus be true\nm31.add( 2 * ct_x2 + (ct_y5 + ct_z5) == 2)\n# force x to be less than 2: it cannot be equal to 3!\nm31.add(x <= 2)\n# maximize sum of x,y,z\nm31.maximize(x+y+z)\nassert m31.solve()\n# the expected solution is: x=2, y=5, z=5\nassert m31.objective_value == 12\nm31.print_solution()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nAs we have seen, constraints can be used in expressions. This includes the `Model.sum()` and `Model.dot()` aggregation methods.\n\nIn the next model, we define ten variables, one of which must be equal to 3 (we dpn't care which one, for now). As we maximize the sum of all `xs` variables, all will end up equal to their upper bound, except for one.", "apps": [], "results": {"msg": [{"data": "

As we have seen, constraints can be used in expressions. This includes the Model.sum() and Model.dot() aggregation methods.

\n

\n

In the next model, we define ten variables, one of which must be equal to 3 (we dpn't care which one, for now). As we maximize the sum of all xs variables, all will end up equal to their upper bound, except for one.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm4 = Model()\nxs = m4.integer_var_list(10, ub=100)\ncts = [xi==3 for xi in xs]\nm4.add( m4.sum(cts) == 1)\nm4.maximize(m4.sum(xs))\nassert m4.solve()\nm4.print_solution()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nAs we can see, all variables but one are set to their upper bound of 100. We cannot predict which variable will be set to 3. \nHowever, let's imagine that we prefer variable with a lower index to be set to 3, how can we express this preference? \n\nThe answer is to use an additional expression to the objective, using a scalar product of constraint truth value", "apps": [], "results": {"msg": [{"data": "

As we can see, all variables but one are set to their upper bound of 100. We cannot predict which variable will be set to 3.

\n

However, let's imagine that we prefer variable with a lower index to be set to 3, how can we express this preference?

\n

\n

The answer is to use an additional expression to the objective, using a scalar product of constraint truth value

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\npreference = m4.dot(cts, (k+1 for k in range(len(xs))))\n# we prefer lower indices for satisfying the x==3 constraint\n# so the final objective is a maximize of sum of xs -minus- the preference\nm4.maximize(m4.sum(xs) - preference)\nassert m4.solve()\nm4.print_solution()", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nAs expected, the `x` variable set to 3 now is the first one.", "apps": [], "results": {"msg": [{"data": "

As expected, the x variable set to 3 now is the first one.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Using truth values to state 'not equals' constraints.\n\nTruth values can be used to express elegantly 'not equal' constraints, by forcing the truth value of an equality constraint to 0.\n\nIn the next model, we illustrate how an equality constraint can be negated by forcing its truth value to zero. This negation forbids y to be equal to 4, as it would be without this negation.\nFinally, the objective is 7 instead of 8.", "apps": [], "results": {"msg": [{"data": "

Using truth values to state 'not equals' constraints.

\n

\n

Truth values can be used to express elegantly 'not equal' constraints, by forcing the truth value of an equality constraint to 0.

\n

\n

In the next model, we illustrate how an equality constraint can be negated by forcing its truth value to zero. This negation forbids y to be equal to 4, as it would be without this negation.

\n

Finally, the objective is 7 instead of 8.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm5 = Model()\nx = m5.integer_var(name='ix', ub=4)\ny = m5.integer_var(name='iy', ub=4)\n# this is the equality constraint we want to negate\nct_y4 = (y == 4)\n# forcing truth value to zero means the constraint is not satisfied.\nnegation = m5.add( ct_y4 == 0)\n# maximize x+y should yield both variables to 4, but y cannot be equal to 4\n# as such we expect y to be equal to 3\nm5.maximize(x + y)\nassert m5.solve()\nm5.print_solution()\n# expecting 7 as objective, not 8\nassert m5.objective_value == 7\n\n# now remove the negation\nm5.remove_constraint(negation)\n# and solve again\nassert m5.solve()\n# the objective is 8 as expected: both x and y are equal to 4\nassert m5.objective_value == 8", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### Summary\n\nWe have seen that linear constraints have an associated binary variable, its _truth value_, whose value is linked to whether or not the constraint is satisfied. \nMoreover, this llink enables to express 'not equals' constraints.# now remove netation", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

We have seen that linear constraints have an associated binary variable, its truth value, whose value is linked to whether or not the constraint is satisfied.

\n

Moreover, this llink enables to express 'not equals' constraints.# now remove netation

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n### Step 3: Learn about equivalence constraints\n\nAs we have seen, using a constraint in expressions automtically generates a truth value variable, whose value is linked to the status of the constraint. \n\nHowever, in some cases, it can be useful to relate the status of a constraint to an _existing_ binary variable. This is the purpose of equivalence constraints.\n\nAn equiavelnec constraints relates an existing binary variable to the status of a discrete linear constraints. The syntax is:\n\n `Model.add_equivalence(bvar, linear_ct, active_value, name)`\n \n - `bvar` is the existing binary variable\n - `linear-ct` is a discrete linear constraint\n - `active_value` can take values 1 or 0 (the default is 1)\n - `name` is an optional string to name the equivalence.", "apps": [], "results": {"msg": [{"data": "

Step 3: Learn about equivalence constraints

\n

\n

As we have seen, using a constraint in expressions automtically generates a truth value variable, whose value is linked to the status of the constraint.

\n

\n

However, in some cases, it can be useful to relate the status of a constraint to an existing binary variable. This is the purpose of equivalence constraints.

\n

\n

An equiavelnec constraints relates an existing binary variable to the status of a discrete linear constraints. The syntax is:

\n

\n
`Model.add_equivalence(bvar, linear_ct, active_value, name)`\n
\n

\n
    \n
  • bvar is the existing binary variable
  • \n
\n
    \n
  • linear-ct is a discrete linear constraint
  • \n
\n
    \n
  • active_value can take values 1 or 0 (the default is 1)
  • \n
\n
    \n
  • name is an optional string to name the equivalence.
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%python\nm6 = Model(name='m6')\nsize = 7\nil = m6.integer_var_list(size, name='i', ub=10)\njl = m6.integer_var_list(size, name='j', ub=10)\nbl = m6.binary_var_list(size, name='b')\nfor k in range(size):\n # for each i, relate bl_k to il_k==5 *and* jl_k == 7\n m6.add_equivalence(bl[k], il[k] == 5)\n m6.add_equivalence(bl[k], jl[k] == 7)\n# now maximize sum of bs\nm6.maximize(m6.sum(bl))\nassert m6.solve()\nm6.print_solution()\n\n", "apps": [], "results": {"msg": [{"data": "", "type": "ANGULAR"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": false, "language": "python"}, "editorMode": "ace/mode/python", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n## Summary\n\n\nYou learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model with logical constraints.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

\n

You learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Mathematical Programming model with logical constraints.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\n#### References\n* [Decision Optimization CPLEX Modeling for Python documentation](https://rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/index.html)\n* [Decision Optimization on Cloud](https://developer.ibm.com/docloud/)\n* Need help with DOcplex or to report a bug? Please go [here](https://developer.ibm.com/answers/smartspace/docloud)\n* Contact us at dofeedback@wwpdl.vnet.ibm.com\"\n", "apps": [], "results": {"msg": [{"data": "

References

\n\n\n
    \n
  • Need help with DOcplex or to report a bug? Please go here
  • \n
\n
    \n
  • Contact us at dofeedback@wwpdl.vnet.ibm.com\"
  • \n
\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}, {"settings": {"forms": {}, "params": {}}, "text": "%md\nCopyright \u00a9 2017-2018 IBM. Sample Materials.", "apps": [], "results": {"msg": [{"data": "

Copyright \u00a9 2017-2018 IBM. Sample Materials.

\n", "type": "HTML"}], "code": "SUCCESS"}, "user": "anonymous", "config": {"editorSetting": {"editOnDblClick": true, "language": "markdown"}, "editorMode": "ace/mode/markdown", "colWidth": 12, "enabled": true, "results": {}}}]} \ No newline at end of file