Skip to content

Commit 375f12a

Browse files
committed
updated to 2.9.141
1 parent 3f8d04b commit 375f12a

34 files changed

+2705
-1173
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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, 2016, 2018
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+
from docplex.cp.config import context
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+
if compare_natural(context.model.version, '12.9') >= 0:
103+
mdl.add_kpi(mdl.sum(demand) / mdl.scal_prod(open, capacity), "Occupancy")
104+
mdl.add_kpi(mdl.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+
# Solve the model
112+
print("Solve the model")
113+
msol = mdl.solve(TimeLimit=10, trace_log=False) # Set trace_log=True to have a real-time view of the KPIs
114+
if msol:
115+
print(" Objective value: {}".format(msol.get_objective_values()[0]))
116+
if context.model.version >= '12.9':
117+
print(" KPIs: {}".format(msol.get_kpis()))
118+
else:
119+
print(" No solution")
120+

0 commit comments

Comments
 (0)