diff --git a/examples/cp/basic/facility.py b/examples/cp/basic/facility.py index ec2623b..d6896c2 100644 --- a/examples/cp/basic/facility.py +++ b/examples/cp/basic/facility.py @@ -35,10 +35,10 @@ # Initialize the problem data #----------------------------------------------------------------------------- -Warehouse = namedtuple('Wharehouse', ('city', # Name of the city - 'capacity', # Capacity of the warehouse - 'cost', # Warehouse building cost - )) +Warehouse = namedtuple('Warehouse', ('city', # Name of the city + 'capacity', # Capacity of the warehouse + 'cost', # Warehouse building cost + )) # List of warehouses WAREHOUSES = (Warehouse("Bonn", 3, 480), diff --git a/examples/cp/zeppelin/SteelMill.json b/examples/cp/zeppelin/SteelMill.json deleted file mode 100644 index cecb94f..0000000 --- a/examples/cp/zeppelin/SteelMill.json +++ /dev/null @@ -1 +0,0 @@ -{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "cp/jupyter/SteelMill", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Building steel coils\n\nThis tutorial includes everything you need to set up decision optimization engines, build constraint programming models.\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 a valid subscription to **Decision Optimization on the Cloud** or a **local installation of CPLEX Optimizers**. \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: Download the library\n * Step 2: Set up the engines\n - Step 3: Model the Data\n * Step 4: 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 solve service\n * Step 5: Investigate the solution and run an example analysis\n* Summary\n****", "apps": [], "results": {"msg": [{"data": "

Building steel coils

\n

\n

This tutorial includes everything you need to set up decision optimization engines, build constraint programming models.

\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 a valid subscription to Decision Optimization on the Cloud or a local installation of CPLEX Optimizers.

\n
\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n\n\n\n
*  Step 1: Download the library\n
\n
*  Step 2: Set up the engines\n
\n
-  Step 3: Model the Data\n
\n
*  Step 4: 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 solve service\n
\n
*  Step 5: Investigate the solution and run an example analysis\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* The problem is to build steel coils from slabs that are available in a work-in-process inventory of semi-finished products. There is no limitation in the number of slabs that can be requested, but only a finite number of slab sizes is available (sizes 11, 13, 16, 17, 19, 20, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 40, 43, 45). \n* The problem is to select a number of slabs to build the coil orders, and to satisfy the following constraints:\n * A coil order can be built from only one slab.\n * Each coil order requires a specific process to build it from a slab. This process is encoded by a color.\n * Several coil orders can be built from the same slab. But a slab can be used to produce at most two different \"colors\" of coils.\n * The sum of the sizes of each coil order built from a slab must not exceed the slab size.\n\n\n* Finally, the production plan should minimize the unused capacity of the selected slabs.\n\n\n* This problem is based on **\"prob038: Steel mill slab design problem\" from CSPLib (www.csplib.org). It is a simplification of an industrial problem described in J. R. Kalagnanam, M. W. Dawande, M. Trumbo, H. S. Lee. \"Inventory Matching Problems in the Steel Industry,\" IBM Research Report RC 21171, 1998**.\n\n* Please refer to documentation for appropriate setup of solving configuration.", "apps": [], "results": {"msg": [{"data": "

Describe the business problem

\n

\n\n\n
* A coil order can be built from only one slab.\n
\n
* Each coil order requires a specific process to build it from a slab. This process is encoded by a color.\n
\n
* Several coil orders can be built from the same slab. But a slab can be used to produce at most two different \"colors\" of coils.\n
\n
* The sum of the sizes of each coil order built from a slab must not exceed the slab size.\n
\n

\n

\n\n

\n

\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*****\n## How decision optimization can help\n* Prescriptive analytics technology recommends actions based on desired outcomes, taking into account specific scenarios, resources, and knowledge of past and current events. This insight can help your organization 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+ For example:\n + Automate complex decisions and trade-offs to better manage 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", "apps": [], "results": {"msg": [{"data": "
\n

How decision optimization can help

\n\n

\n\n

\n\n


\n

\n\n
+ Automate complex decisions and trade-offs to better manage limited resources.\n
\n
+ Take advantage of a future opportunity or mitigate a future risk.\n
\n
+ Proactively update recommendations based on changing events.\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: Download the library\n\nRun the following code to install 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: Download the library

\n

\n

Run the following code to install 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\nimport pip\ntry:\n import docplex.cp\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n pip.main(['install', docplex]) \n else:\n pip.main(['install --user', 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.mp that is dedicated to Mathematical Programming, another branch of optimization.", "apps": [], "results": {"msg": [{"data": "

Note that the more global package docplex contains another subpackage docplex.mp that is dedicated to Mathematical 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: Set up the prescriptive engine\n\n* Subscribe to the [Decision Optimization on Cloud solve service](https://developer.ibm.com/docloud).\n* Get the service URL and your personal API key.\n\n__Set your DOcplexcloud credentials:__\n0. A first option is to set the DOcplexcloud url and key directly in the model source file *(see below)*\n1. For a persistent setting, create a Python file __docloud_config.py__ somewhere that is visible from the __PYTHONPATH__", "apps": [], "results": {"msg": [{"data": "

Step 2: Set up the prescriptive engine

\n

\n\n\n

\n

Set your DOcplexcloud credentials:

\n
    \n
  1. A first option is to set the DOcplexcloud url and key directly in the model source file (see below)
  2. \n
\n
    \n
  1. For a persistent setting, create a Python file docloud_config.py somewhere that is visible from the PYTHONPATH
  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": "%python\nSVC_URL = \"ENTER YOUR URL HERE\"\nSVC_KEY = \"ENTER YOUR KEY 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": "%python\nfrom docplex.cp.model import *", "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: Model the data", "apps": [], "results": {"msg": [{"data": "

Step 3: Model the data

\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\nSet model parameter", "apps": [], "results": {"msg": [{"data": "

Set model parameter

\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 collections import namedtuple\n\n##############################################################################\n# Model configuration\n##############################################################################\n\n# The number of coils to produce\nTUPLE_ORDER = namedtuple(\"TUPLE_ORDER\", [\"index\", \"weight\", \"color\"])\norders = [ TUPLE_ORDER(1, 22, 5),\n TUPLE_ORDER(2, 9, 3),\n TUPLE_ORDER(3, 9, 4),\n TUPLE_ORDER(4, 8, 5),\n TUPLE_ORDER(5, 8, 7),\n TUPLE_ORDER(6, 6, 3),\n TUPLE_ORDER(7, 5, 6),\n TUPLE_ORDER(8, 3, 0),\n TUPLE_ORDER(9, 3, 2),\n TUPLE_ORDER(10, 3, 3),\n TUPLE_ORDER(11, 2, 1),\n TUPLE_ORDER(12, 2, 5)\n ]\n\nNB_SLABS = 12\nMAX_COLOR_PER_SLAB = 2\n\n# The total number of slabs available. In theory this can be unlimited,\n# but we impose a reasonable upper bound in order to produce a practical\n# optimization model.\n\n# The different slab weights available.\nslab_weights = [ 0, 11, 13, 16, 17, 19, 20, 23, 24, 25,\n 26, 27, 28, 29, 30, 33, 34, 40, 43, 45 ]", "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\nnb_orders = len(orders)\nslabs = range(NB_SLABS)\nallcolors = set([ o.color for o in orders ])\n\n# CPO needs lists for pack constraint\norder_weights = [ o.weight for o in orders ]\n\n# The heaviest slab\nmax_slab_weight = max(slab_weights)\n\n# The amount of loss incurred for different amounts of slab use\n# The loss will depend on how much less steel is used than the slab\n# just large enough to produce the coils.\nloss = [ min([sw-use for sw in slab_weights if sw >= use]) for use in range(max_slab_weight+1)]", "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 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": "%md\nCreate CPO model", "apps": [], "results": {"msg": [{"data": "

Create CPO 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\nmdl = CpoModel(name=\"trucks\")", "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\n# Which slab is used to produce each coil\nproduction_slab = integer_var_dict(orders, 0, NB_SLABS-1, \"production_slab\")\n\n# How much of each slab is used\nslab_use = integer_var_list(NB_SLABS, 0, max_slab_weight, \"slab_use\")", "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", "apps": [], "results": {"msg": [{"data": "

Express the business 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\n# The total loss is\ntotal_loss = sum([element(slab_use[s], loss) for s in slabs])\n\n# The orders are allocated to the slabs with capacity\nmdl.add(pack(slab_use, [production_slab[o] for o in orders], order_weights))\n\n# At most MAX_COLOR_PER_SLAB colors per slab\nfor s in slabs:\n su = 0\n for c in allcolors:\n lo = False\n for o in orders:\n if o.color==c:\n lo = (production_slab[o] == s) | lo\n su += lo\n mdl.add(su <= MAX_COLOR_PER_SLAB)", "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", "apps": [], "results": {"msg": [{"data": "

Express 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\n# Add minimization objective\nmdl.add(minimize(total_loss))", "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 solve service", "apps": [], "results": {"msg": [{"data": "

Solve with Decision Optimization solve service

\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(\"\\nSolving model....\")\n# Search strategy\nmdl.set_search_phases([search_phase([production_slab[o] for o in orders])])\n\nmsol = mdl.solve(url=SVC_URL, key=SVC_KEY, FailLimit=100000, TimeLimit=10)", "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 5: Investigate the solution and then run an example analysis", "apps": [], "results": {"msg": [{"data": "

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

\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# Print solution\nif msol:\n print(\"Solution: \")\n from_slabs = [set([o.index for o in orders if msol[production_slab[o]]== s])for s in slabs]\n slab_colors = [set([o.color for o in orders if o.index in from_slabs[s]])for s in slabs]\n for s in slabs:\n if len(from_slabs[s]) > 0:\n print(\"Slab = \" + str(s))\n print(\"\\tLoss = \" + str(loss[msol[slab_use[s]]]))\n print(\"\\tcolors = \" + str(slab_colors[s]))\n print(\"\\tOrders = \" + str(from_slabs[s]) + \"\\n\")\nelse:\n print(\"No solution found\")", "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\nYou learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Constraint Programming model and solve it with IBM Decision Optimization on the cloud.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

You learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Constraint Programming model and solve it with IBM Decision Optimization 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": "%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\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 IBM. IPLA licensed Sample Materials.", "apps": [], "results": {"msg": [{"data": "

Copyright \u00a9 2017 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/cp/zeppelin/golomb_ruler.json b/examples/cp/zeppelin/golomb_ruler.json deleted file mode 100644 index b45b04a..0000000 --- a/examples/cp/zeppelin/golomb_ruler.json +++ /dev/null @@ -1 +0,0 @@ -{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "cp/jupyter/golomb_ruler", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n# Golomb Ruler\n\nThis tutorial includes everything you need to set up decision optimization engines, build constraint programming models.\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 a valid subscription to **Decision Optimization on the Cloud** or 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: Download the library\n * Step 2: Set up the engines\n - Step 3: Model 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 solve service\n * Step 5: Investigate the solution and run an example analysis\n* Summary\n****", "apps": [], "results": {"msg": [{"data": "

Golomb Ruler

\n

\n

This tutorial includes everything you need to set up decision optimization engines, build constraint programming models.

\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 a valid subscription to Decision Optimization on the Cloud or a local installation of CPLEX Optimizers.

\n
\n

\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n\n\n\n
*  Step 1: Download the library\n
\n
*  Step 2: Set up the engines\n
\n
-  Step 3: Model 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 solve service\n
\n
*  Step 5: Investigate the solution and run an example analysis\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 detailed description (from which this paragraph comes from) is available on Wikipedia at https://en.wikipedia.org/wiki/Golomb_ruler.\n\n* In mathematics, a Golomb ruler is a set of marks at integer positions along an imaginary ruler such that no two pairs of marks are the same distance apart. The number of marks on the ruler is its order, and the largest distance between two of its marks is its length. \n\nFollowing is an example of Golomb ruler of order 4 and length 6.\n\n

\nThis problem is not only an intellectual problem. It has a lot of practical applications:\n

\n
\n
\n", "apps": [], "results": {"msg": [{"data": "

Describe the business problem

\n

\n\n

\n\n

\n

Following is an example of Golomb ruler of order 4 and length 6.

\n

\n

\n

This problem is not only an intellectual problem. It has a lot of practical applications:

\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*****\n## How decision optimization can help\n* Prescriptive analytics technology recommends actions based on desired outcomes, taking into account specific scenarios, resources, and knowledge of past and current events. This insight can help your organization 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+ For example:\n + Automate complex decisions and trade-offs to better manage 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", "apps": [], "results": {"msg": [{"data": "
\n

How decision optimization can help

\n\n

\n\n

\n\n


\n

\n\n
+ Automate complex decisions and trade-offs to better manage limited resources.\n
\n
+ Take advantage of a future opportunity or mitigate a future risk.\n
\n
+ Proactively update recommendations based on changing events.\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

Modeling the problem

\n

\nConstraint Programming is a programming paradigm that allows to express a problem using:\n

\n

\nAll this information, plus some configuration parameters, is aggregated into a single object called model. \n

\nThe remainder of this notebook describes in details how to build and solve this problem with IBM CP Optimizer, using its DOcplex Python modeling API.", "apps": [], "results": {"msg": [{"data": "

Modeling the problem

\n

\n

Constraint Programming is a programming paradigm that allows to express a problem using:

\n

\n

\n

All this information, plus some configuration parameters, is aggregated into a single object called model.

\n

\n

The remainder of this notebook describes in details how to build and solve this problem with IBM CP Optimizer, using its DOcplex Python modeling API.

\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: Download the library\n\nRun the following code to install 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: Download the library

\n

\n

Run the following code to install 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\nimport pip\ntry:\n import docplex.cp\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n pip.main(['install', docplex]) \n else:\n pip.main(['install --user', 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.mp that is dedicated to Mathematical Programming, another branch of optimization.", "apps": [], "results": {"msg": [{"data": "

Note that the more global package docplex contains another subpackage docplex.mp that is dedicated to Mathematical 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: Set up the prescriptive engine\n\n* Subscribe to the [Decision Optimization on Cloud solve service](https://developer.ibm.com/docloud).\n* Get the service URL and your personal API key.", "apps": [], "results": {"msg": [{"data": "

Step 2: Set up the prescriptive engine

\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": "%python\n# Initialize IBM Decision Optimization credentials\nSVC_URL = \"ENTER YOUR URL HERE\"\nSVC_KEY = \"ENTER YOUR KEY 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\nNow, we need to import all required modeling functions that are provided by the docplex.cp package:", "apps": [], "results": {"msg": [{"data": "

Now, we need to import all required modeling functions that are provided by the docplex.cp package:

\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# Import Constraint Programming modelization functions\nfrom docplex.cp.model import CpoModel", "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: Model the data\n

Define model input data

\n

\nThe first thing to define is the model input data.\nIn the case of the Golomb Ruler problem, there is only one input which is the order of the ruler, that is the number of marks:", "apps": [], "results": {"msg": [{"data": "

Step 3: Model the data

\n

Define model input data

\n

\n

The first thing to define is the model input data.

\n

In the case of the Golomb Ruler problem, there is only one input which is the order of the ruler, that is the number of marks:

\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# Define required number of marks on the ruler\nORDER = 7", "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 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": "%md\n

Create the model container

\n

\nThe model is represented by a Python object that is filled with the different model elements (variables, constraints, objective function, etc). The first thing to do is then to create such an object:", "apps": [], "results": {"msg": [{"data": "

Create the model container

\n

\n

The model is represented by a Python object that is filled with the different model elements (variables, constraints, objective function, etc). The first thing to do is then to create such an object:

\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# Create model object\nmdl = CpoModel(name=\"GolombRuler\")", "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\n\n* Now, we need to define the variables of the problem. As the expected problem result is the list of mark positions, the simplest choice is to create one integer variable to represent the position of each mark on the ruler.\n\n* Each variable has a a set of possible values called his domain. To reduce the search space, it is important to reduce this domain as far as possible.\n\n* In our case, we can naively estimate that the maximum distance between two adjacent marks is the order of the ruler minus one. Then the maximal position of a mark is (ORDER - 1)\u00b2. Each variable domain is then limited to an interval [0..(ORDER - 1)\u00b2].\n\n* A list of integer variables can be defined using method integer_var_list(). In our case, defining one variable for each mark can be created as follows:", "apps": [], "results": {"msg": [{"data": "

Define the decision variables

\n

\n\n

\n\n

\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": "%python\n# Create array of variables corresponding to ruler marks\nmarks = mdl.integer_var_list(ORDER, 0, (ORDER - 1) ** 2, \"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\n#### Express the business constraints\n\n* We need to express that all possible distances between two marks must be different. To do this, we create an array that contains all these distances:", "apps": [], "results": {"msg": [{"data": "

Express the business constraints

\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": "%python\n# Create an array with all distances between all marks\ndist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)]", "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\nWe have used here the operator '-' to express the difference between variables. It may appear strange as the variables are not instanciated at that time, but the Python operator has been overloaded to construct a CP expression instead of attempting to compute the arithmetic difference. All other standard Python operators can be used to make operations between CP objects (<, >, <=, >=, ==, !=, +, -, /, *, &, |, //, **, ...). Have a look to documentation for details.\n

\nTo force all these distances to be different, we use the special all_diff() constraint as follows:", "apps": [], "results": {"msg": [{"data": "

We have used here the operator '-' to express the difference between variables. It may appear strange as the variables are not instanciated at that time, but the Python operator has been overloaded to construct a CP expression instead of attempting to compute the arithmetic difference. All other standard Python operators can be used to make operations between CP objects (<, >, <=, >=, ==, !=, +, -, /, , &, |, //, *, ...). Have a look to documentation for details.

\n

\n

To force all these distances to be different, we use the special all_diff() constraint as follows:

\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# Force all distances to be different\nmdl.add(mdl.all_diff(dist))", "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 call mdl.add(...) is necessary to express that the constraint must be added to the model.", "apps": [], "results": {"msg": [{"data": "

The call mdl.add(...) is necessary to express that the constraint must be added to the 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": "%md\n

Remove symmetries

\n

\nThe constraint we have expressed above is theoritically enough, and the model can be solved as it is.\n

\nHowever, it does not differentiate between all possible permutations of the different mark positions that are solutions to the problem, for example, 0-1-4-6, 4-6-1-0, 6-0-1-4, etc. As there are ORDER! (factorial of ORDER) such permutations, the search space would be drastically reduced by removing them.\n

\nWe can do that by forcing an order between marks, for example the order of their index:", "apps": [], "results": {"msg": [{"data": "

Remove symmetries

\n

\n

The constraint we have expressed above is theoritically enough, and the model can be solved as it is.

\n

\n

However, it does not differentiate between all possible permutations of the different mark positions that are solutions to the problem, for example, 0-1-4-6, 4-6-1-0, 6-0-1-4, etc. As there are ORDER! (factorial of ORDER) such permutations, the search space would be drastically reduced by removing them.

\n

\n

We can do that by forcing an order between marks, for example the order of their index:

\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# Avoid symmetric solutions by ordering marks\nfor i in range(1, ORDER):\n mdl.add(marks[i] > marks[i - 1])", "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\nWe also know that first mark is at the beginning of the ruler:", "apps": [], "results": {"msg": [{"data": "

We also know that first mark is at the beginning of the ruler:

\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# Force first mark position to zero\nmdl.add(marks[0] == 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": "%md\n

Avoid mirror solutions

\n

\nEach optimal solution has a mirror, with all mark distances in the reverse order, for example, 0-1-4-6 and 0-2-5-6. \nThe following constraint can be added to avoid this: ", "apps": [], "results": {"msg": [{"data": "

Avoid mirror solutions

\n

\n

Each optimal solution has a mirror, with all mark distances in the reverse order, for example, 0-1-4-6 and 0-2-5-6.

\n

The following constraint can be added to avoid this:

\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# Avoid mirror solution\nmdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 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\n#### Express the objective\n\n* Finally, we want to get the shortest Golomb Ruler. This can be expressed by minimizing the position of the last mark.\nAs we have ordered the marks, we can do this using:", "apps": [], "results": {"msg": [{"data": "

Express the objective

\n

\n\n

As we have ordered the marks, we can do this using:

\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 ruler size\nmdl.add(mdl.minimize(marks[ORDER - 1]))", "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\nIf the marks were not ordered, we should have use instead:
\n mdl.add(mdl.minimize(mdl.max(marks)))
", "apps": [], "results": {"msg": [{"data": "

If the marks were not ordered, we should have use instead:

\n

mdl.add(mdl.minimize(mdl.max(marks)))

\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#### Solve with Decision Optimization solve service\n\nIf url and key are None, the Modeling layer will look for a local runtime, otherwise will use the credentials.\nLook at the documentation for a good understanding of the various solving/generation modes.\n\nIf you're using a Community Edition of CPLEX runtimes, depending on the size of the problem, the solve stage may fail and will need a paying subscription or product installation.", "apps": [], "results": {"msg": [{"data": "

Solve with Decision Optimization solve service

\n

\n

If url and key are None, the Modeling layer will look for a local runtime, otherwise will use the credentials.

\n

Look at the documentation for a good understanding of the various solving/generation modes.

\n

\n

If you're using a Community Edition of CPLEX runtimes, depending on the size of the problem, the solve stage may fail and will need a paying subscription or product installation.

\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\nThe model can be solved by calling:", "apps": [], "results": {"msg": [{"data": "

The model can be solved by calling:

\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# Solve the model\nprint(\"Solving model....\")\nmsol = mdl.solve(url=SVC_URL, key=SVC_KEY, TimeLimit=10)", "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 shortest way to output the solution that has been found by the solver is to call the method print_solution() as follows:", "apps": [], "results": {"msg": [{"data": "

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

\n

\n

The shortest way to output the solution that has been found by the solver is to call the method print_solution() as follows:

\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# Print solution\nprint(\"Solution: \")\nmsol.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\nThis output is totally generic and simply prints the value of all model variables, the objective value, and some other solving information.\n

\nA more specific output can be generated by writing more code. The following example illustrates how to access specific elements of the solution. ", "apps": [], "results": {"msg": [{"data": "

This output is totally generic and simply prints the value of all model variables, the objective value, and some other solving information.

\n

\n

A more specific output can be generated by writing more code. The following example illustrates how to access specific elements of the solution.

\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# Print solution\nfrom sys import stdout\nif msol:\n # Print found solution\n stdout.write(\"Solution: \" + msol.get_solve_status() + \"\\n\")\n stdout.write(\"Position of ruler marks: \")\n for v in marks:\n stdout.write(\" \" + str(msol[v]))\n stdout.write(\"\\n\")\n stdout.write(\"Solve time: \" + str(round(msol.get_solve_time(), 2)) + \"s\\n\")\nelse:\n # No solution found\n stdout.write(\"No solution found. Search status: \" + msol.get_solve_status() + \"\\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\nAnother possibility is for example to simulate real ruler using characters, as follows:", "apps": [], "results": {"msg": [{"data": "

Another possibility is for example to simulate real ruler using characters, as follows:

\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# Print solution as a ruler\nif msol:\n stdout.write(\"Ruler: +\")\n for i in range(1, ORDER):\n stdout.write('-' * (msol[marks[i]] - msol[marks[i - 1]] - 1) + '+')\n stdout.write(\"\\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

Going further with Constraint Programming

\n\nThe last available installable package is available on Pypi here: https://pypi.python.org/pypi/docplex\n\nA complete set of modeling examples can be downloaded here: https://github.com/IBMDecisionOptimization/docplex-examples ", "apps": [], "results": {"msg": [{"data": "

Going further with Constraint Programming

\n

\n

The last available installable package is available on Pypi here: https://pypi.python.org/pypi/docplex

\n

\n

A complete set of modeling examples can be downloaded here: https://github.com/IBMDecisionOptimization/docplex-examples

\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## Summary\n\nYou learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Constraint Programming model and solve it with IBM Decision Optimization on the cloud.", "apps": [], "results": {"msg": [{"data": "

Summary

\n

\n

You learned how to set up and use the IBM Decision Optimization CPLEX Modeling for Python to formulate a Constraint Programming model and solve it with IBM Decision Optimization 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": "%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\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 IBM. IPLA licensed Sample Materials.", "apps": [], "results": {"msg": [{"data": "

Copyright \u00a9 2017 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/cp/zeppelin/house_building.json b/examples/cp/zeppelin/house_building.json deleted file mode 100644 index 981f902..0000000 --- a/examples/cp/zeppelin/house_building.json +++ /dev/null @@ -1 +0,0 @@ -{"info": {}, "config": {"looknfeel": "default", "personalizedMode": "false"}, "name": "cp/jupyter/house_building", "paragraphs": [{"settings": {"forms": {}, "params": {}}, "text": "%md\n\n# House Building with worker skills\n\nThis tutorial includes everything you need to set up decision optimization engines, build constraint programming models.\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 a valid subscription to **Decision Optimization on the Cloud** or a **local installation of CPLEX Optimizers**. \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: Download the library\n * Step 2: Set up the engines\n - Step 3: Model 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 solve service\n * Step 5: Investigate the solution and run an example analysis\n* Summary\n****", "apps": [], "results": {"msg": [{"data": "

\n

House Building with worker skills

\n

\n

This tutorial includes everything you need to set up decision optimization engines, build constraint programming models.

\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 a valid subscription to Decision Optimization on the Cloud or a local installation of CPLEX Optimizers.

\n
\n

Discover us here

\n

\n

\n

Table of contents:

\n

\n\n\n\n
*  Step 1: Download the library\n
\n
*  Step 2: Set up the engines\n
\n
-  Step 3: Model 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 solve service\n
\n
*  Step 5: Investigate the solution and run an example analysis\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* This is a problem of building five houses in different locations; the masonry, roofing, painting, etc. must be scheduled. Some tasks must necessarily take place before others and these requirements are expressed through precedence constraints.\n\n* There are three workers, and each worker has a given skill level for each task. Each task requires one worker; the worker assigned must have a non-null skill level for the task. A worker can be assigned to only one task at a time.\n\n* Each house has a deadline. \n\n* The objective is to maximize the skill levels of the workers assigned to the tasks.", "apps": [], "results": {"msg": [{"data": "

Describe the business problem

\n

\n\n

\n\n

\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*****\n## How decision optimization can help\n* Prescriptive analytics technology recommends actions based on desired outcomes, taking into account specific scenarios, resources, and knowledge of past and current events. This insight can help your organization 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+ For example:\n + Automate complex decisions and trade-offs to better manage 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", "apps": [], "results": {"msg": [{"data": "
\n

How decision optimization can help

\n\n

\n\n

\n\n


\n

\n\n
+ Automate complex decisions and trade-offs to better manage limited resources.\n
\n
+ Take advantage of a future opportunity or mitigate a future risk.\n
\n
+ Proactively update recommendations based on changing events.\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

About Detailed Scheduling concepts

\n

\n

", "apps": [], "results": {"msg": [{"data": "

About Detailed Scheduling concepts

\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: Download the library\n\nRun the following code to install 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: Download the library

\n

\n

Run the following code to install 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\nimport pip\ntry:\n import docplex.cp\nexcept:\n if hasattr(sys, 'real_prefix'):\n #we are in a virtual env.\n pip.main(['install', docplex]) \n else:\n pip.main(['install --user', 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.mp that is dedicated to Mathematical Programming, another branch of optimization.", "apps": [], "results": {"msg": [{"data": "

Note that the more global package docplex contains another subpackage docplex.mp that is dedicated to Mathematical 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: Set up the prescriptive engine\n\n* Subscribe to the [Decision Optimization on Cloud solve service](https://developer.ibm.com/docloud).\n* Get the service URL and your personal API key.", "apps": [], "results": {"msg": [{"data": "

Step 2: Set up the prescriptive engine

\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": "%python\nSVC_URL = \"ENTER YOUR URL HERE\"\nSVC_KEY = \"ENTER YOUR KEY 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\nAnd for display of the solution, ensure last version of matplotlib is available:", "apps": [], "results": {"msg": [{"data": "

And for display of the solution, ensure last version of matplotlib is available:

\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\ntry:\n import matplotlib\n if matplotlib.__version__ < \"1.4.3\":\n pip.main(['install --upgrade', matplotlib])\nexcept:\n pip.main(['install --user', matplotlib])", "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\nNow, we need to import all required modeling functions that are provided by the docplex.cp package:", "apps": [], "results": {"msg": [{"data": "

Now, we need to import all required modeling functions that are provided by the docplex.cp package:

\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.cp.model import CpoModel\nfrom sys import stdout\nfrom collections import namedtuple", "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: Model the data", "apps": [], "results": {"msg": [{"data": "

Step 3: Model the data

\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\nPlanning contains the number of houses and the max amount of periods (days) for our schedule", "apps": [], "results": {"msg": [{"data": "

Planning contains the number of houses and the max amount of periods (days) for our schedule

\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_HOUSES = 5\nMAX_AMOUNT_OF_PERIODS = 318\nHOUSES = range(1, NB_HOUSES + 1)", "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\nAll tasks must start and end between 0 and the max amount of periods", "apps": [], "results": {"msg": [{"data": "

All tasks must start and end between 0 and the max amount of periods

\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\nperiod_domain = (0, MAX_AMOUNT_OF_PERIODS)", "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 each task type in the house building project, the following table shows the duration of the task in days along with the tasks that must be finished before the task can start. A worker can only work on one task at a time; each task, once started, may not be interrupted.\n

\n\n| *Task* | *Duration* | *Preceding tasks* |\n|---|---|---|\n| masonry \t| 35 |\t|\n| carpentry | 15 | masonry |\n| plumbing \t| 40 | masonry |\n| ceiling \t| 15 | masonry |\n| roofing \t| 5 | carpentry |\n| painting \t| 10 | ceiling |\n| windows \t| 5 | roofing |\n| facade \t| 10 | roofing, plumbing |\n| garden \t| 5 | roofing, plumbing |\n| moving \t| 5 | windows, facade, garden, painting | ", "apps": [], "results": {"msg": [{"data": "

For each task type in the house building project, the following table shows the duration of the task in days along with the tasks that must be finished before the task can start. A worker can only work on one task at a time; each task, once started, may not be interrupted.

\n

\n

\n

| Task | Duration | Preceding tasks |

\n

|---|---|---|

\n

| masonry | 35 | |

\n

| carpentry | 15 | masonry |

\n

| plumbing | 40 | masonry |

\n

| ceiling | 15 | masonry |

\n

| roofing | 5 | carpentry |

\n

| painting | 10 | ceiling |

\n

| windows | 5 | roofing |

\n

| facade | 10 | roofing, plumbing |

\n

| garden | 5 | roofing, plumbing |

\n

| moving | 5 | windows, facade, garden, painting |

\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##### Tasks' durations", "apps": [], "results": {"msg": [{"data": "
Tasks' durations
\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\nTask = (namedtuple(\"Task\", [\"name\", \"duration\"]))\nTASKS = {Task(\"masonry\", 35),\n Task(\"carpentry\", 15),\n Task(\"plumbing\", 40),\n Task(\"ceiling\", 15),\n Task(\"roofing\", 5),\n Task(\"painting\", 10),\n Task(\"windows\", 5),\n Task(\"facade\", 10),\n Task(\"garden\", 5),\n Task(\"moving\", 5),\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 tasks precedences", "apps": [], "results": {"msg": [{"data": "
The tasks precedences
\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\nTaskPrecedence = (namedtuple(\"TaskPrecedence\", [\"beforeTask\", \"afterTask\"]))\nTASK_PRECEDENCES = {TaskPrecedence(\"masonry\", \"carpentry\"),\n TaskPrecedence(\"masonry\", \"plumbing\"),\n TaskPrecedence(\"masonry\", \"ceiling\"),\n TaskPrecedence(\"carpentry\", \"roofing\"),\n TaskPrecedence(\"ceiling\", \"painting\"),\n TaskPrecedence(\"roofing\", \"windows\"),\n TaskPrecedence(\"roofing\", \"facade\"),\n TaskPrecedence(\"plumbing\", \"facade\"),\n TaskPrecedence(\"roofing\", \"garden\"),\n TaskPrecedence(\"plumbing\", \"garden\"),\n TaskPrecedence(\"windows\", \"moving\"),\n TaskPrecedence(\"facade\", \"moving\"),\n TaskPrecedence(\"garden\", \"moving\"),\n TaskPrecedence(\"painting\", \"moving\"),\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\nThere are three workers with varying skill levels in regard to the ten tasks. If a worker has a skill level of zero for a task, he may not be assigned to the task.\n

\n\n| *Task* | *Joe* | *Jack* | *Jim* |\n|---|---|---|---|\n|masonry |9 |\t5 |\t0|\n|carpentry |7 |\t0 |\t5|\n|plumbing |0 |\t7 |\t0|\n|ceiling |5 |\t8 |\t0|\n|roofing |6 |\t7 |\t0|\n|painting |0 |\t9 |\t6|\n|windows |8 |\t0 |\t5|\n|fa\u00e7ade |5 |\t5 |\t0|\n|garden |5 |\t5 |\t9|\n|moving |6 |\t0 |\t8|", "apps": [], "results": {"msg": [{"data": "

There are three workers with varying skill levels in regard to the ten tasks. If a worker has a skill level of zero for a task, he may not be assigned to the task.

\n

\n

\n

| Task | Joe | Jack | Jim |

\n

|---|---|---|---|

\n

|masonry |9 | 5 | 0|

\n

|carpentry |7 | 0 | 5|

\n

|plumbing |0 | 7 | 0|

\n

|ceiling |5 | 8 | 0|

\n

|roofing |6 | 7 | 0|

\n

|painting |0 | 9 | 6|

\n

|windows |8 | 0 | 5|

\n

|fa\u00e7ade |5 | 5 | 0|

\n

|garden |5 | 5 | 9|

\n

|moving |6 | 0 | 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": "%md\n##### Workers Names", "apps": [], "results": {"msg": [{"data": "
Workers 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\nWORKERS = {\"Joe\", \"Jack\", \"Jim\"}", "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##### Workers Name and level for each of there skill", "apps": [], "results": {"msg": [{"data": "
Workers Name and level for each of there skill
\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\nSkill = (namedtuple(\"Skill\", [\"worker\", \"task\", \"level\"]))\nSKILLS = {Skill(\"Joe\", \"masonry\", 9),\n Skill(\"Joe\", \"carpentry\", 7),\n Skill(\"Joe\", \"ceiling\", 5),\n Skill(\"Joe\", \"roofing\", 6),\n Skill(\"Joe\", \"windows\", 8),\n Skill(\"Joe\", \"facade\", 5),\n Skill(\"Joe\", \"garden\", 5),\n Skill(\"Joe\", \"moving\", 6),\n Skill(\"Jack\", \"masonry\", 5),\n Skill(\"Jack\", \"plumbing\", 7),\n Skill(\"Jack\", \"ceiling\", 8),\n Skill(\"Jack\", \"roofing\", 7),\n Skill(\"Jack\", \"painting\", 9),\n Skill(\"Jack\", \"facade\", 5),\n Skill(\"Jack\", \"garden\", 5),\n Skill(\"Jim\", \"carpentry\", 5),\n Skill(\"Jim\", \"painting\", 6),\n Skill(\"Jim\", \"windows\", 5),\n Skill(\"Jim\", \"garden\", 9),\n Skill(\"Jim\", \"moving\", 8)\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##### Utility functions", "apps": [], "results": {"msg": [{"data": "
Utility functions
\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\nfind_tasks: returns the task it refers to in the TASKS vector", "apps": [], "results": {"msg": [{"data": "

find_tasks: returns the task it refers to in the TASKS vector

\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 find_tasks(name):\n return next(t for t in TASKS if t.name == 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\nfind_skills: returns the skill it refers to in the SKILLS vector", "apps": [], "results": {"msg": [{"data": "

find_skills: returns the skill it refers to in the SKILLS vector

\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 find_skills(worker, task):\n return next(s for s in SKILLS if (s.worker == worker) and (s.task == task))", "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\nfind_max_level_skill: returns the tuple \"skill\" where the level is themaximum for a given task", "apps": [], "results": {"msg": [{"data": "

findmaxlevel_skill: returns the tuple \"skill\" where the level is themaximum for a given task

\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 find_max_level_skill(task):\n st = [s for s in SKILLS if s.task == task]\n return next(sk for sk in st if sk.level == max([s.level for s in st]))", "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 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": "%md\n

Create the model container

\n

\nThe model is represented by a Python object that is filled with the different model elements (variables, constraints, objective function, etc). The first thing to do is then to create such an object:", "apps": [], "results": {"msg": [{"data": "

Create the model container

\n

\n

The model is represented by a Python object that is filled with the different model elements (variables, constraints, objective function, etc). The first thing to do is then to create such an object:

\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 = CpoModel(name=\"HouseBuilding\")", "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": "%md\n
Concept: interval variable
\n

\n

", "apps": [], "results": {"msg": [{"data": "
Concept: interval variable
\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\nFor each house, an interval variable is created for each task.
\nThis interval must start and end inside the period_domain and its duration is set as the value stated in TASKS definition.", "apps": [], "results": {"msg": [{"data": "

For each house, an interval variable is created for each task.

\n

This interval must start and end inside the period_domain and its duration is set as the value stated in TASKS definition.

\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\ntasks = {} # dict of interval variable for each house and task\nfor house in HOUSES:\n for task in TASKS:\n tasks[(house, task)] = mdl.interval_var(start=period_domain,\n end=period_domain,\n size=task.duration,\n name=\"house {} task {}\".format(house, task))", "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
Concept: optional interval variable
\n

\n

", "apps": [], "results": {"msg": [{"data": "
Concept: optional interval variable
\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\nFor each house, an __optional__ interval variable is created for each skill.
\nSkill being a tuple (worker, task, level), this means that for each house, an __optional__ interval variable is created for each couple worker-task such that the skill level of this worker for this task is > 0.

\nThe \"**set_optional()**\" specifier allows a choice between different variables, thus between different couples house-skill.\nThis means that the engine decides if the interval will be present or absent in the solution.", "apps": [], "results": {"msg": [{"data": "

For each house, an optional interval variable is created for each skill.

\n

Skill being a tuple (worker, task, level), this means that for each house, an optional interval variable is created for each couple worker-task such that the skill level of this worker for this task is > 0.

\n

The \"set_optional()\" specifier allows a choice between different variables, thus between different couples house-skill.

\n

This means that the engine decides if the interval will be present or absent in the solution.

\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\nwtasks = {} # dict of interval variable for each house and skill\nfor house in HOUSES:\n for skill in SKILLS:\n iv = mdl.interval_var(name='H' + str(house) + '-' + skill.task + '(' + skill.worker + ')')\n iv.set_optional()\n wtasks[(house, skill)] = iv", "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", "apps": [], "results": {"msg": [{"data": "

Express the business 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
Temporal constraints
", "apps": [], "results": {"msg": [{"data": "
Temporal 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
Concept: precedence constraint
\n

\n