├── .gitignore ├── LICENSE.txt ├── README.md ├── examples ├── cp │ ├── basic │ │ ├── Cutting_stock_with_flexible_length.py │ │ ├── color.py │ │ ├── cvrptw.py │ │ ├── data │ │ │ ├── cvrptw_C101_25.data │ │ │ ├── jobshop_blackbox_default.data │ │ │ └── plant_location.data │ │ ├── facility.py │ │ ├── golomb_ruler.py │ │ ├── golomb_ruler_all_solutions.py │ │ ├── golomb_ruler_with_propagate.py │ │ ├── golomb_ruler_with_refine_conflicts.py │ │ ├── hitori.py │ │ ├── house_building.py │ │ ├── kmeans.py │ │ ├── latin_cube.py │ │ ├── latin_square.py │ │ ├── light_up.py │ │ ├── linear_peg_solitaire.py │ │ ├── n_queen.py │ │ ├── plant_location_with_cpo_callback.py │ │ ├── plant_location_with_kpis.py │ │ ├── plant_location_with_starting_point.py │ │ ├── sched_jobshop_blackbox.py │ │ ├── shapes_with_blackboxes.py │ │ ├── steelmill.py │ │ ├── sudoku.py │ │ ├── trimloss.py │ │ ├── truck_fleet.py │ │ └── vietnamese_problem.py │ ├── jupyter │ │ ├── SteelMill.ipynb │ │ ├── golomb_ruler.ipynb │ │ ├── house_building.ipynb │ │ ├── house_building_utils │ │ │ ├── activity.PNG │ │ │ ├── alternative.PNG │ │ │ ├── intervalVar.PNG │ │ │ └── noOverlap.PNG │ │ ├── n_queen.ipynb │ │ ├── n_queen_utils │ │ │ ├── BQueen.png │ │ │ └── WQueen.png │ │ ├── sched_square.ipynb │ │ ├── scheduling_tuto.ipynb │ │ ├── sports_scheduling.ipynb │ │ ├── sudoku.ipynb │ │ └── truck_fleet.ipynb │ └── visu │ │ ├── data │ │ ├── flowshop_default.data │ │ ├── flowshop_tail20_10_2.data │ │ ├── flowshop_tail20_20_5.data │ │ ├── flowshop_tail20_5_3.data │ │ ├── flowshop_tail50_10_6.data │ │ ├── flowshop_tail50_5_9.data │ │ ├── jobshop_ft06.data │ │ ├── jobshop_ft10.data │ │ ├── jobshop_ft20.data │ │ ├── jobshopflex_16a.data │ │ ├── jobshopflex_default.data │ │ ├── jobshopflex_la21v.data │ │ ├── jobshopflex_la27r.data │ │ ├── jobshopflex_mk08.data │ │ ├── jobshopflex_seti5xx.data │ │ ├── jobshopflex_tiny.data │ │ ├── learningeffect_default.data │ │ ├── openshop_default.data │ │ ├── openshop_gp10-05.data │ │ ├── openshop_gp10-08.data │ │ ├── openshop_j8-per10-2.data │ │ ├── openshop_tail20_20_7.data │ │ ├── openshop_tail20_20_9.data │ │ ├── plant_location.data │ │ ├── rcpsp_default.data │ │ ├── rcpsp_j120_1_2.data │ │ ├── rcpsp_j120_22_6.data │ │ ├── rcpsp_j120_2_9.data │ │ ├── rcpsp_j120_32_8.data │ │ ├── rcpsp_j120_41_5.data │ │ ├── rcpsp_j30_5_6.data │ │ ├── rcpspmm_default.data │ │ ├── rcpspmm_default.json │ │ ├── rcpspmm_j30_12_8.data │ │ ├── rcpspmm_j30_12_8.json │ │ ├── rcpspmm_j30_17_7.data │ │ ├── rcpspmm_j30_17_7.json │ │ ├── rcpspmm_j30_27_6.data │ │ ├── rcpspmm_j30_27_6.json │ │ ├── rcpspmm_j30_46_1.data │ │ ├── rcpspmm_j30_46_1.json │ │ ├── rcpspmm_j30_62_10.data │ │ ├── rcpspmm_j30_62_10.json │ │ └── stochastic_jobshop_default.data │ │ ├── flow_shop.py │ │ ├── flow_shop_permutation.py │ │ ├── house_building_basic.py │ │ ├── house_building_calendar.py │ │ ├── house_building_cumul.py │ │ ├── house_building_optional.py │ │ ├── house_building_state.py │ │ ├── house_building_time.py │ │ ├── job_shop_basic.py │ │ ├── job_shop_flexible.py │ │ ├── job_shop_stochastic.py │ │ ├── open_shop.py │ │ ├── plant_location_with_solver_listener.py │ │ ├── rcpsp.py │ │ ├── rcpsp_multi_mode.py │ │ ├── rcpsp_multi_mode_json.py │ │ ├── setup_costs.py │ │ ├── setup_times.py │ │ └── squaring_square.py └── mp │ ├── callbacks │ ├── branch_callback.py │ ├── cut_callback.py │ ├── data │ │ └── location.lp │ ├── heuristic_callback.py │ ├── incumbent_callback.py │ └── lazy_callback.py │ ├── jupyter │ ├── Benders_decomposition.ipynb │ ├── boxes.ipynb │ ├── chicago_coffee_shops.ipynb │ ├── efficient.ipynb │ ├── green_truck.ipynb │ ├── incremental_modeling.ipynb │ ├── infeasible.ipynb │ ├── lagrangian_relaxation.ipynb │ ├── lifegame.ipynb │ ├── load_balancing.ipynb │ ├── logical_cts.ipynb │ ├── marketing_campaign.ipynb │ ├── mining_pandas.ipynb │ ├── nurses_data.xls │ ├── nurses_pandas-multi_objective.ipynb │ ├── nurses_pandas.ipynb │ ├── nurses_scheduling.ipynb │ ├── oil_blending.ipynb │ ├── pasta_production.ipynb │ ├── progress.ipynb │ ├── sktrans │ │ └── transformers.ipynb │ ├── sparktrans │ │ ├── SparkML_transformers.ipynb │ │ └── SparkML_transformers_pipeline.ipynb │ ├── sports_scheduling.ipynb │ ├── tutorials │ │ ├── Beyond_Linear_Programming.ipynb │ │ └── Linear_Programming.ipynb │ └── ucp_pandas.ipynb │ ├── modeling │ ├── diet.py │ ├── nurses.py │ ├── nurses_multiobj.py │ ├── production.py │ ├── sailcopw.py │ └── sport_scheduling.py │ └── workflow │ ├── cutstock.py │ ├── lagrangian_relaxation.py │ ├── load_balancing.py │ ├── populate.py │ └── sports.lp └── info.json /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IBM® Decision Optimization Modeling for Python (DOcplex) 2 | 3 | Welcome to the IBM® Decision Optimization Modeling for Python. 4 | Licensed under the Apache License v2.0. 5 | 6 | With this library, you can quickly and easily add the power of optimization to 7 | your application. You need IBM ILOG CPLEX Optimization Studio to solve the models. 8 | 9 | This library is composed of 2 modules: 10 | 11 | * IBM® Decision Optimization CPLEX Optimizer Modeling for Python - with namespace docplex.mp 12 | * IBM® Decision Optimization CP Optimizer Modeling for Python - with namespace docplex.cp 13 | 14 | Solving with CPLEX requires that IBM® ILOG CPLEX Optimization Studio V12.10 or later 15 | is installed on your machine. 16 | 17 | This library is numpy friendly. 18 | 19 | ## Install the library 20 | 21 | ``` 22 | pip install docplex 23 | ``` 24 | 25 | ## Get the documentation and examples 26 | 27 | * [Latest documentation](http://ibmdecisionoptimization.github.io/docplex-doc/) 28 | * Documentation archives: 29 | * [2.23.222](http://ibmdecisionoptimization.github.io/docplex-doc/2.23.222) 30 | * [2.22.213](http://ibmdecisionoptimization.github.io/docplex-doc/2.22.213) 31 | * [2.21.207](http://ibmdecisionoptimization.github.io/docplex-doc/2.21.207) 32 | * [2.20.204](http://ibmdecisionoptimization.github.io/docplex-doc/2.20.204) 33 | * [2.19.202](http://ibmdecisionoptimization.github.io/docplex-doc/2.19.202) 34 | * [2.18.200](http://ibmdecisionoptimization.github.io/docplex-doc/2.18.200) 35 | * [2.16.195](http://ibmdecisionoptimization.github.io/docplex-doc/2.16.195) 36 | * [Examples](https://github.com/IBMDecisionOptimization/docplex-examples) 37 | 38 | ## Get your IBM® ILOG CPLEX Optimization Studio edition 39 | 40 | - You can get a free [Community Edition](https://www.ibm.com/account/reg/us-en/signup?formid=urx-20028) 41 | of CPLEX Optimization Studio, with limited solving capabilities in term of problem size. 42 | 43 | - Faculty members, research professionals at accredited institutions can get access to an unlimited version of CPLEX through the 44 | [IBM® Academic Initiative](http://ibm.biz/cplex-free-for-students). 45 | 46 | ## Dependencies 47 | 48 | These third-party dependencies are automatically installed with ``pip`` 49 | 50 | - [futures](https://pypi.python.org/pypi/futures) 51 | - [requests](https://pypi.python.org/pypi/requests) 52 | - [six](https://pypi.python.org/pypi/six) 53 | - [certifi](https://pypi.python.org/pypi/certifi) 54 | 55 | 56 | 57 | ## License 58 | 59 | This library is delivered under the Apache License Version 2.0, January 2004 (see LICENSE.txt). 60 | -------------------------------------------------------------------------------- /examples/cp/basic/color.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The problem involves choosing colors for the countries on a map in 9 | such a way that at most four colors (blue, white, yellow, green) are 10 | used and no neighboring countries are the same color. In this exercise, 11 | you will find a solution for a map coloring problem with six countries: 12 | Belgium, Denmark, France, Germany, Luxembourg, and the Netherlands. 13 | 14 | Please refer to documentation for appropriate setup of solving configuration. 15 | """ 16 | 17 | from docplex.cp.model import CpoModel 18 | 19 | # Create CPO model 20 | mdl = CpoModel() 21 | 22 | # Create model variables containing colors of the countries 23 | Belgium = mdl.integer_var(0, 3, "Belgium") 24 | Denmark = mdl.integer_var(0, 3, "Denmark") 25 | France = mdl.integer_var(0, 3, "France") 26 | Germany = mdl.integer_var(0, 3, "Germany") 27 | Luxembourg = mdl.integer_var(0, 3, "Luxembourg") 28 | Netherlands = mdl.integer_var(0, 3, "Netherlands") 29 | ALL_COUNTRIES = (Belgium, Denmark, France, Germany, Luxembourg, Netherlands) 30 | 31 | # Create constraints 32 | mdl.add(Belgium != France) 33 | mdl.add(Belgium != Germany) 34 | mdl.add(Belgium != Netherlands) 35 | mdl.add(Belgium != Luxembourg) 36 | mdl.add(Denmark != Germany) 37 | mdl.add(France != Germany) 38 | mdl.add(France != Luxembourg) 39 | mdl.add(Germany != Luxembourg) 40 | mdl.add(Germany != Netherlands) 41 | 42 | # Solve model 43 | print("\nSolving model....") 44 | msol = mdl.solve(TimeLimit=10) 45 | 46 | if msol: 47 | print("Solution status: " + msol.get_solve_status()) 48 | colors = ("Yellow", "Red", "Green", "Blue") 49 | for country in ALL_COUNTRIES: 50 | print(" " + country.get_name() + ": " + colors[msol[country]]) 51 | else: 52 | print("No solution found") 53 | 54 | # Print solver log 55 | # print("\nSolver log:") 56 | # print(msol.get_solver_log()) 57 | -------------------------------------------------------------------------------- /examples/cp/basic/data/cvrptw_C101_25.data: -------------------------------------------------------------------------------- 1 | C101 2 | 3 | VEHICLE 4 | NUMBER CAPACITY 5 | 25 200 6 | 7 | CUSTOMER 8 | CUST NO. XCOORD. YCOORD. DEMAND READY TIME DUE DATE SERVICE TIME 9 | 10 | 0 40 50 0 0 1236 0 11 | 1 45 68 10 912 967 90 12 | 2 45 70 30 825 870 90 13 | 3 42 66 10 65 146 90 14 | 4 42 68 10 727 782 90 15 | 5 42 65 10 15 67 90 16 | 6 40 69 20 621 702 90 17 | 7 40 66 20 170 225 90 18 | 8 38 68 20 255 324 90 19 | 9 38 70 10 534 605 90 20 | 10 35 66 10 357 410 90 21 | 11 35 69 10 448 505 90 22 | 12 25 85 20 652 721 90 23 | 13 22 75 30 30 92 90 24 | 14 22 85 10 567 620 90 25 | 15 20 80 40 384 429 90 26 | 16 20 85 40 475 528 90 27 | 17 18 75 20 99 148 90 28 | 18 15 75 20 179 254 90 29 | 19 15 80 10 278 345 90 30 | 20 30 50 10 10 73 90 31 | 21 30 52 20 914 965 90 32 | 22 28 52 20 812 883 90 33 | 23 28 55 10 732 777 90 34 | 24 25 50 10 65 144 90 35 | 25 25 52 40 169 224 90 36 | -------------------------------------------------------------------------------- /examples/cp/basic/data/jobshop_blackbox_default.data: -------------------------------------------------------------------------------- 1 | 10 10 2 | 0 2500 3300 1 7400 8200 2 900 900 3 3200 4000 4 4900 4900 5 1100 1100 6 5900 6500 7 5600 5600 8 3900 4900 9 2000 2200 3 | 0 3900 4700 2 8900 9100 4 6700 8300 9 1100 1100 3 6300 7500 1 2500 3100 6 4600 4600 5 4300 4900 7 7100 7300 8 2700 3300 4 | 1 8600 9600 0 7700 9300 3 3400 4400 2 6400 8400 8 8900 9100 5 1000 1000 7 1100 1300 6 8700 9100 9 4100 4900 4 3100 3500 5 | 1 7900 8300 2 9400 9600 0 6200 8000 4 9200 10600 6 900 900 8 4600 5800 7 7400 9600 3 9000 10600 9 2100 2300 5 4100 4500 6 | 2 1300 1500 0 600 600 1 2200 2200 5 5300 6900 3 2500 2700 4 6400 7400 8 2000 2200 7 4600 5200 9 7200 7200 6 4600 6000 7 | 2 7500 9300 1 200 200 5 5200 5200 3 8900 10100 8 4300 5300 9 7000 7400 0 4400 5000 6 6200 6800 4 600 600 7 2300 2700 8 | 1 4300 4900 0 3400 4000 3 6000 6200 2 1300 1300 6 2800 3600 5 2000 2200 9 2900 3500 8 8300 9500 7 2900 3100 4 5400 5600 9 | 2 2900 3300 0 8600 8600 1 4600 4600 5 6500 8300 4 2900 3500 6 7900 9700 8 1700 2100 9 4500 5100 7 3500 3700 3 6900 8900 10 | 0 7200 8000 1 6300 7500 3 6700 8500 5 5100 5100 2 7700 9300 9 1000 1200 6 3600 4400 7 8300 9500 4 2600 2600 8 7300 7500 11 | 1 8100 8900 0 1300 1300 2 5800 6400 6 700 700 8 5900 6900 9 7000 8200 5 4600 4800 3 5000 5400 4 8200 9800 7 4100 4900 12 | -------------------------------------------------------------------------------- /examples/cp/basic/facility.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | A company has 8 stores. 9 | Each store must be supplied by one warehouse. 10 | The company has 5 possible locations where it has property and can build a 11 | supplier warehouse: Bonn, Bordeaux, London, Paris, and Rome. 12 | 13 | The warehouse locations have different capacities. A warehouse built in Bordeaux 14 | or Rome could supply only one store ; a warehouse built in London could supply 15 | two stores; a warehouse built in Bonn could supply three stores; and a warehouse 16 | built in Paris could supply four stores. 17 | 18 | The supply costs vary for each store, depending on which warehouse is the 19 | supplier. For example, a store that is located in Paris would have low supply 20 | costs if it were supplied by a warehouse also in Paris. That same store would 21 | have much higher supply costs if it were supplied by the other warehouses. 22 | 23 | The cost of building a warehouse varies depending on warehouse location. 24 | 25 | The problem is to find the most cost-effective solution to this problem, while 26 | making sure that each store is supplied by a warehouse. 27 | 28 | Please refer to documentation for appropriate setup of solving configuration. 29 | """ 30 | 31 | from docplex.cp.model import CpoModel 32 | from collections import namedtuple 33 | 34 | #----------------------------------------------------------------------------- 35 | # Initialize the problem data 36 | #----------------------------------------------------------------------------- 37 | 38 | Warehouse = namedtuple('Warehouse', ('city', # Name of the city 39 | 'capacity', # Capacity of the warehouse 40 | 'cost', # Warehouse building cost 41 | )) 42 | 43 | # List of warehouses 44 | WAREHOUSES = (Warehouse("Bonn", 3, 480), 45 | Warehouse("Bordeaux", 1, 200), 46 | Warehouse("London", 2, 320), 47 | Warehouse("Paris", 4, 340), 48 | Warehouse("Rome", 1, 300)) 49 | NB_WAREHOUSES = len(WAREHOUSES) 50 | 51 | # Number of stores 52 | NB_STORES = 8 53 | 54 | # Supply cost for each store and warehouse 55 | SUPPLY_COST = ((24, 74, 31, 51, 84), 56 | (57, 54, 86, 61, 68), 57 | (57, 67, 29, 91, 71), 58 | (54, 54, 65, 82, 94), 59 | (98, 81, 16, 61, 27), 60 | (13, 92, 34, 94, 87), 61 | (54, 72, 41, 12, 78), 62 | (54, 64, 65, 89, 89)) 63 | 64 | 65 | #----------------------------------------------------------------------------- 66 | # Build the model 67 | #----------------------------------------------------------------------------- 68 | 69 | # Create CPO model 70 | mdl = CpoModel() 71 | 72 | # Create one variable per store to contain the index of its supplying warehouse 73 | NB_WAREHOUSES = len(WAREHOUSES) 74 | supplier = mdl.integer_var_list(NB_STORES, 0, NB_WAREHOUSES - 1, "supplier") 75 | 76 | # Create one variable per warehouse to indicate if it is open (1) or not (0) 77 | open = mdl.integer_var_list(NB_WAREHOUSES, 0, 1, "open") 78 | 79 | # Add constraints stating that the supplying warehouse of each store must be open 80 | for s in supplier: 81 | mdl.add(mdl.element(open, s) == 1) 82 | 83 | # Add constraints stating that the number of stores supplied by each warehouse must not exceed its capacity 84 | for wx in range(NB_WAREHOUSES): 85 | mdl.add(mdl.count(supplier, wx) <= WAREHOUSES[wx].capacity) 86 | 87 | # Build an expression that computes total cost 88 | total_cost = mdl.scal_prod(open, [w.cost for w in WAREHOUSES]) 89 | for sx in range(NB_STORES): 90 | total_cost = total_cost + mdl.element(supplier[sx], SUPPLY_COST[sx]) 91 | 92 | # Minimize total cost 93 | mdl.add(mdl.minimize(total_cost)) 94 | 95 | 96 | #----------------------------------------------------------------------------- 97 | # Solve the model and display the result 98 | #----------------------------------------------------------------------------- 99 | 100 | # Solve model 101 | print("\nSolving model....") 102 | msol = mdl.solve(TimeLimit=10) 103 | 104 | # Print solution 105 | if msol: 106 | for wx in range(NB_WAREHOUSES): 107 | if msol[open[wx]] == 1: 108 | print("Warehouse '{}' open to supply stores: {}" 109 | .format(WAREHOUSES[wx].city, 110 | ", ".join(str(sx) for sx in range(NB_STORES) if msol[supplier[sx]] == wx))) 111 | print("Total cost is: {}".format(msol.get_objective_values()[0])) 112 | else: 113 | print("No solution found.") 114 | -------------------------------------------------------------------------------- /examples/cp/basic/golomb_ruler.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In mathematics, a Golomb ruler is a set of marks at integer positions along 9 | an imaginary ruler such that no two pairs of marks are the same distance apart. 10 | The number of marks on the ruler is its order, and the largest distance 11 | between two of its marks is its length. 12 | 13 | See https://en.wikipedia.org/wiki/Golomb_ruler for more information. 14 | 15 | For order 5: 2 solutions 0 1 4 9 11 ; 0 2 7 8 11 16 | 17 | Please refer to documentation for appropriate setup of solving configuration. 18 | """ 19 | 20 | from docplex.cp.model import CpoModel 21 | from sys import stdout 22 | 23 | 24 | #----------------------------------------------------------------------------- 25 | # Initialize the problem data 26 | #----------------------------------------------------------------------------- 27 | 28 | # Number of marks on the ruler 29 | ORDER = 8 30 | 31 | 32 | #----------------------------------------------------------------------------- 33 | # Prepare the data for modeling 34 | #----------------------------------------------------------------------------- 35 | 36 | # Estimate an upper bound to the ruler length 37 | MAX_LENGTH = (ORDER - 1) ** 2 38 | 39 | 40 | #----------------------------------------------------------------------------- 41 | # Build the model 42 | #----------------------------------------------------------------------------- 43 | 44 | # Create model 45 | mdl = CpoModel() 46 | 47 | # Create array of variables corresponding to position ruler marks 48 | marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, "M") 49 | 50 | # Create marks distances that should be all different 51 | dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)] 52 | mdl.add(mdl.all_diff(dist)) 53 | 54 | # Avoid symmetric solutions by ordering marks 55 | mdl.add(marks[0] == 0) 56 | for i in range(1, ORDER): 57 | mdl.add(marks[i] > marks[i - 1]) 58 | 59 | # Avoid mirror solution 60 | mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2])) 61 | 62 | # Minimize ruler size (position of the last mark) 63 | mdl.add(mdl.minimize(marks[ORDER - 1])) 64 | 65 | 66 | #----------------------------------------------------------------------------- 67 | # Solve the model and display the result 68 | #----------------------------------------------------------------------------- 69 | 70 | print("\nSolving model....") 71 | msol = mdl.solve(TimeLimit=100) 72 | 73 | # Print solution 74 | if msol: 75 | stdout.write("Solution: " + msol.get_solve_status() + "\n") 76 | stdout.write("Position of ruler marks: ") 77 | for v in marks: 78 | stdout.write(" " + str(msol[v])) 79 | stdout.write("\n") 80 | stdout.write("Solve time: " + str(round(msol.get_solve_time(), 2)) + "s\n") 81 | else: 82 | stdout.write("Search status: " + msol.get_solve_status() + "\n") 83 | -------------------------------------------------------------------------------- /examples/cp/basic/golomb_ruler_all_solutions.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In mathematics, a Golomb ruler is a set of marks at integer positions along 9 | an imaginary ruler such that no two pairs of marks are the same distance apart. 10 | The number of marks on the ruler is its order, and the largest distance 11 | between two of its marks is its length. 12 | 13 | This implementation differs from the 'basic' implementation, given in the 14 | examp;e module golomb_ruler.py, because it calls the solver twice: 15 | * First time to know the minimal size of the ruler for the required order, 16 | * A second time to list all possible rulers for this optimal size 17 | 18 | See https://en.wikipedia.org/wiki/Golomb_ruler for more information. 19 | 20 | For order 5: 2 solutions: 0 1 4 9 11 21 | 0 2 7 8 11 22 | For order 7: 6 solutions: 0 1 4 10 18 23 25 23 | 0 1 7 11 20 23 25 24 | 0 1 11 16 19 23 25 25 | 0 2 3 10 16 21 25 26 | 0 2 7 13 21 22 25 27 | 28 | Please refer to documentation for appropriate setup of solving configuration. 29 | """ 30 | 31 | 32 | from docplex.cp.model import CpoModel 33 | from docplex.cp.utils import CpoNotSupportedException 34 | from sys import stdout 35 | 36 | #----------------------------------------------------------------------------- 37 | # Initialize the problem data 38 | #----------------------------------------------------------------------------- 39 | 40 | # Number of marks on the ruler 41 | ORDER = 7 42 | 43 | 44 | #----------------------------------------------------------------------------- 45 | # Prepare the data for modeling 46 | #----------------------------------------------------------------------------- 47 | 48 | # Estimate an upper bound to the ruler length 49 | MAX_LENGTH = (ORDER - 1) ** 2 50 | 51 | 52 | #----------------------------------------------------------------------------- 53 | # Build the model 54 | #----------------------------------------------------------------------------- 55 | 56 | # Create model 57 | mdl = CpoModel() 58 | 59 | # Create array of variables corresponding to position rule marks 60 | marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, "M") 61 | 62 | # Create marks distances that should be all different 63 | dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)] 64 | mdl.add(mdl.all_diff(dist)) 65 | 66 | # Avoid symmetric solutions by ordering marks 67 | mdl.add(marks[0] == 0) 68 | for i in range(1, ORDER): 69 | mdl.add(marks[i] > marks[i - 1]) 70 | 71 | # Avoid mirror solution 72 | mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2])) 73 | 74 | # Minimize ruler size (position of the last mark) 75 | minexpr = mdl.minimize(marks[ORDER - 1]) 76 | mdl.add(minexpr) 77 | 78 | 79 | #----------------------------------------------------------------------------- 80 | # Solve the model and display the result 81 | #----------------------------------------------------------------------------- 82 | 83 | # First solve the model to find the smallest ruler length 84 | msol = mdl.solve(TimeLimit=100) 85 | if not msol: 86 | print("No Golomb ruler available for order " + str(ORDER)) 87 | else: 88 | rsize = msol[marks[ORDER - 1]] 89 | print("Shortest ruler for order " + str(ORDER) + " has length " + str(rsize)) 90 | # Remove minimization from the model 91 | mdl.remove(minexpr) 92 | # Force position of last mark 93 | mdl.add(marks[ORDER - 1] == rsize) 94 | 95 | # Request all solutions 96 | print("List of all possible rulers for length {}:".format(rsize)) 97 | siter = mdl.start_search(SearchType='DepthFirst', Workers=1, TimeLimit=100) # Parameters needed to avoid duplicate solutions 98 | try: 99 | for i, msol in enumerate(siter): 100 | stdout.write(str(i + 1) + ": ") 101 | for v in marks: 102 | stdout.write(" " + str(msol[v])) 103 | stdout.write("\n") 104 | except CpoNotSupportedException: 105 | print("This instance of the solver does not support solution iteration.") 106 | -------------------------------------------------------------------------------- /examples/cp/basic/golomb_ruler_with_propagate.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In mathematics, a Golomb ruler is a set of marks at integer positions along 9 | an imaginary ruler such that no two pairs of marks are the same distance apart. 10 | The number of marks on the ruler is its order, and the largest distance 11 | between two of its marks is its length. 12 | 13 | This implementation differs from the 'basic' one because it calls the solver 14 | twice: 15 | * First time to know the minimal size of the ruler for the required order, 16 | * A second time to list all possible rulers for this optimal size 17 | 18 | See https://en.wikipedia.org/wiki/Golomb_ruler for more information. 19 | 20 | For order 5: 2 solutions 0 1 4 9 11 ; 0 2 7 8 11 21 | 22 | Please refer to documentation for appropriate setup of solving configuration. 23 | """ 24 | 25 | from docplex.cp.model import CpoModel, CpoNotSupportedException 26 | 27 | 28 | #----------------------------------------------------------------------------- 29 | # Initialize the problem data 30 | #----------------------------------------------------------------------------- 31 | 32 | # Number of marks on the ruler 33 | ORDER = 8 34 | 35 | 36 | #----------------------------------------------------------------------------- 37 | # Prepare the data for modeling 38 | #----------------------------------------------------------------------------- 39 | 40 | # Estimate an upper bound to the ruler length 41 | MAX_LENGTH = (ORDER - 1) ** 2 42 | 43 | 44 | #----------------------------------------------------------------------------- 45 | # Build the model 46 | #----------------------------------------------------------------------------- 47 | 48 | # Create model 49 | mdl = CpoModel() 50 | 51 | # Create array of variables corresponding to position rule marks 52 | marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, "M") 53 | 54 | # Create marks distances that should be all different 55 | dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)] 56 | mdl.add(mdl.all_diff(dist)) 57 | 58 | # Avoid symmetric solutions by ordering marks 59 | mdl.add(marks[0] == 0) 60 | for i in range(1, ORDER): 61 | mdl.add(marks[i] > marks[i - 1]) 62 | 63 | # Avoid mirror solution 64 | mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2])) 65 | 66 | # Minimize ruler size (position of the last mark) 67 | mdl.add(mdl.minimize(marks[ORDER - 1])) 68 | 69 | 70 | #----------------------------------------------------------------------------- 71 | # Solve the model and display the result 72 | #----------------------------------------------------------------------------- 73 | 74 | # Call propagation 75 | try: 76 | msol = mdl.propagate() 77 | msol.print_solution() 78 | except CpoNotSupportedException: 79 | print("Method 'propagate' not supported by this solver agent") 80 | -------------------------------------------------------------------------------- /examples/cp/basic/golomb_ruler_with_refine_conflicts.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In mathematics, a Golomb ruler is a set of marks at integer positions along 9 | an imaginary ruler such that no two pairs of marks are the same distance apart. 10 | The number of marks on the ruler is its order, and the largest distance 11 | between two of its marks is its length. 12 | 13 | This implementation differs from the 'basic' one because it calls the solver 14 | twice: 15 | * First time to know the minimal size of the ruler for the required order, 16 | * A second time to list all possible rulers for this optimal size 17 | 18 | See https://en.wikipedia.org/wiki/Golomb_ruler for more information. 19 | 20 | For order 5: 2 solutions 0 1 4 9 11 ; 0 2 7 8 11 21 | 22 | Please refer to documentation for appropriate setup of solving configuration. 23 | """ 24 | 25 | 26 | from docplex.cp.model import CpoModel 27 | 28 | #----------------------------------------------------------------------------- 29 | # Initialize the problem data 30 | #----------------------------------------------------------------------------- 31 | 32 | # Number of marks on the ruler 33 | ORDER = 5 34 | 35 | 36 | #----------------------------------------------------------------------------- 37 | # Prepare the data for modeling (Voluntarily wrong) 38 | #----------------------------------------------------------------------------- 39 | 40 | # Estimate an upper bound to the ruler length 41 | MAX_LENGTH = 10 # TOO SHORT 42 | 43 | 44 | #----------------------------------------------------------------------------- 45 | # Build the model 46 | #----------------------------------------------------------------------------- 47 | 48 | # Create model 49 | mdl = CpoModel() 50 | 51 | # Create array of variables corresponding to position rule marks 52 | marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, "M") 53 | 54 | # Create marks distances that should be all different 55 | dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)] 56 | mdl.add(mdl.all_diff(dist)) 57 | 58 | # Avoid symmetric solutions by ordering marks 59 | mdl.add(marks[0] == 0) 60 | for i in range(1, ORDER): 61 | mdl.add(marks[i] > marks[i - 1]) 62 | 63 | # Avoid mirror solution 64 | mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2])) 65 | 66 | # Minimize ruler size (position of the last mark) 67 | mdl.add(mdl.minimize(marks[ORDER - 1])) 68 | 69 | 70 | #----------------------------------------------------------------------------- 71 | # Solve the model and display the result 72 | #----------------------------------------------------------------------------- 73 | 74 | # First solve the model 75 | msol = mdl.solve() 76 | # if msol: 77 | # msol.print_solution() 78 | # else: 79 | if True: 80 | rsol = mdl.refine_conflict() 81 | rsol.print_conflict() 82 | -------------------------------------------------------------------------------- /examples/cp/basic/kmeans.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2021, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | K-means is a way of clustering points in a multi-dimensional space 9 | where the set of points to be clustered are partitioned into k subsets. 10 | The idea is to minimize the inter-point distances inside a cluster in 11 | order to produce clusters which group together close points. 12 | 13 | See https://en.wikipedia.org/wiki/K-means_clustering 14 | """ 15 | 16 | 17 | import numpy as np 18 | from docplex.cp.model import CpoModel 19 | import docplex.cp.solver.solver as solver 20 | from docplex.cp.utils import compare_natural 21 | 22 | def make_model(coords, k, trust_numerics=True): 23 | """ 24 | Build a K-means model from a set of coordinate vectors (points), 25 | and a given number of clusters k. 26 | 27 | We assign each point to a cluster and minimize the objective which 28 | is the sum of the squares of the distances of each point to 29 | the centre of gravity of the cluster to which it belongs. 30 | 31 | Here, there are two ways of building the objective function. One 32 | uses the sum of squares of the coordinates of points in a cluster 33 | minus the size of the cluster times the center value. This is akin 34 | to the calculation of variance vi E[X^2] - E[X]^2. This is the most 35 | efficient but can be numerically unstable due to massive cancellation. 36 | 37 | The more numerically stable (but less efficient) way to calculate the 38 | objective is the analog of the variance calculation (sum_i(X_i - mu_i)^2)/n 39 | """ 40 | # Sizes and ranges 41 | n, d = coords.shape 42 | N, D, K = range(n), range(d), range(k) 43 | 44 | # Model, and decision variables. x[c] = cluster to which node c belongs 45 | mdl = CpoModel() 46 | x = [mdl.integer_var(0, k-1, "C_{}".format(i)) for i in N] 47 | 48 | # Size (number of nodes) in each cluster. If this is zero, we make 49 | # it 1 to avoid division by zero later (if a particular cluster is 50 | # not used). 51 | csize = [mdl.max(1, mdl.count(x, c)) for c in K] 52 | 53 | # Calculate total distance squared 54 | total_dist2 = 0 55 | for c in K: # For each cluster 56 | # Boolean vector saying which points are in this cluster 57 | included = [x[i] == c for i in N] 58 | for dim in D: # For each dimension 59 | # Points for each point in the given dimension (x, y, z, ...) 60 | point = coords[:, dim] 61 | 62 | # Calculate the cluster centre for this dimension 63 | centre = mdl.scal_prod(included, point) / csize[c] 64 | 65 | # Calculate the total distance^2 for this cluster & dimension 66 | if trust_numerics: 67 | sum_of_x2 = mdl.scal_prod(included, (p**2 for p in point)) 68 | dist2 = sum_of_x2 - centre**2 * csize[c] 69 | else: 70 | all_dist2 = ((centre - p)**2 for p in point) 71 | dist2 = mdl.scal_prod(included, all_dist2) 72 | 73 | # Keep the total distance squared in a sum 74 | total_dist2 += dist2 75 | 76 | # Minimize the total distance squared 77 | mdl.minimize(total_dist2) 78 | return mdl 79 | 80 | 81 | if __name__ == "__main__": 82 | import sys 83 | # Default values 84 | n, d, k, sd = 500, 2, 5, 1234 85 | 86 | # Accept number of points, number of dimensions, number of clusters, seed 87 | if len(sys.argv) > 1: 88 | n = int(sys.argv[1]) 89 | if len(sys.argv) > 2: 90 | d = int(sys.argv[2]) 91 | if len(sys.argv) > 3: 92 | k = int(sys.argv[3]) 93 | if len(sys.argv) > 4: 94 | sd = int(sys.argv[4]) 95 | 96 | # Message 97 | print("Generating with N = {}, D = {}, K = {}".format(n, d, k)) 98 | 99 | # Seed and generate coordinates on the unit hypercube 100 | np.random.seed(sd) 101 | coords = np.random.uniform(0, 1, size=(n, d)) 102 | 103 | # Build model 104 | mdl = make_model(coords, k) 105 | 106 | # Solve using constraint programming 107 | mdl.solve(SearchType="Restart", TimeLimit=10, LogPeriod=50000) 108 | 109 | if compare_natural(solver.get_solver_version(), '22.1') >= 0: 110 | # Solve using neighborhood search 111 | mdl.solve(SearchType="Neighborhood", TimeLimit=10, LogPeriod=50000) 112 | -------------------------------------------------------------------------------- /examples/cp/basic/latin_cube.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In combinatorics and in experimental design, a Latin cube is a 3 dimensions extension of the Latin square. 9 | 10 | The latin cube is a n x n x n array filled with n different symbols, 11 | each occurring exactly once in each row and exactly once in each column. 12 | 13 | Please refer to documentation for appropriate setup of solving configuration. 14 | """ 15 | 16 | from docplex.cp.model import CpoModel 17 | from sys import stdout 18 | 19 | 20 | #----------------------------------------------------------------------------- 21 | # Initialize the problem data 22 | #----------------------------------------------------------------------------- 23 | 24 | # Size of the cube 25 | CUBE_SIZE = 4 26 | 27 | # Indicate to constrain each square diagonal with all different symbols 28 | CONSTRAIN_DIAGONALS = True 29 | 30 | 31 | #----------------------------------------------------------------------------- 32 | # Build the model 33 | #----------------------------------------------------------------------------- 34 | 35 | # Create CPO model 36 | mdl = CpoModel() 37 | 38 | # Create grid of variables 39 | GRNG = range(CUBE_SIZE) 40 | grid = [[[mdl.integer_var(min=0, max=CUBE_SIZE - 1, name="C_{}_{}_{}".format(x, y, z)) for x in GRNG] for y in GRNG] for z in GRNG] 41 | 42 | # Add constraints for each slice on direction x 43 | for x in GRNG: 44 | # Add alldiff constraints for lines 45 | for l in GRNG: 46 | mdl.add(mdl.all_diff([grid[x][l][c] for c in GRNG])) 47 | 48 | # Add alldiff constraints for columns 49 | for c in GRNG: 50 | mdl.add(mdl.all_diff([grid[x][l][c] for l in GRNG])) 51 | 52 | # Add alldiff constraints for diagonals 53 | if CONSTRAIN_DIAGONALS: 54 | mdl.add(mdl.all_diff([grid[x][l][l] for l in GRNG])) 55 | mdl.add(mdl.all_diff([grid[x][l][CUBE_SIZE - l - 1] for l in GRNG])) 56 | 57 | # Add constraints for each slice on direction y 58 | for y in GRNG: 59 | # Add alldiff constraints for lines 60 | for l in GRNG: 61 | mdl.add(mdl.all_diff([grid[l][y][c] for c in GRNG])) 62 | 63 | # Add alldiff constraints for columns 64 | for c in GRNG: 65 | mdl.add(mdl.all_diff([grid[l][y][c] for l in GRNG])) 66 | 67 | # Add alldiff constraints for diagonals 68 | if CONSTRAIN_DIAGONALS: 69 | mdl.add(mdl.all_diff([grid[l][y][l] for l in GRNG])) 70 | mdl.add(mdl.all_diff([grid[l][y][CUBE_SIZE - l - 1] for l in GRNG])) 71 | 72 | # Add constraints for each slice on direction z 73 | for z in GRNG: 74 | # Add alldiff constraints for lines 75 | for l in GRNG: 76 | mdl.add(mdl.all_diff([grid[l][c][z] for c in GRNG])) 77 | 78 | # Add alldiff constraints for columns 79 | for c in GRNG: 80 | mdl.add(mdl.all_diff([grid[l][c][z] for l in GRNG])) 81 | 82 | # Add alldiff constraints for diagonals 83 | if CONSTRAIN_DIAGONALS: 84 | mdl.add(mdl.all_diff([grid[l][l][z] for l in GRNG])) 85 | mdl.add(mdl.all_diff([grid[l][CUBE_SIZE - l - 1][z] for l in GRNG])) 86 | 87 | # Force first line to natural sequence 88 | for c in GRNG: 89 | mdl.add(grid[0][0][c] == c) 90 | 91 | 92 | #----------------------------------------------------------------------------- 93 | # Solve the model and display the result 94 | #----------------------------------------------------------------------------- 95 | 96 | # Solve model 97 | print("\nSolving model....") 98 | msol = mdl.solve(TimeLimit=10) 99 | 100 | # Print solution 101 | stdout.write("Solution:\n") 102 | if msol: 103 | for x in GRNG: 104 | for l in GRNG: 105 | for c in GRNG: 106 | stdout.write(" " + chr(ord('A') + msol[grid[x][l][c]])) 107 | stdout.write('\n') 108 | stdout.write('\n') 109 | else: 110 | stdout.write("No solution found\n") 111 | -------------------------------------------------------------------------------- /examples/cp/basic/latin_square.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In combinatorics and in experimental design, a Latin square is an n x n array filled with n different symbols, 9 | each occurring exactly once in each row and exactly once in each column. 10 | Here is an example: 11 | 12 | A B C D 13 | D C B A 14 | B A D C 15 | C D A B 16 | 17 | More information is available on https://en.wikipedia.org/wiki/Latin_square 18 | 19 | Please refer to documentation for appropriate setup of solving configuration. 20 | """ 21 | 22 | from docplex.cp.model import CpoModel 23 | from sys import stdout 24 | 25 | 26 | #----------------------------------------------------------------------------- 27 | # Initialize the problem data 28 | #----------------------------------------------------------------------------- 29 | 30 | # Size of the square 31 | SQUARE_SIZE = 16 32 | 33 | 34 | #----------------------------------------------------------------------------- 35 | # Build the model 36 | #----------------------------------------------------------------------------- 37 | 38 | # Create CPO model 39 | mdl = CpoModel() 40 | 41 | # Create grid of variables 42 | GRNG = range(SQUARE_SIZE) 43 | grid = [[mdl.integer_var(min=0, max=SQUARE_SIZE - 1, name="C_{}_{}".format(l, c)) for l in GRNG] for c in GRNG] 44 | 45 | # Add alldiff constraints for lines 46 | for l in GRNG: 47 | mdl.add(mdl.all_diff([grid[l][c] for c in GRNG])) 48 | 49 | # Add alldiff constraints for columns 50 | for c in GRNG: 51 | mdl.add(mdl.all_diff([grid[l][c] for l in GRNG])) 52 | 53 | # Add alldiff constraints for diagonals 54 | mdl.add(mdl.all_diff([grid[l][l] for l in GRNG])) 55 | mdl.add(mdl.all_diff([grid[l][SQUARE_SIZE - l - 1] for l in GRNG])) 56 | 57 | # Force first line to natural sequence 58 | for c in GRNG: 59 | mdl.add(grid[0][c] == c) 60 | 61 | 62 | #----------------------------------------------------------------------------- 63 | # Solve the model and display the result 64 | #----------------------------------------------------------------------------- 65 | 66 | # Solve model 67 | print("\nSolving model....") 68 | msol = mdl.solve(TimeLimit=10) 69 | 70 | # Print solution 71 | stdout.write("Solution:\n") 72 | if msol: 73 | for l in GRNG: 74 | for c in GRNG: 75 | stdout.write(" " + chr(ord('A') + msol[grid[l][c]])) 76 | stdout.write('\n') 77 | else: 78 | stdout.write("No solution found\n") 79 | -------------------------------------------------------------------------------- /examples/cp/basic/linear_peg_solitaire.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This game is a solitaire game whose objective is to exchange two groups or red and blue pegs 9 | disposed linearly around a hole. The default game contains 2 pegs of each color, but may be extended 10 | to more. 11 | 12 | For two pegs of each color, the initial state is two red pegs and two blue pegs separated by a hole: RReBB. 13 | Objective is to reach final state BBeRR using only the following allowed moves: 14 | - A red peg can step one position to the right into the empty space. 15 | - A red peg can jump two positions to the right into the empty space. 16 | - A blue peg can step one position to the left into the empty space. 17 | - A blue peg can jump two positions to the left into the empty space. 18 | 19 | For example, for 2 pegs of each colors, the sequence of states is: 20 | RR.BB 21 | R.RBB 22 | RBR.B 23 | RBRB. 24 | RB.BR 25 | .BRBR 26 | B.RBR 27 | BBR.R 28 | BB.RR 29 | 30 | More information on http://www.cems.uvm.edu/~rsnapp/teaching/cs32/lectures/pegsolitaire.pdf 31 | (Robert Snapp, Department of Computer Science, University of Vermont) 32 | 33 | Please refer to documentation for appropriate setup of solving configuration. 34 | """ 35 | 36 | from docplex.cp.model import CpoModel 37 | from sys import stdout 38 | 39 | 40 | #----------------------------------------------------------------------------- 41 | # Initialize the problem data 42 | #----------------------------------------------------------------------------- 43 | 44 | # Number of pegs of each color 45 | NB_PEGS = 6 46 | 47 | 48 | #----------------------------------------------------------------------------- 49 | # Prepare the data for modeling 50 | #----------------------------------------------------------------------------- 51 | 52 | # Total number of holes (empty hole in the middle) 53 | SIZE = 2 * NB_PEGS + 1 54 | 55 | # Required number of moves (see reference document) 56 | NB_MOVES = NB_PEGS * (NB_PEGS + 2) 57 | 58 | # Integer values representing hole states 59 | HOLE = 0 60 | RED = 1 61 | BLUE = 2 62 | 63 | # Letters used to print the different pegs 64 | PEG_LETTERS = ('.', 'R', 'B') 65 | 66 | 67 | #----------------------------------------------------------------------------- 68 | # Build the model 69 | #----------------------------------------------------------------------------- 70 | 71 | # Create model 72 | mdl = CpoModel() 73 | 74 | # Create sequence of states. Each variable has 3 possible values: 0: Hole, 1: red peg, 2: blue peg 75 | states = [] 76 | for s in range(NB_MOVES + 1): 77 | states.append(mdl.integer_var_list(SIZE, HOLE, BLUE, "State_" + str(s) + "_")) 78 | 79 | # Create variables representing from index and to index for each move 80 | fromIndex = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "From_") 81 | toIndex = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "To_") 82 | 83 | # Add constraints between each state 84 | for m in range(NB_MOVES): 85 | fvar = fromIndex[m] 86 | tvar = toIndex[m] 87 | fromState = states[m] 88 | toState = states[m + 1] 89 | # Constrain location of holes 90 | mdl.add(mdl.element(fromState, tvar) == HOLE) 91 | # Constrain move size and direction 92 | delta = tvar - fvar 93 | mdl.add(mdl.allowed_assignments(delta, [-2, -1, 1, 2])) 94 | peg = mdl.element(fromState, fvar) 95 | mdl.add( ((peg == RED) & (delta > 0)) | ((peg == BLUE) & (delta < 0)) ) 96 | # Make moves 97 | mdl.add(mdl.element(toState, tvar) == mdl.element(fromState, fvar)) 98 | mdl.add(mdl.element(toState, fvar) == HOLE) 99 | # Force equality of other positions 100 | for p in range(SIZE): 101 | mdl.add(mdl.if_then((p != fvar) & (p != tvar), fromState[p] == toState[p])) 102 | 103 | # Set initial position 104 | for p in range(NB_PEGS): 105 | mdl.add(states[0][p] == RED) 106 | mdl.add(states[0][p + NB_PEGS + 1] == BLUE) 107 | mdl.add(states[0][NB_PEGS] == HOLE) 108 | 109 | # Force last state to be final 110 | expr = states[NB_MOVES][NB_PEGS] == HOLE 111 | for p in range(NB_PEGS): 112 | expr &= states[NB_MOVES][p] == BLUE 113 | expr &= states[NB_MOVES][p + NB_PEGS + 1] == RED 114 | mdl.add(expr) 115 | 116 | 117 | #----------------------------------------------------------------------------- 118 | # Solve the model and display the result 119 | #----------------------------------------------------------------------------- 120 | 121 | # Solve model 122 | print("Solving model....") 123 | msol = mdl.solve(TimeLimit=50) 124 | 125 | # Print solution 126 | if msol: 127 | print("Number of moves: " + str(NB_MOVES)) 128 | for m in range(NB_MOVES + 1): 129 | rstr = " " + ''.join(PEG_LETTERS[msol[states[m][x]]] for x in range(SIZE)) 130 | if (m < NB_MOVES): 131 | rstr += " {0} -> {1}".format(msol[fromIndex[m]], msol[toIndex[m]]) 132 | print(rstr) 133 | else: 134 | stdout.write("Solve status: " + msol.get_solve_status() + ", fail status: " + msol.get_fail_status() + "\n") 135 | -------------------------------------------------------------------------------- /examples/cp/basic/n_queen.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The eight queens puzzle is the problem of placing eight chess queens on an 8x8 9 | chessboard so that no two queens threaten each other. Thus, a solution requires 10 | that no two queens share the same row, column, or diagonal. 11 | 12 | The eight queens puzzle is an example of the more general n-queens problem of 13 | placing n queens on an nxn chessboard, where solutions exist for all natural 14 | numbers n with the exception of n=2 and n=3. 15 | 16 | See https://en.wikipedia.org/wiki/Eight_queens_puzzle for more information. 17 | 18 | Please refer to documentation for appropriate setup of solving configuration. 19 | """ 20 | 21 | from docplex.cp.model import CpoModel 22 | from sys import stdout 23 | 24 | #----------------------------------------------------------------------------- 25 | # Initialize the problem data 26 | #----------------------------------------------------------------------------- 27 | 28 | # Set model parameters 29 | NB_QUEEN = 8 30 | 31 | 32 | #----------------------------------------------------------------------------- 33 | # Build the model 34 | #----------------------------------------------------------------------------- 35 | 36 | # Create model 37 | mdl = CpoModel() 38 | 39 | # Create column index of each queen 40 | x = mdl.integer_var_list(NB_QUEEN, 0, NB_QUEEN - 1, "X") 41 | 42 | # One queen per raw 43 | mdl.add(mdl.all_diff(x)) 44 | 45 | # One queen per diagonal xi - xj != i - j 46 | mdl.add(mdl.all_diff(x[i] + i for i in range(NB_QUEEN))) 47 | 48 | # One queen per diagonal xi - xj != j - i 49 | mdl.add(mdl.all_diff(x[i] - i for i in range(NB_QUEEN))) 50 | 51 | 52 | #----------------------------------------------------------------------------- 53 | # Solve the model and display the result 54 | #----------------------------------------------------------------------------- 55 | 56 | # Solve model 57 | print("Solving model....") 58 | msol = mdl.solve(TimeLimit=10) 59 | 60 | # Print solution 61 | if msol: 62 | stdout.write("Solution:") 63 | for v in x: 64 | stdout.write(" {}".format(msol[v])) 65 | stdout.write("\n") 66 | # Draw chess board 67 | for l in range(NB_QUEEN): 68 | qx = msol[x[l]] 69 | for c in range(NB_QUEEN): 70 | stdout.write(" ") 71 | stdout.write("Q" if c == qx else ".") 72 | stdout.write("\n") 73 | else: 74 | stdout.write("Solve status: {}\n".format(msol.get_solve_status())) 75 | -------------------------------------------------------------------------------- /examples/cp/basic/plant_location_with_cpo_callback.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | A ship-building company has a certain number of customers. Each customer is supplied 9 | by exactly one plant. In turn, a plant can supply several customers. The problem is 10 | to decide where to set up the plants in order to supply every customer while minimizing 11 | the cost of building each plant and the transportation cost of supplying the customers. 12 | 13 | For each possible plant location there is a fixed cost and a production capacity. 14 | Both take into account the country and the geographical conditions. 15 | 16 | For every customer, there is a demand and a transportation cost with respect to 17 | each plant location. 18 | 19 | While a first solution of this problem can be found easily by CP Optimizer, it can take 20 | quite some time to improve it to a very good one. We illustrate the warm start capabilities 21 | of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. 22 | This solution could be one from an expert or the result of another optimization engine 23 | applied to the problem. 24 | 25 | In the solution we only give a value to the variables that determine which plant delivers 26 | a customer. This is sufficient to define a complete solution on all model variables. 27 | CP Optimizer first extends the solution to all variables and then starts to improve it. 28 | 29 | The solve is enriched with a CPO callback, available from version of COS greater or equal to 12.10.0.0. 30 | This callback displays various information generated during the solve, in particular intermediate 31 | solutions that are found before the end of the solve. 32 | """ 33 | 34 | from docplex.cp.model import CpoModel 35 | import docplex.cp.solver.solver as solver 36 | from docplex.cp.utils import compare_natural 37 | from collections import deque 38 | import os 39 | from docplex.cp.solver.cpo_callback import CpoCallback 40 | 41 | 42 | #----------------------------------------------------------------------------- 43 | # Initialize the problem data 44 | #----------------------------------------------------------------------------- 45 | 46 | # Read problem data from a file and convert it as a list of integers 47 | filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" 48 | data = deque() 49 | with open(filename, "r") as file: 50 | for val in file.read().split(): 51 | data.append(int(val)) 52 | 53 | # Read number of customers and locations 54 | nbCustomer = data.popleft() 55 | nbLocation = data.popleft() 56 | 57 | # Initialize cost. cost[c][p] = cost to deliver customer c from plant p 58 | cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) 59 | 60 | # Initialize demand of each customer 61 | demand = list([data.popleft() for c in range(nbCustomer)]) 62 | 63 | # Initialize fixed cost of each location 64 | fixedCost = list([data.popleft() for p in range(nbLocation)]) 65 | 66 | # Initialize capacity of each location 67 | capacity = list([data.popleft() for p in range(nbLocation)]) 68 | 69 | 70 | #----------------------------------------------------------------------------- 71 | # Build the model 72 | #----------------------------------------------------------------------------- 73 | 74 | mdl = CpoModel() 75 | 76 | # Create variables identifying which location serves each customer 77 | cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") 78 | 79 | # Create variables indicating which plant location is open 80 | open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") 81 | 82 | # Create variables indicating load of each plant 83 | load = [mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] 84 | 85 | # Associate plant openness to its load 86 | for p in range(nbLocation): 87 | mdl.add(open[p] == (load[p] > 0)) 88 | 89 | # Add constraints 90 | mdl.add(mdl.pack(load, cust, demand)) 91 | 92 | # Add objective 93 | obj = mdl.scal_prod(fixedCost, open) 94 | for c in range(nbCustomer): 95 | obj += mdl.element(cust[c], cost[c]) 96 | mdl.add(mdl.minimize(obj)) 97 | 98 | 99 | #----------------------------------------------------------------------------- 100 | # Solve the model, tracking objective with a callback 101 | #----------------------------------------------------------------------------- 102 | 103 | class MyCallback(CpoCallback): 104 | def invoke(self, solver, event, jsol): 105 | # Get important elements 106 | obj_val = jsol.get_objective_values() 107 | obj_bnds = jsol.get_objective_bounds() 108 | obj_gaps = jsol.get_objective_gaps() 109 | solvests = jsol.get_solve_status() 110 | srchsts = jsol.get_search_status() 111 | #allvars = jsol.get_solution().get_all_var_solutions() if jsol.is_solution() else None 112 | solve_time = jsol.get_info('SolveTime') 113 | memory = jsol.get_info('MemoryUsage') 114 | print("CALLBACK: {}: {}, {}, objective: {} bounds: {}, gaps: {}, time: {}, memory: {}".format(event, solvests, srchsts, obj_val, obj_bnds, obj_gaps, solve_time, memory)) 115 | 116 | if compare_natural(solver.get_solver_version(), '12.10') >= 0: 117 | mdl.add_solver_callback(MyCallback()) 118 | 119 | # Solve the model 120 | print("Solve the model") 121 | msol = mdl.solve(TimeLimit=10) 122 | msol.write() 123 | -------------------------------------------------------------------------------- /examples/cp/basic/plant_location_with_kpis.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | A ship-building company has a certain number of customers. Each customer is supplied 9 | by exactly one plant. In turn, a plant can supply several customers. The problem is 10 | to decide where to set up the plants in order to supply every customer while minimizing 11 | the cost of building each plant and the transportation cost of supplying the customers. 12 | 13 | For each possible plant location there is a fixed cost and a production capacity. 14 | Both take into account the country and the geographical conditions. 15 | 16 | For every customer, there is a demand and a transportation cost with respect to 17 | each plant location. 18 | 19 | While a first solution of this problem can be found easily by CP Optimizer, it can take 20 | quite some time to improve it to a very good one. We illustrate the warm start capabilities 21 | of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. 22 | This solution could be one from an expert or the result of another optimization engine 23 | applied to the problem. 24 | 25 | In the solution we only give a value to the variables that determine which plant delivers 26 | a customer. This is sufficient to define a complete solution on all model variables. 27 | CP Optimizer first extends the solution to all variables and then starts to improve it. 28 | 29 | The model has been enriched by the addition of KPIs (key performance indicators), operational with a 30 | version of COS greater or equal to 12.9.0.0. 31 | These are named expressions which are of interest to help get an idea of the performance of the model. 32 | Here, we are interested in two indicators: 33 | - the first is the `occupancy'' defined as the total demand divided by the total plant capacity. 34 | - the second indicator is the occupancy which is the lowest of all the plants. 35 | 36 | The KPIs are displayed in the log whenever an improving solution is found and at the end of the search. 37 | """ 38 | 39 | from docplex.cp.model import CpoModel 40 | import docplex.cp.solver.solver as solver 41 | from docplex.cp.utils import compare_natural 42 | from collections import deque 43 | import os 44 | 45 | #----------------------------------------------------------------------------- 46 | # Initialize the problem data 47 | #----------------------------------------------------------------------------- 48 | 49 | # Read problem data from a file and convert it as a list of integers 50 | filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" 51 | data = deque() 52 | with open(filename, "r") as file: 53 | for val in file.read().split(): 54 | data.append(int(val)) 55 | 56 | # Read number of customers and locations 57 | nbCustomer = data.popleft() 58 | nbLocation = data.popleft() 59 | 60 | # Initialize cost. cost[c][p] = cost to deliver customer c from plant p 61 | cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) 62 | 63 | # Initialize demand of each customer 64 | demand = list([data.popleft() for c in range(nbCustomer)]) 65 | 66 | # Initialize fixed cost of each location 67 | fixedCost = list([data.popleft() for p in range(nbLocation)]) 68 | 69 | # Initialize capacity of each location 70 | capacity = list([data.popleft() for p in range(nbLocation)]) 71 | 72 | 73 | #----------------------------------------------------------------------------- 74 | # Build the model 75 | #----------------------------------------------------------------------------- 76 | 77 | mdl = CpoModel() 78 | 79 | # Create variables identifying which location serves each customer 80 | cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") 81 | 82 | # Create variables indicating which plant location is open 83 | open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") 84 | 85 | # Create variables indicating load of each plant 86 | load = [mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] 87 | 88 | # Associate plant openness to its load 89 | for p in range(nbLocation): 90 | mdl.add(open[p] == (load[p] > 0)) 91 | 92 | # Add constraints 93 | mdl.add(mdl.pack(load, cust, demand)) 94 | 95 | # Add objective 96 | obj = mdl.scal_prod(fixedCost, open) 97 | for c in range(nbCustomer): 98 | obj += mdl.element(cust[c], cost[c]) 99 | mdl.add(mdl.minimize(obj)) 100 | 101 | # Add KPIs 102 | sol_version = solver.get_solver_version() 103 | if compare_natural(sol_version, '12.9') >= 0: 104 | mdl.add_kpi(mdl.sum(demand) / mdl.scal_prod(open, capacity), "Occupancy") 105 | mdl.add_kpi(mdl.min([load[l] / capacity[l] + (1 - open[l]) for l in range(nbLocation)]), "Min occupancy") 106 | 107 | 108 | #----------------------------------------------------------------------------- 109 | # Solve the model and display the result 110 | #----------------------------------------------------------------------------- 111 | 112 | # Solve the model 113 | print("Solve the model") 114 | msol = mdl.solve(TimeLimit=10, trace_log=False) # Set trace_log=True to have a real-time view of the KPIs 115 | if msol: 116 | print(" Objective value: {}".format(msol.get_objective_values()[0])) 117 | if compare_natural(sol_version, '12.9') >= 0: 118 | print(" KPIs: {}".format(msol.get_kpis())) 119 | else: 120 | print(" No solution") 121 | -------------------------------------------------------------------------------- /examples/cp/basic/plant_location_with_starting_point.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | A ship-building company has a certain number of customers. Each customer is supplied 9 | by exactly one plant. In turn, a plant can supply several customers. The problem is 10 | to decide where to set up the plants in order to supply every customer while minimizing 11 | the cost of building each plant and the transportation cost of supplying the customers. 12 | 13 | For each possible plant location there is a fixed cost and a production capacity. 14 | Both take into account the country and the geographical conditions. 15 | 16 | For every customer, there is a demand and a transportation cost with respect to 17 | each plant location. 18 | 19 | While a first solution of this problem can be found easily by CP Optimizer, it can take 20 | quite some time to improve it to a very good one. We illustrate the warm start capabilities 21 | of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. 22 | This solution could be one from an expert or the result of another optimization engine 23 | applied to the problem. 24 | 25 | In the solution we only give a value to the variables that determine which plant delivers 26 | a customer. This is sufficient to define a complete solution on all model variables. 27 | CP Optimizer first extends the solution to all variables and then starts to improve it. 28 | 29 | Please refer to documentation for appropriate setup of solving configuration. 30 | """ 31 | 32 | from docplex.cp.model import CpoModel 33 | from docplex.cp.solution import CpoModelSolution 34 | from collections import deque 35 | import os 36 | 37 | #----------------------------------------------------------------------------- 38 | # Initialize the problem data 39 | #----------------------------------------------------------------------------- 40 | 41 | # Read problem data from a file and convert it as a list of integers 42 | filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" 43 | data = deque() 44 | with open(filename, "r") as file: 45 | for val in file.read().split(): 46 | data.append(int(val)) 47 | 48 | # Read number of customers and locations 49 | nbCustomer = data.popleft() 50 | nbLocation = data.popleft() 51 | 52 | # Initialize cost. cost[c][p] = cost to deliver customer c from plant p 53 | cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) 54 | 55 | # Initialize demand of each customer 56 | demand = list([data.popleft() for c in range(nbCustomer)]) 57 | 58 | # Initialize fixed cost of each location 59 | fixedCost = list([data.popleft() for p in range(nbLocation)]) 60 | 61 | # Initialize capacity of each location 62 | capacity = list([data.popleft() for p in range(nbLocation)]) 63 | 64 | 65 | #----------------------------------------------------------------------------- 66 | # Build the model 67 | #----------------------------------------------------------------------------- 68 | 69 | mdl = CpoModel() 70 | 71 | # Create variables identifying which location serves each customer 72 | cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") 73 | 74 | # Create variables indicating which plant location is open 75 | open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") 76 | 77 | # Create variables indicating load of each plant 78 | load = [mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] 79 | 80 | # Associate plant openness to its load 81 | for p in range(nbLocation): 82 | mdl.add(open[p] == (load[p] > 0)) 83 | 84 | # Add constraints 85 | mdl.add(mdl.pack(load, cust, demand)) 86 | 87 | # Add objective 88 | obj = mdl.scal_prod(fixedCost, open) 89 | for c in range(nbCustomer): 90 | obj += mdl.element(cust[c], cost[c]) 91 | mdl.add(mdl.minimize(obj)) 92 | 93 | 94 | #----------------------------------------------------------------------------- 95 | # Solve the model and display the result 96 | #----------------------------------------------------------------------------- 97 | 98 | # Solve without starting point 99 | print("Solve the model with no starting point") 100 | msol = mdl.solve(TimeLimit=10) 101 | if msol: 102 | print(" Objective value: " + str(msol.get_objective_values()[0])) 103 | else: 104 | print(" No solution") 105 | 106 | # Solve with starting point 107 | print("Solve the model with starting point") 108 | custValues = [19, 0, 11, 8, 29, 9, 29, 28, 17, 15, 7, 9, 18, 15, 1, 17, 25, 18, 17, 27, 109 | 22, 1, 26, 3, 22, 2, 20, 27, 2, 16, 1, 16, 12, 28, 19, 2, 20, 14, 13, 27, 110 | 3, 9, 18, 0, 13, 19, 27, 14, 12, 1, 15, 14, 17, 0, 7, 12, 11, 0, 25, 16, 111 | 22, 13, 16, 8, 18, 27, 19, 23, 26, 13, 11, 11, 19, 22, 28, 26, 23, 3, 18, 23, 112 | 26, 14, 29, 18, 9, 7, 12, 27, 8, 20] 113 | sp = CpoModelSolution() 114 | for c in range(nbCustomer): 115 | sp.add_integer_var_solution(cust[c], custValues[c]) 116 | mdl.set_starting_point(sp) 117 | 118 | try: 119 | msol = mdl.solve(TimeLimit=10) 120 | if msol: 121 | print(" Objective value: " + str(msol.get_objective_values()[0])) 122 | else: 123 | print(" No solution") 124 | except: 125 | print(" Starting point seems not available with your solver version.") 126 | -------------------------------------------------------------------------------- /examples/cp/basic/sudoku.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | Sudoku is a logic-based, combinatorial number-placement puzzle. 9 | The objective is to fill a 9x9 grid with digits so that each column, each row, 10 | and each of the nine 3x3 sub-grids that compose the grid contains all of the digits from 1 to 9. 11 | The puzzle setter provides a partially completed grid, which for a well-posed puzzle has a unique solution. 12 | 13 | See https://en.wikipedia.org/wiki/Sudoku for details 14 | 15 | Please refer to documentation for appropriate setup of solving configuration. 16 | """ 17 | 18 | from docplex.cp.model import CpoModel 19 | from sys import stdout 20 | 21 | 22 | #----------------------------------------------------------------------------- 23 | # Initialize the problem data 24 | #----------------------------------------------------------------------------- 25 | 26 | # Problem 1 (zero means cell to be filled with appropriate value) 27 | SUDOKU_PROBLEM_1 = ( (0, 0, 0, 0, 9, 0, 1, 0, 0), 28 | (2, 8, 0, 0, 0, 5, 0, 0, 0), 29 | (7, 0, 0, 0, 0, 6, 4, 0, 0), 30 | 31 | (8, 0, 5, 0, 0, 3, 0, 0, 6), 32 | (0, 0, 1, 0, 0, 4, 0, 0, 0), 33 | (0, 7, 0, 2, 0, 0, 0, 0, 0), 34 | 35 | (3, 0, 0, 0, 0, 1, 0, 8, 0), 36 | (0, 0, 0, 0, 0, 0, 0, 5, 0), 37 | (0, 9, 0, 0, 0, 0, 0, 7, 0), 38 | ) 39 | 40 | # Problem 2 41 | SUDOKU_PROBLEM_2 = ( (0, 7, 0, 0, 0, 0, 0, 4, 9), 42 | (0, 0, 0, 4, 0, 0, 0, 0, 0), 43 | (4, 0, 3, 5, 0, 7, 0, 0, 8), 44 | 45 | (0, 0, 7, 2, 5, 0, 4, 0, 0), 46 | (0, 0, 0, 0, 0, 0, 8, 0, 0), 47 | (0, 0, 4, 0, 3, 0, 5, 9, 2), 48 | 49 | (6, 1, 8, 0, 0, 0, 0, 0, 5), 50 | (0, 9, 0, 1, 0, 0, 0, 3, 0), 51 | (0, 0, 5, 0, 0, 0, 0, 0, 7), 52 | ) 53 | 54 | 55 | #----------------------------------------------------------------------------- 56 | # Build the model 57 | #----------------------------------------------------------------------------- 58 | 59 | # Create CPO model 60 | mdl = CpoModel() 61 | 62 | # Grid range 63 | GRNG = range(9) 64 | 65 | # Create grid of variables 66 | grid = [[mdl.integer_var(min=1, max=9, name="C" + str(l) + str(c)) for l in GRNG] for c in GRNG] 67 | 68 | # Add alldiff constraints for lines 69 | for l in GRNG: 70 | mdl.add(mdl.all_diff([grid[l][c] for c in GRNG])) 71 | 72 | # Add alldiff constraints for columns 73 | for c in GRNG: 74 | mdl.add(mdl.all_diff([grid[l][c] for l in GRNG])) 75 | 76 | # Add alldiff constraints for sub-squares 77 | ssrng = range(0, 9, 3) 78 | for sl in ssrng: 79 | for sc in ssrng: 80 | mdl.add(mdl.all_diff([grid[l][c] for l in range(sl, sl + 3) for c in range(sc, sc + 3)])) 81 | 82 | # Initialize known cells 83 | problem = SUDOKU_PROBLEM_2 84 | for l in GRNG: 85 | for c in GRNG: 86 | v = problem[l][c] 87 | if v > 0: 88 | grid[l][c].set_domain((v, v)) 89 | 90 | 91 | #----------------------------------------------------------------------------- 92 | # Solve the model and display the result 93 | #----------------------------------------------------------------------------- 94 | 95 | def print_grid(grid): 96 | """ Print Sudoku grid """ 97 | for l in GRNG: 98 | if (l > 0) and (l % 3 == 0): 99 | stdout.write('\n') 100 | for c in GRNG: 101 | v = grid[l][c] 102 | stdout.write(' ' if (c % 3 == 0) else ' ') 103 | stdout.write(str(v) if v > 0 else '.') 104 | stdout.write('\n') 105 | 106 | # Solve model 107 | print("\nSolving model....") 108 | msol = mdl.solve(TimeLimit=10) 109 | 110 | # Print solution 111 | stdout.write("Initial problem:\n") 112 | print_grid(problem) 113 | stdout.write("Solution:\n") 114 | if msol: 115 | sol = [[msol[grid[l][c]] for c in GRNG] for l in GRNG] 116 | print_grid(sol) 117 | else: 118 | stdout.write("No solution found\n") 119 | -------------------------------------------------------------------------------- /examples/cp/basic/trimloss.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2020 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The trim loss problems arises in the paper industry. 9 | 10 | The problem is to cut wide papers rolls into sub rolls (orders). 11 | The wide roll are cut into pieces with a cutting pattern. 12 | 13 | A cutting pattern defines the blades positions for cutting the roll. 14 | A maximum number of orders is allowed in a cutting pattern (here it is 6). 15 | When cutting a wide roll, we can have a loss of paper that is wasted. 16 | This loss is contrained to be not more than a given value (here it is 100) 17 | 18 | An order is characterised by a demand, a roll width, and a maximum number of 19 | time it can appear in a cutting pattern. 20 | 21 | The goal is to meet the demand while minimizing the roll used and the number 22 | of different cutting patterns used for production. 23 | 24 | In this example we also use: 25 | - extra constraints to avoid assigning orders to unused patterns, 26 | - lexicographic constraints to break symmetries between cutting patterns 27 | - strong constraints to have a better domain reduction by enumerating possible 28 | patterns configurations 29 | All this makes the proof of optimality rather fast. 30 | """ 31 | 32 | from docplex.cp.model import * 33 | from sys import stdout 34 | 35 | #----------------------------------------------------------------------------- 36 | # Initialize the problem data 37 | #----------------------------------------------------------------------------- 38 | 39 | # Data 40 | ROLL_WIDTH = 2200 # Width of roll to be cutted into pieces 41 | MAX_WASTE = 100 # Maximum waste per roll 42 | MAX_ORDER_PER_CUT = 5 # Maximum number of order per cutting pattern 43 | 44 | # Orders demand, width and max occurence in a cutting pattern 45 | ORDER_DEMAND = ( 8, 16, 12, 7, 14, 16) 46 | ORDER_WIDTH = (330, 360, 380, 430, 490, 530) 47 | ORDER_MAX_REPEAT = ( 2, 3, 3, 5, 3, 4) 48 | # Number of different order types 49 | NUM_ORDER_TYPE = len(ORDER_DEMAND) 50 | # Maximum number of cutting pattern 51 | NUM_PATTERN_TYPE = 6 52 | # Maximum of time a cutting pattern is used 53 | MAX_PATTERN_USAGE = 16 54 | # Cost of using a pattern 55 | PATTERN_COST = 0.1 56 | # Cost of a roll 57 | ROLL_COST = 1 58 | 59 | PATTERNS = range(NUM_PATTERN_TYPE) 60 | ORDERS = range(NUM_ORDER_TYPE) 61 | 62 | 63 | #----------------------------------------------------------------------------- 64 | # Build the model 65 | #----------------------------------------------------------------------------- 66 | 67 | model = CpoModel() 68 | 69 | # Decision variables : pattern usage 70 | patternUsage = [model.integer_var(0, MAX_PATTERN_USAGE, "PatternUsage_"+str(p)) for p in PATTERNS] 71 | 72 | # Decision variables : order quantity per pattern 73 | x = [[model.integer_var(0, max, "x["+str(o)+","+str(p)+"]") 74 | for (o, max) in enumerate(ORDER_MAX_REPEAT)] 75 | for p in PATTERNS] 76 | 77 | # Maximum number of orders per cutting pattern 78 | for p in PATTERNS : 79 | model.add(sum(x[p]) <= MAX_ORDER_PER_CUT) 80 | 81 | # Roll capacity 82 | usage = [0] + [v for v in range(ROLL_WIDTH - MAX_WASTE, ROLL_WIDTH+1)] # usage is [0, 2100..2200] 83 | rollUsage = [model.integer_var(domain = usage, name = "RollUsage_"+str(p)) for p in PATTERNS] 84 | 85 | for p in PATTERNS : 86 | model.add(sum(ORDER_WIDTH[o] * x[p][o] for o in ORDERS) == rollUsage[p]) 87 | 88 | # Production requirement 89 | for o in ORDERS : 90 | model.add(model.sum(x[p][o] * patternUsage[p] for p in PATTERNS) >= ORDER_DEMAND[o]) 91 | 92 | # Objective 93 | model.add(minimize(model.sum((patternUsage[p] > 0) * PATTERN_COST + patternUsage[p] * ROLL_COST 94 | for p in PATTERNS))) 95 | 96 | # Extra constraint to avoid assigning orders to an unused pattern 97 | for p in PATTERNS : 98 | model.add((patternUsage[p] == 0) == (rollUsage[p] == 0)) 99 | 100 | # Extra lexicographic constraint to break symmetries 101 | for p in range(NUM_PATTERN_TYPE - 1) : 102 | model.add(model.lexicographic([patternUsage[p]] + x[p], [patternUsage[p+1]] + x[p+1])) 103 | 104 | # Strong constraints to improve the time to prove optimality 105 | for p in PATTERNS : 106 | model.add(model.strong(x[p])) 107 | 108 | # KPIs : Number of rolls, of pattern used and total loss of paper 109 | model.add_kpi(model.sum([patternUsage[p] for p in PATTERNS]), "Rolls") 110 | model.add_kpi(model.sum([(patternUsage[p] > 0) for p in PATTERNS]), "Patterns") 111 | model.add_kpi(model.sum([patternUsage[p] * (ROLL_WIDTH - rollUsage[p]) for p in PATTERNS]), "Loss") 112 | 113 | 114 | #----------------------------------------------------------------------------- 115 | # Solve the model and display the result 116 | #----------------------------------------------------------------------------- 117 | 118 | print("Solve the model...") 119 | msol = model.solve(LogPeriod=1000000, TimeLimit=300) 120 | if msol: 121 | print("patternUsage = ") 122 | for p in PATTERNS: 123 | l = ROLL_WIDTH - msol[rollUsage[p]] 124 | stdout.write("Pattern {} , usage = {}, roll usage = {}, loss = {}, orders =".format(p, msol[patternUsage[p]], msol[rollUsage[p]], l)) 125 | for o in ORDERS: 126 | stdout.write(" {}".format(msol[x[p][o]])) 127 | stdout.write('\n') 128 | else: 129 | print("No solution found") 130 | -------------------------------------------------------------------------------- /examples/cp/basic/vietnamese_problem.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | Mathematical problem asked to 8 years old vietnamese children. 9 | 10 | See: http://www.slate.fr/story/101809/puzzle-maths-vietnam for more information. 11 | 12 | Please refer to documentation for appropriate setup of solving configuration. 13 | """ 14 | 15 | from docplex.cp.model import CpoModel 16 | 17 | #----------------------------------------------------------------------------- 18 | # Build the model 19 | #----------------------------------------------------------------------------- 20 | 21 | # Create model 22 | mdl = CpoModel() 23 | 24 | # Create model variables 25 | V = mdl.integer_var_list(size=9, min=1, max=9, name="V") 26 | mdl.add(mdl.all_diff(V)) 27 | 28 | # Create constraint 29 | mdl.add(V[0] + 13 * V[1] / V[2] + V[3] + 12 * V[4] - V[5] - 11 + V[6] * V[7] / V[8] - 10 == 66) 30 | 31 | 32 | #----------------------------------------------------------------------------- 33 | # Solve the model and display the result 34 | #----------------------------------------------------------------------------- 35 | 36 | # Solve model 37 | print("Solving model....") 38 | msol = mdl.solve(TimeLimit=10) 39 | 40 | print("Solution: ") 41 | msol.print_solution() 42 | -------------------------------------------------------------------------------- /examples/cp/jupyter/house_building_utils/activity.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/house_building_utils/activity.PNG -------------------------------------------------------------------------------- /examples/cp/jupyter/house_building_utils/alternative.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/house_building_utils/alternative.PNG -------------------------------------------------------------------------------- /examples/cp/jupyter/house_building_utils/intervalVar.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/house_building_utils/intervalVar.PNG -------------------------------------------------------------------------------- /examples/cp/jupyter/house_building_utils/noOverlap.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/house_building_utils/noOverlap.PNG -------------------------------------------------------------------------------- /examples/cp/jupyter/n_queen_utils/BQueen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/n_queen_utils/BQueen.png -------------------------------------------------------------------------------- /examples/cp/jupyter/n_queen_utils/WQueen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/cp/jupyter/n_queen_utils/WQueen.png -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_default.data: -------------------------------------------------------------------------------- 1 | 20 5 2 | 62 22 77 88 39 3 | 68 94 66 57 48 4 | 57 6 20 24 86 5 | 54 37 87 50 78 6 | 50 80 62 60 58 7 | 59 78 79 93 88 8 | 36 55 10 13 43 9 | 46 81 36 13 36 10 | 83 67 39 1 88 11 | 23 54 25 8 2 12 | 2 57 82 63 16 13 | 38 20 93 15 13 14 | 82 51 66 89 63 15 | 9 34 42 42 46 16 | 76 25 13 13 23 17 | 99 34 77 24 41 18 | 76 23 96 56 84 19 | 12 94 2 5 9 20 | 13 84 57 78 72 21 | 19 86 6 58 27 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_tail20_10_2.data: -------------------------------------------------------------------------------- 1 | 20 10 2 | 80 59 59 31 30 53 93 90 65 64 3 | 13 83 70 64 88 19 79 92 97 38 4 | 64 85 76 11 14 99 88 35 27 44 5 | 77 85 10 9 22 62 77 13 25 46 6 | 17 70 65 32 93 88 94 75 61 66 7 | 78 35 19 58 48 93 39 55 24 31 8 | 82 2 77 98 10 34 74 80 97 48 9 | 4 76 86 95 7 72 46 67 61 27 10 | 72 46 21 25 14 42 17 3 75 82 11 | 93 72 75 4 91 65 30 93 92 51 12 | 68 69 96 45 5 39 62 54 73 90 13 | 25 46 3 60 43 79 77 67 21 63 14 | 67 3 50 87 30 9 43 25 29 85 15 | 80 57 57 31 79 26 98 77 3 36 16 | 43 71 66 1 39 72 48 38 96 69 17 | 93 77 84 96 34 29 14 98 51 67 18 | 21 33 98 22 77 36 45 96 26 81 19 | 33 49 55 95 81 48 25 20 44 18 20 | 14 59 70 73 11 57 98 15 56 81 21 | 30 82 32 77 10 95 30 36 31 72 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_tail20_20_5.data: -------------------------------------------------------------------------------- 1 | 20 20 2 | 72 72 79 95 1 90 37 92 94 15 8 62 89 96 89 54 46 94 40 28 3 | 47 45 55 67 83 30 32 82 82 50 35 44 99 47 93 68 88 91 58 23 4 | 52 73 95 93 17 88 42 95 24 27 46 89 23 39 74 26 61 88 85 59 5 | 40 94 46 90 69 69 3 18 98 12 25 20 34 43 2 47 6 56 69 85 6 | 49 76 59 73 72 51 5 85 74 59 41 21 68 45 54 51 33 94 67 4 7 | 86 28 89 63 61 7 79 27 98 97 50 72 23 13 60 44 17 13 41 14 8 | 75 58 16 25 67 26 33 92 93 38 24 96 31 95 57 21 21 33 6 53 9 | 26 98 40 36 83 5 79 77 80 83 46 73 14 89 21 34 27 68 24 14 10 | 37 65 28 7 89 1 56 68 25 84 1 34 77 27 65 61 57 27 65 70 11 | 29 7 51 26 99 90 96 46 99 54 16 10 97 71 70 52 4 74 20 76 12 | 34 77 80 86 5 40 57 57 19 79 65 99 11 43 27 73 14 81 12 41 13 | 86 1 95 50 47 78 23 61 34 51 81 46 60 24 93 45 86 11 9 50 14 | 96 75 41 80 84 68 19 4 12 93 9 66 21 3 8 45 72 74 4 88 15 | 36 46 18 48 76 31 24 58 55 95 82 42 25 22 35 3 10 27 70 58 16 | 55 61 14 12 68 91 25 94 71 66 26 33 56 76 9 68 39 51 98 29 17 | 41 93 65 57 36 23 73 50 21 12 38 70 86 38 99 46 19 36 10 66 18 | 97 79 26 34 30 55 69 31 5 80 77 95 11 82 60 60 71 58 87 19 19 | 74 23 5 4 38 14 24 25 61 20 96 57 2 94 38 8 61 39 35 64 20 | 55 71 7 99 62 44 19 34 37 28 65 40 77 25 43 6 72 48 90 77 21 | 61 46 75 20 61 22 5 80 22 86 43 19 98 72 14 70 94 46 61 25 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_tail20_5_3.data: -------------------------------------------------------------------------------- 1 | 20 5 2 | 77 39 14 11 83 3 | 94 31 21 2 13 4 | 9 46 15 36 84 5 | 57 18 10 30 46 6 | 29 93 85 89 20 7 | 79 58 46 10 33 8 | 55 85 42 88 74 9 | 73 58 18 22 42 10 | 65 97 36 31 33 11 | 86 10 2 9 71 12 | 25 79 44 43 32 13 | 39 93 89 91 48 14 | 76 2 6 26 42 15 | 24 87 3 3 99 16 | 38 17 1 75 7 17 | 5 18 43 99 54 18 | 91 10 81 63 8 19 | 29 50 57 83 73 20 | 22 8 76 70 30 21 | 27 26 59 84 75 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_tail50_10_6.data: -------------------------------------------------------------------------------- 1 | 50 10 2 | 65 55 87 38 38 22 34 99 81 50 3 | 4 99 72 19 90 63 88 59 51 99 4 | 10 12 33 37 23 63 4 6 80 94 5 | 87 40 50 75 59 38 98 45 55 1 6 | 31 7 77 8 15 53 83 6 52 73 7 | 52 8 83 63 72 73 76 27 64 58 8 | 35 14 89 91 63 37 89 31 2 1 9 | 89 68 90 38 48 68 22 95 59 8 10 | 28 4 26 92 94 38 23 91 88 41 11 | 45 63 93 25 12 10 70 94 11 97 12 | 24 27 8 19 63 74 69 21 68 67 13 | 68 61 86 42 46 27 30 72 16 1 14 | 94 65 39 89 60 84 11 65 75 58 15 | 71 7 13 80 72 65 89 41 94 73 16 | 70 14 59 11 33 40 79 9 43 62 17 | 2 16 99 84 50 97 29 56 23 9 18 | 83 3 98 33 25 82 52 33 5 88 19 | 85 31 76 42 14 98 68 98 53 6 20 | 97 56 52 51 20 50 14 11 76 34 21 | 65 67 43 18 50 23 99 51 60 5 22 | 64 74 79 56 32 66 4 7 51 59 23 | 38 59 64 83 87 56 3 94 96 16 24 | 54 81 4 49 42 30 4 43 50 13 25 | 26 43 19 14 70 27 33 47 38 80 26 | 40 57 45 1 92 36 98 77 28 54 27 | 75 11 80 23 10 19 44 89 8 96 28 | 59 32 15 72 75 28 34 53 70 48 29 | 38 21 43 24 57 66 13 34 51 72 30 | 40 73 37 63 30 70 78 79 77 96 31 | 89 75 49 15 45 79 15 85 83 91 32 | 64 46 36 33 91 21 25 4 71 49 33 | 84 34 33 93 20 26 35 12 41 92 34 | 47 50 83 5 32 81 16 99 60 3 35 | 62 47 28 78 9 61 37 80 25 45 36 | 74 22 46 33 72 19 69 42 38 28 37 | 38 81 71 91 11 91 82 89 97 37 38 | 79 42 59 56 5 43 13 85 13 51 39 | 57 4 15 99 17 34 51 46 5 96 40 | 8 49 50 29 66 85 48 4 58 88 41 | 46 24 53 15 17 73 53 58 22 83 42 | 27 54 51 54 92 82 13 17 17 24 43 | 28 29 56 46 10 15 46 98 51 58 44 | 62 87 76 2 93 65 39 71 52 21 45 | 34 38 48 90 36 42 1 81 15 25 46 | 18 19 11 96 40 48 72 26 1 12 47 | 63 65 35 93 74 28 28 80 99 85 48 | 74 23 88 3 99 25 20 70 62 58 49 | 26 77 59 53 86 84 90 49 72 48 50 | 28 71 51 97 29 37 84 24 45 37 51 | 78 90 13 51 70 88 38 41 90 3 52 | -------------------------------------------------------------------------------- /examples/cp/visu/data/flowshop_tail50_5_9.data: -------------------------------------------------------------------------------- 1 | 50 5 2 | 34 24 20 65 47 3 | 40 85 61 39 62 4 | 22 19 69 68 11 5 | 6 94 28 40 6 6 | 50 59 69 82 21 7 | 64 65 35 31 60 8 | 48 42 17 29 82 9 | 74 8 59 17 2 10 | 67 10 16 69 31 11 | 22 15 54 44 27 12 | 26 96 6 19 81 13 | 13 63 18 29 34 14 | 24 30 2 60 7 15 | 54 20 4 27 6 16 | 22 31 80 93 53 17 | 9 94 45 35 19 18 | 28 35 2 17 28 19 | 48 84 18 1 63 20 | 83 83 83 99 29 21 | 85 53 21 96 34 22 | 79 57 41 1 96 23 | 78 25 51 62 39 24 | 40 71 85 84 19 25 | 15 22 56 42 45 26 | 95 31 88 60 64 27 | 75 35 40 42 72 28 | 73 40 20 66 26 29 | 41 76 16 1 59 30 | 52 14 22 1 51 31 | 71 48 98 31 74 32 | 84 42 56 41 3 33 | 73 11 69 62 11 34 | 25 92 90 83 96 35 | 41 68 9 74 50 36 | 74 55 81 38 23 37 | 15 88 65 56 43 38 | 58 52 38 57 36 39 | 55 36 75 54 52 40 | 47 62 60 45 9 41 | 12 42 81 39 44 42 | 36 51 59 85 32 43 | 48 68 94 40 2 44 | 96 10 3 21 78 45 | 47 38 19 84 83 46 | 64 29 15 17 69 47 | 5 56 29 24 47 48 | 24 23 94 65 17 49 | 78 71 48 98 35 50 | 59 45 39 90 45 51 | 4 98 3 46 30 52 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshop_ft06.data: -------------------------------------------------------------------------------- 1 | 6 6 2 | 2 1 0 3 1 6 3 7 5 3 4 6 3 | 1 8 2 5 4 10 5 10 0 10 3 4 4 | 2 5 3 4 5 8 0 9 1 1 4 7 5 | 1 5 0 5 2 5 3 3 4 8 5 9 6 | 2 9 1 3 4 5 5 4 0 3 3 1 7 | 1 3 3 3 5 9 0 10 4 4 2 1 8 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshop_ft10.data: -------------------------------------------------------------------------------- 1 | 10 10 2 | 0 29 1 78 2 9 3 36 4 49 5 11 6 62 7 56 8 44 9 21 3 | 0 43 2 90 4 75 9 11 3 69 1 28 6 46 5 46 7 72 8 30 4 | 1 91 0 85 3 39 2 74 8 90 5 10 7 12 6 89 9 45 4 33 5 | 1 81 2 95 0 71 4 99 6 9 8 52 7 85 3 98 9 22 5 43 6 | 2 14 0 6 1 22 5 61 3 26 4 69 8 21 7 49 9 72 6 53 7 | 2 84 1 2 5 52 3 95 8 48 9 72 0 47 6 65 4 6 7 25 8 | 1 46 0 37 3 61 2 13 6 32 5 21 9 32 8 89 7 30 4 55 9 | 2 31 0 86 1 46 5 74 4 32 6 88 8 19 9 48 7 36 3 79 10 | 0 76 1 69 3 76 5 51 2 85 9 11 6 40 7 89 4 26 8 74 11 | 1 85 0 13 2 61 6 7 8 64 9 76 5 47 3 52 4 90 7 45 12 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshop_ft20.data: -------------------------------------------------------------------------------- 1 | 20 5 2 | 0 29 1 9 2 49 3 62 4 44 3 | 0 43 1 75 3 69 2 46 4 72 4 | 1 91 0 39 2 90 4 12 3 45 5 | 1 81 0 71 4 9 2 85 3 22 6 | 2 14 1 22 0 26 3 21 4 72 7 | 2 84 1 52 4 48 0 47 3 6 8 | 1 46 0 61 2 32 3 32 4 30 9 | 2 31 1 46 0 32 3 19 4 36 10 | 0 76 3 76 2 85 1 40 4 26 11 | 1 85 2 61 0 64 3 47 4 90 12 | 1 78 3 36 0 11 4 56 2 21 13 | 2 90 0 11 1 28 3 46 4 30 14 | 0 85 2 74 1 10 3 89 4 33 15 | 2 95 0 99 1 52 3 98 4 43 16 | 0 6 1 61 4 69 2 49 3 53 17 | 1 2 0 95 3 72 4 65 2 25 18 | 0 37 2 13 1 21 3 89 4 55 19 | 0 86 1 74 4 88 2 48 3 79 20 | 1 69 2 51 0 11 3 89 4 74 21 | 0 13 1 7 2 76 3 52 4 45 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_16a.data: -------------------------------------------------------------------------------- 1 | 20 10 2 | 15 3 4 67 7 69 8 67 1 10 32 1 5 16 1 8 66 1 6 90 3 4 44 8 46 9 38 1 9 89 1 9 63 1 2 44 1 7 87 1 3 73 2 2 33 9 31 3 2 90 3 92 7 96 1 2 16 1 1 19 3 | 20 1 4 90 2 3 27 10 27 1 9 77 1 10 40 1 8 70 3 1 47 9 45 10 47 1 1 56 1 6 44 2 3 50 5 50 3 4 69 7 67 10 68 3 1 75 4 73 10 74 1 10 75 2 5 79 10 79 1 6 45 1 10 94 1 7 65 2 2 31 10 25 1 4 85 3 3 75 6 71 8 71 3 1 44 4 45 6 45 4 | 23 1 1 55 1 4 53 1 4 35 1 5 93 1 10 33 1 8 62 1 5 66 1 10 61 1 7 56 1 6 29 2 2 27 5 22 1 1 37 2 3 71 4 66 2 2 76 5 72 1 4 69 2 3 61 7 67 1 10 49 1 2 57 3 4 57 7 60 9 59 2 2 63 4 67 1 5 90 1 10 27 1 5 58 5 | 18 2 8 22 9 24 1 3 61 1 2 35 1 6 92 1 4 30 1 10 79 2 1 44 4 42 2 1 62 8 63 1 1 93 1 1 69 1 3 89 1 7 49 1 2 38 3 4 54 6 54 8 54 1 7 87 2 3 46 7 38 3 1 82 6 81 7 81 2 3 40 9 40 6 | 21 1 3 86 1 6 65 1 2 94 1 5 50 1 4 31 1 9 59 1 4 92 1 2 67 1 4 60 1 9 93 1 5 45 1 8 95 2 2 71 8 63 1 7 79 1 2 68 2 8 21 9 21 1 3 35 1 10 36 2 9 24 10 24 1 6 90 1 6 85 7 | 15 1 10 70 1 6 20 1 8 81 1 5 42 1 10 70 1 5 43 1 2 95 1 10 22 1 10 35 1 5 87 1 6 72 1 9 86 1 10 52 1 6 32 1 5 47 8 | 17 1 3 62 3 4 55 6 58 10 60 4 7 89 8 96 9 95 10 92 2 1 70 4 71 2 1 72 6 76 1 8 15 1 10 36 1 7 55 1 4 48 1 2 22 2 7 59 9 58 1 8 80 1 8 45 1 5 71 1 2 33 3 2 48 8 52 10 51 1 3 51 9 | 25 1 5 34 1 3 75 1 10 41 2 2 70 7 67 1 6 63 2 6 40 10 44 1 10 21 3 6 31 8 36 9 33 2 5 43 6 45 1 10 94 2 3 55 4 62 1 8 38 1 2 70 1 1 25 2 1 29 4 29 1 2 64 1 6 57 1 7 63 1 1 42 2 1 47 4 44 1 1 82 1 10 43 1 7 79 1 1 51 1 6 74 10 | 23 1 2 37 2 3 78 7 76 1 3 46 1 1 75 1 1 47 1 9 22 1 8 65 1 6 99 1 2 20 1 6 41 1 6 97 1 3 84 1 6 44 1 2 82 1 10 41 1 9 61 1 5 56 1 1 33 2 2 60 3 64 2 5 49 8 55 3 4 86 5 88 7 88 2 4 35 8 30 2 5 79 10 78 11 | 19 1 2 41 1 9 35 1 3 40 1 4 77 1 7 69 4 3 62 7 64 9 65 10 63 1 1 74 1 7 24 1 7 51 1 2 21 2 6 45 10 37 3 2 25 7 25 9 23 2 1 73 8 75 1 3 86 2 4 59 9 60 1 4 90 1 3 54 1 2 79 1 4 60 12 | 19 1 9 63 2 3 88 4 87 1 4 46 2 2 83 6 79 1 2 69 1 6 47 1 10 91 3 3 86 4 88 9 83 1 4 38 1 4 68 1 8 20 1 6 51 1 6 22 1 4 60 1 9 22 1 1 82 1 2 23 1 7 83 1 3 50 13 | 21 1 8 52 2 6 62 10 59 2 3 21 5 16 1 4 64 1 9 67 1 1 46 2 2 47 4 47 1 3 38 1 5 12 1 6 78 1 9 13 1 9 93 1 1 28 1 7 81 4 2 33 4 37 5 40 6 39 1 8 40 1 2 45 1 7 51 1 9 59 1 4 55 1 10 30 14 | 16 1 9 97 2 2 89 7 84 2 1 41 4 42 1 8 56 1 3 80 1 7 94 1 6 87 1 1 86 2 2 57 5 58 1 5 22 1 1 88 1 8 65 1 8 67 1 6 91 1 5 40 3 4 53 8 49 9 57 15 | 16 1 3 60 3 3 26 8 27 9 27 1 5 81 1 5 14 1 8 17 1 1 63 1 6 60 1 2 42 1 9 69 1 2 73 1 8 50 1 10 23 1 4 48 1 3 72 1 4 28 2 3 41 6 36 16 | 25 1 10 15 1 2 48 2 4 22 8 23 3 1 70 6 70 7 73 4 1 40 4 35 7 40 9 35 1 10 84 1 1 14 1 7 53 1 8 50 1 9 77 2 2 78 9 78 1 3 73 1 8 85 1 4 36 1 8 53 2 1 22 5 25 1 4 48 2 1 34 4 30 1 2 45 1 10 32 1 8 55 1 9 29 1 1 59 1 6 15 1 8 89 17 | 17 1 6 55 1 1 69 3 1 64 3 63 5 63 1 4 39 1 8 29 1 4 38 1 10 67 1 8 58 1 3 43 1 5 38 2 4 67 8 63 1 6 83 1 8 26 2 6 34 7 32 1 3 82 1 10 72 2 2 68 7 68 18 | 21 1 5 74 1 1 65 1 8 39 1 8 25 2 2 82 3 78 1 3 29 2 1 58 6 55 1 2 81 1 1 43 1 8 67 1 6 56 1 9 48 2 1 56 6 59 2 2 54 8 54 1 9 41 1 7 77 1 2 88 1 1 22 1 8 38 2 3 61 6 61 1 8 83 19 | 17 2 4 16 8 15 3 5 43 8 39 10 39 1 6 16 1 3 78 2 1 47 7 47 2 6 78 8 77 1 9 23 1 3 92 3 3 73 4 75 8 75 1 4 44 1 6 84 2 5 76 6 73 1 8 90 2 1 39 6 39 1 2 47 1 3 94 1 8 90 20 | 23 1 7 62 1 4 85 1 7 75 1 9 22 1 1 21 1 8 22 2 6 48 7 42 1 2 67 1 2 22 2 8 71 10 71 3 4 27 6 23 10 23 2 2 27 9 24 2 2 47 6 45 1 4 25 1 1 67 1 2 23 1 2 85 1 6 45 2 2 82 7 81 1 5 34 1 3 44 1 1 16 2 1 27 10 27 21 | 16 2 3 51 4 48 1 1 19 1 6 92 1 2 27 2 3 34 7 32 1 1 92 1 8 68 1 1 47 2 4 48 6 44 1 6 54 1 9 89 1 7 76 1 8 72 2 3 55 7 57 1 1 67 1 9 82 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_default.data: -------------------------------------------------------------------------------- 1 | 20 10 2 | 10 2 6 3 6 19 2 3 19 4 20 2 1 18 4 20 1 10 8 1 10 19 1 1 6 2 5 12 4 7 1 6 12 2 6 19 3 10 1 5 4 3 | 14 1 2 12 1 5 7 1 1 6 2 4 16 6 5 1 10 16 1 9 11 2 3 16 3 16 2 9 11 7 7 1 10 17 2 6 18 7 7 2 8 7 2 6 1 9 11 1 3 12 2 10 11 5 6 4 | 14 1 7 8 1 3 6 1 2 14 1 7 11 1 10 9 1 7 18 1 8 11 1 1 19 1 3 9 1 7 6 1 6 6 2 3 14 4 13 2 3 17 5 9 1 4 9 5 | 14 1 10 1 1 4 20 1 2 10 2 9 3 1 14 2 7 19 4 5 2 7 17 5 17 2 10 5 3 11 1 9 5 1 6 15 2 3 20 4 18 1 4 20 1 8 10 1 2 8 1 1 19 6 | 13 2 5 5 4 19 1 1 3 1 7 2 1 3 9 1 10 3 1 1 4 1 2 7 2 10 19 7 3 2 10 3 9 12 1 3 2 1 5 4 1 1 5 1 3 5 7 | 14 2 3 14 4 3 1 6 9 1 7 19 2 4 17 9 4 1 4 3 1 6 7 2 9 1 1 8 1 6 4 1 9 3 1 5 17 1 10 17 2 8 15 4 4 1 2 7 1 7 1 8 | 10 2 8 5 3 19 2 4 12 7 3 1 7 17 2 1 13 9 18 1 5 19 1 8 2 1 1 1 1 8 1 1 2 20 1 6 18 9 | 11 1 6 9 1 2 15 1 4 18 2 2 7 6 2 1 9 20 2 1 3 3 19 1 9 6 1 6 9 1 9 14 1 5 15 2 6 1 9 8 10 | 11 1 5 17 2 3 2 3 8 2 3 2 5 11 1 5 8 1 2 16 1 10 1 2 4 7 8 6 1 8 14 2 4 1 9 7 1 8 2 1 10 14 11 | 11 1 8 6 1 5 2 1 6 3 1 9 12 1 5 8 1 10 19 1 10 3 1 8 1 1 7 2 1 6 15 1 3 10 12 | 10 1 5 14 1 3 16 1 3 20 1 7 19 1 8 9 2 7 11 3 11 1 5 12 1 1 11 1 1 4 1 2 4 13 | 12 1 6 1 1 7 19 1 5 1 1 3 18 1 5 15 1 7 5 1 3 16 1 4 19 2 6 14 8 5 1 10 4 1 4 19 1 10 5 14 | 10 2 8 5 8 13 1 9 7 2 5 16 8 4 1 1 14 2 8 8 7 12 1 6 7 1 1 18 2 10 14 5 16 1 9 6 1 6 17 15 | 14 1 6 13 1 1 20 2 10 3 10 13 1 8 9 2 5 16 6 17 2 6 10 4 9 1 3 14 2 10 3 7 16 2 9 1 4 3 1 3 5 1 6 17 1 5 4 1 1 10 1 2 3 16 | 13 2 5 18 10 5 1 1 7 1 4 6 1 8 4 2 5 8 3 12 2 8 9 3 16 2 5 18 10 6 2 1 9 5 3 2 5 14 6 6 1 1 3 1 1 19 1 5 6 2 5 10 9 15 17 | 11 2 9 9 6 3 1 7 1 2 1 15 1 2 2 8 8 2 5 1 10 2 1 8 18 2 7 16 3 1 2 1 12 3 6 1 3 3 1 5 9 1 9 10 18 | 13 1 2 16 1 2 9 1 2 9 1 8 18 2 8 4 3 1 2 10 14 9 5 1 8 9 2 1 16 4 2 1 9 18 1 9 3 1 9 9 2 6 4 2 11 2 5 20 10 4 19 | 14 1 10 17 1 7 5 1 7 20 1 3 3 1 10 13 1 2 12 1 5 10 2 5 6 7 16 1 2 2 1 5 1 1 10 20 1 8 18 1 7 4 1 5 9 20 | 12 2 6 6 6 20 2 10 4 1 2 1 6 18 2 3 10 6 10 2 8 9 6 16 1 1 13 2 9 4 8 19 2 3 16 4 20 1 3 3 1 9 5 2 8 13 7 20 1 3 5 21 | 11 1 4 10 2 4 2 7 2 1 5 13 2 7 20 3 12 2 7 6 1 15 2 5 5 4 4 2 10 2 8 5 2 1 14 7 13 2 4 7 9 19 2 8 3 4 6 1 9 12 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_la27r.data: -------------------------------------------------------------------------------- 1 | 20 10 2 | 10 1 4 60 1 5 48 2 6 95 3 95 2 1 87 6 87 1 2 72 2 10 5 8 5 2 9 35 8 35 3 8 39 10 39 7 39 3 7 54 4 54 10 54 2 3 66 1 66 3 | 10 3 8 37 3 37 10 37 2 7 34 5 34 2 1 97 2 97 2 6 55 9 55 2 3 21 1 21 1 4 20 2 5 59 9 59 1 10 46 1 9 19 3 2 46 9 46 1 46 4 | 10 2 5 45 9 45 3 3 73 4 73 10 73 1 2 24 3 9 28 4 28 10 28 1 1 28 2 4 25 6 25 1 6 23 1 8 83 3 10 5 3 5 2 5 1 7 78 5 | 10 2 1 53 10 53 3 3 12 2 12 10 12 1 10 12 3 2 37 10 37 1 37 3 9 33 2 33 3 33 2 4 71 3 71 1 7 55 3 6 29 2 29 4 29 3 8 87 5 87 3 87 1 5 38 6 | 10 1 5 90 2 3 49 1 49 2 10 27 1 27 2 8 65 10 65 2 6 7 1 7 2 7 23 4 23 2 1 48 9 48 1 4 83 2 9 17 2 17 2 2 40 5 40 7 | 10 3 4 85 8 85 6 85 2 5 25 2 25 3 3 84 9 84 6 84 3 7 64 5 64 8 64 2 10 13 7 13 1 2 66 1 8 46 1 9 59 2 1 62 5 62 1 6 19 8 | 10 2 6 88 5 88 2 7 67 10 67 1 5 14 2 1 41 3 41 3 2 73 8 73 6 73 2 8 57 2 57 2 3 53 7 53 1 4 80 2 10 47 9 47 3 9 74 2 74 3 74 9 | 10 1 2 78 1 6 64 1 5 63 3 7 46 3 46 8 46 1 4 84 2 1 84 7 84 2 9 28 7 28 3 10 52 1 52 3 52 2 8 26 6 26 2 3 41 5 41 10 | 10 1 2 11 1 1 64 1 7 97 3 10 38 2 38 5 38 3 3 17 10 17 8 17 3 5 85 2 85 9 85 1 6 73 3 4 10 9 10 10 10 1 9 95 2 8 67 1 67 11 | 10 3 4 93 1 93 9 93 2 3 95 9 95 3 8 43 3 43 2 43 1 2 65 1 9 32 3 1 59 8 59 5 59 1 7 85 3 6 46 1 46 10 46 1 10 85 2 5 60 4 60 12 | 10 3 3 61 6 61 5 61 1 4 41 1 6 49 3 5 23 4 23 7 23 3 1 66 4 66 7 66 3 8 49 1 49 2 49 1 9 70 2 10 99 2 99 1 2 90 1 7 17 13 | 10 2 5 13 8 13 2 8 7 5 7 2 2 98 5 98 3 9 57 2 57 3 57 3 1 73 6 73 10 73 3 4 73 9 73 2 73 3 3 68 5 68 8 68 2 6 40 8 40 3 10 98 1 98 9 98 2 7 9 6 9 14 | 10 1 10 86 3 7 76 6 76 4 76 2 5 14 6 14 1 4 41 3 2 85 8 85 9 85 2 1 37 9 37 2 9 19 4 19 1 3 17 1 8 54 2 6 79 3 79 15 | 10 1 2 40 1 3 53 1 8 97 3 6 87 3 87 5 87 3 9 96 1 96 5 96 2 5 84 9 84 2 4 16 7 16 1 7 66 2 10 52 2 52 2 1 95 7 95 16 | 10 2 7 33 2 33 3 2 33 4 33 5 33 3 4 87 5 87 8 87 3 1 18 8 18 10 18 1 3 55 3 9 13 5 13 10 13 2 5 77 8 77 3 8 60 1 60 10 60 3 10 42 3 42 8 42 2 6 74 1 74 17 | 10 3 8 92 2 92 5 92 2 6 91 8 91 3 9 79 1 79 6 79 1 3 54 1 5 69 2 7 79 4 79 3 4 33 9 33 1 33 1 2 61 2 10 39 9 39 3 1 16 9 16 4 16 18 | 10 3 7 82 9 82 3 82 3 2 41 3 41 1 41 3 5 28 10 28 3 28 1 6 64 2 3 78 2 78 2 4 76 7 76 1 8 6 1 9 49 3 10 47 9 47 7 47 3 1 58 9 58 5 58 19 | 10 3 1 52 9 52 8 52 2 6 42 3 42 1 9 24 1 10 91 3 4 47 7 47 6 47 1 7 88 3 5 91 8 91 1 91 2 8 52 10 52 3 3 28 8 28 9 28 1 2 35 20 | 10 1 6 82 1 3 76 3 4 86 5 86 8 86 2 7 93 10 93 2 5 84 4 84 2 8 38 1 38 2 9 95 6 95 1 10 37 2 2 21 5 21 1 1 23 21 | 10 2 10 77 2 77 1 5 8 2 7 42 6 42 1 8 64 1 1 70 1 3 45 2 9 45 4 45 2 6 28 7 28 2 4 67 1 67 1 2 86 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_mk08.data: -------------------------------------------------------------------------------- 1 | 20 10 2 | 10 2 7 18 4 5 2 5 7 7 7 1 3 19 1 7 14 2 4 5 10 12 1 1 10 1 10 18 2 7 10 8 19 2 3 11 8 9 2 3 5 8 12 3 | 12 1 2 5 2 7 18 4 5 2 3 5 8 12 1 1 10 1 10 19 2 3 15 4 19 1 7 14 1 5 9 2 5 14 9 5 1 1 19 2 7 10 8 19 1 1 16 4 | 14 2 5 14 9 5 1 1 19 1 1 10 1 3 19 2 7 18 4 5 2 4 5 10 12 2 3 5 8 12 1 10 10 1 5 9 1 1 7 2 7 10 8 19 1 1 10 1 10 19 1 10 18 5 | 10 1 10 10 2 5 7 7 7 1 7 14 1 1 10 1 10 18 2 3 15 7 13 2 10 14 5 7 2 3 11 8 9 1 9 11 1 5 9 6 | 12 1 5 9 2 5 14 9 5 2 7 18 4 5 2 3 11 8 9 1 1 10 1 9 11 1 1 7 1 7 14 2 4 5 10 12 2 3 15 4 19 1 8 18 1 10 19 7 | 10 2 3 15 7 13 1 3 19 1 5 9 1 10 19 2 3 5 8 12 2 7 18 4 5 2 8 14 10 9 2 4 5 10 12 1 10 18 1 1 7 8 | 12 1 1 10 1 10 18 1 1 7 1 5 9 2 8 14 10 9 2 7 10 8 19 2 3 15 4 19 2 10 14 5 7 1 8 18 1 10 19 1 1 19 1 1 10 9 | 11 1 1 10 1 7 14 1 1 10 2 3 15 4 19 2 5 14 9 5 2 7 18 4 5 1 3 19 1 1 19 2 4 5 10 12 1 5 9 1 10 19 10 | 14 2 7 10 8 19 2 8 14 10 9 1 1 19 1 10 19 2 10 14 5 7 1 2 5 2 4 5 10 12 2 5 7 7 7 1 1 16 1 1 7 1 9 11 1 3 19 1 1 10 1 10 18 11 | 11 1 10 19 2 10 14 5 7 1 8 18 2 3 11 8 9 1 1 7 1 1 10 2 5 14 9 5 2 3 15 4 19 1 10 18 1 3 19 1 1 19 12 | 11 2 5 14 9 5 1 1 10 1 8 18 2 3 15 4 19 2 7 10 8 19 2 3 5 8 12 2 3 11 8 9 2 8 14 10 9 1 10 10 1 9 11 1 3 19 13 | 10 1 10 19 2 3 11 8 9 2 5 7 7 7 1 1 16 1 7 14 2 7 18 4 5 2 4 5 10 12 1 1 10 1 8 18 2 5 14 9 5 14 | 11 2 10 14 5 7 1 10 19 2 7 10 8 19 2 3 15 4 19 1 1 19 1 8 18 2 8 14 10 9 2 3 11 8 9 1 10 18 2 5 14 9 5 1 2 5 15 | 11 1 1 10 2 5 7 7 7 1 1 10 1 9 11 1 7 14 2 3 15 7 13 2 8 14 10 9 1 1 16 2 3 5 8 12 2 5 14 9 5 1 2 5 16 | 11 2 5 14 9 5 2 5 7 7 7 1 7 14 1 10 10 2 7 10 8 19 2 3 15 4 19 2 7 18 4 5 1 1 7 2 3 11 8 9 1 1 19 1 8 18 17 | 11 1 2 5 2 7 10 8 19 1 10 10 1 9 11 1 8 18 2 10 14 5 7 2 5 14 9 5 1 1 10 1 1 19 2 3 15 7 13 2 8 14 10 9 18 | 13 1 10 10 2 5 14 9 5 1 5 9 1 10 19 1 1 10 2 3 5 8 12 1 2 5 2 10 14 5 7 1 1 10 2 8 14 10 9 2 3 15 7 13 1 1 16 1 7 14 19 | 11 2 3 15 7 13 1 2 5 1 10 19 1 3 19 1 8 18 1 1 7 1 5 9 1 7 14 2 7 18 4 5 1 1 10 2 5 14 9 5 20 | 10 2 7 10 8 19 1 2 5 2 3 11 8 9 1 9 11 2 4 5 10 12 1 10 18 2 7 18 4 5 2 8 14 10 9 2 3 5 8 12 1 10 19 21 | 10 1 10 18 1 10 10 1 7 14 1 9 11 2 3 15 7 13 1 2 5 2 8 14 10 9 2 3 5 8 12 1 5 9 1 1 16 -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_seti5xx.data: -------------------------------------------------------------------------------- 1 | 15 17 2 | 15 1 10 65 1 11 28 1 5 74 1 13 33 1 3 51 3 15 75 16 75 17 75 1 6 73 1 9 32 1 7 13 1 4 81 1 2 35 1 8 59 1 14 38 1 12 55 1 1 27 3 | 15 1 1 64 1 2 53 1 12 83 1 3 33 1 5 6 1 10 52 3 15 72 16 72 17 72 1 9 7 1 14 90 1 13 21 1 7 23 1 4 10 1 11 39 1 6 49 1 8 72 4 | 15 3 15 73 16 73 17 73 1 4 82 1 2 23 1 13 62 1 7 88 1 6 21 1 9 65 1 12 70 1 8 53 1 11 81 1 3 93 1 14 77 1 1 61 1 10 28 1 5 78 5 | 15 1 2 12 1 7 51 1 8 33 1 5 15 3 15 72 16 72 17 72 1 11 98 1 10 94 1 6 12 1 12 42 1 3 24 1 14 15 1 9 28 1 4 6 1 13 99 1 1 41 6 | 15 1 13 97 1 6 7 1 10 96 1 5 15 3 15 73 16 73 17 73 1 14 43 1 1 32 1 9 22 1 12 42 1 2 94 1 3 23 1 8 86 1 7 78 1 11 24 1 4 31 7 | 15 1 2 72 1 6 88 1 3 93 1 14 13 1 5 44 3 15 66 16 66 17 66 1 7 63 1 8 14 1 10 67 1 11 17 1 12 85 1 1 35 1 4 68 1 13 5 1 9 49 8 | 15 1 10 15 1 8 82 1 7 21 3 15 53 16 53 17 53 1 4 72 1 14 49 1 3 99 1 5 26 1 13 56 1 9 45 1 2 68 1 11 51 1 1 8 1 6 27 1 12 96 9 | 15 1 4 54 1 8 24 1 5 14 1 9 38 1 6 36 1 3 52 3 15 55 16 55 17 55 1 13 37 1 12 48 1 1 93 1 14 60 1 11 70 1 2 23 1 7 23 1 10 83 10 | 15 1 4 12 1 9 69 1 7 26 1 10 23 3 15 28 16 28 17 28 1 2 82 1 6 33 1 5 45 1 14 64 1 8 15 1 12 9 1 13 73 1 11 59 1 3 37 1 1 62 11 | 15 1 1 87 1 6 12 1 8 80 1 5 50 1 11 48 1 13 90 1 2 72 1 14 24 1 7 14 1 9 71 1 12 44 1 10 46 1 3 15 3 15 61 16 61 17 61 1 4 92 12 | 15 1 3 54 1 1 22 1 7 61 1 5 46 1 4 73 1 6 16 1 13 6 1 10 94 3 15 93 16 93 17 93 1 14 67 1 9 54 1 8 75 1 12 32 1 11 40 1 2 97 13 | 15 1 11 92 3 15 36 16 36 17 36 1 5 22 1 10 9 1 4 47 1 2 77 1 13 79 1 14 36 1 7 30 1 9 98 1 12 79 1 8 7 1 6 55 1 3 6 1 1 30 14 | 15 1 1 49 1 14 83 1 4 73 1 7 82 1 2 82 3 15 92 16 92 17 92 1 12 73 1 5 31 1 11 35 1 10 54 1 6 7 1 9 37 1 8 72 1 3 52 1 13 76 15 | 15 1 11 98 1 13 34 1 14 52 1 5 26 1 2 28 1 4 39 1 9 80 1 6 29 1 10 70 1 1 43 1 7 48 1 8 58 1 3 45 3 15 94 16 94 17 94 1 12 96 16 | 15 1 2 70 1 11 17 1 7 90 1 13 67 1 5 14 1 9 23 1 4 21 1 8 18 1 14 43 1 12 84 1 6 26 1 10 36 1 3 93 3 15 84 16 84 17 84 1 1 42 17 | -------------------------------------------------------------------------------- /examples/cp/visu/data/jobshopflex_tiny.data: -------------------------------------------------------------------------------- 1 | 2 3 2 | 2 1 1 10 1 2 20 3 | 2 2 1 10 1 20 1 3 30 4 | 5 | -------------------------------------------------------------------------------- /examples/cp/visu/data/learningeffect_default.data: -------------------------------------------------------------------------------- 1 | 6 6 2 | 5 400 1 300 4 300 3 200 0 100 2 200 3 | 1 300 0 800 5 700 2 200 4 900 3 300 4 | 3 100 4 900 1 900 0 700 5 500 2 500 5 | 3 800 4 200 1 100 5 700 2 800 0 900 6 | 1 600 3 200 4 500 5 500 0 300 2 100 7 | 4 1000 2 400 0 400 3 300 1 200 5 300 8 | 88 79 85 65 77 77 9 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_default.data: -------------------------------------------------------------------------------- 1 | 8 8 2 | 254 222 113 7 131 48 106 46 3 | 8 236 189 21 211 22 83 63 4 | 93 22 2 36 32 276 263 49 5 | 12 31 35 272 168 19 115 253 6 | 4 16 2 177 118 250 51 1 7 | 1 13 28 6 157 2 107 85 8 | 36 255 5 253 232 2 31 32 9 | 120 248 23 44 8 239 91 22 10 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_gp10-05.data: -------------------------------------------------------------------------------- 1 | 10 10 2 | 4 155 1 3 262 162 3 6 5 399 3 | 141 130 1 1 47 126 184 355 14 1 4 | 294 32 104 298 1 1 39 5 1 225 5 | 5 324 3 126 43 1 177 2 26 293 6 | 63 94 300 62 4 9 218 2 247 1 7 | 7 1 452 1 251 24 261 1 1 1 8 | 1 1 127 1 5 165 3 1 695 1 9 | 1 151 1 473 177 65 1 56 6 69 10 | 64 111 10 11 1 446 1 346 1 9 11 | 420 1 1 24 209 1 113 226 4 1 12 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_gp10-08.data: -------------------------------------------------------------------------------- 1 | 10 10 2 | 1 15 114 389 3 1 1 441 18 17 3 | 252 1 4 512 107 1 1 120 1 1 4 | 1 218 406 8 38 6 2 28 17 276 5 | 335 8 277 3 1 366 2 1 6 1 6 | 1 26 1 1 523 1 47 1 329 70 7 | 79 1 1 1 3 83 605 71 53 103 8 | 1 1 190 7 12 6 1 1 337 444 9 | 1 494 5 12 1 2 338 1 65 81 10 | 52 195 1 63 1 356 2 323 1 6 11 | 277 41 1 4 311 178 1 13 173 1 12 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_j8-per10-2.data: -------------------------------------------------------------------------------- 1 | 8 8 2 | 39 204 10 384 75 56 26 120 3 | 187 202 222 11 17 143 122 44 4 | 52 86 208 244 126 30 167 62 5 | 110 325 67 178 43 167 97 8 6 | 7 66 132 18 258 155 286 43 7 | 303 44 10 44 167 3 103 260 8 | 108 5 143 16 35 253 155 207 9 | 194 44 167 54 184 130 21 156 10 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_tail20_20_7.data: -------------------------------------------------------------------------------- 1 | 20 20 2 | 63 8 50 54 58 51 93 61 50 44 29 13 15 34 22 93 27 36 76 85 3 | 34 27 20 25 37 6 57 23 14 14 83 63 24 30 4 44 62 81 37 27 4 | 93 88 21 6 84 18 96 57 3 26 40 28 70 85 36 26 5 62 68 37 5 | 57 90 93 75 14 23 4 64 52 42 85 37 39 83 40 62 64 88 95 34 6 | 28 52 26 3 37 40 95 49 9 44 7 85 98 68 5 60 79 71 28 19 7 | 22 57 91 71 41 70 59 97 83 88 38 38 32 23 78 85 88 99 80 54 8 | 56 61 95 68 59 89 49 91 40 61 63 41 12 90 71 98 91 40 28 29 9 | 98 45 61 83 50 82 42 16 77 47 13 78 84 29 3 38 85 75 76 36 10 | 77 71 31 73 12 18 99 91 78 55 17 87 5 46 21 97 91 93 94 90 11 | 39 60 38 77 84 39 85 66 99 88 92 17 76 25 86 53 79 43 78 50 12 | 92 79 3 88 27 22 8 19 11 51 5 2 67 79 84 25 43 18 74 11 13 | 23 50 41 54 24 19 84 19 37 5 25 7 31 57 1 19 67 20 48 46 14 | 87 57 12 9 49 56 88 71 77 91 97 24 68 73 29 53 34 77 58 38 15 | 48 97 91 60 89 76 50 11 19 99 91 64 67 10 36 87 97 62 62 72 16 | 24 68 62 69 9 57 90 31 42 57 18 55 88 2 75 26 30 99 4 15 17 | 9 69 97 99 81 99 72 48 22 60 10 7 82 74 33 2 93 81 8 43 18 | 40 22 79 8 49 81 17 81 62 62 16 91 18 10 63 28 76 55 57 97 19 | 12 75 1 62 53 39 26 24 15 97 77 33 96 88 68 44 24 78 36 22 20 | 26 25 98 84 3 65 38 75 94 40 54 53 64 31 78 49 54 27 88 58 21 | 44 96 7 76 49 90 65 70 74 2 16 39 85 87 81 20 56 55 1 24 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/openshop_tail20_20_9.data: -------------------------------------------------------------------------------- 1 | 20 20 2 | 92 22 87 56 73 81 88 16 58 23 12 21 25 33 84 73 43 56 44 7 3 | 9 15 97 74 56 86 19 97 84 36 95 14 34 60 8 79 35 7 77 84 4 | 11 62 38 49 95 25 32 15 89 10 47 49 36 46 72 2 26 76 1 55 5 | 67 6 86 50 35 49 98 42 97 11 98 1 61 77 71 59 48 31 27 8 6 | 14 59 18 62 24 98 80 64 36 49 99 80 42 39 38 71 43 49 2 49 7 | 50 3 56 2 69 55 47 8 51 93 57 16 95 95 28 52 58 20 49 37 8 | 2 57 1 24 70 13 68 30 43 22 42 88 66 26 59 38 15 82 9 46 9 | 3 12 94 24 59 25 21 47 56 13 51 70 52 79 35 28 18 33 14 90 10 | 5 23 54 59 60 38 74 98 29 86 24 42 20 48 70 97 26 1 6 90 11 | 70 44 92 18 42 72 37 6 96 15 62 33 98 40 44 29 96 77 96 65 12 | 8 4 19 34 54 89 28 93 40 24 73 69 79 97 93 31 42 95 85 64 13 | 92 16 76 87 34 35 56 74 66 88 88 57 88 31 76 14 23 19 4 19 14 | 58 32 89 80 50 25 83 59 74 61 50 30 39 24 61 78 80 27 70 33 15 | 47 42 77 57 78 68 48 62 32 49 61 36 42 96 61 89 7 66 95 28 16 | 39 11 95 63 51 93 56 62 89 85 57 43 13 88 14 10 71 69 19 98 17 | 96 63 58 69 60 62 19 11 4 53 97 86 48 65 80 25 18 63 11 54 18 | 57 22 39 62 76 30 95 76 8 91 92 17 86 45 97 6 67 18 18 17 19 | 48 10 22 91 92 45 19 56 55 99 85 18 91 62 4 65 91 82 46 26 20 | 65 49 81 75 93 43 73 63 7 50 94 48 83 15 91 54 89 8 93 59 21 | 20 84 75 70 73 21 99 6 37 78 5 52 19 3 55 99 73 79 77 73 22 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_default.data: -------------------------------------------------------------------------------- 1 | 35 4 2 | 5 5 5 5 3 | 0 0 0 0 0 3 2 3 4 4 | 5 1 0 0 0 3 5 6 7 5 | 9 1 0 0 0 2 11 12 6 | 3 1 2 0 0 3 8 9 10 7 | 5 0 4 2 0 1 11 8 | 6 2 1 2 0 1 11 9 | 1 3 2 2 0 1 16 10 | 4 0 0 0 3 1 13 11 | 8 0 1 1 0 1 13 12 | 1 3 2 0 0 1 13 13 | 4 1 2 0 0 4 14 15 16 17 14 | 2 0 4 2 4 4 14 15 16 17 15 | 2 0 1 1 0 1 19 16 | 5 3 3 0 0 1 18 17 | 6 0 2 0 1 1 18 18 | 3 0 0 0 1 2 18 19 19 | 3 0 0 0 3 2 18 19 20 | 8 1 0 0 2 2 21 22 21 | 6 0 2 0 1 2 20 24 22 | 8 0 3 1 3 1 22 23 | 7 0 0 2 0 1 25 24 | 1 0 1 1 2 1 25 25 | 2 0 2 1 2 1 26 26 | 4 3 0 0 0 1 26 27 | 5 0 3 0 2 2 27 28 28 | 3 3 0 1 2 2 29 32 29 | 6 0 0 0 0 1 31 30 | 5 1 0 2 0 1 30 31 | 2 2 0 3 1 1 30 32 | 2 0 0 0 1 1 35 33 | 9 0 0 3 2 3 32 33 34 34 | 2 0 0 0 2 1 35 35 | 6 0 0 1 3 1 34 36 | 4 0 0 2 2 1 35 37 | 0 0 0 0 0 0 38 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j120_1_2.data: -------------------------------------------------------------------------------- 1 | 122 4 2 | 13 13 13 12 3 | 0 0 0 0 0 3 2 3 4 4 | 1 0 0 3 0 3 5 6 29 5 | 5 0 0 1 0 1 25 6 | 3 4 0 0 0 2 7 62 7 | 1 9 0 0 0 1 8 8 | 4 0 0 0 10 3 11 28 30 9 | 7 0 0 0 8 3 9 14 19 10 | 4 0 0 0 5 3 10 12 15 11 | 9 0 0 7 0 3 16 75 83 12 | 1 0 0 10 0 3 13 18 22 13 | 3 0 0 0 8 3 54 100 101 14 | 2 0 0 10 0 2 37 69 15 | 9 0 0 0 3 3 20 21 31 16 | 5 0 0 7 0 3 23 32 38 17 | 2 6 0 0 0 1 26 18 | 5 0 0 0 2 2 17 27 19 | 1 0 0 0 4 3 24 47 60 20 | 2 0 4 0 0 1 31 21 | 2 0 0 0 7 3 42 55 82 22 | 3 0 0 0 6 1 43 23 | 8 2 0 0 0 1 96 24 | 7 0 0 9 0 3 57 86 114 25 | 8 4 0 0 0 2 35 96 26 | 6 0 6 0 0 2 40 80 27 | 4 0 10 0 0 1 31 28 | 6 0 0 0 10 3 45 70 112 29 | 5 0 0 10 0 2 36 73 30 | 10 0 0 10 0 1 110 31 | 7 5 0 0 0 1 74 32 | 8 0 1 0 0 2 34 85 33 | 8 8 0 0 0 2 52 53 34 | 5 0 0 3 0 3 33 39 49 35 | 4 0 0 0 9 1 41 36 | 7 0 5 0 0 3 59 63 94 37 | 2 0 0 7 0 1 44 38 | 6 0 0 0 7 2 76 91 39 | 7 0 0 0 6 1 50 40 | 10 8 0 0 0 2 51 115 41 | 6 0 0 9 0 2 90 93 42 | 8 0 0 4 0 1 64 43 | 7 0 0 7 0 2 66 104 44 | 8 0 7 0 0 2 46 81 45 | 6 0 0 0 4 3 48 56 57 46 | 9 0 6 0 0 3 79 97 119 47 | 7 5 0 0 0 1 87 48 | 9 0 0 0 2 1 120 49 | 1 0 8 0 0 1 51 50 | 10 0 0 0 6 1 54 51 | 8 4 0 0 0 1 111 52 | 5 0 8 0 0 1 105 53 | 7 0 0 0 2 1 107 54 | 4 0 0 5 0 1 58 55 | 1 9 0 0 0 1 78 56 | 9 0 0 0 4 2 60 61 57 | 4 0 0 0 8 3 67 68 72 58 | 4 0 0 0 7 1 103 59 | 2 0 0 0 9 1 91 60 | 4 10 0 0 0 1 102 61 | 1 0 0 0 3 1 79 62 | 6 0 0 0 5 1 74 63 | 4 0 0 8 0 2 65 71 64 | 2 0 0 0 2 1 82 65 | 4 0 3 0 0 2 104 118 66 | 1 0 0 0 3 1 89 67 | 5 6 0 0 0 1 106 68 | 6 0 2 0 0 1 111 69 | 5 0 0 4 0 1 87 70 | 6 0 10 0 0 2 85 108 71 | 10 0 4 0 0 1 84 72 | 9 0 0 1 0 1 81 73 | 4 0 10 0 0 3 77 92 98 74 | 1 0 6 0 0 1 84 75 | 7 0 0 5 0 1 86 76 | 2 0 0 6 0 2 95 121 77 | 8 0 8 0 0 1 111 78 | 10 0 2 0 0 1 87 79 | 3 0 5 0 0 1 81 80 | 4 0 7 0 0 2 107 113 81 | 8 0 0 5 0 1 107 82 | 10 3 0 0 0 1 93 83 | 5 0 0 0 5 1 99 84 | 2 0 3 0 0 1 90 85 | 8 7 0 0 0 1 106 86 | 6 0 0 7 0 1 88 87 | 7 0 0 0 2 1 95 88 | 5 0 0 0 9 2 102 117 89 | 4 5 0 0 0 1 88 90 | 10 0 9 0 0 1 108 91 | 8 6 0 0 0 2 105 108 92 | 8 0 0 3 0 1 101 93 | 2 0 0 8 0 1 109 94 | 1 0 0 0 7 1 113 95 | 2 0 0 0 10 1 115 96 | 3 0 0 0 6 1 104 97 | 6 0 0 9 0 1 103 98 | 7 0 4 0 0 1 109 99 | 3 0 0 9 0 1 120 100 | 5 0 0 0 6 1 102 101 | 8 0 0 0 2 1 116 102 | 2 0 0 5 0 1 103 103 | 5 1 0 0 0 1 112 104 | 4 0 10 0 0 1 119 105 | 2 1 0 0 0 1 117 106 | 2 0 0 8 0 1 105 107 | 4 5 0 0 0 1 114 108 | 8 0 9 0 0 2 115 119 109 | 7 0 9 0 0 1 110 110 | 8 0 0 8 0 1 114 111 | 7 0 4 0 0 1 113 112 | 7 0 0 0 1 1 112 113 | 6 0 0 4 0 1 121 114 | 10 0 0 1 0 1 118 115 | 2 0 0 0 4 1 116 116 | 2 0 0 0 2 1 116 117 | 6 0 0 0 7 1 117 118 | 9 8 0 0 0 1 121 119 | 10 0 1 0 0 1 118 120 | 3 1 0 0 0 1 120 121 | 3 0 0 0 2 1 122 122 | 5 0 0 0 2 1 122 123 | 8 0 0 0 4 1 122 124 | 0 0 0 0 0 0 125 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j120_22_6.data: -------------------------------------------------------------------------------- 1 | 122 4 2 | 13 16 12 17 3 | 0 0 0 0 0 3 2 3 4 4 | 10 0 0 1 0 3 10 14 28 5 | 10 3 0 0 0 3 6 7 17 6 | 6 0 0 0 9 2 5 68 7 | 6 1 0 0 0 2 13 29 8 | 7 0 0 8 0 3 8 16 42 9 | 5 0 7 0 0 3 18 19 38 10 | 3 7 0 0 0 3 9 49 51 11 | 7 0 2 0 0 3 12 26 41 12 | 1 0 0 1 0 3 11 15 86 13 | 5 0 0 1 0 3 36 44 54 14 | 8 0 0 0 9 3 22 23 53 15 | 2 0 4 0 0 3 31 40 71 16 | 5 0 9 0 0 1 27 17 | 10 0 0 0 9 2 20 33 18 | 4 0 1 0 0 3 25 58 60 19 | 1 10 0 0 0 3 47 79 102 20 | 3 0 8 0 0 2 21 26 21 | 8 8 0 0 0 1 92 22 | 6 0 6 0 0 1 24 23 | 5 0 0 10 0 3 30 39 81 24 | 5 0 0 0 10 3 66 99 118 25 | 9 10 0 0 0 1 43 26 | 1 2 0 0 0 3 30 31 57 27 | 2 8 0 0 0 1 80 28 | 6 0 10 0 0 3 34 46 52 29 | 10 2 0 0 0 2 32 60 30 | 1 0 0 0 5 2 37 87 31 | 2 8 0 0 0 1 106 32 | 10 2 0 0 0 1 110 33 | 6 0 0 0 4 1 59 34 | 5 0 0 0 10 2 35 86 35 | 6 0 0 0 10 3 56 74 97 36 | 5 0 0 3 0 2 37 88 37 | 1 9 0 0 0 2 65 104 38 | 10 0 8 0 0 2 50 55 39 | 3 0 0 1 0 1 75 40 | 10 0 0 0 5 3 50 64 101 41 | 7 0 0 0 9 2 66 68 42 | 7 0 0 0 8 2 63 70 43 | 10 0 0 7 0 2 45 83 44 | 5 4 0 0 0 1 72 45 | 10 0 0 0 8 2 57 65 46 | 4 0 0 0 9 3 49 103 121 47 | 4 0 0 3 0 3 60 76 79 48 | 2 8 0 0 0 2 48 113 49 | 5 0 3 0 0 2 89 109 50 | 8 0 10 0 0 1 98 51 | 4 0 0 0 2 2 62 69 52 | 3 0 0 5 0 3 83 94 97 53 | 4 0 0 1 0 2 105 120 54 | 1 3 0 0 0 1 65 55 | 9 0 10 0 0 3 54 105 112 56 | 1 4 0 0 0 2 88 109 57 | 9 2 0 0 0 3 57 61 66 58 | 10 0 10 0 0 3 81 82 105 59 | 6 0 0 9 0 1 90 60 | 6 0 0 0 2 1 89 61 | 4 0 3 0 0 1 78 62 | 8 0 4 0 0 1 94 63 | 8 0 6 0 0 2 84 112 64 | 6 0 0 0 2 2 67 91 65 | 9 1 0 0 0 1 77 66 | 5 9 0 0 0 2 94 117 67 | 10 0 6 0 0 1 95 68 | 10 0 0 0 5 1 80 69 | 2 0 9 0 0 3 76 87 96 70 | 7 0 1 0 0 1 77 71 | 3 0 0 0 6 2 71 80 72 | 2 0 0 0 7 3 73 86 100 73 | 3 0 0 0 10 3 79 90 100 74 | 8 0 0 2 0 3 78 85 92 75 | 9 9 0 0 0 3 81 88 118 76 | 4 1 0 0 0 3 82 107 119 77 | 4 0 0 3 0 3 84 90 106 78 | 4 0 0 0 9 1 101 79 | 4 0 0 0 10 2 85 93 80 | 2 0 0 6 0 3 87 96 111 81 | 4 0 8 0 0 1 93 82 | 9 0 0 5 0 2 83 108 83 | 8 0 2 0 0 1 102 84 | 2 0 1 0 0 1 84 85 | 6 0 0 0 7 1 100 86 | 2 0 4 0 0 1 85 87 | 9 0 1 0 0 1 109 88 | 4 0 6 0 0 3 99 108 117 89 | 5 0 0 2 0 1 115 90 | 9 0 3 0 0 1 116 91 | 3 0 0 5 0 1 104 92 | 6 0 0 0 10 1 91 93 | 5 0 0 0 10 1 112 94 | 9 4 0 0 0 2 93 117 95 | 4 7 0 0 0 2 96 98 96 | 2 0 1 0 0 2 99 103 97 | 2 8 0 0 0 2 101 107 98 | 2 0 0 6 0 1 115 99 | 5 0 0 0 3 1 106 100 | 6 0 0 4 0 1 108 101 | 6 0 7 0 0 1 104 102 | 9 0 2 0 0 1 119 103 | 7 0 0 7 0 1 111 104 | 7 0 5 0 0 1 103 105 | 3 0 0 1 0 1 116 106 | 3 0 0 0 10 1 114 107 | 10 0 3 0 0 2 107 119 108 | 4 8 0 0 0 1 113 109 | 4 9 0 0 0 1 118 110 | 2 0 6 0 0 2 110 116 111 | 3 0 0 0 1 1 110 112 | 3 0 0 0 2 1 111 113 | 4 5 0 0 0 1 114 114 | 2 0 0 0 7 1 113 115 | 2 10 0 0 0 1 114 116 | 10 0 1 0 0 1 115 117 | 4 0 0 1 0 1 120 118 | 8 1 0 0 0 1 120 119 | 2 0 0 0 3 1 121 120 | 10 0 0 0 1 1 121 121 | 1 0 0 0 10 1 122 122 | 2 2 0 0 0 1 122 123 | 6 0 2 0 0 1 122 124 | 0 0 0 0 0 0 125 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j120_2_9.data: -------------------------------------------------------------------------------- 1 | 122 4 2 | 15 15 16 15 3 | 0 0 0 0 0 3 2 3 4 4 | 10 0 3 0 0 3 5 13 93 5 | 4 0 3 0 0 1 112 6 | 5 0 0 0 9 3 37 51 55 7 | 2 0 7 0 0 3 6 8 57 8 | 10 0 0 0 1 3 7 9 16 9 | 5 0 7 0 0 1 15 10 | 7 0 10 0 0 3 12 20 22 11 | 10 0 1 0 0 3 10 11 17 12 | 2 0 5 0 0 3 21 24 84 13 | 7 0 0 6 0 1 101 14 | 2 0 7 0 0 3 18 71 72 15 | 1 0 7 0 0 3 14 27 30 16 | 7 1 0 0 0 1 19 17 | 8 0 0 9 0 1 39 18 | 7 0 0 0 10 1 59 19 | 2 0 0 0 8 2 34 50 20 | 4 0 9 0 0 3 25 26 28 21 | 1 1 0 0 0 1 81 22 | 9 0 0 0 2 3 32 44 91 23 | 10 0 0 0 9 2 61 63 24 | 9 3 0 0 0 3 23 36 59 25 | 6 4 0 0 0 1 102 26 | 6 0 0 0 5 1 29 27 | 10 0 0 0 3 3 35 60 89 28 | 3 0 0 0 3 3 31 83 116 29 | 10 0 0 4 0 1 47 30 | 1 10 0 0 0 2 39 41 31 | 4 0 0 4 0 1 51 32 | 10 8 0 0 0 1 69 33 | 9 0 3 0 0 1 43 34 | 6 0 0 2 0 3 33 40 107 35 | 4 0 0 9 0 1 101 36 | 7 4 0 0 0 1 54 37 | 7 10 0 0 0 3 38 45 90 38 | 5 6 0 0 0 3 46 48 69 39 | 5 8 0 0 0 3 49 76 94 40 | 10 0 0 0 1 1 55 41 | 7 0 0 4 0 1 42 42 | 8 0 0 0 7 1 82 43 | 10 0 0 0 3 1 100 44 | 5 0 0 0 10 1 67 45 | 8 0 8 0 0 1 88 46 | 7 1 0 0 0 1 100 47 | 4 0 0 8 0 3 66 73 103 48 | 5 0 0 6 0 3 52 62 114 49 | 1 2 0 0 0 2 58 77 50 | 7 0 0 7 0 1 91 51 | 1 8 0 0 0 3 54 56 80 52 | 10 0 1 0 0 1 67 53 | 10 6 0 0 0 1 64 54 | 5 0 0 0 7 2 53 74 55 | 4 4 0 0 0 2 65 108 56 | 2 0 0 0 9 1 70 57 | 5 5 0 0 0 2 115 117 58 | 8 4 0 0 0 1 75 59 | 7 0 0 0 8 2 61 81 60 | 9 0 0 0 4 1 115 61 | 3 0 0 0 5 2 79 111 62 | 8 0 0 9 0 1 86 63 | 1 0 0 7 0 1 87 64 | 10 0 0 5 0 1 83 65 | 2 3 0 0 0 1 65 66 | 7 3 0 0 0 1 104 67 | 9 6 0 0 0 1 101 68 | 10 0 3 0 0 1 78 69 | 2 2 0 0 0 3 68 82 97 70 | 2 0 0 0 3 2 92 102 71 | 4 3 0 0 0 1 115 72 | 5 9 0 0 0 1 109 73 | 1 0 10 0 0 1 99 74 | 2 5 0 0 0 2 78 119 75 | 6 0 5 0 0 2 88 96 76 | 1 4 0 0 0 1 97 77 | 9 0 9 0 0 2 78 96 78 | 2 2 0 0 0 1 77 79 | 7 0 9 0 0 1 98 80 | 4 0 0 10 0 1 84 81 | 5 0 0 0 7 1 109 82 | 3 6 0 0 0 1 85 83 | 7 0 1 0 0 1 96 84 | 8 9 0 0 0 2 86 105 85 | 8 0 0 10 0 1 89 86 | 5 0 5 0 0 1 100 87 | 1 3 0 0 0 2 86 110 88 | 9 0 0 4 0 1 113 89 | 3 0 0 0 3 1 110 90 | 2 0 0 9 0 1 91 91 | 9 0 10 0 0 1 106 92 | 9 0 6 0 0 1 92 93 | 7 9 0 0 0 1 114 94 | 5 0 0 4 0 2 108 110 95 | 6 0 0 0 1 1 102 96 | 6 0 10 0 0 1 95 97 | 1 0 0 0 3 1 113 98 | 10 2 0 0 0 1 120 99 | 8 0 1 0 0 1 106 100 | 5 0 0 0 4 1 118 101 | 2 9 0 0 0 1 111 102 | 4 0 0 10 0 1 112 103 | 2 0 0 0 10 1 118 104 | 2 0 0 1 0 1 107 105 | 6 0 0 9 0 1 113 106 | 7 0 0 0 4 1 105 107 | 9 6 0 0 0 1 106 108 | 8 0 9 0 0 1 117 109 | 2 0 5 0 0 1 120 110 | 7 0 4 0 0 1 111 111 | 5 0 10 0 0 1 116 112 | 9 0 0 0 6 1 117 113 | 5 0 0 0 7 1 116 114 | 7 0 0 0 3 1 121 115 | 1 1 0 0 0 1 114 116 | 2 0 6 0 0 1 121 117 | 4 0 6 0 0 1 118 118 | 5 0 0 0 9 1 121 119 | 1 0 0 0 1 1 119 120 | 2 0 8 0 0 1 120 121 | 6 0 0 6 0 1 122 122 | 5 0 0 10 0 1 122 123 | 7 10 0 0 0 1 122 124 | 0 0 0 0 0 0 125 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j120_32_8.data: -------------------------------------------------------------------------------- 1 | 122 4 2 | 24 21 24 25 3 | 0 0 0 0 0 3 2 3 4 4 | 8 0 3 0 0 3 6 13 14 5 | 4 2 5 0 0 3 5 24 96 6 | 2 7 6 0 7 3 7 8 48 7 | 2 4 0 9 6 3 10 40 45 8 | 7 8 9 7 8 3 11 15 30 9 | 6 0 0 3 10 3 9 34 64 10 | 5 3 3 6 0 3 29 30 32 11 | 4 10 10 5 10 3 19 52 54 12 | 5 5 10 9 4 3 12 16 44 13 | 3 0 4 7 9 3 20 21 22 14 | 4 8 1 0 0 1 119 15 | 8 0 0 8 10 1 92 16 | 10 0 6 7 0 3 17 25 36 17 | 5 3 3 0 6 3 58 69 92 18 | 7 0 6 6 8 3 18 27 55 19 | 3 0 1 5 4 3 22 23 71 20 | 4 8 0 0 1 1 82 21 | 6 0 6 6 9 2 38 44 22 | 5 4 1 5 0 2 35 77 23 | 9 0 6 1 0 3 33 59 68 24 | 5 3 0 10 7 2 39 51 25 | 7 9 4 0 9 3 26 72 74 26 | 5 8 0 3 6 2 73 102 27 | 5 5 7 0 1 2 87 90 28 | 7 8 0 10 0 3 28 53 79 29 | 1 5 1 1 6 1 41 30 | 3 0 3 8 6 3 29 54 98 31 | 3 2 0 5 0 2 59 92 32 | 10 5 9 5 8 3 31 37 101 33 | 9 8 6 2 0 3 42 57 60 34 | 8 10 4 10 6 3 43 50 81 35 | 6 6 10 9 8 3 83 94 115 36 | 8 0 0 9 9 3 58 100 121 37 | 5 0 3 3 3 3 46 56 67 38 | 1 10 1 2 5 1 39 39 | 7 6 7 0 4 1 49 40 | 10 3 0 8 1 1 84 41 | 9 9 0 0 0 3 75 78 98 42 | 7 0 1 2 4 1 47 43 | 1 0 5 0 0 1 54 44 | 9 1 0 3 0 2 52 74 45 | 1 6 5 4 9 1 80 46 | 6 0 8 8 7 1 56 47 | 9 0 3 3 0 2 69 88 48 | 6 9 0 5 2 2 94 105 49 | 8 4 7 8 6 2 69 82 50 | 10 9 1 3 9 1 120 51 | 3 2 8 1 9 1 63 52 | 4 0 6 6 0 3 63 68 70 53 | 5 0 0 3 7 3 65 73 87 54 | 10 6 6 10 8 3 95 113 117 55 | 9 2 0 4 1 1 68 56 | 2 3 7 0 1 2 86 118 57 | 5 2 6 7 5 1 61 58 | 8 6 7 7 0 1 80 59 | 1 7 10 0 2 2 66 76 60 | 5 4 6 8 0 3 65 91 102 61 | 9 6 7 7 3 1 110 62 | 2 0 0 9 3 3 62 76 108 63 | 2 2 3 8 0 1 78 64 | 10 3 6 0 8 2 77 81 65 | 4 1 0 6 10 3 76 85 91 66 | 10 9 6 0 7 1 93 67 | 6 6 6 5 9 1 117 68 | 5 2 10 0 4 1 116 69 | 5 6 6 0 7 3 70 74 80 70 | 5 0 5 10 8 1 93 71 | 10 2 0 10 0 2 75 87 72 | 4 2 1 7 0 1 94 73 | 8 2 10 10 10 1 91 74 | 7 0 2 6 1 2 83 109 75 | 2 0 8 0 0 2 75 77 76 | 4 9 0 3 10 2 90 93 77 | 2 7 8 7 3 2 79 97 78 | 2 7 5 3 3 1 106 79 | 5 4 10 3 0 1 114 80 | 5 4 2 0 9 1 82 81 | 8 0 0 3 0 1 108 82 | 2 3 8 0 0 1 103 83 | 8 2 2 3 5 2 107 112 84 | 3 6 10 0 6 3 90 97 99 85 | 4 3 8 0 8 1 114 86 | 4 6 5 5 7 2 102 121 87 | 2 0 1 7 6 2 107 112 88 | 6 3 4 3 1 1 103 89 | 1 9 6 9 2 1 99 90 | 6 8 3 8 3 2 89 100 91 | 5 2 10 10 4 2 95 101 92 | 9 9 8 3 10 1 103 93 | 3 7 8 1 0 2 109 114 94 | 8 0 4 8 7 1 95 95 | 3 7 4 0 0 1 104 96 | 1 6 7 2 5 1 97 97 | 5 0 0 3 1 2 111 121 98 | 1 0 1 10 3 2 98 105 99 | 8 8 6 6 0 2 101 104 100 | 4 5 2 0 5 1 108 101 | 2 9 10 9 0 2 100 118 102 | 4 3 9 0 1 2 111 115 103 | 1 8 2 5 7 1 116 104 | 5 9 3 0 5 2 105 109 105 | 4 3 0 0 7 2 106 111 106 | 1 1 6 8 0 1 110 107 | 4 5 0 0 2 1 106 108 | 2 0 1 2 5 1 107 109 | 4 0 8 8 2 1 115 110 | 2 1 4 9 3 1 112 111 | 4 0 1 7 1 1 110 112 | 2 6 3 0 10 1 113 113 | 4 5 0 3 3 1 116 114 | 9 9 6 4 0 1 113 115 | 8 1 9 1 5 1 118 116 | 9 0 8 7 0 1 120 117 | 1 0 0 0 8 1 117 118 | 7 6 4 3 3 1 120 119 | 8 8 3 1 6 1 119 120 | 2 4 5 3 0 1 119 121 | 6 0 10 10 10 1 122 122 | 2 5 4 1 6 1 122 123 | 3 9 4 1 2 1 122 124 | 0 0 0 0 0 0 125 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j120_41_5.data: -------------------------------------------------------------------------------- 1 | 122 4 2 | 12 12 11 12 3 | 0 0 0 0 0 3 2 3 4 4 | 8 0 10 0 0 3 40 48 61 5 | 5 7 0 0 0 3 19 34 46 6 | 3 2 0 0 0 3 5 10 11 7 | 10 0 0 8 0 3 6 13 32 8 | 9 0 10 0 0 3 7 8 20 9 | 10 0 0 3 0 3 29 33 70 10 | 10 1 0 0 0 3 9 12 16 11 | 5 0 0 0 9 3 14 18 39 12 | 2 0 0 6 0 2 22 63 13 | 10 4 0 0 0 3 48 58 117 14 | 2 0 0 6 0 3 24 28 30 15 | 4 6 0 0 0 2 51 61 16 | 6 6 0 0 0 3 15 61 110 17 | 7 6 0 0 0 2 49 107 18 | 1 0 0 2 0 3 17 41 89 19 | 10 0 0 0 5 3 40 64 80 20 | 9 0 3 0 0 3 21 23 65 21 | 10 0 0 0 10 3 45 58 89 22 | 5 7 0 0 0 3 29 37 43 23 | 1 0 4 0 0 3 26 35 50 24 | 1 0 0 0 8 2 72 95 25 | 9 1 0 0 0 3 57 63 73 26 | 10 0 6 0 0 3 25 27 43 27 | 4 10 0 0 0 3 67 75 91 28 | 10 0 0 8 0 2 36 71 29 | 6 0 0 4 0 1 35 30 | 1 3 0 0 0 3 35 66 105 31 | 8 0 0 0 6 1 108 32 | 5 0 0 6 0 3 31 33 80 33 | 3 0 0 0 2 3 44 52 97 34 | 6 10 0 0 0 3 47 67 82 35 | 2 0 0 0 8 3 68 78 103 36 | 7 0 0 0 3 3 87 94 99 37 | 9 0 0 3 0 3 47 56 90 38 | 5 5 0 0 0 1 112 39 | 10 0 0 5 0 3 38 51 102 40 | 3 7 0 0 0 1 119 41 | 2 0 0 6 0 3 41 62 81 42 | 9 0 9 0 0 2 42 75 43 | 6 0 1 0 0 2 57 66 44 | 3 0 0 0 10 3 49 83 92 45 | 3 0 3 0 0 1 81 46 | 7 8 0 0 0 3 49 74 92 47 | 1 0 0 0 5 1 77 48 | 1 0 1 0 0 3 56 69 83 49 | 7 10 0 0 0 1 104 50 | 5 0 3 0 0 3 53 56 59 51 | 8 0 1 0 0 2 53 108 52 | 7 0 0 7 0 3 53 54 60 53 | 1 0 0 0 2 3 52 55 71 54 | 2 5 0 0 0 3 59 63 75 55 | 1 0 0 0 3 1 102 56 | 4 0 0 0 7 3 55 76 78 57 | 7 0 0 4 0 3 58 68 83 58 | 10 0 0 2 0 1 62 59 | 9 0 0 1 0 2 69 90 60 | 1 0 0 0 7 2 72 104 61 | 8 0 0 1 0 3 62 70 113 62 | 1 0 6 0 0 3 66 70 86 63 | 4 0 0 0 7 3 73 84 93 64 | 2 0 0 0 1 3 72 87 88 65 | 8 1 0 0 0 2 68 78 66 | 6 8 0 0 0 3 74 95 98 67 | 7 0 9 0 0 3 77 88 105 68 | 2 0 9 0 0 2 79 106 69 | 5 6 0 0 0 3 77 93 94 70 | 6 0 0 0 6 3 84 85 99 71 | 4 0 3 0 0 2 93 108 72 | 3 0 10 0 0 1 115 73 | 9 0 0 0 1 3 79 86 114 74 | 4 0 0 0 8 1 110 75 | 1 0 5 0 0 3 74 79 100 76 | 3 1 0 0 0 2 82 85 77 | 9 0 9 0 0 3 87 88 101 78 | 4 0 0 9 0 2 80 90 79 | 2 7 0 0 0 2 85 98 80 | 8 0 0 0 8 2 84 105 81 | 9 0 0 2 0 2 91 92 82 | 10 0 0 0 7 3 81 91 103 83 | 8 0 4 0 0 1 82 84 | 6 0 10 0 0 1 101 85 | 2 0 0 3 0 2 94 95 86 | 5 0 2 0 0 2 86 100 87 | 5 8 0 0 0 1 101 88 | 5 8 0 0 0 3 89 107 111 89 | 2 0 0 0 4 1 109 90 | 2 0 0 8 0 1 115 91 | 10 0 0 0 7 1 109 92 | 6 0 0 0 2 3 98 110 111 93 | 2 7 0 0 0 2 96 99 94 | 2 0 0 0 6 3 96 103 116 95 | 8 1 0 0 0 2 97 117 96 | 5 0 6 0 0 1 96 97 | 7 5 0 0 0 2 97 119 98 | 10 0 4 0 0 2 111 118 99 | 3 0 0 0 1 1 104 100 | 8 0 6 0 0 3 100 102 107 101 | 1 0 0 0 4 1 121 102 | 9 0 6 0 0 1 106 103 | 7 0 0 0 10 1 118 104 | 1 0 5 0 0 1 113 105 | 10 0 0 0 2 1 112 106 | 1 0 0 0 4 1 106 107 | 1 0 0 0 4 1 113 108 | 2 0 0 0 6 1 114 109 | 9 0 0 0 2 1 109 110 | 2 0 2 0 0 1 121 111 | 7 0 4 0 0 1 118 112 | 4 0 0 6 0 2 112 116 113 | 6 0 0 7 0 2 117 119 114 | 1 0 8 0 0 1 120 115 | 6 0 0 0 10 1 114 116 | 5 0 6 0 0 1 115 117 | 6 9 0 0 0 1 116 118 | 1 0 0 0 7 1 120 119 | 9 0 0 0 8 1 120 120 | 7 0 0 0 9 1 121 121 | 5 0 0 10 0 1 122 122 | 4 0 0 0 6 1 122 123 | 10 0 0 8 0 1 122 124 | 0 0 0 0 0 0 125 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpsp_j30_5_6.data: -------------------------------------------------------------------------------- 1 | 32 4 2 | 15 17 12 14 3 | 0 0 0 0 0 3 2 3 4 4 | 1 7 0 2 0 2 19 29 5 | 3 0 3 3 6 3 7 10 20 6 | 8 9 0 3 4 3 5 6 16 7 | 1 4 0 7 7 3 8 11 13 8 | 4 2 0 0 0 2 12 14 9 | 4 9 0 0 8 1 15 10 | 3 10 5 10 0 1 9 11 | 7 0 0 0 5 1 22 12 | 9 8 0 0 0 2 21 24 13 | 2 2 0 2 0 1 17 14 | 8 0 10 6 0 1 17 15 | 6 0 9 2 0 3 23 25 27 16 | 2 8 6 3 0 1 26 17 | 8 0 6 0 1 2 23 25 18 | 9 0 7 0 10 3 18 28 30 19 | 2 5 0 4 0 1 31 20 | 10 0 0 0 6 2 27 29 21 | 8 10 0 0 0 1 25 22 | 7 0 4 3 8 1 28 23 | 5 5 6 0 0 1 26 24 | 5 0 8 10 0 1 23 25 | 8 0 9 3 1 1 29 26 | 8 6 0 0 10 1 30 27 | 1 3 0 1 5 1 26 28 | 10 8 0 0 0 1 28 29 | 5 6 0 0 4 1 31 30 | 10 4 7 3 10 1 31 31 | 3 0 1 0 0 1 32 32 | 8 0 0 7 0 1 32 33 | 10 0 0 2 0 1 32 34 | 0 0 0 0 0 0 35 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_default.data: -------------------------------------------------------------------------------- 1 | 35 2 2 2 | 25 25 3 | 240 240 4 | 5 | 0 1 3 1 2 3 6 | 1 3 3 4 5 6 7 | 2 3 2 10 11 8 | 3 3 3 7 8 9 9 | 4 3 1 10 10 | 5 3 1 10 11 | 6 3 1 15 12 | 7 3 1 12 13 | 8 3 1 12 14 | 9 3 1 12 15 | 10 3 4 13 14 15 16 16 | 11 3 4 13 14 15 16 17 | 12 3 1 18 18 | 13 3 1 17 19 | 14 3 1 17 20 | 15 3 2 17 18 21 | 16 3 2 17 18 22 | 17 3 2 20 21 23 | 18 3 2 19 23 24 | 19 3 1 21 25 | 20 3 1 24 26 | 21 3 1 24 27 | 22 3 1 25 28 | 23 3 1 25 29 | 24 3 2 26 27 30 | 25 3 2 28 31 31 | 26 3 1 30 32 | 27 3 1 29 33 | 28 3 1 29 34 | 29 3 1 34 35 | 30 3 3 31 32 33 36 | 31 3 1 34 37 | 32 3 1 33 38 | 33 3 1 34 39 | 34 1 0 40 | 41 | 0 1 0 0 0 0 0 42 | 1 1 5 10 13 7 0 43 | 1 2 1 15 19 0 17 44 | 1 3 7 15 2 0 0 45 | 2 1 1 17 16 4 13 46 | 2 2 3 7 2 1 17 47 | 2 3 5 0 0 19 5 48 | 3 1 4 0 2 8 13 49 | 3 2 1 19 19 18 7 50 | 3 3 3 0 17 0 0 51 | 4 1 3 5 0 18 19 52 | 4 2 3 17 8 0 0 53 | 4 3 6 0 0 0 11 54 | 5 1 10 0 0 0 7 55 | 5 2 7 0 0 0 8 56 | 5 3 7 0 12 0 0 57 | 6 1 7 0 0 1 18 58 | 6 2 4 8 7 0 0 59 | 6 3 4 0 7 2 13 60 | 7 1 9 0 0 0 9 61 | 7 2 6 0 6 11 4 62 | 7 3 8 0 0 8 7 63 | 8 1 1 11 20 20 12 64 | 8 2 10 0 0 11 0 65 | 8 3 9 0 0 4 5 66 | 9 1 4 0 0 0 13 67 | 9 2 5 0 19 0 0 68 | 9 3 2 0 19 0 18 69 | 10 1 10 10 0 3 0 70 | 10 2 7 2 10 0 0 71 | 10 3 5 0 10 0 0 72 | 11 1 6 0 19 0 0 73 | 11 2 10 0 0 10 1 74 | 11 3 1 15 19 13 16 75 | 12 1 7 0 4 0 8 76 | 12 2 6 0 7 3 0 77 | 12 3 6 0 0 7 7 78 | 13 1 2 11 0 7 17 79 | 13 2 4 0 2 19 13 80 | 13 3 10 0 0 0 9 81 | 14 1 7 0 16 0 0 82 | 14 2 4 5 0 13 0 83 | 14 3 1 10 20 19 18 84 | 15 1 5 0 0 11 11 85 | 15 2 2 7 0 13 20 86 | 15 3 3 15 0 8 0 87 | 16 1 5 0 9 12 5 88 | 16 2 1 17 14 17 12 89 | 16 3 9 0 13 0 0 90 | 17 1 3 1 11 19 17 91 | 17 2 4 0 0 13 11 92 | 17 3 5 0 0 0 14 93 | 18 1 5 0 3 0 9 94 | 18 2 8 0 0 17 0 95 | 18 3 8 4 0 0 8 96 | 19 1 1 19 10 11 13 97 | 19 2 7 0 6 0 15 98 | 19 3 6 7 0 0 8 99 | 20 1 5 2 16 0 0 100 | 20 2 8 0 0 0 12 101 | 20 3 6 19 0 0 0 102 | 21 1 1 15 17 7 20 103 | 21 2 5 14 0 0 3 104 | 21 3 10 9 0 0 4 105 | 22 1 3 14 0 20 0 106 | 22 2 3 20 0 14 7 107 | 22 3 3 19 16 0 0 108 | 23 1 7 0 0 2 17 109 | 23 2 10 0 10 0 0 110 | 23 3 7 14 0 0 5 111 | 24 1 3 9 6 13 0 112 | 24 2 4 4 0 0 10 113 | 24 3 3 18 4 10 7 114 | 25 1 7 12 0 0 0 115 | 25 2 9 7 2 0 0 116 | 25 3 2 8 9 5 9 117 | 26 1 1 3 16 19 17 118 | 26 2 4 7 14 0 2 119 | 26 3 6 0 10 0 7 120 | 27 1 6 0 0 4 15 121 | 27 2 9 1 0 12 0 122 | 27 3 5 14 0 0 4 123 | 28 1 6 0 0 9 12 124 | 28 2 4 15 1 0 17 125 | 28 3 5 6 3 15 0 126 | 29 1 9 0 4 0 5 127 | 29 2 9 8 0 3 4 128 | 29 3 5 0 0 17 0 129 | 30 1 1 12 13 10 15 130 | 30 2 5 15 1 0 0 131 | 30 3 2 0 6 19 0 132 | 31 1 5 15 0 0 9 133 | 31 2 3 0 13 18 4 134 | 31 3 10 6 0 2 2 135 | 32 1 4 0 0 19 3 136 | 32 2 2 11 0 0 20 137 | 32 3 5 13 0 3 6 138 | 33 1 8 18 0 0 0 139 | 33 2 7 8 0 0 0 140 | 33 3 3 8 13 0 4 141 | 34 1 0 0 0 0 0 142 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_j30_12_8.data: -------------------------------------------------------------------------------- 1 | 30 2 2 2 | 3 | 33 42 4 | 77 94 5 | 6 | 0 3 3 3 5 14 7 | 1 3 3 4 6 7 8 | 2 3 2 8 13 9 | 3 3 2 11 29 10 | 4 3 1 17 11 | 5 3 3 9 11 21 12 | 6 3 2 10 13 13 | 7 3 3 8 9 23 14 | 8 3 1 25 15 | 9 3 3 10 15 24 16 | 10 3 2 16 20 17 | 11 3 3 12 15 16 18 | 12 3 1 17 19 | 13 3 3 15 16 21 20 | 14 3 1 27 21 | 15 3 1 19 22 | 16 3 2 18 26 23 | 17 3 1 20 24 | 18 3 1 22 25 | 19 3 2 20 22 26 | 20 3 2 26 27 27 | 21 3 3 23 24 25 28 | 22 3 1 25 29 | 23 3 3 27 28 29 30 | 24 3 1 26 31 | 25 3 1 28 32 | 26 3 1 28 33 | 27 3 0 34 | 28 3 0 35 | 29 3 0 36 | 37 | 0 1 6 1 0 10 0 38 | 0 2 6 0 5 10 0 39 | 0 3 7 0 4 0 2 40 | 1 1 1 0 8 7 0 41 | 1 2 4 0 6 6 0 42 | 1 3 8 9 0 0 9 43 | 2 1 4 0 6 0 9 44 | 2 2 6 1 0 0 8 45 | 2 3 7 0 5 5 0 46 | 3 1 2 0 7 0 6 47 | 3 2 3 0 6 0 4 48 | 3 3 8 8 0 0 1 49 | 4 1 3 8 0 0 7 50 | 4 2 8 7 0 0 7 51 | 4 3 8 5 0 9 0 52 | 5 1 2 9 0 0 4 53 | 5 2 3 0 6 3 0 54 | 5 3 4 4 0 0 3 55 | 6 1 3 0 9 0 8 56 | 6 2 7 6 0 10 0 57 | 6 3 7 0 9 1 0 58 | 7 1 7 0 5 5 0 59 | 7 2 10 5 0 0 2 60 | 7 3 10 0 5 0 4 61 | 8 1 3 8 0 7 0 62 | 8 2 6 0 8 7 0 63 | 8 3 10 0 7 0 3 64 | 9 1 7 1 0 9 0 65 | 9 2 7 0 8 7 0 66 | 9 3 8 0 7 0 10 67 | 10 1 3 9 0 0 4 68 | 10 2 3 0 10 2 0 69 | 10 3 10 0 9 2 0 70 | 11 1 1 0 7 6 0 71 | 11 2 4 8 0 6 0 72 | 11 3 8 0 4 0 5 73 | 12 1 2 7 0 0 6 74 | 12 2 3 3 0 0 6 75 | 12 3 8 0 8 7 0 76 | 13 1 4 9 0 9 0 77 | 13 2 6 0 9 0 6 78 | 13 3 9 0 5 7 0 79 | 14 1 5 6 0 7 0 80 | 14 2 8 5 0 0 7 81 | 14 3 8 0 8 0 8 82 | 15 1 3 10 0 0 4 83 | 15 2 5 0 4 0 4 84 | 15 3 6 7 0 0 2 85 | 16 1 2 0 8 0 8 86 | 16 2 6 0 7 8 0 87 | 16 3 7 0 7 0 6 88 | 17 1 2 0 4 0 5 89 | 17 2 3 7 0 1 0 90 | 17 3 4 6 0 0 5 91 | 18 1 3 5 0 3 0 92 | 18 2 10 0 6 0 4 93 | 18 3 10 3 0 3 0 94 | 19 1 2 9 0 0 6 95 | 19 2 8 0 9 4 0 96 | 19 3 8 0 9 0 4 97 | 20 1 1 0 10 0 10 98 | 20 2 3 0 6 0 9 99 | 20 3 5 0 3 3 0 100 | 21 1 7 0 10 0 7 101 | 21 2 7 0 9 4 0 102 | 21 3 7 7 0 4 0 103 | 22 1 2 8 0 0 3 104 | 22 2 3 2 0 5 0 105 | 22 3 7 0 1 3 0 106 | 23 1 1 0 7 5 0 107 | 23 2 1 5 0 0 7 108 | 23 3 3 4 0 0 7 109 | 24 1 1 0 7 5 0 110 | 24 2 10 5 0 3 0 111 | 24 3 10 0 7 4 0 112 | 25 1 2 2 0 5 0 113 | 25 2 3 0 9 0 5 114 | 25 3 9 0 4 3 0 115 | 26 1 1 0 7 0 6 116 | 26 2 4 0 3 0 6 117 | 26 3 8 4 0 0 3 118 | 27 1 2 0 3 0 7 119 | 27 2 10 2 0 0 7 120 | 27 3 10 0 3 0 6 121 | 28 1 1 0 9 0 7 122 | 28 2 6 6 0 5 0 123 | 28 3 10 4 0 0 5 124 | 29 1 1 4 0 0 6 125 | 29 2 1 3 0 7 0 126 | 29 3 10 0 5 5 0 127 | 128 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_j30_17_7.data: -------------------------------------------------------------------------------- 1 | 30 2 2 2 | 3 | 14 12 4 | 132 130 5 | 6 | 0 3 3 4 6 15 7 | 1 3 2 3 5 8 | 2 3 3 10 26 27 9 | 3 3 1 7 10 | 4 3 1 9 11 | 5 3 1 10 12 | 6 3 3 8 14 21 13 | 7 3 2 11 14 14 | 8 3 1 12 15 | 9 3 1 23 16 | 10 3 2 16 20 17 | 11 3 3 12 13 20 18 | 12 3 3 22 25 27 19 | 13 3 3 17 18 19 20 | 14 3 3 16 26 28 21 | 15 3 2 19 20 22 | 16 3 1 29 23 | 17 3 2 21 25 24 | 18 3 3 21 22 23 25 | 19 3 3 22 23 24 26 | 20 3 2 24 29 27 | 21 3 2 24 27 28 | 22 3 1 28 29 | 23 3 1 25 30 | 24 3 1 28 31 | 25 3 1 26 32 | 26 3 1 29 33 | 27 3 0 34 | 28 3 0 35 | 29 3 0 36 | 37 | 0 1 4 0 2 0 8 38 | 0 2 5 2 0 0 4 39 | 0 3 6 0 2 3 0 40 | 1 1 4 10 0 0 9 41 | 1 2 6 10 0 9 0 42 | 1 3 9 9 0 0 8 43 | 2 1 6 0 6 0 4 44 | 2 2 9 7 0 0 3 45 | 2 3 9 0 3 5 0 46 | 3 1 2 0 8 3 0 47 | 3 2 5 0 6 0 6 48 | 3 3 7 2 0 3 0 49 | 4 1 4 2 0 9 0 50 | 4 2 7 0 6 9 0 51 | 4 3 10 0 6 0 4 52 | 5 1 2 7 0 8 0 53 | 5 2 3 5 0 0 9 54 | 5 3 5 3 0 0 3 55 | 6 1 2 4 0 5 0 56 | 6 2 3 0 6 0 5 57 | 6 3 5 0 5 5 0 58 | 7 1 2 0 4 0 6 59 | 7 2 7 0 3 0 5 60 | 7 3 7 3 0 0 4 61 | 8 1 1 4 0 5 0 62 | 8 2 2 0 5 0 6 63 | 8 3 4 1 0 0 5 64 | 9 1 2 7 0 8 0 65 | 9 2 4 0 9 0 6 66 | 9 3 5 6 0 0 4 67 | 10 1 1 7 0 0 5 68 | 10 2 4 3 0 8 0 69 | 10 3 5 2 0 5 0 70 | 11 1 5 0 9 2 0 71 | 11 2 6 6 0 2 0 72 | 11 3 7 0 9 0 4 73 | 12 1 1 0 9 0 10 74 | 12 2 2 2 0 0 9 75 | 12 3 10 2 0 3 0 76 | 13 1 3 10 0 0 7 77 | 13 2 6 7 0 7 0 78 | 13 3 10 4 0 7 0 79 | 14 1 4 7 0 6 0 80 | 14 2 6 7 0 0 9 81 | 14 3 9 0 10 4 0 82 | 15 1 2 0 8 3 0 83 | 15 2 6 0 2 0 9 84 | 15 3 9 6 0 0 9 85 | 16 1 2 8 0 5 0 86 | 16 2 2 0 7 4 0 87 | 16 3 9 0 4 3 0 88 | 17 1 2 0 7 6 0 89 | 17 2 9 0 4 3 0 90 | 17 3 10 0 3 0 6 91 | 18 1 5 0 3 5 0 92 | 18 2 6 0 2 0 5 93 | 18 3 10 0 2 0 4 94 | 19 1 2 9 0 5 0 95 | 19 2 5 4 0 4 0 96 | 19 3 5 5 0 0 9 97 | 20 1 3 0 6 8 0 98 | 20 2 5 0 6 0 4 99 | 20 3 6 0 4 0 4 100 | 21 1 1 0 8 9 0 101 | 21 2 1 4 0 10 0 102 | 21 3 6 1 0 0 5 103 | 22 1 4 0 7 8 0 104 | 22 2 9 0 7 5 0 105 | 22 3 9 8 0 0 4 106 | 23 1 1 0 5 0 6 107 | 23 2 2 0 3 9 0 108 | 23 3 8 0 1 0 5 109 | 24 1 3 0 6 0 6 110 | 24 2 5 0 4 5 0 111 | 24 3 9 0 3 0 4 112 | 25 1 2 0 4 3 0 113 | 25 2 3 9 0 2 0 114 | 25 3 10 3 0 2 0 115 | 26 1 2 6 0 6 0 116 | 26 2 6 3 0 6 0 117 | 26 3 9 1 0 0 5 118 | 27 1 2 6 0 0 6 119 | 27 2 3 0 5 8 0 120 | 27 3 6 1 0 8 0 121 | 28 1 5 10 0 7 0 122 | 28 2 5 0 8 8 0 123 | 28 3 9 0 8 0 2 124 | 29 1 4 6 0 0 7 125 | 29 2 5 0 4 0 6 126 | 29 3 8 6 0 4 0 127 | 128 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_j30_27_6.data: -------------------------------------------------------------------------------- 1 | 30 2 2 2 | 3 | 26 29 4 | 188 157 5 | 6 | 0 3 2 4 5 7 | 1 3 2 6 14 8 | 2 3 3 3 12 13 9 | 3 3 3 7 20 24 10 | 4 3 1 16 11 | 5 3 3 8 10 24 12 | 6 3 2 18 25 13 | 7 3 3 11 21 23 14 | 8 3 3 9 17 26 15 | 9 3 2 13 14 16 | 10 3 2 15 21 17 | 11 3 2 26 29 18 | 12 3 3 15 17 22 19 | 13 3 1 19 20 | 14 3 1 15 21 | 15 3 1 29 22 | 16 3 2 19 21 23 | 17 3 1 23 24 | 18 3 2 20 22 25 | 19 3 2 20 23 26 | 20 3 1 28 27 | 21 3 3 25 26 29 28 | 22 3 2 24 27 29 | 23 3 2 25 27 30 | 24 3 1 28 31 | 25 3 1 28 32 | 26 3 1 27 33 | 27 3 0 34 | 28 3 0 35 | 29 3 0 36 | 37 | 0 1 4 3 0 0 4 38 | 0 2 8 0 6 4 0 39 | 0 3 10 0 4 4 0 40 | 1 1 6 7 0 7 0 41 | 1 2 7 6 0 6 0 42 | 1 3 7 7 0 5 0 43 | 2 1 3 0 9 0 6 44 | 2 2 8 0 6 3 0 45 | 2 3 10 0 4 0 3 46 | 3 1 1 7 0 9 0 47 | 3 2 3 4 0 0 3 48 | 3 3 9 3 0 0 3 49 | 4 1 3 0 5 0 7 50 | 4 2 6 0 5 5 0 51 | 4 3 9 6 0 0 5 52 | 5 1 1 0 4 9 0 53 | 5 2 5 0 1 0 4 54 | 5 3 8 7 0 7 0 55 | 6 1 2 0 5 0 8 56 | 6 2 5 7 0 5 0 57 | 6 3 10 6 0 0 8 58 | 7 1 3 3 0 0 9 59 | 7 2 4 0 4 5 0 60 | 7 3 10 0 1 0 8 61 | 8 1 1 4 0 3 0 62 | 8 2 3 0 2 2 0 63 | 8 3 5 3 0 2 0 64 | 9 1 1 9 0 4 0 65 | 9 2 2 0 6 3 0 66 | 9 3 8 8 0 0 4 67 | 10 1 4 0 7 0 9 68 | 10 2 6 1 0 5 0 69 | 10 3 6 0 6 0 9 70 | 11 1 6 8 0 9 0 71 | 11 2 6 7 0 0 7 72 | 11 3 8 0 9 10 0 73 | 12 1 4 3 0 0 9 74 | 12 2 7 0 6 0 7 75 | 12 3 9 0 4 0 4 76 | 13 1 4 0 10 6 0 77 | 13 2 6 0 9 0 5 78 | 13 3 10 9 0 0 4 79 | 14 1 1 6 0 7 0 80 | 14 2 4 5 0 0 9 81 | 14 3 8 0 7 3 0 82 | 15 1 2 9 0 0 8 83 | 15 2 3 0 4 0 2 84 | 15 3 7 5 0 7 0 85 | 16 1 3 0 9 8 0 86 | 16 2 7 9 0 8 0 87 | 16 3 8 0 5 8 0 88 | 17 1 4 7 0 7 0 89 | 17 2 9 6 0 3 0 90 | 17 3 10 3 0 0 6 91 | 18 1 2 0 4 6 0 92 | 18 2 2 8 0 0 2 93 | 18 3 4 7 0 6 0 94 | 19 1 6 6 0 0 6 95 | 19 2 7 0 4 9 0 96 | 19 3 9 0 3 7 0 97 | 20 1 6 6 0 0 5 98 | 20 2 7 0 1 0 3 99 | 20 3 8 3 0 0 1 100 | 21 1 2 7 0 9 0 101 | 21 2 7 0 2 9 0 102 | 21 3 8 2 0 8 0 103 | 22 1 4 0 6 0 6 104 | 22 2 4 0 6 5 0 105 | 22 3 10 0 3 1 0 106 | 23 1 3 0 8 10 0 107 | 23 2 3 0 6 0 6 108 | 23 3 10 0 2 0 6 109 | 24 1 3 6 0 0 5 110 | 24 2 7 4 0 9 0 111 | 24 3 8 0 8 8 0 112 | 25 1 3 0 5 0 7 113 | 25 2 4 0 5 7 0 114 | 25 3 8 3 0 0 7 115 | 26 1 6 3 0 3 0 116 | 26 2 7 0 3 3 0 117 | 26 3 9 0 2 0 8 118 | 27 1 4 0 4 0 7 119 | 27 2 8 0 4 0 6 120 | 27 3 8 3 0 7 0 121 | 28 1 2 7 0 10 0 122 | 28 2 4 0 6 5 0 123 | 28 3 8 0 2 5 0 124 | 29 1 1 6 0 9 0 125 | 29 2 5 6 0 0 7 126 | 29 3 9 0 8 0 3 127 | 128 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_j30_46_1.data: -------------------------------------------------------------------------------- 1 | 30 2 2 2 | 3 | 25 29 4 | 159 157 5 | 6 | 0 3 3 6 9 10 7 | 1 3 3 5 7 17 8 | 2 3 3 3 4 8 9 | 3 3 3 9 11 19 10 | 4 3 2 16 25 11 | 5 3 1 19 12 | 6 3 3 19 26 27 13 | 7 3 1 12 14 | 8 3 2 13 23 15 | 9 3 2 14 23 16 | 10 3 2 13 18 17 | 11 3 1 29 18 | 12 3 1 14 19 | 13 3 3 14 16 17 20 | 14 3 2 15 21 21 | 15 3 2 20 26 22 | 16 3 2 24 26 23 | 17 3 1 21 24 | 18 3 2 23 24 25 | 19 3 1 22 26 | 20 3 2 22 25 27 | 21 3 2 22 25 28 | 22 3 1 24 29 | 23 3 3 27 28 29 30 | 24 3 1 28 31 | 25 3 2 27 29 32 | 26 3 1 28 33 | 27 3 0 34 | 28 3 0 35 | 29 3 0 36 | 37 | 0 1 3 7 4 6 7 38 | 0 2 4 7 4 5 7 39 | 0 3 6 6 4 4 5 40 | 1 1 1 6 7 9 8 41 | 1 2 2 4 5 9 7 42 | 1 3 7 3 5 8 7 43 | 2 1 2 9 6 6 5 44 | 2 2 5 5 6 6 5 45 | 2 3 6 1 5 5 4 46 | 3 1 1 8 9 10 6 47 | 3 2 1 9 8 10 6 48 | 3 3 9 7 6 8 6 49 | 4 1 2 7 6 5 5 50 | 4 2 6 4 3 5 5 51 | 4 3 10 2 3 5 5 52 | 5 1 1 3 5 9 3 53 | 5 2 6 3 4 6 3 54 | 5 3 7 1 3 5 2 55 | 6 1 2 2 8 4 8 56 | 6 2 4 2 6 3 5 57 | 6 3 9 2 6 2 3 58 | 7 1 4 3 6 10 4 59 | 7 2 5 3 6 9 4 60 | 7 3 9 2 6 8 2 61 | 8 1 3 8 3 8 6 62 | 8 2 7 8 3 7 4 63 | 8 3 9 8 3 7 3 64 | 9 1 1 9 9 3 10 65 | 9 2 3 9 9 2 10 66 | 9 3 7 9 7 2 10 67 | 10 1 2 7 9 7 8 68 | 10 2 4 3 1 7 7 69 | 10 3 4 2 5 7 6 70 | 11 1 3 5 8 5 8 71 | 11 2 5 5 7 5 5 72 | 11 3 6 2 7 4 2 73 | 12 1 4 9 7 7 5 74 | 12 2 8 7 6 5 5 75 | 12 3 9 5 6 3 5 76 | 13 1 1 9 8 6 7 77 | 13 2 2 9 7 5 4 78 | 13 3 6 8 7 3 4 79 | 14 1 3 8 10 10 10 80 | 14 2 6 8 9 6 7 81 | 14 3 8 6 9 4 7 82 | 15 1 1 6 5 8 8 83 | 15 2 6 4 4 8 7 84 | 15 3 10 3 4 7 6 85 | 16 1 2 10 6 4 8 86 | 16 2 7 8 5 4 7 87 | 16 3 10 7 4 4 6 88 | 17 1 2 6 4 6 3 89 | 17 2 3 4 3 6 3 90 | 17 3 4 2 3 2 2 91 | 18 1 2 9 10 7 5 92 | 18 2 5 9 9 6 5 93 | 18 3 6 8 9 4 5 94 | 19 1 1 4 9 6 8 95 | 19 2 3 4 6 5 5 96 | 19 3 10 3 1 5 3 97 | 20 1 2 6 4 5 9 98 | 20 2 4 5 3 5 9 99 | 20 3 5 2 2 1 7 100 | 21 1 2 9 8 5 5 101 | 21 2 3 7 8 3 5 102 | 21 3 5 4 8 2 4 103 | 22 1 6 4 7 4 4 104 | 22 2 8 1 7 4 2 105 | 22 3 8 1 7 2 4 106 | 23 1 3 8 8 5 2 107 | 23 2 4 7 7 4 2 108 | 23 3 8 5 4 3 2 109 | 24 1 2 4 7 9 6 110 | 24 2 6 3 6 8 5 111 | 24 3 8 3 2 8 4 112 | 25 1 7 7 3 5 5 113 | 25 2 10 7 3 2 5 114 | 25 3 10 7 3 4 3 115 | 26 1 5 7 8 7 9 116 | 26 2 7 7 7 6 7 117 | 26 3 8 6 6 3 7 118 | 27 1 1 7 9 4 2 119 | 27 2 5 5 6 3 2 120 | 27 3 8 2 5 1 2 121 | 28 1 6 4 7 9 2 122 | 28 2 8 3 5 6 2 123 | 28 3 9 3 1 3 1 124 | 29 1 3 8 7 4 8 125 | 29 2 7 8 5 4 6 126 | 29 3 8 6 3 3 4 127 | 128 | -------------------------------------------------------------------------------- /examples/cp/visu/data/rcpspmm_j30_62_10.data: -------------------------------------------------------------------------------- 1 | 30 2 2 2 | 3 | 27 27 4 | 185 193 5 | 6 | 0 3 2 3 18 7 | 1 3 2 7 24 8 | 2 3 3 4 5 8 9 | 3 3 3 7 9 20 10 | 4 3 1 6 11 | 5 3 3 10 12 17 12 | 6 3 1 28 13 | 7 3 3 16 17 26 14 | 8 3 3 9 10 15 15 | 9 3 3 11 19 23 16 | 10 3 2 18 22 17 | 11 3 1 13 18 | 12 3 3 14 20 21 19 | 13 3 2 16 17 20 | 14 3 1 22 21 | 15 3 1 29 22 | 16 3 2 27 29 23 | 17 3 1 27 24 | 18 3 2 20 21 25 | 19 3 2 21 24 26 | 20 3 3 23 26 28 27 | 21 3 1 25 28 | 22 3 3 23 24 25 29 | 23 3 1 27 30 | 24 3 1 28 31 | 25 3 1 26 32 | 26 3 1 29 33 | 27 3 0 34 | 28 3 0 35 | 29 3 0 36 | 37 | 0 1 2 6 4 5 3 38 | 0 2 5 4 3 4 2 39 | 0 3 8 3 3 4 2 40 | 1 1 1 8 2 9 7 41 | 1 2 1 9 2 8 8 42 | 1 3 8 8 2 7 7 43 | 2 1 3 9 4 5 6 44 | 2 2 3 7 4 5 10 45 | 2 3 8 5 2 2 3 46 | 3 1 1 6 4 6 7 47 | 3 2 5 5 3 5 6 48 | 3 3 9 2 3 2 6 49 | 4 1 3 8 4 10 6 50 | 4 2 3 9 3 10 6 51 | 4 3 6 5 2 10 6 52 | 5 1 1 7 8 10 7 53 | 5 2 8 6 6 9 7 54 | 5 3 9 5 5 9 4 55 | 6 1 1 4 10 6 8 56 | 6 2 3 3 4 4 6 57 | 6 3 3 4 6 4 3 58 | 7 1 5 5 7 9 9 59 | 7 2 7 3 5 6 8 60 | 7 3 9 1 4 3 8 61 | 8 1 2 7 7 6 7 62 | 8 2 3 6 6 5 7 63 | 8 3 5 4 5 3 6 64 | 9 1 5 10 6 4 6 65 | 9 2 9 6 3 4 5 66 | 9 3 9 6 1 3 6 67 | 10 1 2 8 10 6 3 68 | 10 2 5 6 5 3 3 69 | 10 3 6 5 5 1 2 70 | 11 1 1 6 9 9 2 71 | 11 2 5 6 4 8 1 72 | 11 3 9 6 3 8 1 73 | 12 1 4 8 7 9 10 74 | 12 2 4 7 8 9 10 75 | 12 3 10 6 6 7 9 76 | 13 1 3 9 9 4 5 77 | 13 2 7 8 6 4 4 78 | 13 3 8 8 5 2 2 79 | 14 1 1 8 8 5 9 80 | 14 2 5 6 7 3 7 81 | 14 3 7 6 6 3 4 82 | 15 1 1 4 9 5 3 83 | 15 2 2 3 6 5 3 84 | 15 3 9 3 5 4 2 85 | 16 1 1 5 6 3 4 86 | 16 2 6 4 5 2 4 87 | 16 3 6 2 4 3 3 88 | 17 1 2 9 5 5 3 89 | 17 2 3 8 5 2 2 90 | 17 3 3 8 4 4 1 91 | 18 1 4 8 7 7 8 92 | 18 2 10 8 5 6 7 93 | 18 3 10 8 7 5 8 94 | 19 1 1 5 5 7 10 95 | 19 2 4 2 5 6 10 96 | 19 3 9 1 4 5 10 97 | 20 1 2 9 6 5 10 98 | 20 2 3 9 3 4 9 99 | 20 3 5 7 2 3 8 100 | 21 1 4 8 4 4 6 101 | 21 2 8 6 4 3 4 102 | 21 3 10 4 4 2 3 103 | 22 1 3 4 9 9 6 104 | 22 2 4 4 7 9 5 105 | 22 3 10 2 6 9 4 106 | 23 1 3 5 8 6 5 107 | 23 2 7 5 8 6 4 108 | 23 3 10 5 8 5 4 109 | 24 1 4 4 9 5 9 110 | 24 2 9 4 9 3 7 111 | 24 3 10 4 8 3 2 112 | 25 1 6 10 6 3 8 113 | 25 2 8 10 6 3 6 114 | 25 3 10 9 4 3 5 115 | 26 1 2 6 10 5 6 116 | 26 2 5 6 10 5 5 117 | 26 3 9 4 10 2 4 118 | 27 1 2 2 8 9 2 119 | 27 2 3 2 6 6 2 120 | 27 3 6 1 1 4 1 121 | 28 1 1 9 10 3 5 122 | 28 2 2 7 10 2 4 123 | 28 3 3 6 9 1 3 124 | 29 1 3 5 8 6 7 125 | 29 2 3 5 8 5 8 126 | 29 3 6 5 8 3 3 127 | 128 | -------------------------------------------------------------------------------- /examples/cp/visu/data/stochastic_jobshop_default.data: -------------------------------------------------------------------------------- 1 | 6 6 20 2 | 3 | 5 1 4 3 0 2 4 | 1 0 5 2 4 3 5 | 3 4 1 0 5 2 6 | 3 4 1 5 2 0 7 | 1 3 4 5 0 2 8 | 4 2 0 3 1 5 9 | 10 | 218 284 321 201 101 199 11 | 296 1498 697 193 876 302 12 | 103 928 857 766 492 490 13 | 839 197 102 102 828 900 14 | 587 199 513 522 306 103 15 | 962 404 410 304 188 298 16 | 17 | 259 313 311 191 93 211 18 | 297 184 698 201 924 295 19 | 105 897 880 676 451 479 20 | 755 209 101 454 834 899 21 | 609 210 488 517 294 99 22 | 957 396 387 296 210 299 23 | 24 | 663 299 286 204 97 184 25 | 305 1252 704 186 893 298 26 | 99 940 846 724 477 484 27 | 813 192 100 595 761 901 28 | 565 208 506 514 315 100 29 | 1038 402 415 298 205 301 30 | 31 | 461 292 324 216 107 186 32 | 296 431 703 199 879 307 33 | 96 860 897 669 487 510 34 | 818 202 100 384 777 900 35 | 572 189 490 509 296 100 36 | 1014 403 412 305 218 299 37 | 38 | 622 296 309 187 100 189 39 | 295 677 697 214 904 308 40 | 101 853 931 683 461 482 41 | 808 206 100 1368 797 900 42 | 631 206 493 501 292 100 43 | 951 397 401 301 216 300 44 | 45 | 420 287 294 189 108 197 46 | 300 1416 702 210 921 294 47 | 98 903 886 745 549 527 48 | 829 203 101 524 792 900 49 | 602 209 510 520 285 98 50 | 1003 401 407 304 207 301 51 | 52 | 56 308 314 211 105 214 53 | 301 1087 696 184 918 305 54 | 108 884 954 648 518 524 55 | 787 200 103 876 766 901 56 | 606 202 494 483 297 101 57 | 968 396 413 301 191 299 58 | 59 | 784 289 281 206 102 216 60 | 298 595 704 191 887 303 61 | 100 916 937 690 503 476 62 | 792 195 100 1016 844 899 63 | 569 211 515 491 317 102 64 | 1032 399 404 303 182 302 65 | 66 | 339 314 291 213 99 196 67 | 304 20 698 218 873 306 68 | 97 891 869 731 456 496 69 | 776 204 97 1087 756 900 70 | 576 205 512 493 303 103 71 | 997 401 394 297 193 298 72 | 73 | 137 291 289 214 104 191 74 | 303 348 703 195 884 296 75 | 95 959 891 662 508 513 76 | 771 198 102 946 849 900 77 | 628 192 509 480 313 98 78 | 986 402 399 300 195 301 79 | 80 | 582 301 306 208 92 187 81 | 302 513 699 209 890 293 82 | 92 847 852 717 472 487 83 | 803 196 99 665 751 900 84 | 635 194 504 512 299 101 85 | 945 398 393 295 214 302 86 | 87 | 97 303 284 186 98 192 88 | 302 1169 705 207 907 305 89 | 106 934 863 710 523 507 90 | 766 199 98 805 772 899 91 | 617 198 487 478 287 100 92 | 1009 398 391 300 201 301 93 | 94 | 299 286 319 199 91 201 95 | 299 102 702 203 913 301 96 | 102 878 874 634 534 501 97 | 761 193 99 32 823 901 98 | 620 191 496 488 283 98 99 | 1026 401 396 296 186 298 100 | 101 | 178 306 299 197 94 208 102 | 298 1580 700 182 896 292 103 | 100 841 903 703 544 516 104 | 824 200 98 243 808 900 105 | 613 204 491 486 304 99 106 | 1049 404 398 297 190 300 107 | 108 | 541 311 316 209 96 209 109 | 300 923 700 216 916 300 110 | 95 947 943 641 539 499 111 | 750 201 103 1298 839 900 112 | 624 190 501 475 308 101 113 | 1020 397 409 303 209 300 114 | 115 | 744 304 296 194 106 206 116 | 297 759 701 205 901 299 117 | 104 866 920 738 482 493 118 | 850 208 101 735 787 899 119 | 583 195 502 499 290 97 120 | 1043 400 390 302 197 299 121 | 122 | 703 294 276 184 109 194 123 | 304 841 696 188 899 300 124 | 93 953 914 697 466 518 125 | 834 205 98 313 782 899 126 | 580 203 499 507 310 102 127 | 980 399 402 299 203 301 128 | 129 | 380 316 279 192 103 204 130 | 299 1334 701 197 882 295 131 | 105 909 926 655 528 473 132 | 797 207 97 173 803 901 133 | 591 196 507 496 288 99 134 | 1055 399 406 299 184 299 135 | 136 | 16 297 304 196 100 203 137 | 301 1005 699 212 910 304 138 | 94 922 909 752 513 521 139 | 782 191 102 1227 813 901 140 | 598 197 498 525 312 102 141 | 974 400 385 302 199 302 142 | 143 | 501 309 301 203 95 213 144 | 303 266 695 190 927 297 145 | 107 872 948 759 497 504 146 | 845 194 99 1157 818 900 147 | 594 201 485 504 301 97 148 | 991 403 388 298 212 300 149 | -------------------------------------------------------------------------------- /examples/cp/visu/flow_shop.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This problem is a special case of Job-Shop Scheduling problem (see job_shop_basic.py) 9 | for which all jobs have the same processing order on machines because there is a 10 | technological order on the machines for the different jobs to follow. 11 | 12 | This problem is also similar that the one proposed in open_shop.py except 13 | that job operations must be executed in fixed order. 14 | 15 | Please refer to documentation for appropriate setup of solving configuration. 16 | """ 17 | 18 | from docplex.cp.model import * 19 | import os 20 | 21 | #----------------------------------------------------------------------------- 22 | # Initialize the problem data 23 | #----------------------------------------------------------------------------- 24 | 25 | # Read the input data file. 26 | # Available files are flowshop_default, and different flowshop_XXXXX. 27 | # First line contains the number of jobs, and the number of machines. 28 | # The rest of the file consists of one line per job that contains the list of 29 | # operations given as durations for each machines. 30 | 31 | filename = os.path.dirname(os.path.abspath(__file__)) + '/data/flowshop_default.data' 32 | with open(filename, 'r') as file: 33 | NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()] 34 | OP_DURATIONS = [[int(v) for v in file.readline().split()] for i in range(NB_JOBS)] 35 | 36 | #----------------------------------------------------------------------------- 37 | # Build the model 38 | #----------------------------------------------------------------------------- 39 | 40 | # Create model 41 | mdl = CpoModel() 42 | 43 | # Create one interval variable per job operation 44 | operations = [[interval_var(size=OP_DURATIONS[j][m], name='J{}-M{}'.format(j, m)) for m in range(NB_MACHINES)] for j in range(NB_JOBS)] 45 | 46 | # Force each operation to start after the end of the previous 47 | for j in range(NB_JOBS): 48 | for m in range(1,NB_MACHINES): 49 | mdl.add(end_before_start(operations[j][m-1], operations[j][m])) 50 | 51 | # Force no overlap for operations executed on a same machine 52 | for m in range(NB_MACHINES): 53 | mdl.add(no_overlap(operations[j][m] for j in range(NB_JOBS))) 54 | 55 | # Minimize termination date 56 | mdl.add(minimize(max(end_of(operations[i][NB_MACHINES-1]) for i in range(NB_JOBS)))) 57 | 58 | #----------------------------------------------------------------------------- 59 | # Solve the model and display the result 60 | #----------------------------------------------------------------------------- 61 | 62 | # Solve model 63 | print('Solving model...') 64 | res = mdl.solve(TimeLimit=10,LogPeriod=1000000) 65 | print('Solution:') 66 | res.print_solution() 67 | 68 | # Display solution 69 | import docplex.cp.utils_visu as visu 70 | if res and visu.is_visu_enabled(): 71 | visu.timeline('Solution for flow-shop ' + filename) 72 | visu.panel('Jobs') 73 | for i in range(NB_JOBS): 74 | visu.sequence(name='J' + str(i), 75 | intervals=[(res.get_var_solution(operations[i][j]), j, 'M' + str(j)) for j in range(NB_MACHINES)]) 76 | visu.panel('Machines') 77 | for j in range(NB_MACHINES): 78 | visu.sequence(name='M' + str(j), 79 | intervals=[(res.get_var_solution(operations[i][j]), j, 'J' + str(i)) for i in range(NB_JOBS)]) 80 | visu.show() 81 | -------------------------------------------------------------------------------- /examples/cp/visu/flow_shop_permutation.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The general Flow-Shop scheduling problem is a production problem where 9 | a set of n jobs have to be processed with identical flow pattern on m 10 | machines (see flow_shop.py). 11 | 12 | In permutation flow-shops the sequence of jobs is the same on all machines. 13 | For example, if machine 1 runs jobs J2, J1, J5, then the order is the same 14 | on all other machines. 15 | 16 | Please refer to documentation for appropriate setup of solving configuration. 17 | """ 18 | 19 | from docplex.cp.model import * 20 | import os 21 | 22 | 23 | #----------------------------------------------------------------------------- 24 | # Initialize the problem data 25 | #----------------------------------------------------------------------------- 26 | 27 | # Read the input data file. 28 | # Available files are flowshop_default, and different flowshop_tailXXXX. 29 | # First line contains the number of jobs, and the number of machines. 30 | # The rest of the file consists of one line per job that contains the list of 31 | # operations given as durations for each machines. 32 | filename = os.path.dirname(os.path.abspath(__file__)) + '/data/flowshop_default.data' 33 | with open(filename, 'r') as file: 34 | NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()] 35 | OP_DURATIONS = [[int(v) for v in file.readline().split()] for i in range(NB_JOBS)] 36 | 37 | 38 | #----------------------------------------------------------------------------- 39 | # Build the model 40 | #----------------------------------------------------------------------------- 41 | 42 | # Create model 43 | mdl = CpoModel() 44 | 45 | # Create one interval variable per job operation 46 | operations = [[interval_var(size=OP_DURATIONS[j][m], name='J{}-M{}'.format(j, m)) for m in range(NB_MACHINES)] for j in range(NB_JOBS)] 47 | 48 | # Create sequence of operation for each machine 49 | op_sequences = [sequence_var([operations[i][j] for i in range(NB_JOBS)], name='M{}'.format(j)) for j in range(NB_MACHINES)] 50 | 51 | # Force each operation to start after the end of the previous 52 | for j in range(NB_JOBS): 53 | for m in range(1, NB_MACHINES): 54 | mdl.add(end_before_start(operations[j][m-1], operations[j][m])) 55 | 56 | # Force no overlap for operations executed on a same machine 57 | for m in range(NB_MACHINES): 58 | mdl.add(no_overlap(op_sequences[m])) 59 | 60 | # Force sequences to be all identical on all machines 61 | for m in range(1, NB_MACHINES): 62 | mdl.add(same_sequence(op_sequences[0], op_sequences[m])) 63 | 64 | # Minimize termination date 65 | mdl.add(minimize(max([end_of(operations[i][NB_MACHINES-1]) for i in range(NB_JOBS)]))) 66 | 67 | 68 | #----------------------------------------------------------------------------- 69 | # Solve the model and display the result 70 | #----------------------------------------------------------------------------- 71 | 72 | # Solve model 73 | print('Solving model...') 74 | res = mdl.solve(FailLimit=10000, TimeLimit=10) 75 | 76 | # Draw solution 77 | import docplex.cp.utils_visu as visu 78 | if res and visu.is_visu_enabled(): 79 | visu.timeline('Solution for permutation flow-shop ' + filename) 80 | visu.panel('Jobs') 81 | for i in range(NB_JOBS): 82 | visu.sequence(name='J' + str(i), 83 | intervals=[(res.get_var_solution(operations[i][j]), j, 'M' + str(j)) for j in range(NB_MACHINES)]) 84 | visu.panel('Machines') 85 | for j in range(NB_MACHINES): 86 | visu.sequence(name='M' + str(j), 87 | intervals=[(res.get_var_solution(operations[i][j]), j, 'J' + str(i)) for i in range(NB_JOBS)]) 88 | visu.show() 89 | -------------------------------------------------------------------------------- /examples/cp/visu/house_building_basic.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This is a basic problem that involves building a house. 9 | The masonry, roofing, painting, etc. must be scheduled. 10 | Some tasks must necessarily take place before others, and these requirements are 11 | expressed through precedence constraints. 12 | 13 | Please refer to documentation for appropriate setup of solving configuration. 14 | """ 15 | 16 | from docplex.cp.model import * 17 | 18 | 19 | #----------------------------------------------------------------------------- 20 | # Build the model 21 | #----------------------------------------------------------------------------- 22 | 23 | # Create model 24 | mdl = CpoModel() 25 | 26 | masonry = interval_var(name='masonry', size=35) 27 | carpentry = interval_var(name='carpentry', size=15) 28 | plumbing = interval_var(name='plumbing', size=40) 29 | ceiling = interval_var(name='ceiling', size=15) 30 | roofing = interval_var(name='roofing', size=5) 31 | painting = interval_var(name='painting', size=10) 32 | windows = interval_var(name='windows', size=5) 33 | facade = interval_var(name='facade', size=10) 34 | garden = interval_var(name='garden', size=5) 35 | moving = interval_var(name='moving', size=5) 36 | 37 | # Add precedence constraints 38 | mdl.add(end_before_start(masonry, carpentry)) 39 | mdl.add(end_before_start(masonry, plumbing)) 40 | mdl.add(end_before_start(masonry, ceiling)) 41 | mdl.add(end_before_start(carpentry, roofing)) 42 | mdl.add(end_before_start(ceiling, painting)) 43 | mdl.add(end_before_start(roofing, windows)) 44 | mdl.add(end_before_start(roofing, facade)) 45 | mdl.add(end_before_start(plumbing, facade)) 46 | mdl.add(end_before_start(roofing, garden)) 47 | mdl.add(end_before_start(plumbing, garden)) 48 | mdl.add(end_before_start(windows, moving)) 49 | mdl.add(end_before_start(facade, moving)) 50 | mdl.add(end_before_start(garden, moving)) 51 | mdl.add(end_before_start(painting, moving)) 52 | 53 | 54 | #----------------------------------------------------------------------------- 55 | # Solve the model and display the result 56 | #----------------------------------------------------------------------------- 57 | 58 | # Solve model 59 | print('Solving model...') 60 | res = mdl.solve(TimeLimit=10) 61 | print('Solution:') 62 | res.print_solution() 63 | 64 | # Draw solution 65 | import docplex.cp.utils_visu as visu 66 | if res and visu.is_visu_enabled(): 67 | visu.show(res) 68 | -------------------------------------------------------------------------------- /examples/cp/visu/house_building_cumul.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This is a problem of building five houses in different locations. 9 | The masonry, roofing, painting, etc. must be scheduled. 10 | Some tasks must necessarily take place before others and these requirements are 11 | expressed through precedence constraints. 12 | 13 | There are three workers, and each task requires a worker. 14 | There is also a cash budget which starts with a given balance. 15 | Each task costs a given amount of cash per day which must be available at the start of the task. 16 | A cash payment is received periodically. 17 | The objective is to minimize the overall completion date. 18 | 19 | Please refer to documentation for appropriate setup of solving configuration. 20 | """ 21 | 22 | from docplex.cp.model import * 23 | 24 | #----------------------------------------------------------------------------- 25 | # Initialize the problem data 26 | #----------------------------------------------------------------------------- 27 | 28 | # List of tasks to be executed for each house 29 | TASKS = { 30 | 'masonry' : 35, 31 | 'carpentry' : 15, 32 | 'plumbing' : 40, 33 | 'ceiling' : 15, 34 | 'roofing' : 5, 35 | 'painting' : 10, 36 | 'windows' : 5, 37 | 'facade' : 10, 38 | 'garden' : 5, 39 | 'moving' : 5 40 | } 41 | 42 | # Tasks precedence constraints (each tuple (X, Y) means X ends before start of Y) 43 | PRECEDENCES = [ 44 | ('masonry', 'carpentry'), 45 | ('masonry', 'plumbing'), 46 | ('masonry', 'ceiling'), 47 | ('carpentry', 'roofing'), 48 | ('ceiling', 'painting'), 49 | ('roofing', 'windows'), 50 | ('roofing', 'facade'), 51 | ('plumbing', 'facade'), 52 | ('roofing', 'garden'), 53 | ('plumbing', 'garden'), 54 | ('windows', 'moving'), 55 | ('facade', 'moving'), 56 | ('garden', 'moving'), 57 | ('painting', 'moving'), 58 | ] 59 | 60 | # Number of workers 61 | NB_WORKERS = 3 62 | 63 | # List of houses to build. Value is the minimum start date 64 | HOUSES = [ 31, 0, 90, 120, 90 ] 65 | 66 | # Cash parameters 67 | NB_PAYMENTS = 5 68 | PAYMENT_AMOUNT = 30000 69 | PAYMENT_INTERVAL = 60 70 | 71 | #----------------------------------------------------------------------------- 72 | # Build the model 73 | #----------------------------------------------------------------------------- 74 | 75 | # Create model 76 | mdl = CpoModel() 77 | 78 | # Initialize cumul function 79 | workers_usage = 0 # Total worker usage 80 | cash = sum(step_at(PAYMENT_INTERVAL * p, PAYMENT_AMOUNT) for p in range(NB_PAYMENTS)) 81 | 82 | all_tasks = [] # Array of all tasks 83 | 84 | # Utility function 85 | def make_house(loc, rd): 86 | ''' Create model elements corresponding to the building of one house 87 | loc: Identification (index) of the house to build 88 | rd: Minimal start date 89 | ''' 90 | 91 | # Create interval variable for each task for this house 92 | tasks = { t: interval_var(size=TASKS[t], name='H{}-{}'.format(loc,t)) for t in TASKS } 93 | 94 | # Add precedence constraints 95 | mdl.add(end_before_start(tasks[p], tasks[s]) for p,s in PRECEDENCES) 96 | 97 | # Update cumul functions 98 | global workers_usage 99 | global cash 100 | workers_usage += sum(pulse(tasks[t], 1) for t in TASKS) 101 | cash -= sum(step_at_start(tasks[t], 200 * TASKS[t]) for t in TASKS) 102 | 103 | # Update cost 104 | all_tasks.extend(tasks.values()) 105 | 106 | 107 | # Make houses 108 | for i, sd in enumerate(HOUSES): 109 | make_house(i, sd) 110 | 111 | # Number of workers should not be greater than the limit 112 | mdl.add(workers_usage <= NB_WORKERS) 113 | 114 | # Cash should not be negative 115 | mdl.add(cash >= 0) 116 | 117 | # Minimize overall completion date 118 | mdl.add(minimize(max(end_of(task) for task in all_tasks))) 119 | 120 | 121 | #----------------------------------------------------------------------------- 122 | # Solve the model and display the result 123 | #----------------------------------------------------------------------------- 124 | 125 | def compact(name): 126 | # Example: H3-garden -> G3 127 | # ^ ^ 128 | loc, task = name[1:].split('-', 1) 129 | return int(loc), task[0].upper() + loc 130 | 131 | # Solve model 132 | print('Solving model...') 133 | res = mdl.solve(FailLimit=10000,TimeLimit=10) 134 | print('Solution:') 135 | res.print_solution() 136 | 137 | # Display result 138 | import docplex.cp.utils_visu as visu 139 | if res and visu.is_visu_enabled(): 140 | workersF = CpoStepFunction() 141 | cashF = CpoStepFunction() 142 | for p in range(NB_PAYMENTS): 143 | cashF.add_value(PAYMENT_INTERVAL * p, INT_MAX, PAYMENT_AMOUNT) 144 | for task in all_tasks: 145 | itv = res.get_var_solution(task) 146 | workersF.add_value(itv.get_start(), itv.get_end(), 1) 147 | cashF.add_value(itv.start, INT_MAX, -200 * itv.get_length()) 148 | visu.timeline('Solution SchedCumul') 149 | visu.panel(name='Schedule') 150 | for task in all_tasks: 151 | visu.interval(res.get_var_solution(task), *compact(task.get_name())) 152 | visu.panel(name='Workers') 153 | visu.function(segments=workersF, style='area') 154 | visu.panel(name='Cash') 155 | visu.function(segments=cashF, style='area', color='gold') 156 | visu.show() 157 | -------------------------------------------------------------------------------- /examples/cp/visu/house_building_optional.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This is a problem of building five houses. The masonry, roofing, 9 | painting, etc. must be scheduled. Some tasks must necessarily take 10 | place before others and these requirements are expressed through 11 | precedence constraints. 12 | 13 | There are three workers, and each worker has a given non-negative 14 | skill level for each task. Each task requires one worker that will 15 | have to be selected among the ones who have a non null skill level for 16 | that task. A worker can be assigned to only one task at a time. Each 17 | house has a deadline. The objective is to maximize the skill levels of 18 | the workers assigned to the tasks while respecting the deadlines. 19 | 20 | Please refer to documentation for appropriate setup of solving configuration. 21 | """ 22 | 23 | from docplex.cp.model import * 24 | 25 | #----------------------------------------------------------------------------- 26 | # Initialize the problem data 27 | #----------------------------------------------------------------------------- 28 | 29 | NB_HOUSES = 5 30 | DEADLINE = 318 31 | WORKERS = ['Joe', 'Jack', 'Jim'] 32 | NB_WORKERS = len(WORKERS) 33 | 34 | # List of tasks to be executed for each house 35 | TASKS = { 36 | 'masonry' : (35, [9, 5, 0], 1), 37 | 'carpentry' : (15, [7, 0, 5], 2), 38 | 'plumbing' : (40, [0, 7, 0], 3), 39 | 'ceiling' : (15, [5, 8, 0], 4), 40 | 'roofing' : ( 5, [6, 7, 0], 5), 41 | 'painting' : (10, [0, 9, 6], 6), 42 | 'windows' : ( 5, [8, 0, 5], 7), 43 | 'facade' : (10, [5, 5, 0], 8), 44 | 'garden' : ( 5, [5, 5, 9], 9), 45 | 'moving' : ( 5, [6, 0, 8], 10) 46 | } 47 | 48 | # Tasks precedence constraints (each tuple (X, Y) means X ends before start of Y) 49 | PRECEDENCES = [ 50 | ('masonry', 'carpentry'), 51 | ('masonry', 'plumbing'), 52 | ('masonry', 'ceiling'), 53 | ('carpentry', 'roofing'), 54 | ('ceiling', 'painting'), 55 | ('roofing', 'windows'), 56 | ('roofing', 'facade'), 57 | ('plumbing', 'facade'), 58 | ('roofing', 'garden'), 59 | ('plumbing', 'garden'), 60 | ('windows', 'moving'), 61 | ('facade', 'moving'), 62 | ('garden', 'moving'), 63 | ('painting', 'moving'), 64 | ] 65 | 66 | #----------------------------------------------------------------------------- 67 | # Build the model 68 | #----------------------------------------------------------------------------- 69 | 70 | # Create model 71 | mdl = CpoModel() 72 | 73 | # Initialize model variable sets 74 | total_skill = 0 # Expression computing total of skills 75 | worker_tasks = [[] for w in range(NB_WORKERS)] # Tasks (interval variables) assigned to a each worker 76 | 77 | # Utility function 78 | def make_house(loc, deadline): 79 | ''' Create model elements corresponding to the building of a house 80 | loc Identification of house location 81 | deadline Deadline for finishing the house 82 | ''' 83 | 84 | # Create interval variable for each task for this house 85 | tasks = {t: interval_var(size=TASKS[t][0], end=(0, deadline), name='H{}-{}'.format(loc,t)) for t in TASKS} 86 | 87 | # Add precedence constraints 88 | mdl.add(end_before_start(tasks[p], tasks[s]) for p,s in PRECEDENCES) 89 | 90 | # Allocate tasks to workers 91 | global total_skill 92 | allocs = { (t,w) : interval_var(optional=True, name='H{}-{}-{}'.format(loc, t, w)) for t in TASKS for w in range(NB_WORKERS) if TASKS[t][1][w] > 0 } 93 | total_skill += sum((TASKS[t][1][w] * presence_of(allocs[t,w])) for t,w in allocs) 94 | for t in TASKS: 95 | mdl.add(alternative(tasks[t], [allocs[t2,w] for t2,w in allocs if t==t2])) 96 | for t,w in allocs: 97 | worker_tasks[w].append(allocs[t,w]) 98 | 99 | # Make houses 100 | for h in range(NB_HOUSES): 101 | make_house(h, DEADLINE) 102 | 103 | # Avoid overlapping between tasks of each worker 104 | for w in range(NB_WORKERS): 105 | mdl.add(no_overlap(worker_tasks[w])) 106 | 107 | # Maximize total of skills 108 | mdl.add(maximize(total_skill)) 109 | 110 | 111 | #----------------------------------------------------------------------------- 112 | # Solve the model and display the result 113 | #----------------------------------------------------------------------------- 114 | 115 | def compact(name): 116 | # Example: H3-garden -> G3 117 | # ^ ^ 118 | loc, task, worker = name[1:].split('-', 2) 119 | # Returns color index and compacted name 120 | return int(TASKS[task][2]), task[0].upper() + loc 121 | 122 | # Solve model 123 | print('Solving model...') 124 | res = mdl.solve(FailLimit=10000, TimeLimit=10) 125 | 126 | print('Solution:') 127 | res.print_solution() 128 | 129 | # Draw solution 130 | import docplex.cp.utils_visu as visu 131 | if res and visu.is_visu_enabled(): 132 | visu.timeline('Solution house building', 0, DEADLINE) 133 | for w in range(NB_WORKERS): 134 | visu.sequence(name=WORKERS[w]) 135 | for t in worker_tasks[w]: 136 | wt = res.get_var_solution(t) 137 | if wt.is_present(): 138 | visu.interval(wt, *compact(wt.get_name())) 139 | visu.show() 140 | -------------------------------------------------------------------------------- /examples/cp/visu/house_building_time.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This is a problem of building a house. The masonry, roofing, painting, 9 | etc. must be scheduled. Some tasks must necessarily take place before 10 | others and these requirements are expressed through precedence 11 | constraints. 12 | 13 | Moreover, there are earliness and tardiness costs associated with some tasks. 14 | The objective is to minimize these costs. 15 | 16 | Please refer to documentation for appropriate setup of solving configuration. 17 | """ 18 | 19 | from docplex.cp.model import * 20 | 21 | #----------------------------------------------------------------------------- 22 | # Initialize the problem data 23 | #----------------------------------------------------------------------------- 24 | 25 | # Create model 26 | mdl = CpoModel() 27 | 28 | # List of tasks to be executed for the house 29 | TASKS = { 30 | 'masonry' : (35 , 1, {'release_date':25, 'earliness_cost':200.0} ), 31 | 'carpentry' : (15 , 2, {'release_date':75, 'earliness_cost':300.0} ), 32 | 'plumbing' : (40 , 3, {} ), 33 | 'ceiling' : (15 , 4, {'release_date':75, 'earliness_cost':100.0} ), 34 | 'roofing' : ( 5 , 5, {} ), 35 | 'painting' : (10 , 6, {} ), 36 | 'windows' : ( 5 , 7, {} ), 37 | 'facade' : (10 , 8, {} ), 38 | 'garden' : ( 5 , 9, {} ), 39 | 'moving' : ( 5 , 10, {'due_date':100, 'tardiness_cost':400.0} ) 40 | } 41 | 42 | # Tasks precedence constraints (each tuple (X, Y) means X ends before start of Y) 43 | PRECEDENCES = [ 44 | ('masonry', 'carpentry'), 45 | ('masonry', 'plumbing'), 46 | ('masonry', 'ceiling'), 47 | ('carpentry', 'roofing'), 48 | ('ceiling', 'painting'), 49 | ('roofing', 'windows'), 50 | ('roofing', 'facade'), 51 | ('plumbing', 'facade'), 52 | ('roofing', 'garden'), 53 | ('plumbing', 'garden'), 54 | ('windows', 'moving'), 55 | ('facade', 'moving'), 56 | ('garden', 'moving'), 57 | ('painting', 'moving'), 58 | ] 59 | 60 | #----------------------------------------------------------------------------- 61 | # Build the model 62 | #----------------------------------------------------------------------------- 63 | 64 | # Create model 65 | mdl = CpoModel() 66 | 67 | # Create interval variable for each building task 68 | tasks = { t: interval_var(size=TASKS[t][0], name=t) for t in TASKS } 69 | 70 | # Add precedence constraints 71 | mdl.add(end_before_start(tasks[p], tasks[s]) for p,s in PRECEDENCES) 72 | 73 | # Cost function 74 | fearliness = dict() # Task earliness cost function 75 | ftardiness = dict() # Task tardiness cost function 76 | 77 | for t in TASKS: 78 | if 'release_date' in TASKS[t][2]: 79 | fearliness[t] = CpoSegmentedFunction((-TASKS[t][2]['earliness_cost'], 0), [(TASKS[t][2]['release_date'], 0, 0)]) 80 | if 'due_date' in TASKS[t][2]: 81 | ftardiness[t] = CpoSegmentedFunction((0, 0), [(TASKS[t][2]['due_date'], 0, TASKS[t][2]['tardiness_cost'],)]) 82 | 83 | # Minimize cost 84 | mdl.add(minimize( sum( start_eval(tasks[t], fearliness[t]) for t in fearliness) + 85 | sum( end_eval (tasks[t], ftardiness[t]) for t in ftardiness) )) 86 | 87 | #----------------------------------------------------------------------------- 88 | # Solve the model and display the result 89 | #----------------------------------------------------------------------------- 90 | 91 | print('Solving model...') 92 | res = mdl.solve(TimeLimit=10) 93 | print('Solution:') 94 | res.print_solution() 95 | 96 | import docplex.cp.utils_visu as visu 97 | if res and visu.is_visu_enabled(): 98 | visu.timeline('Solution house building', origin=10, horizon=120) 99 | visu.panel('Schedule') 100 | for t in TASKS: 101 | visu.interval(res.get_var_solution(tasks[t]), TASKS[t][1], t) 102 | for t in TASKS: 103 | itvsol = res.get_var_solution(tasks[t]) 104 | if 'release_date' in TASKS[t][2]: 105 | visu.panel('Earliness') 106 | cost = fearliness[t].get_value(itvsol.get_start()) 107 | visu.function(segments=[(itvsol, cost, t)], color=TASKS[t][1], style='interval') 108 | visu.function(segments=fearliness[t], color=TASKS[t][1]) 109 | if 'due_date' in TASKS[t][2]: 110 | visu.panel('Tardiness') 111 | cost = ftardiness[t].get_value(itvsol.get_end()) 112 | visu.function(segments=[(itvsol, cost, t)], color=TASKS[t][1], style='interval') 113 | visu.function(segments=ftardiness[t], color=TASKS[t][1]) 114 | visu.show() 115 | -------------------------------------------------------------------------------- /examples/cp/visu/job_shop_basic.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | In the classical Job-Shop Scheduling problem a finite set of jobs is processed 9 | on a finite set of machines. 10 | Each job is characterized by a fixed order of operations, each of which is to 11 | be processed on a specific machine for a specified duration. 12 | All machines are used by each job. 13 | Each machine can process at most one operation at a time and once an operation 14 | initiates processing on a given machine it must complete processing uninterrupted. 15 | 16 | The objective of the problem is to find a schedule that minimizes the makespan (end date) of the schedule. 17 | 18 | Please refer to documentation for appropriate setup of solving configuration. 19 | """ 20 | 21 | from docplex.cp.model import * 22 | import os 23 | 24 | 25 | #----------------------------------------------------------------------------- 26 | # Initialize the problem data 27 | #----------------------------------------------------------------------------- 28 | 29 | # Read the input data file. 30 | # Available files are jobshop_ft06, jobshop_ft10 and jobshop_ft20 31 | # First line contains the number of jobs, and the number of machines. 32 | # The rest of the file consists of one line per job. 33 | # Each line contains list of operations, each one given by 2 numbers: machine and duration 34 | filename = os.path.dirname(os.path.abspath(__file__)) + '/data/jobshop_ft06.data' 35 | with open(filename, 'r') as file: 36 | NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()] 37 | JOBS = [[int(v) for v in file.readline().split()] for i in range(NB_JOBS)] 38 | 39 | 40 | #----------------------------------------------------------------------------- 41 | # Prepare the data for modeling 42 | #----------------------------------------------------------------------------- 43 | 44 | # Build list of machines. MACHINES[j][s] = id of the machine for the operation s of the job j 45 | MACHINES = [[JOBS[j][2 * s] for s in range(NB_MACHINES)] for j in range(NB_JOBS)] 46 | 47 | # Build list of durations. DURATION[j][s] = duration of the operation s of the job j 48 | DURATION = [[JOBS[j][2 * s + 1] for s in range(NB_MACHINES)] for j in range(NB_JOBS)] 49 | 50 | 51 | #----------------------------------------------------------------------------- 52 | # Build the model 53 | #----------------------------------------------------------------------------- 54 | 55 | # Create model 56 | mdl = CpoModel() 57 | 58 | # Create one interval variable per job operation 59 | job_operations = [[interval_var(size=DURATION[j][m], name='O{}-{}'.format(j,m)) for m in range(NB_MACHINES)] for j in range(NB_JOBS)] 60 | 61 | # Each operation must start after the end of the previous 62 | for j in range(NB_JOBS): 63 | for s in range(1, NB_MACHINES): 64 | mdl.add(end_before_start(job_operations[j][s-1], job_operations[j][s])) 65 | 66 | # Force no overlap for operations executed on a same machine 67 | machine_operations = [[] for m in range(NB_MACHINES)] 68 | for j in range(NB_JOBS): 69 | for s in range(NB_MACHINES): 70 | machine_operations[MACHINES[j][s]].append(job_operations[j][s]) 71 | for mops in machine_operations: 72 | mdl.add(no_overlap(mops)) 73 | 74 | # Minimize termination date 75 | mdl.add(minimize(max(end_of(job_operations[i][NB_MACHINES-1]) for i in range(NB_JOBS)))) 76 | 77 | 78 | #----------------------------------------------------------------------------- 79 | # Solve the model and display the result 80 | #----------------------------------------------------------------------------- 81 | 82 | # Solve model 83 | print('Solving model...') 84 | res = mdl.solve(TimeLimit=10) 85 | print('Solution:') 86 | res.print_solution() 87 | 88 | # Draw solution 89 | import docplex.cp.utils_visu as visu 90 | if res and visu.is_visu_enabled(): 91 | visu.timeline('Solution for job-shop ' + filename) 92 | visu.panel('Jobs') 93 | for i in range(NB_JOBS): 94 | visu.sequence(name='J' + str(i), 95 | intervals=[(res.get_var_solution(job_operations[i][j]), MACHINES[i][j], 'M' + str(MACHINES[i][j])) for j in 96 | range(NB_MACHINES)]) 97 | visu.panel('Machines') 98 | for k in range(NB_MACHINES): 99 | visu.sequence(name='M' + str(k), 100 | intervals=[(res.get_var_solution(machine_operations[k][i]), k, 'J' + str(i)) for i in range(NB_JOBS)]) 101 | visu.show() 102 | -------------------------------------------------------------------------------- /examples/cp/visu/job_shop_flexible.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | This problem is an extension of the classical Job-Shop Scheduling problem 9 | (see job_shop_basic.py) which allows an operation to be processed by any machine 10 | from a given set. 11 | The operation processing time depends on the allocated machine. 12 | The problem is to assign each operation to a machine and to order the operations 13 | on the machines such that the maximal completion time (makespan) of all 14 | operations is minimized. 15 | 16 | Please refer to documentation for appropriate setup of solving configuration. 17 | """ 18 | 19 | from docplex.cp.model import * 20 | import os 21 | 22 | 23 | #----------------------------------------------------------------------------- 24 | # Initialize the problem data 25 | #----------------------------------------------------------------------------- 26 | 27 | # Read the input data file. 28 | # Available files are jobshopflex_default and multiple other jobshopflex_XXXX. 29 | # First line contains the number of jobs, and the number of machines. 30 | # The rest of the file consists of one line per job. 31 | # First integer is the number of job steps, followed by the choices for each step. 32 | # For each step, first integer indicates the number of choices, followed 33 | # by the choices expressed with two integers: machine and duration 34 | filename = os.path.dirname(os.path.abspath(__file__)) + '/data/jobshopflex_default.data' 35 | with open(filename, 'r') as file: 36 | NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()] 37 | list_jobs = [[int(v) for v in file.readline().split()] for i in range(NB_JOBS)] 38 | 39 | 40 | #----------------------------------------------------------------------------- 41 | # Prepare the data for modeling 42 | #----------------------------------------------------------------------------- 43 | 44 | # Build final list of jobs. 45 | # Each job is a list of operations. 46 | # Each operation is a list of choices expressed as tuples (machine, duration) 47 | JOBS = [] 48 | for jline in list_jobs: 49 | nbstps = jline.pop(0) 50 | job = [] 51 | for stp in range(nbstps): 52 | nbc = jline.pop(0) 53 | choices = [] 54 | for c in range(nbc): 55 | m = jline.pop(0) 56 | d = jline.pop(0) 57 | choices.append((m - 1, d)) 58 | job.append(choices) 59 | JOBS.append(job) 60 | 61 | 62 | #----------------------------------------------------------------------------- 63 | # Build the model 64 | #----------------------------------------------------------------------------- 65 | 66 | # Create model 67 | mdl = CpoModel() 68 | 69 | # Following code creates: 70 | # - creates one interval variable 'ops' for each possible operation choice 71 | # - creates one interval variable mops' for each operation, as an alternative of all operation choices 72 | # - setup precedence constraints between operations of each job 73 | # - creates a no_overlap constraint an the operations of each machine 74 | 75 | ops = { (j,o) : interval_var(name='J{}_O{}'.format(j,o)) 76 | for j,J in enumerate(JOBS) for o,O in enumerate(J)} 77 | mops = { (j,o,k,m) : interval_var(name='J{}_O{}_C{}_M{}'.format(j,o,k,m), optional=True, size=d) 78 | for j,J in enumerate(JOBS) for o,O in enumerate(J) for k, (m, d) in enumerate(O)} 79 | 80 | # Precedence constraints between operations of a job 81 | mdl.add(end_before_start(ops[j,o], ops[j,o-1]) for j,o in ops if 0 0) for p in range(nbLocation)) 93 | 94 | # Add constraints 95 | mdl.add(pack(load, cust, demand)) 96 | 97 | # Add objective 98 | obj = scal_prod(fixedCost, open) + sum(element(cust[c], cost[c]) for c in range(nbCustomer)) 99 | mdl.add(minimize(obj)) 100 | 101 | # Add KPIs 102 | if compare_natural(context.model.version, '12.9') >= 0: 103 | mdl.add_kpi(sum(demand) / scal_prod(open, capacity), 'Average Occupancy') 104 | mdl.add_kpi(min([load[l] / capacity[l] + (1 - open[l]) for l in range(nbLocation)]), 'Min occupancy') 105 | 106 | 107 | #----------------------------------------------------------------------------- 108 | # Solve the model and display the result 109 | #----------------------------------------------------------------------------- 110 | 111 | if context.visu_enabled: 112 | mdl.add_solver_listener(SolverProgressPanelListener(parse_log=True)) 113 | 114 | # Solve the model 115 | print('Solve the model') 116 | res = mdl.solve(TimeLimit=20, LogPeriod=1000) 117 | res.write() 118 | -------------------------------------------------------------------------------- /examples/cp/visu/rcpsp.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The RCPSP (Resource-Constrained Project Scheduling Problem) is a generalization 9 | of the production-specific Job-Shop (see job_shop_basic.py), Flow-Shop 10 | (see flow_shop.py) and Open-Shop(see open_shop.py) scheduling problems. 11 | 12 | Given: 13 | - a set of q resources with given capacities, 14 | - a network of precedence constraints between the activities, and 15 | - for each activity and each resource the amount of the resource 16 | required by the activity over its execution, 17 | the goal of the RCPSP is to find a schedule meeting all the 18 | constraints whose makespan (i.e., the time at which all activities are 19 | finished) is minimal. 20 | 21 | Please refer to documentation for appropriate setup of solving configuration. 22 | """ 23 | 24 | from docplex.cp.model import * 25 | import os 26 | 27 | #----------------------------------------------------------------------------- 28 | # Initialize the problem data 29 | #----------------------------------------------------------------------------- 30 | 31 | # Read the input data file. 32 | # Available files are rcpsp_default, and different rcpsp_XXXXXX. 33 | # First line contains the number of tasks, and the number of resources. 34 | # Second line contains the capacities of the resources. 35 | # The rest of the file consists of one line per task, organized as follows: 36 | # - duration of the task 37 | # - the demand on each resource (one integer per resource) 38 | # - the number of successors followed by the list of successor numbers 39 | 40 | filename = os.path.dirname(os.path.abspath(__file__)) + '/data/rcpsp_default.data' 41 | with open(filename, 'r') as file: 42 | NB_TASKS, NB_RESOURCES = [int(v) for v in file.readline().split()] 43 | CAPACITIES = [int(v) for v in file.readline().split()] 44 | TASKS = [[int(v) for v in file.readline().split()] for i in range(NB_TASKS)] 45 | 46 | 47 | #----------------------------------------------------------------------------- 48 | # Prepare the data for modeling 49 | #----------------------------------------------------------------------------- 50 | 51 | # Extract duration of each task 52 | DURATIONS = [TASKS[t][0] for t in range(NB_TASKS)] 53 | 54 | # Extract demand of each task 55 | DEMANDS = [TASKS[t][1:NB_RESOURCES+1] for t in range(NB_TASKS)] 56 | 57 | # Extract successors of each task 58 | SUCCESSORS = [TASKS[t][NB_RESOURCES+2:] for t in range(NB_TASKS)] 59 | 60 | 61 | #----------------------------------------------------------------------------- 62 | # Build the model 63 | #----------------------------------------------------------------------------- 64 | 65 | # Create model 66 | mdl = CpoModel() 67 | 68 | # Create task interval variables 69 | tasks = [interval_var(name='T{}'.format(i+1), size=DURATIONS[i]) for i in range(NB_TASKS)] 70 | 71 | # Add precedence constraints 72 | mdl.add(end_before_start(tasks[t], tasks[s-1]) for t in range(NB_TASKS) for s in SUCCESSORS[t]) 73 | 74 | # Constrain capacity of resources 75 | mdl.add(sum(pulse(tasks[t], DEMANDS[t][r]) for t in range(NB_TASKS) if DEMANDS[t][r] > 0) <= CAPACITIES[r] for r in range(NB_RESOURCES)) 76 | 77 | # Minimize end of all tasks 78 | mdl.add(minimize(max(end_of(t) for t in tasks))) 79 | 80 | 81 | #----------------------------------------------------------------------------- 82 | # Solve the model and display the result 83 | #----------------------------------------------------------------------------- 84 | 85 | # Solve model 86 | print('Solving model...') 87 | res = mdl.solve(FailLimit=100000,TimeLimit=10) 88 | print('Solution: ') 89 | res.print_solution() 90 | 91 | import docplex.cp.utils_visu as visu 92 | if res and visu.is_visu_enabled(): 93 | load = [CpoStepFunction() for j in range(NB_RESOURCES)] 94 | for i in range(NB_TASKS): 95 | itv = res.get_var_solution(tasks[i]) 96 | for j in range(NB_RESOURCES): 97 | if 0 < DEMANDS[i][j]: 98 | load[j].add_value(itv.get_start(), itv.get_end(), DEMANDS[i][j]) 99 | 100 | visu.timeline('Solution for RCPSP ' + filename) 101 | visu.panel('Tasks') 102 | for i in range(NB_TASKS): 103 | visu.interval(res.get_var_solution(tasks[i]), i, tasks[i].get_name()) 104 | for j in range(NB_RESOURCES): 105 | visu.panel('R' + str(j+1)) 106 | visu.function(segments=[(INTERVAL_MIN, INTERVAL_MAX, CAPACITIES[j])], style='area', color='lightgrey') 107 | visu.function(segments=load[j], style='area', color=j) 108 | visu.show() 109 | -------------------------------------------------------------------------------- /examples/cp/visu/setup_costs.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The problem is to schedule a set of tasks on two alternative machines with 9 | different setup times. 10 | 11 | The objective is to minimize the number of "long" setup times on machines. 12 | A setup time is considered to be long if it is larger than 30. 13 | 14 | Please refer to documentation for appropriate setup of solving configuration. 15 | """ 16 | 17 | from docplex.cp.model import * 18 | 19 | #----------------------------------------------------------------------------- 20 | # Initialize the problem data 21 | #----------------------------------------------------------------------------- 22 | 23 | # Number of types 24 | NB_TYPES = 10 25 | 26 | # Setup times of machine M1 27 | SETUP_M1 = [ 28 | [22, 24, 7, 10, 9, 41, 14, 30, 24, 6], 29 | [63, 21, 42, 1, 24, 17, 35, 25, 0, 68], 30 | [60, 70, 37, 70, 39, 84, 44, 60, 67, 36], 31 | [77, 57, 65, 33, 81, 74, 72, 82, 57, 83], 32 | [51, 31, 18, 32, 48, 45, 51, 21, 28, 45], 33 | [46, 42, 29, 11, 11, 21, 59, 8, 4, 51], 34 | [35, 59, 42, 45, 44, 76, 37, 65, 59, 41], 35 | [38, 62, 45, 14, 33, 24, 52, 32, 7, 44], 36 | [63, 57, 44, 7, 26, 17, 55, 25, 21, 68], 37 | [24, 34, 1, 34, 3, 48, 8, 24, 31, 30] 38 | ] 39 | 40 | # Setup times of machine M2 41 | SETUP_M2 = [ 42 | [27, 48, 44, 52, 21, 61, 33, 5, 37, 64], 43 | [42, 44, 42, 40, 17, 40, 49, 41, 66, 29], 44 | [36, 53, 31, 56, 50, 56, 7, 41, 49, 60], 45 | [6, 43, 46, 38, 16, 44, 39, 11, 43, 12], 46 | [25, 27, 45, 67, 37, 67, 52, 30, 62, 56], 47 | [6, 43, 2, 0, 16, 35, 9, 11, 43, 12], 48 | [29, 70, 25, 62, 43, 62, 26, 34, 42, 61], 49 | [22, 43, 53, 47, 16, 56, 28, 10, 32, 59], 50 | [56, 93, 73, 76, 66, 82, 48, 61, 51, 50], 51 | [18, 55, 34, 26, 28, 32, 40, 12, 44, 25] 52 | ] 53 | 54 | # Task duration 55 | TASK_DURATION = [ 56 | 19, 18, 16, 11, 16, 15, 19, 18, 17, 17, 57 | 20, 16, 16, 14, 19, 11, 10, 16, 12, 20, 58 | 14, 14, 20, 12, 18, 16, 10, 15, 11, 13, 59 | 15, 11, 11, 13, 19, 17, 11, 20, 19, 17, 60 | 15, 19, 13, 16, 20, 13, 13, 13, 13, 15 61 | ] 62 | 63 | # Number of tasks 64 | NB_TASKS = len(TASK_DURATION) 65 | 66 | # Task type 67 | TASK_TYPE = [ 68 | 8, 1, 6, 3, 4, 8, 8, 4, 3, 5, 69 | 9, 4, 1, 5, 8, 8, 4, 1, 9, 2, 70 | 6, 0, 8, 9, 1, 0, 1, 7, 5, 9, 71 | 3, 1, 9, 3, 0, 7, 0, 7, 1, 4, 72 | 5, 7, 4, 0, 9, 1, 5, 4, 5, 1 73 | ] 74 | 75 | 76 | #----------------------------------------------------------------------------- 77 | # Build the model 78 | #----------------------------------------------------------------------------- 79 | 80 | # Create model 81 | mdl = CpoModel() 82 | 83 | # Build tasks for machine M1 and M2 84 | tasks_m1 = [interval_var(name='A{}_M1_TP{}'.format(i, TASK_TYPE[i]), optional=True) for i in range(NB_TASKS)] 85 | tasks_m2 = [interval_var(name='A{}_M2_TP{}'.format(i, TASK_TYPE[i]), optional=True) for i in range(NB_TASKS)] 86 | 87 | # Build actual tasks as an alternative between machines 88 | tasks = [interval_var(name='A{}_TP{}'.format(i, TASK_TYPE[i]), size=TASK_DURATION[i]) for i in range(NB_TASKS)] 89 | mdl.add(alternative(tasks[i], [tasks_m1[i], tasks_m2[i]]) for i in range(NB_TASKS)) 90 | 91 | # Build a map to retrieve task id from variable name (for display purpose) 92 | task_id = dict() 93 | for i in range(NB_TASKS): 94 | task_id[tasks_m1[i].get_name()] = i 95 | task_id[tasks_m2[i].get_name()] = i 96 | 97 | # Constrain tasks to no overlap on each machine 98 | s1 = sequence_var(tasks_m1, types=TASK_TYPE, name='M1') 99 | s2 = sequence_var(tasks_m2, types=TASK_TYPE, name='M2') 100 | mdl.add(no_overlap(s1, SETUP_M1, 1)) 101 | mdl.add(no_overlap(s2, SETUP_M2, 1)) 102 | 103 | # Minimize the number of 'long' setup times on machines. 104 | nbLongSetups = 0 105 | for i in range(NB_TASKS): 106 | tpi = TASK_TYPE[i] 107 | isLongSetup1 = [1 if 30 <= SETUP_M1[tpi][j] else 0 for j in range(NB_TYPES)] + [0] 108 | isLongSetup2 = [1 if 30 <= SETUP_M2[tpi][j] else 0 for j in range(NB_TYPES)] + [0] 109 | nbLongSetups += element(type_of_next(s1, tasks_m1[i], NB_TYPES, NB_TYPES), isLongSetup1) 110 | nbLongSetups += element(type_of_next(s2, tasks_m2[i], NB_TYPES, NB_TYPES), isLongSetup2) 111 | 112 | mdl.add(minimize(nbLongSetups)) 113 | 114 | 115 | #----------------------------------------------------------------------------- 116 | # Solve the model and display the result 117 | #----------------------------------------------------------------------------- 118 | 119 | def compact(name): 120 | # Example: A31_M1_TP1 -> 31 121 | task, foo = name.split('_', 1) 122 | return task[1:] 123 | 124 | # Solve model 125 | print('Solving model...') 126 | res = mdl.solve(TimeLimit=10, FailLimit=1000000) 127 | print('Solution: ') 128 | res.print_solution() 129 | 130 | import docplex.cp.utils_visu as visu 131 | 132 | def showsequence(s, setup): 133 | seq = res.get_var_solution(s) 134 | visu.sequence(name=s.get_name()) 135 | vs = seq.get_value() 136 | for v in vs: 137 | nm = v.get_name() 138 | visu.interval(v, TASK_TYPE[task_id[nm]], compact(nm)) 139 | for i in range(len(vs) - 1): 140 | end = vs[i].get_end() 141 | tp1 = TASK_TYPE[task_id[vs[i].get_name()]] 142 | tp2 = TASK_TYPE[task_id[vs[i + 1].get_name()]] 143 | visu.transition(end, end + setup[tp1][tp2]) 144 | 145 | if res and visu.is_visu_enabled(): 146 | visu.timeline('Solution for transition costs') 147 | showsequence(s1, SETUP_M1) 148 | showsequence(s2, SETUP_M2) 149 | visu.show() 150 | -------------------------------------------------------------------------------- /examples/cp/visu/squaring_square.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2022 5 | # -------------------------------------------------------------------------- 6 | 7 | """ 8 | The aim of the square example is to place a set of small squares of 9 | different sizes into a large square. 10 | 11 | See https://en.wikipedia.org/wiki/Squaring_the_square for details on this classical problem. 12 | 13 | This version is extended and uses matplotlib to draw the result at the end. 14 | Requires installation of numpy (installer) and following python packages: 15 | "pip install matplotlib python-dateutil pyparsing" 16 | 17 | Please refer to documentation for appropriate setup of solving configuration. 18 | """ 19 | 20 | from docplex.cp.model import * 21 | 22 | 23 | #----------------------------------------------------------------------------- 24 | # Initialize the problem data 25 | #----------------------------------------------------------------------------- 26 | 27 | # Size of the englobing square 28 | SIZE_SQUARE = 112 29 | 30 | # Sizes of the sub-squares 31 | SIZE_SUBSQUARE = [50, 42, 37, 35, 33, 29, 27, 25, 24, 19, 18, 17, 16, 15, 11, 9, 8, 7, 6, 4, 2] 32 | NB_SUBSQUARE = len(SIZE_SUBSQUARE) 33 | 34 | #----------------------------------------------------------------------------- 35 | # Build the model 36 | #----------------------------------------------------------------------------- 37 | 38 | # Create model 39 | mdl = CpoModel() 40 | 41 | # Create array of variables for subsquares 42 | vx = [interval_var(size=SIZE_SUBSQUARE[i], name='X{}'.format(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)] 43 | vy = [interval_var(size=SIZE_SUBSQUARE[i], name='Y{}'.format(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)] 44 | 45 | # Create dependencies between variables 46 | for i in range(len(SIZE_SUBSQUARE)): 47 | for j in range(i): 48 | mdl.add( (end_of(vx[i]) <= start_of(vx[j])) | (end_of(vx[j]) <= start_of(vx[i])) 49 | | (end_of(vy[i]) <= start_of(vy[j])) | (end_of(vy[j]) <= start_of(vy[i]))) 50 | 51 | # To speed-up the search, create cumulative expressions on each dimension 52 | rx = sum([pulse(vx[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)]) 53 | mdl.add(always_in(rx, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE)) 54 | 55 | ry = sum([pulse(vy[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)]) 56 | mdl.add(always_in(ry, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE)) 57 | 58 | # Define search phases, also to speed-up the search 59 | mdl.set_search_phases([search_phase(vx), search_phase(vy)]) 60 | 61 | 62 | #----------------------------------------------------------------------------- 63 | # Solve the model and display the result 64 | #----------------------------------------------------------------------------- 65 | 66 | # Solve model 67 | print('Solving model...') 68 | res = mdl.solve(TimeLimit=20, LogPeriod=50000) 69 | print('Solution: ') 70 | res.print_solution() 71 | 72 | import docplex.cp.utils_visu as visu 73 | if res and visu.is_visu_enabled(): 74 | import matplotlib.pyplot as plt 75 | import matplotlib.cm as cm 76 | from matplotlib.patches import Polygon 77 | 78 | # Plot external square 79 | print('Plotting squares...') 80 | fig, ax = plt.subplots() 81 | plt.plot((0, 0), (0, SIZE_SQUARE), (SIZE_SQUARE, SIZE_SQUARE), (SIZE_SQUARE, 0)) 82 | for i in range(len(SIZE_SUBSQUARE)): 83 | # Display square i 84 | sx, sy = res.get_var_solution(vx[i]), res.get_var_solution(vy[i]) 85 | (sx1, sx2, sy1, sy2) = (sx.get_start(), sx.get_end(), sy.get_start(), sy.get_end()) 86 | poly = Polygon([(sx1, sy1), (sx1, sy2), (sx2, sy2), (sx2, sy1)], fc=cm.Set2(float(i) / len(SIZE_SUBSQUARE))) 87 | ax.add_patch(poly) 88 | # Display identifier of square i at its center 89 | ax.text(float(sx1 + sx2) / 2, float(sy1 + sy2) / 2, str(SIZE_SUBSQUARE[i]), ha='center', va='center') 90 | plt.margins(0) 91 | plt.show() 92 | -------------------------------------------------------------------------------- /examples/mp/callbacks/data/location.lp: -------------------------------------------------------------------------------- 1 | Minimize 2 | obj: cost 3 | Subject To 4 | c1: - cost + fixed + transport = 0 5 | c2: - fixed + 130 x1 + 150 x2 + 170 x3 + 180 x4 = 0 6 | c3: - transport 7 | + 10 y11 + 30 y12 + 25 y13 + 55 y14 8 | + 10 y21 + 25 y22 + 25 y23 + 45 y24 9 | + 20 y31 + 23 y32 + 30 y33 + 40 y34 10 | + 25 y41 + 10 y42 + 26 y43 + 40 y44 11 | + 28 y51 + 12 y52 + 20 y53 + 29 y54 12 | + 36 y61 + 19 y62 + 16 y63 + 22 y64 13 | + 40 y71 + 39 y72 + 22 y73 + 27 y74 14 | + 75 y81 + 65 y82 + 55 y83 + 35 y84 15 | + 34 y91 + 43 y92 + 41 y93 + 62 y94 = 0 16 | c4: 10 y11 + 10 y21 + 12 y31 + 15 y41 + 15 y51 + 15 y61 + 20 y71 + 25 y81 + 17 | 30 y91 - 90 x1 <= 0 18 | c5: 10 y12 + 10 y22 + 12 y32 + 15 y42 + 15 y52 + 15 y62 + 20 y72 + 25 y82 + 19 | 30 y92 - 110 x2 <= 0 20 | c6: 10 y13 + 10 y23 + 12 y33 + 15 y43 + 15 y53 + 15 y63 + 20 y73 + 25 y83 + 21 | 30 y93 - 130 x3 <= 0 22 | c7: 10 y14 + 10 y24 + 12 y34 + 15 y44 + 15 y54 + 15 y64 + 20 y74 + 25 y84 + 23 | 30 y94 - 150 x4 <= 0 24 | c8: y11 + y12 + y13 + y14 = 1 25 | c9: y21 + y22 + y23 + y24 = 1 26 | c10: y31 + y32 + y33 + y34 = 1 27 | c11: y41 + y42 + y43 + y44 = 1 28 | c12: y51 + y52 + y53 + y54 = 1 29 | c13: y61 + y62 + y63 + y64 = 1 30 | c14: y71 + y72 + y73 + y74 = 1 31 | c15: y81 + y82 + y83 + y84 = 1 32 | c16: y91 + y92 + y93 + y94 = 1 33 | c17: x1 - y11 >= 0 34 | c18: x1 - y21 >= 0 35 | c19: x1 - y31 >= 0 36 | c20: x1 - y41 >= 0 37 | c21: x1 - y51 >= 0 38 | c22: x1 - y61 >= 0 39 | c23: x1 - y71 >= 0 40 | c24: x1 - y81 >= 0 41 | c25: x1 - y91 >= 0 42 | c26: x2 - y12 >= 0 43 | c27: x2 - y22 >= 0 44 | c28: x2 - y32 >= 0 45 | c29: x2 - y42 >= 0 46 | c30: x2 - y52 >= 0 47 | c31: x2 - y62 >= 0 48 | c32: x2 - y72 >= 0 49 | c33: x2 - y82 >= 0 50 | c34: x2 - y92 >= 0 51 | c35: x3 - y13 >= 0 52 | c36: x3 - y23 >= 0 53 | c37: x3 - y33 >= 0 54 | c38: x3 - y43 >= 0 55 | c39: x3 - y53 >= 0 56 | c40: x3 - y63 >= 0 57 | c41: x3 - y73 >= 0 58 | c42: x3 - y83 >= 0 59 | c43: x3 - y93 >= 0 60 | c44: x4 - y14 >= 0 61 | c45: x4 - y24 >= 0 62 | c46: x4 - y34 >= 0 63 | c47: x4 - y44 >= 0 64 | c48: x4 - y54 >= 0 65 | c49: x4 - y64 >= 0 66 | c50: x4 - y74 >= 0 67 | c51: x4 - y84 >= 0 68 | c52: x4 - y94 >= 0 69 | Binaries 70 | x1 x2 x3 x4 71 | y11 y12 y13 y14 y21 y22 y23 y24 y31 y32 y33 y34 72 | y41 y42 y43 y44 y51 y52 y53 y54 y61 y62 y63 y64 73 | y71 y72 y73 y74 y81 y82 y83 y84 y91 y92 y93 y94 74 | End 75 | 76 | -------------------------------------------------------------------------------- /examples/mp/callbacks/heuristic_callback.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2018 5 | # -------------------------------------------------------------------------- 6 | 7 | # heuristic_callback.py - Use the heuristic callback 8 | # for optimizing a MIP problem 9 | # 10 | # To run this example, the user must specify a problem file. 11 | # 12 | # You can run this example at the command line by 13 | # 14 | # python heuristic_callback.py 15 | 16 | import sys 17 | 18 | from cplex.callbacks import HeuristicCallback 19 | 20 | from docplex.mp.callbacks.cb_mixin import * 21 | 22 | 23 | class RoundDown(ModelCallbackMixin, HeuristicCallback): 24 | def __init__(self, env): 25 | HeuristicCallback.__init__(self, env) 26 | ModelCallbackMixin.__init__(self) 27 | 28 | @print_called('--> calling my_round_down callback... #{0}') 29 | def __call__(self): 30 | feas = self.get_feasibilities() 31 | var_indices = [j for j, f in enumerate(feas) if f == self.feasibility_status.feasible] 32 | if var_indices: 33 | # this shows how to get back to the DOcplex variable from the index 34 | # but is not necessary for the logic. 35 | dvars = [self.index_to_var(v) for v in var_indices] 36 | print('* rounded vars = [{0}]'.format(', '.join([v.name for v in dvars[:3]]))) 37 | # -- calling set-solution in cplex callback class 38 | self.set_solution([var_indices, [0.0] * len(var_indices)]) 39 | 40 | 41 | def try_heuristic_cb_on_model(mdl): 42 | mdl.register_callback(RoundDown) 43 | # tweak cplex parameters 44 | mdl.parameters.mip.tolerances.mipgap = 1.0e-6 45 | mdl.parameters.mip.strategy.search = 0 46 | 47 | s = mdl.solve() 48 | assert s is not None 49 | 50 | mdl.report() 51 | return s 52 | 53 | 54 | def try_heuristic_cb_on_file(filename): 55 | from docplex.mp.model_reader import ModelReader 56 | mdl = ModelReader.read(filename) 57 | if mdl: 58 | return mdl, try_heuristic_cb_on_model(mdl) 59 | 60 | 61 | 62 | if __name__ == "__main__": 63 | if len(sys.argv) < 2: 64 | data_file = "data/location.lp" 65 | expected = 499 66 | elif len(sys.argv) == 2: 67 | data_file = sys.argv[1] 68 | expected = None 69 | else: 70 | print("Usage: heuristic_callback.py filename") 71 | print(" filename Name of a file, with .mps, .lp, or .sav") 72 | print(" extension, and a possible, additional .gz") 73 | print(" extension") 74 | sys.exit(-1) 75 | mdl, s = try_heuristic_cb_on_file(data_file) 76 | if expected: 77 | assert abs(s.objective_value - expected) <= 1 78 | mdl.end() 79 | -------------------------------------------------------------------------------- /examples/mp/callbacks/incumbent_callback.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2018 5 | # -------------------------------------------------------------------------- 6 | 7 | # This file shows how to connect CPLEX incumbent callbacks to a DOcplex model. 8 | # It is inspired from a blog article on Linear Programming: http://brg.a2hosted.com/?page_id=1316 9 | 10 | import cplex.callbacks as cpx_cb 11 | import cplex._internal._constants as cpxcst 12 | 13 | from docplex.mp.callbacks.cb_mixin import * 14 | from docplex.mp.model import Model 15 | 16 | 17 | class CustomIncumbentCallback(ModelCallbackMixin, cpx_cb.IncumbentCallback): 18 | 19 | incumbent_sources = { 20 | cpxcst.CPX_CALLBACK_MIP_INCUMBENT_NODESOLN: 'node', 21 | cpxcst.CPX_CALLBACK_MIP_INCUMBENT_HEURSOLN: 'heuristic', 22 | cpxcst.CPX_CALLBACK_MIP_INCUMBENT_USERSOLN: 'user', 23 | cpxcst.CPX_CALLBACK_MIP_INCUMBENT_MIPSTART: 'mipstart' 24 | } 25 | 26 | def __init__(self, env): 27 | # non public... 28 | cpx_cb.IncumbentCallback.__init__(self, env) 29 | ModelCallbackMixin.__init__(self) 30 | self.nb_incumbents = 0 31 | 32 | def __call__(self): 33 | self.nb_incumbents += 1 34 | obj = self.get_objective_value() 35 | src = self.get_solution_source() 36 | src_name = self.incumbent_sources.get(src, ' unknown???') 37 | print('{0}> found incumbent with objective value {1}, coming from: {2}'.format(self.nb_incumbents, obj, src_name)) 38 | 39 | 40 | # the circles are numbered as follows: 41 | # 42 | # 1 (1, 1) 43 | # 2 3 (2, 1) (2, 2) 44 | # 4 5 6 (3, 1) (3, 2) (3, 3) 45 | # .... 46 | def build_hearts(r, **kwargs): 47 | # initialize the model 48 | mdl = Model('love_hearts_%d' % r, **kwargs) 49 | 50 | # the dictionary of decision variables, one variable 51 | # for each circle with i in (1 .. r) as the row and 52 | # j in (1 .. i) as the position within the row 53 | idx = [(i, j) for i in range(1, r + 1) for j in range(1, i + 1)] 54 | a = mdl.binary_var_dict(idx, name=lambda idx_tuple: "a_%d_%d" % (idx_tuple[0], idx_tuple[1])) 55 | 56 | # the constraints - enumerate all equilateral triangles 57 | # and prevent any such triangles being formed by keeping 58 | # the number of included circles at its vertexes below 3 59 | 60 | # for each row except the last 61 | for i in range(1, r): 62 | # for each position in this row 63 | for j in range(1, i + 1): 64 | # for each triangle of side length (k) with its upper vertex at 65 | # (i, j) and its sides parallel to those of the overall shape 66 | for k in range(1, r - i + 1): 67 | # the sets of 3 points at the same distances clockwise along the 68 | # sides of these triangles form k equilateral triangles 69 | for m in range(k): 70 | u, v, w = (i + m, j), (i + k, j + m), (i + k - m, j + k - m) 71 | mdl.add_constraint(a[u] + a[v] + a[w] <= 2) 72 | 73 | mdl.maximize(mdl.sum(a)) 74 | return mdl 75 | 76 | 77 | if __name__ == "__main__": 78 | love = build_hearts(r=11) 79 | love.register_callback(CustomIncumbentCallback) 80 | 81 | love.parameters.mip.interval = 1 82 | 83 | s10 = love.solve(log_output=False) 84 | assert s10 is not None 85 | love.report() 86 | love.end() 87 | 88 | -------------------------------------------------------------------------------- /examples/mp/jupyter/nurses_data.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBMDecisionOptimization/docplex-examples/d5462342f16786915fa3f6f191b79f42a9080441/examples/mp/jupyter/nurses_data.xls -------------------------------------------------------------------------------- /examples/mp/modeling/diet.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2018 5 | # -------------------------------------------------------------------------- 6 | 7 | # The goal of the diet problem is to select a set of foods that satisfies 8 | # a set of daily nutritional requirements at minimal cost. 9 | # Source of data: http://www.neos-guide.org/content/diet-problem-solver 10 | 11 | from collections import namedtuple 12 | 13 | from docplex.mp.model import Model 14 | from docplex.util.environment import get_environment 15 | # ---------------------------------------------------------------------------- 16 | # Initialize the problem data 17 | # ---------------------------------------------------------------------------- 18 | 19 | FOODS = [ 20 | ("Roasted Chicken", 0.84, 0, 10), 21 | ("Spaghetti W/ Sauce", 0.78, 0, 10), 22 | ("Tomato,Red,Ripe,Raw", 0.27, 0, 10), 23 | ("Apple,Raw,W/Skin", .24, 0, 10), 24 | ("Grapes", 0.32, 0, 10), 25 | ("Chocolate Chip Cookies", 0.03, 0, 10), 26 | ("Lowfat Milk", 0.23, 0, 10), 27 | ("Raisin Brn", 0.34, 0, 10), 28 | ("Hotdog", 0.31, 0, 10) 29 | ] 30 | 31 | NUTRIENTS = [ 32 | ("Calories", 2000, 2500), 33 | ("Calcium", 800, 1600), 34 | ("Iron", 10, 30), 35 | ("Vit_A", 5000, 50000), 36 | ("Dietary_Fiber", 25, 100), 37 | ("Carbohydrates", 0, 300), 38 | ("Protein", 50, 100) 39 | ] 40 | 41 | FOOD_NUTRIENTS = [ 42 | ("Roasted Chicken", 277.4, 21.9, 1.8, 77.4, 0, 0, 42.2), 43 | ("Spaghetti W/ Sauce", 358.2, 80.2, 2.3, 3055.2, 11.6, 58.3, 8.2), 44 | ("Tomato,Red,Ripe,Raw", 25.8, 6.2, 0.6, 766.3, 1.4, 5.7, 1), 45 | ("Apple,Raw,W/Skin", 81.4, 9.7, 0.2, 73.1, 3.7, 21, 0.3), 46 | ("Grapes", 15.1, 3.4, 0.1, 24, 0.2, 4.1, 0.2), 47 | ("Chocolate Chip Cookies", 78.1, 6.2, 0.4, 101.8, 0, 9.3, 0.9), 48 | ("Lowfat Milk", 121.2, 296.7, 0.1, 500.2, 0, 11.7, 8.1), 49 | ("Raisin Brn", 115.1, 12.9, 16.8, 1250.2, 4, 27.9, 4), 50 | ("Hotdog", 242.1, 23.5, 2.3, 0, 0, 18, 10.4) 51 | ] 52 | 53 | Food = namedtuple("Food", ["name", "unit_cost", "qmin", "qmax"]) 54 | Nutrient = namedtuple("Nutrient", ["name", "qmin", "qmax"]) 55 | 56 | 57 | # ---------------------------------------------------------------------------- 58 | # Build the model 59 | # ---------------------------------------------------------------------------- 60 | 61 | 62 | def build_diet_model(mdl, **kwargs): 63 | ints = kwargs.pop('ints', False) 64 | 65 | # Create tuples with named fields for foods and nutrients 66 | foods = [Food(*f) for f in FOODS] 67 | nutrients = [Nutrient(*row) for row in NUTRIENTS] 68 | 69 | food_nutrients = {(fn[0], nutrients[n].name): 70 | fn[1 + n] for fn in FOOD_NUTRIENTS for n in range(len(NUTRIENTS))} 71 | 72 | # Decision variables, limited to be >= Food.qmin and <= Food.qmax 73 | ftype = mdl.integer_vartype if ints else mdl.continuous_vartype 74 | qty = mdl.var_dict(foods, ftype, lb=lambda f: f.qmin, ub=lambda f: f.qmax, name=lambda f: "q_%s" % f.name) 75 | 76 | # Limit range of nutrients, and mark them as KPIs 77 | for n in nutrients: 78 | amount = mdl.sum(qty[f] * food_nutrients[f.name, n.name] for f in foods) 79 | mdl.add_range(n.qmin, amount, n.qmax) 80 | mdl.add_kpi(amount, publish_name="Total %s" % n.name) 81 | 82 | # Minimize cost 83 | total_cost = mdl.sum(qty[f] * f.unit_cost for f in foods) 84 | mdl.add_kpi(total_cost, 'Total cost') 85 | 86 | # add a functional KPI , taking a model and a solution as argument 87 | # this KPI counts the number of foods used. 88 | def nb_products(mdl_, s_): 89 | qvs = mdl_.find_matching_vars(pattern="q_") 90 | return sum(1 for qv in qvs if s_[qv] >= 1e-5) 91 | 92 | mdl.add_kpi(nb_products, 'Nb foods') 93 | mdl.minimize(total_cost) 94 | 95 | return mdl 96 | 97 | 98 | # ---------------------------------------------------------------------------- 99 | # Solve the model and display the result 100 | # ---------------------------------------------------------------------------- 101 | 102 | if __name__ == '__main__': 103 | with Model(name="diet", log_output=True, float_precision=6) as mdl: 104 | build_diet_model(mdl, ints=True) 105 | mdl.print_information() 106 | 107 | s = mdl.solve() 108 | if s: 109 | qty_vars = mdl.find_matching_vars(pattern="q_") 110 | for fv in qty_vars: 111 | food_name = fv.name[2:] 112 | print("Buy {0:<25} = {1:9.6g}".format(food_name, fv.solution_value)) 113 | 114 | mdl.report_kpis() 115 | # Save the CPLEX solution as "solution.json" program output 116 | with get_environment().get_output_stream("solution.json") as fp: 117 | mdl.solution.export(fp, "json") 118 | else: 119 | print("* model has no solution") 120 | -------------------------------------------------------------------------------- /examples/mp/modeling/production.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2018 5 | # -------------------------------------------------------------------------- 6 | 7 | """The model aims at minimizing the production cost for a number of products 8 | while satisfying customer demand. Each product can be produced either inside 9 | the company or outside, at a higher cost. 10 | 11 | The inside production is constrained by the company's resources, while outside 12 | production is considered unlimited. 13 | 14 | The model first declares the products and the resources. 15 | The data consists of the description of the products (the demand, the inside 16 | and outside costs, and the resource consumption) and the capacity of the 17 | various resources. 18 | 19 | The variables for this problem are the inside and outside production for each 20 | product. 21 | """ 22 | 23 | from docplex.mp.model import Model 24 | from docplex.util.environment import get_environment 25 | 26 | 27 | # ---------------------------------------------------------------------------- 28 | # Initialize the problem data 29 | # ---------------------------------------------------------------------------- 30 | PRODUCTS = [("kluski", 100, 0.6, 0.8), 31 | ("capellini", 200, 0.8, 0.9), 32 | ("fettucine", 300, 0.3, 0.4)] 33 | 34 | # resources are a list of simple tuples (name, capacity) 35 | RESOURCES = [("flour", 20), 36 | ("eggs", 40)] 37 | 38 | CONSUMPTIONS = {("kluski", "flour"): 0.5, 39 | ("kluski", "eggs"): 0.2, 40 | ("capellini", "flour"): 0.4, 41 | ("capellini", "eggs"): 0.4, 42 | ("fettucine", "flour"): 0.3, 43 | ("fettucine", "eggs"): 0.6} 44 | 45 | 46 | # ---------------------------------------------------------------------------- 47 | # Build the model 48 | # ---------------------------------------------------------------------------- 49 | def build_production_problem(mdl, products, resources, consumptions, **kwargs): 50 | """ Takes as input: 51 | - a list of product tuples (name, demand, inside, outside) 52 | - a list of resource tuples (name, capacity) 53 | - a list of consumption tuples (product_name, resource_named, consumed) 54 | """ 55 | # --- decision variables --- 56 | mdl.inside_vars = mdl.continuous_var_dict(products, name=lambda p: 'inside_%s' % p[0]) 57 | mdl.outside_vars = mdl.continuous_var_dict(products, name=lambda p: 'outside_%s' % p[0]) 58 | 59 | # --- constraints --- 60 | # demand satisfaction 61 | mdl.add_constraints((mdl.inside_vars[prod] + mdl.outside_vars[prod] >= prod[1], 'ct_demand_%s' % prod[0]) for prod in products) 62 | 63 | # --- resource capacity --- 64 | mdl.add_constraints((mdl.sum(mdl.inside_vars[p] * consumptions[p[0], res[0]] for p in products) <= res[1], 65 | 'ct_res_%s' % res[0]) for res in resources) 66 | 67 | # --- objective --- 68 | mdl.total_inside_cost = mdl.sum(mdl.inside_vars[p] * p[2] for p in products) 69 | mdl.add_kpi(mdl.total_inside_cost, "inside cost") 70 | mdl.total_outside_cost = mdl.sum(mdl.outside_vars[p] * p[3] for p in products) 71 | mdl.add_kpi(mdl.total_outside_cost, "outside cost") 72 | mdl.minimize(mdl.total_inside_cost + mdl.total_outside_cost) 73 | return mdl 74 | 75 | 76 | def print_production_solution(mdl, products): 77 | obj = mdl.objective_value 78 | print("* Production model solved with objective: {:g}".format(obj)) 79 | print("* Total inside cost=%g" % mdl.total_inside_cost.solution_value) 80 | for p in products: 81 | print("Inside production of {product}: {ins_var}".format 82 | (product=p[0], ins_var=mdl.inside_vars[p].solution_value)) 83 | print("* Total outside cost=%g" % mdl.total_outside_cost.solution_value) 84 | for p in products: 85 | print("Outside production of {product}: {out_var}".format 86 | (product=p[0], out_var=mdl.outside_vars[p].solution_value)) 87 | 88 | def build_default_production_problem(**kwargs): 89 | mdl = Model( **kwargs) 90 | return build_production_problem(mdl, PRODUCTS, RESOURCES, CONSUMPTIONS) 91 | # ---------------------------------------------------------------------------- 92 | # Solve the model and display the result 93 | # ---------------------------------------------------------------------------- 94 | if __name__ == '__main__': 95 | # Build the model 96 | with Model(name='production') as model: 97 | model = build_production_problem(model, PRODUCTS, RESOURCES, CONSUMPTIONS) 98 | model.print_information() 99 | # Solve the model. 100 | if model.solve(): 101 | print_production_solution(model, PRODUCTS) 102 | # Save the CPLEX solution as "solution.json" program output 103 | with get_environment().get_output_stream("solution.json") as fp: 104 | model.solution.export(fp, "json") 105 | else: 106 | print("Problem has no solution") 107 | 108 | -------------------------------------------------------------------------------- /examples/mp/modeling/sailcopw.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- 2 | # Source file provided under Apache License, Version 2.0, January 2004, 3 | # http://www.apache.org/licenses/ 4 | # (c) Copyright IBM Corp. 2015, 2018 5 | # -------------------------------------------------------------------------- 6 | 7 | 8 | from docplex.mp.model import Model 9 | from docplex.util.environment import get_environment 10 | 11 | 12 | # The company Sailco must determine how many sailboats to produce over several time periods, 13 | # while satisfying demand and minimizing costs. 14 | # The demand for the periods is known and an inventory of boats is available initially. 15 | # In each period, Sailco can produce boats inside at a fixed cost per boat. 16 | # Additional boats can be produced outside at a higher cost per boat. 17 | # There is an inventory cost per boat per period. 18 | # The business objective is to minimize the overall cost, which is the sum of the 19 | # production cost and inventory cost. 20 | # The production cost is modeled using a *piecewise-linear* function. 21 | 22 | # ---------------------------------------------------------------------------- 23 | # Initialize the problem data 24 | # ---------------------------------------------------------------------------- 25 | nb_periods = 4 26 | demand = {1: 40, 2: 60, 3: 75, 4: 25} 27 | 28 | regular_cost = 400 29 | capacity = 40 30 | extra_cost = 450 31 | 32 | initial_inventory = 10 33 | inventory_cost = 20 34 | 35 | # ---------------------------------------------------------------------------- 36 | # Build the model 37 | # ---------------------------------------------------------------------------- 38 | 39 | def build_default_sailcopw_model(**kwargs): 40 | mdl = Model("sailcopw") 41 | return build_sailcopw_model(mdl, **kwargs) 42 | 43 | def build_sailcopw_model(mdl, **kwargs): 44 | periods0 = range(nb_periods + 1) 45 | periods1 = range(1, nb_periods + 1) 46 | 47 | boats = mdl.continuous_var_dict(periods1, name="boat") 48 | # full range from 0 to nb_periods 49 | inv = mdl.continuous_var_dict(periods0, name="inv") 50 | 51 | # --- 52 | # piecewise cost: 53 | # up to zero boat cost is zero. 54 | # up to capacity, each boat costs the regular cost 55 | # above capacity, unit cost is extra cost (higher than regular cost...) 56 | pwc = mdl.piecewise(preslope=0, breaksxy=[(0,0), (capacity, capacity * regular_cost)], postslope=extra_cost) 57 | total_pw_cost = mdl.sum(pwc(boats[t]) for t in periods1) 58 | mdl.add_kpi(total_pw_cost, "Total piecewise cost") 59 | total_inventory_cost = inventory_cost * mdl.sum(inv[t1] for t1 in periods1) 60 | mdl.add_kpi(total_inventory_cost, 'Total inventory cost') 61 | 62 | mdl.minimize(total_pw_cost + total_inventory_cost) 63 | 64 | # initial inventory 65 | mdl.add_constraint(inv[0] == initial_inventory) 66 | # balance 67 | mdl.add_constraints([boats[t] + inv[t - 1] == inv[t] + demand.get(t,0) for t in periods1]) 68 | 69 | return mdl 70 | 71 | # ---------------------------------------------------------------------------- 72 | # Solve the model and display the result 73 | # ---------------------------------------------------------------------------- 74 | 75 | if __name__ == '__main__': 76 | with Model(name="sailcopw") as sailm: 77 | build_sailcopw_model(sailm) 78 | s = sailm.solve(log_output=True) 79 | if s: 80 | sailm.report() 81 | sailm.print_solution() 82 | 83 | # Save the CPLEX solution as "solution.json" program output 84 | with get_environment().get_output_stream("solution.json") as fp: 85 | sailm.solution.export(fp, "json") 86 | else: 87 | print("Problem has no solution") 88 | -------------------------------------------------------------------------------- /info.json: -------------------------------------------------------------------------------- 1 | { 2 | "provider": ["IBM"], 3 | "name": "Decision Optimization Modeling for Python (DOcplex) samples" , 4 | "model": [ "CPLEX", "CPO" ], 5 | "development": [ "Python" ], 6 | "category": [ {"MODELING":["ADVANCED MODELING"]} ], 7 | "industry": [ "Operational research" ], 8 | "abstract": "These samples demonstrate how to use the DOcplex library to model and solve optimization problems." 9 | } --------------------------------------------------------------------------------