-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
630 additions
and
71 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# -------------------------------------------------------------------------- | ||
# Source file provided under Apache License, Version 2.0, January 2004, | ||
# http://www.apache.org/licenses/ | ||
# (c) Copyright IBM Corp. 2015, 2016 | ||
# -------------------------------------------------------------------------- | ||
|
||
""" | ||
In mathematics, a Golomb ruler is a set of marks at integer positions along | ||
an imaginary ruler such that no two pairs of marks are the same distance apart. | ||
The number of marks on the ruler is its order, and the largest distance | ||
between two of its marks is its length. | ||
This implementation differs from the 'basic' implementation, given in the | ||
examp;e module golomb_ruler.py, because it calls the solver twice: | ||
* First time to know the minimal size of the ruler for the required order, | ||
* A second time to list all possible rulers for this optimal size | ||
See https://en.wikipedia.org/wiki/Golomb_ruler for more information. | ||
For order 5: 2 solutions: 0 1 4 9 11 | ||
0 2 7 8 11 | ||
For order 7: 6 solutions: 0 1 4 10 18 23 25 | ||
0 1 7 11 20 23 25 | ||
0 1 11 16 19 23 25 | ||
0 2 3 10 16 21 25 | ||
0 2 7 13 21 22 25 | ||
Please refer to documentation for appropriate setup of solving configuration. | ||
""" | ||
|
||
|
||
from docplex.cp.model import * | ||
from sys import stdout | ||
|
||
# Set model parameters | ||
ORDER = 7 # Number of marks | ||
MAX_LENGTH = (ORDER - 1) ** 2 # Max rule length | ||
|
||
# Create model | ||
mdl = CpoModel() | ||
|
||
# Create array of variables corresponding to position rule marks | ||
marks = integer_var_list(ORDER, 0, MAX_LENGTH, "M") | ||
|
||
# Create marks distances that should be all different | ||
dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)] | ||
mdl.add(all_diff(dist)) | ||
|
||
# Avoid symmetric solutions by ordering marks | ||
mdl.add(marks[0] == 0) | ||
for i in range(1, ORDER): | ||
mdl.add(marks[i] > marks[i - 1]) | ||
|
||
# Avoid mirror solution | ||
mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2])) | ||
|
||
# Minimize ruler size (position of the last mark) | ||
minexpr = minimize(marks[ORDER - 1]) | ||
mdl.add(minexpr) | ||
|
||
# First solve the model to find the smallest ruler length | ||
msol = mdl.solve() | ||
if not msol: | ||
print("No Golomb ruler available for order " + str(ORDER)) | ||
else: | ||
rsize = msol[marks[ORDER - 1]] | ||
print("Shortest ruler for order " + str(ORDER) + " has length " + str(rsize)) | ||
# Remove minimization from the model | ||
mdl.remove(minexpr) | ||
# Force position of last mark | ||
mdl.add(marks[ORDER - 1] == rsize) | ||
|
||
# Request all solutions | ||
print("List of all possible rulers for length {}:".format(rsize)) | ||
solver = CpoSolver(mdl, SearchType='DepthFirst', Workers=1) # Parameters needed to avoid duplicate solutions | ||
try: | ||
for i, msol in enumerate(solver): | ||
stdout.write(str(i + 1) + ": ") | ||
for v in marks: | ||
stdout.write(" " + str(msol[v])) | ||
stdout.write("\n") | ||
except CpoNotSupportedException: | ||
print("This instance of the solver does not support solution iteration.") |
117 changes: 117 additions & 0 deletions
117
examples/cp/basic/plant_location_with_starting_point.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# -------------------------------------------------------------------------- | ||
# Source file provided under Apache License, Version 2.0, January 2004, | ||
# http://www.apache.org/licenses/ | ||
# (c) Copyright IBM Corp. 2015, 2016 | ||
# -------------------------------------------------------------------------- | ||
|
||
""" | ||
A ship-building company has a certain number of customers. Each customer is supplied | ||
by exactly one plant. In turn, a plant can supply several customers. The problem is | ||
to decide where to set up the plants in order to supply every customer while minimizing | ||
the cost of building each plant and the transportation cost of supplying the customers. | ||
For each possible plant location there is a fixed cost and a production capacity. | ||
Both take into account the country and the geographical conditions. | ||
For every customer, there is a demand and a transportation cost with respect to | ||
each plant location. | ||
While a first solution of this problem can be found easily by CP Optimizer, it can take | ||
quite some time to improve it to a very good one. We illustrate the warm start capabilities | ||
of CP Optimizer by giving a good starting point solution that CP Optimizer will try to improve. | ||
This solution could be one from an expert or the result of another optimization engine | ||
applied to the problem. | ||
In the solution we only give a value to the variables that determine which plant delivers | ||
a customer. This is sufficient to define a complete solution on all model variables. | ||
CP Optimizer first extends the solution to all variables and then starts to improve it. | ||
Please refer to documentation for appropriate setup of solving configuration. | ||
""" | ||
|
||
from docplex.cp.model import * | ||
from collections import deque | ||
|
||
############################################################################## | ||
# Initialize model data | ||
############################################################################## | ||
|
||
# Read data from file | ||
filename = os.path.dirname(os.path.abspath(__file__)) + "/data/plant_location.data" | ||
data = deque() | ||
with open(filename, "r") as file: | ||
for val in file.read().split(): | ||
data.append(int(val)) | ||
|
||
# Initialize main dimensions | ||
nbCustomer = data.popleft() | ||
nbLocation = data.popleft() | ||
|
||
# Initialize cost. cost[c][p] = cost to deliver customer c from plant p | ||
cost = list([list([data.popleft() for l in range(nbLocation)]) for c in range(nbCustomer)]) | ||
|
||
# Initialize demand of each customer | ||
demand = list([data.popleft() for c in range(nbCustomer)]) | ||
|
||
# Initialize fixed cost of each location | ||
fixedCost = list([data.popleft() for p in range(nbLocation)]) | ||
|
||
# Initialize capacity of each location | ||
capacity = list([data.popleft() for p in range(nbLocation)]) | ||
|
||
|
||
############################################################################## | ||
# Create the model | ||
############################################################################## | ||
|
||
mdl = CpoModel() | ||
|
||
# Create variables identifying which location serves each customer | ||
cust = integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") | ||
|
||
# Create variables indicating which plant location is open | ||
open = integer_var_list(nbLocation, 0, 1, "OpenLocation") | ||
|
||
# Create variables indicating load of each plant | ||
load = [integer_var(0, capacity[p], "PlantLoad_" + str(p)) for p in range(nbLocation)] | ||
|
||
# Associate plant openness to its load | ||
for p in range(nbLocation): | ||
mdl.add(open[p] == (load[p] > 0)) | ||
|
||
# Add constraints | ||
mdl.add(pack(load, cust, demand)) | ||
|
||
# Add objective | ||
obj = scal_prod(fixedCost, open) | ||
for c in range(nbCustomer): | ||
obj += element(cust[c], cost[c]) | ||
mdl.add(minimize(obj)) | ||
|
||
|
||
############################################################################## | ||
# Solve the model | ||
############################################################################## | ||
|
||
# Solve without starting point | ||
print("Solve the model with no starting point") | ||
msol = mdl.solve(TimeLimit=10) | ||
print(" Objective value: " + str(msol.get_objective_values()[0])) | ||
|
||
# Solve with starting point | ||
print("Solve the model with starting point") | ||
custValues = [19, 0, 11, 8, 29, 9, 29, 28, 17, 15, 7, 9, 18, 15, 1, 17, 25, 18, 17, 27, | ||
22, 1, 26, 3, 22, 2, 20, 27, 2, 16, 1, 16, 12, 28, 19, 2, 20, 14, 13, 27, | ||
3, 9, 18, 0, 13, 19, 27, 14, 12, 1, 15, 14, 17, 0, 7, 12, 11, 0, 25, 16, | ||
22, 13, 16, 8, 18, 27, 19, 23, 26, 13, 11, 11, 19, 22, 28, 26, 23, 3, 18, 23, | ||
26, 14, 29, 18, 9, 7, 12, 27, 8, 20] | ||
sp = CpoModelSolution() | ||
for c in range(nbCustomer): | ||
sp.add_integer_var_solution(cust[c], custValues[c]) | ||
mdl.set_starting_point(sp) | ||
|
||
try: | ||
msol = mdl.solve(TimeLimit=10) | ||
print(" Objective value: " + str(msol.get_objective_values()[0])) | ||
except: | ||
print(" Starting point is available only with CPO 13 and later.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.