Skip to content

Commit 2dbbc1f

Browse files
committed
2.2.34
1 parent f190089 commit 2dbbc1f

13 files changed

+7084
-47
lines changed

examples/cp/basic/facility.py

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
# --------------------------------------------------------------------------
66

77
"""
8-
A company has 10 stores. Each store must be supplied by one warehouse. The
9-
company has five possible locations where it has property and can build a
10-
supplier warehouse: Bonn, Bordeaux, London, Paris, and Rome. The warehouse
11-
locations have different capacities. A warehouse built in Bordeaux or Rome
12-
could supply only one store. A warehouse built in London could supply two
13-
stores; a warehouse built in Bonn could supply three stores; and a warehouse
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
1416
built in Paris could supply four stores.
1517
1618
The supply costs vary for each store, depending on which warehouse is the
@@ -26,24 +28,38 @@
2628
Please refer to documentation for appropriate setup of solving configuration.
2729
"""
2830

29-
from docplex.cp.model import *
31+
from docplex.cp.model import CpoModel
32+
from collections import namedtuple
3033

3134
##############################################################################
3235
## Problem data
3336
##############################################################################
3437

35-
nbLocations = 5
36-
nbStores = 8
37-
capacity = (3, 1, 2, 4, 1)
38-
fixedCost = (480, 200, 320, 340, 300)
39-
cost = ((24, 74, 31, 51, 84),
40-
(57, 54, 86, 61, 68),
41-
(57, 67, 29, 91, 71),
42-
(54, 54, 65, 82, 94),
43-
(98, 81, 16, 61, 27),
44-
(13, 92, 34, 94, 87),
45-
(54, 72, 41, 12, 78),
46-
(54, 64, 65, 89, 89))
38+
Warehouse = namedtuple('Wharehouse', ('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))
4763

4864

4965
##############################################################################
@@ -53,21 +69,28 @@
5369
# Create CPO model
5470
mdl = CpoModel()
5571

56-
supplier = integer_var_list(nbStores, 0, nbLocations - 1, "supplier")
57-
open = integer_var_list(nbLocations, 0, 1, "open")
58-
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
5980
for s in supplier:
60-
mdl.add(element(open, s) == 1)
81+
mdl.add(mdl.element(open, s) == 1)
6182

62-
for j in range(nbLocations):
63-
mdl.add(count(supplier, j) <= capacity[j])
64-
65-
obj = scal_prod(open, fixedCost)
66-
for i in range(nbStores):
67-
obj = obj + element(supplier[i], cost[i])
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)
6886

69-
# Add minimization objective
70-
mdl.add(minimize(obj))
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))
7194

7295

7396
##############################################################################
@@ -77,4 +100,14 @@
77100
# Solve model
78101
print("\nSolving model....")
79102
msol = mdl.solve(TimeLimit=10)
80-
msol.print_solution()
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.")

examples/cp/basic/golomb_ruler_all_solutions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@
7272

7373
# Request all solutions
7474
print("List of all possible rulers for length {}:".format(rsize))
75-
solver = CpoSolver(mdl, SearchType='DepthFirst', Workers=1, TimeLimit=100) # Parameters needed to avoid duplicate solutions
75+
siter = mdl.start_search(SearchType='DepthFirst', Workers=1, TimeLimit=100) # Parameters needed to avoid duplicate solutions
7676
try:
77-
for i, msol in enumerate(solver):
77+
for i, msol in enumerate(siter):
7878
stdout.write(str(i + 1) + ": ")
7979
for v in marks:
8080
stdout.write(" " + str(msol[v]))

examples/cp/jupyter/house_building.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"<ul>\n",
8181
"<li> Scheduling consists of assigning starting and completion times to a set of activities while satisfying different types of constraints (resource availability, precedence relationships, … ) and optimizing some criteria (minimizing tardiness, …)\n",
8282
"<!-- <img src = \"./house_building_utils/activity.png\" > -->\n",
83-
"<img src = \"https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/cp/jupyter/house_building_utils/activity.PNG?raw=true\" >\n",
83+
"<img src = \"https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/cp/jupyter/house_building_utils/activity.PNG?raw=true \" >\n",
8484
"<li> Time is considered as a continuous dimension: domain of possible start/completion times for an activity is potentially very large\n",
8585
"<li>Beside start and completion times of activities, other types of decision variables are often involved in real industrial scheduling problems (resource allocation, optional activities …)\n",
8686
"</ul>"
@@ -715,9 +715,9 @@
715715
"<li> Absent interval variables are ignored.\n",
716716
"<li>It is possible to constrain minimum delays between intervals using transition matrix.\n",
717717
"<li>It is possible to constraint the first, last in the sequence or next or preceding interval\n",
718+
"</ul>\n",
718719
"<!-- <img src = \"./house_building_utils/noOverlap.png\" > -->\n",
719-
"<img src = \"https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/cp/jupyter/house_building_utils/noOverlap.PNG?raw=true\" >\n",
720-
"</ul>"
720+
"<img src = \"https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/cp/jupyter/house_building_utils/noOverlap.PNG?raw=true\" >"
721721
]
722722
},
723723
{

0 commit comments

Comments
 (0)