reindent python examples, polish a few of thems
This commit is contained in:
@@ -74,21 +74,21 @@ def main(sol='CBC'):
|
||||
]
|
||||
|
||||
# distance
|
||||
d = [[M, 1, M, M, M, M, M, M, 1, M, M, M, M, M,
|
||||
M], [M, M, 1, M, M, M, M, M, M, M, M, M, M, M,
|
||||
M], [M, M, M, 1, M, M, M, M, 1, M, M, M, M, M,
|
||||
M], [M, M, M, M, 1, M, M, M, M, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, 1, M, M, 1, M, M, M, M, M,
|
||||
M], [M, M, M, M, M, M, 1, M, M, M, M, M, M, M,
|
||||
M], [M, M, M, M, M, M, M, 1, 1, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, M, M, M,
|
||||
1], [M, M, M, M, M, M, M, M, M, 1, M, M, M, M,
|
||||
M], [M, 1, M, M, M, M, M, M, M, M, 1, M, M, M, M],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, 1, M, M,
|
||||
M], [M, 1, M, M, M, M, M, M, M, M, M, M, 1, M,
|
||||
M], [M, M, M, M, M, M, M, M, M, M, M, M, M, 1, M], [
|
||||
M, 1, M, M, M, M, M, M, M, M, M, M, M, M, 1
|
||||
], [M, M, M, M, M, M, M, M, M, M, M, M, M, M, M]]
|
||||
d = [[M, 1, M, M, M, M, M, M, 1, M, M, M, M, M, M],
|
||||
[M, M, 1, M, M, M, M, M, M, M, M, M, M, M, M],
|
||||
[M, M, M, 1, M, M, M, M, 1, M, M, M, M, M, M],
|
||||
[M, M, M, M, 1, M, M, M, M, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, 1, M, M, 1, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, M, 1, M, M, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, M, M, 1, 1, M, M, M, M, M, M],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, M, M, M, 1],
|
||||
[M, M, M, M, M, M, M, M, M, 1, M, M, M, M, M],
|
||||
[M, 1, M, M, M, M, M, M, M, M, 1, M, M, M, M],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, 1, M, M, M],
|
||||
[M, 1, M, M, M, M, M, M, M, M, M, M, 1, M, M],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, M, M, 1, M],
|
||||
[M, 1, M, M, M, M, M, M, M, M, M, M, M, M, 1],
|
||||
[M, M, M, M, M, M, M, M, M, M, M, M, M, M, M]]
|
||||
|
||||
#
|
||||
# variables
|
||||
|
||||
@@ -117,8 +117,8 @@ def regular(x, Q, S, d, q0, F):
|
||||
solver.Add(x[i] <= S)
|
||||
|
||||
# Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
|
||||
solver.Add(a[i + 1] == solver.Element(d2_flatten, (
|
||||
(a[i]) * S) + (x[i] - 1)))
|
||||
solver.Add(
|
||||
a[i + 1] == solver.Element(d2_flatten, ((a[i]) * S) + (x[i] - 1)))
|
||||
|
||||
|
||||
def main(n):
|
||||
|
||||
@@ -91,9 +91,9 @@ def main(problem_str="SEND+MORE=MONEY", base=10):
|
||||
this_len = len(prob)
|
||||
|
||||
# sum all the digits with proper exponents to a number
|
||||
solver.Add(sums[ix] == solver.Sum([(base**i) *
|
||||
x[lookup[prob[this_len - i - 1]]]
|
||||
for i in range(this_len)[::-1]]))
|
||||
solver.Add(
|
||||
sums[ix] == solver.Sum([(base**i) * x[lookup[prob[this_len - i - 1]]]
|
||||
for i in range(this_len)[::-1]]))
|
||||
# leading digits must be > 0
|
||||
solver.Add(x[lookup[prob[0]]] > 0)
|
||||
ix += 1
|
||||
|
||||
@@ -28,6 +28,7 @@ PARSER.add_argument(
|
||||
PARSER.add_argument(
|
||||
'--num_workers', default=98, type=int, help='Maximum number of workers.')
|
||||
|
||||
|
||||
def find_combinations(durations, load_min, load_max, commute_time):
|
||||
"""This methods find all valid combinations of appointments.
|
||||
|
||||
@@ -39,6 +40,7 @@ def find_combinations(durations, load_min, load_max, commute_time):
|
||||
load_min: The min number of worked minutes for a valid selection.
|
||||
load_max: The max number of worked minutes for a valid selection.
|
||||
commute_time: The commute time between two appointments in minutes.
|
||||
|
||||
Returns:
|
||||
A matrix where each line is a valid combinations of appointments.
|
||||
"""
|
||||
@@ -59,6 +61,7 @@ def find_combinations(durations, load_min, load_max, commute_time):
|
||||
solver.EndSearch()
|
||||
return results
|
||||
|
||||
|
||||
def select(combinations, loads, max_number_of_workers):
|
||||
"""This method selects the optimal combination of appointments.
|
||||
|
||||
@@ -110,10 +113,11 @@ def select(combinations, loads, max_number_of_workers):
|
||||
]
|
||||
return -1, []
|
||||
|
||||
|
||||
def get_optimal_schedule(demand, args):
|
||||
"""Computes the optimal schedule for the appointment selection problem."""
|
||||
combinations = find_combinations([a[2] for a in demand], args.load_min,
|
||||
args.load_max, args.commute_time)
|
||||
args.load_max, args.commute_time)
|
||||
print('found %d possible combinations of appointements' % len(combinations))
|
||||
|
||||
cost, selection = select(combinations, [a[0] for a in demand],
|
||||
@@ -125,6 +129,7 @@ def get_optimal_schedule(demand, args):
|
||||
if selection[i] != 0]
|
||||
return cost, output
|
||||
|
||||
|
||||
def main(args):
|
||||
demand = [(40, 'A1', 90), (30, 'A2', 120), (25, 'A3', 180)]
|
||||
print('appointments: ')
|
||||
@@ -140,5 +145,6 @@ def main(args):
|
||||
for t in template[1]:
|
||||
print(' %d installation of type %s' % (t[0], t[1]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(PARSER.parse_args())
|
||||
|
||||
@@ -43,6 +43,7 @@ from __future__ import print_function
|
||||
import sys
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
||||
|
||||
def main(sol='CBC'):
|
||||
|
||||
# Create the solver.
|
||||
@@ -80,10 +81,9 @@ def main(sol='CBC'):
|
||||
# Optimal solution is 76
|
||||
# """
|
||||
c = [[13, 21, 20, 12, 8, 26, 22, 11], [12, 36, 25, 41, 40, 11, 4, 8],
|
||||
[35, 32, 13, 36, 26, 21, 13, 37], [34, 54, 7, 8, 12, 22, 11,
|
||||
40], [21, 6, 45, 18, 24, 34, 12, 48],
|
||||
[42, 19, 39, 15, 14, 16, 28, 46], [16, 34, 38, 3, 34, 40, 22,
|
||||
24], [26, 20, 5, 17, 45, 31, 37, 43]]
|
||||
[35, 32, 13, 36, 26, 21, 13, 37], [34, 54, 7, 8, 12, 22, 11, 40],
|
||||
[21, 6, 45, 18, 24, 34, 12, 48], [42, 19, 39, 15, 14, 16, 28, 46],
|
||||
[16, 34, 38, 3, 34, 40, 22, 24], [26, 20, 5, 17, 45, 31, 37, 43]]
|
||||
|
||||
#
|
||||
# variables
|
||||
|
||||
@@ -17,11 +17,11 @@ from ortools.sat.python import cp_model
|
||||
|
||||
def main():
|
||||
# Instantiate a cp model.
|
||||
cost = [[90, 76, 75, 70, 50, 74, 12, 68], [35, 85, 55, 65, 48, 101, 70, 83], [
|
||||
125, 95, 90, 105, 59, 120, 36, 73
|
||||
], [45, 110, 95, 115, 104, 83, 37, 71], [60, 105, 80, 75, 59, 62, 93, 88], [
|
||||
45, 65, 110, 95, 47, 31, 81, 34
|
||||
], [38, 51, 107, 41, 69, 99, 115, 48], [47, 85, 57, 71, 92, 77, 109, 36],
|
||||
cost = [[90, 76, 75, 70, 50, 74, 12, 68], [35, 85, 55, 65, 48, 101, 70, 83],
|
||||
[125, 95, 90, 105, 59, 120, 36, 73],
|
||||
[45, 110, 95, 115, 104, 83, 37, 71],
|
||||
[60, 105, 80, 75, 59, 62, 93, 88], [45, 65, 110, 95, 47, 31, 81, 34],
|
||||
[38, 51, 107, 41, 69, 99, 115, 48], [47, 85, 57, 71, 92, 77, 109, 36],
|
||||
[39, 63, 97, 49, 118, 56, 92, 61], [47, 101, 71, 60, 88, 109, 52, 90]]
|
||||
|
||||
sizes = [10, 7, 3, 12, 15, 4, 11, 5]
|
||||
|
||||
@@ -17,14 +17,12 @@ from ortools.constraint_solver import pywrapcp
|
||||
def main():
|
||||
# Instantiate a cp solver.
|
||||
solver = pywrapcp.Solver('transportation_with_sizes')
|
||||
cost = [[90, 76, 75, 70, 50, 74], [35, 85, 55, 65, 48,
|
||||
101], [125, 95, 90, 105, 59, 120],
|
||||
[45, 110, 95, 115, 104, 83], [60, 105, 80, 75, 59, 62], [
|
||||
45, 65, 110, 95, 47, 31
|
||||
], [38, 51, 107, 41, 69, 99], [47, 85, 57, 71,
|
||||
92, 77], [39, 63, 97, 49, 118, 56],
|
||||
[47, 101, 71, 60, 88, 109], [17, 39, 103, 64, 61,
|
||||
92], [101, 45, 83, 59, 92, 27]]
|
||||
cost = [[90, 76, 75, 70, 50, 74], [35, 85, 55, 65, 48, 101],
|
||||
[125, 95, 90, 105, 59, 120], [45, 110, 95, 115, 104, 83],
|
||||
[60, 105, 80, 75, 59, 62], [45, 65, 110, 95, 47, 31],
|
||||
[38, 51, 107, 41, 69, 99], [47, 85, 57, 71, 92, 77],
|
||||
[39, 63, 97, 49, 118, 56], [47, 101, 71, 60, 88, 109],
|
||||
[17, 39, 103, 64, 61, 92], [101, 45, 83, 59, 92, 27]]
|
||||
|
||||
group1 = [
|
||||
[0, 0, 1, 1], # Workers 2, 3
|
||||
|
||||
@@ -16,14 +16,12 @@ from ortools.sat.python import cp_model
|
||||
|
||||
def main():
|
||||
# Data.
|
||||
cost = [[90, 76, 75, 70, 50, 74], [35, 85, 55, 65, 48,
|
||||
101], [125, 95, 90, 105, 59, 120],
|
||||
[45, 110, 95, 115, 104, 83], [60, 105, 80, 75, 59, 62], [
|
||||
45, 65, 110, 95, 47, 31
|
||||
], [38, 51, 107, 41, 69, 99], [47, 85, 57, 71,
|
||||
92, 77], [39, 63, 97, 49, 118, 56],
|
||||
[47, 101, 71, 60, 88, 109], [17, 39, 103, 64, 61,
|
||||
92], [101, 45, 83, 59, 92, 27]]
|
||||
cost = [[90, 76, 75, 70, 50, 74], [35, 85, 55, 65, 48, 101],
|
||||
[125, 95, 90, 105, 59, 120], [45, 110, 95, 115, 104, 83],
|
||||
[60, 105, 80, 75, 59, 62], [45, 65, 110, 95, 47, 31],
|
||||
[38, 51, 107, 41, 69, 99], [47, 85, 57, 71, 92, 77],
|
||||
[39, 63, 97, 49, 118, 56], [47, 101, 71, 60, 88, 109],
|
||||
[17, 39, 103, 64, 61, 92], [101, 45, 83, 59, 92, 27]]
|
||||
|
||||
group1 = [
|
||||
[0, 0, 1, 1], # Workers 2, 3
|
||||
|
||||
@@ -20,108 +20,21 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
||||
# Data.
|
||||
|
||||
num_groups = 10
|
||||
num_items = 100
|
||||
num_colors = 3
|
||||
min_items_of_same_color_per_group = 4
|
||||
|
||||
all_groups = range(num_groups)
|
||||
all_items = range(num_items)
|
||||
all_colors = range(num_colors)
|
||||
|
||||
# Values for each items.
|
||||
values = [1 + i + (i * i // 200) for i in all_items]
|
||||
# Color for each item (simple modulo).
|
||||
colors = [i % num_colors for i in all_items]
|
||||
|
||||
sum_of_values = sum(values)
|
||||
average_sum_per_group = sum_of_values // num_groups
|
||||
|
||||
num_items_per_group = num_items // num_groups
|
||||
|
||||
# Collect all items in a given color.
|
||||
items_per_color = {}
|
||||
for c in all_colors:
|
||||
items_per_color[c] = []
|
||||
for i in all_items:
|
||||
if colors[i] == c:
|
||||
items_per_color[c].append(i)
|
||||
|
||||
print('Model has %i items, %i groups, and %i colors' %
|
||||
(num_items, num_groups, num_colors))
|
||||
print(' average sum per group = %i' % average_sum_per_group)
|
||||
|
||||
# Model.
|
||||
|
||||
model = cp_model.CpModel()
|
||||
|
||||
item_in_group = {}
|
||||
for i in all_items:
|
||||
for g in all_groups:
|
||||
item_in_group[(i, g)] = model.NewBoolVar('item %d in group %d' % (i, g))
|
||||
|
||||
e = model.NewIntVar(0, 550, 'epsilon')
|
||||
|
||||
|
||||
# Each group must have the same size.
|
||||
for g in all_groups:
|
||||
model.Add(sum(item_in_group[(i, g)]
|
||||
for i in all_items) == num_items_per_group)
|
||||
|
||||
# One item must belong to exactly one group.
|
||||
for i in all_items:
|
||||
model.Add(sum(item_in_group[(i, g)] for g in all_groups) == 1)
|
||||
|
||||
# Constrain the sum of values in one group around the average sum per group.
|
||||
for g in all_groups:
|
||||
model.Add(sum(item_in_group[(i, g)] * values[i] for i in all_items) <=
|
||||
average_sum_per_group + e)
|
||||
model.Add(sum(item_in_group[(i, g)] * values[i] for i in all_items) >=
|
||||
average_sum_per_group - e)
|
||||
|
||||
# color_in_group variables.
|
||||
color_in_group = {}
|
||||
for g in all_groups:
|
||||
for c in all_colors:
|
||||
color_in_group[(c, g)] = model.NewBoolVar(
|
||||
'color %d is in group %d' % (c, g))
|
||||
|
||||
# Item is in a group implies its color is in that group.
|
||||
for i in all_items:
|
||||
for g in all_groups:
|
||||
model.AddImplication(item_in_group[(i, g)],
|
||||
color_in_group[(colors[i], g)])
|
||||
|
||||
# If a color is in a group, it must contains at least
|
||||
# min_items_of_same_color_per_group items from that color.
|
||||
for c in all_colors:
|
||||
for g in all_groups:
|
||||
literal = color_in_group[(c, g)]
|
||||
model.Add(sum(item_in_group[(i, g)] for i in items_per_color[c]) >=
|
||||
min_items_of_same_color_per_group).OnlyEnforceIf(literal)
|
||||
|
||||
# Compute the maximum number of colors in a group.
|
||||
max_color = num_items_per_group // min_items_of_same_color_per_group
|
||||
# Redundant contraint: The problem does not solve in reasonable time without it.
|
||||
if max_color < num_colors:
|
||||
for g in all_groups:
|
||||
model.Add(sum(color_in_group[(c, g)] for c in all_colors) <= max_color)
|
||||
|
||||
# Minimize epsilon
|
||||
model.Minimize(e)
|
||||
|
||||
# Create a solution printer.
|
||||
class SolutionPrinter(cp_model.CpSolverSolutionCallback):
|
||||
"""Print intermediate solutions."""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, values, colors, all_groups, all_items, item_in_group):
|
||||
cp_model.CpSolverSolutionCallback.__init__(self)
|
||||
self.__solution_count = 0
|
||||
self.__values = values
|
||||
self.__colors = colors
|
||||
self.__all_groups = all_groups
|
||||
self.__all_items = all_items
|
||||
self.__item_in_group = item_in_group
|
||||
|
||||
def OnSolutionCallback(self):
|
||||
print('Solution %i' % self.__solution_count)
|
||||
@@ -129,35 +42,137 @@ class SolutionPrinter(cp_model.CpSolverSolutionCallback):
|
||||
|
||||
print(' objective value = %i' % self.ObjectiveValue())
|
||||
groups = {}
|
||||
for g in all_groups:
|
||||
groups[g] = []
|
||||
for i in all_items:
|
||||
if self.BooleanValue(item_in_group[(i, g)]):
|
||||
groups[g].append(i)
|
||||
sums = {}
|
||||
for g in self.__all_groups:
|
||||
groups[g] = []
|
||||
sums[g] = 0
|
||||
for item in self.__all_items:
|
||||
if self.BooleanValue(self.__item_in_group[(item, g)]):
|
||||
groups[g].append(item)
|
||||
sums[g] += self.__values[item]
|
||||
|
||||
for g in all_groups:
|
||||
group = groups[g]
|
||||
print ('group %i: sum = %0.2f [' % (
|
||||
g, sum(values[i] for i in group)), end='')
|
||||
for item in groups[g]:
|
||||
value = values[item]
|
||||
color = colors[item]
|
||||
print(' (%i, %i, %i)' % (item, value, color), end='')
|
||||
print(']')
|
||||
for g in self.__all_groups:
|
||||
group = groups[g]
|
||||
print('group %i: sum = %0.2f [' % (g, sums[g]), end='')
|
||||
for item in group:
|
||||
value = self.__values[item]
|
||||
color = self.__colors[item]
|
||||
print(' (%i, %i, %i)' % (item, value, color), end='')
|
||||
print(']')
|
||||
|
||||
def SolutionCount(self):
|
||||
return self.__solution_count
|
||||
|
||||
|
||||
solver = cp_model.CpSolver()
|
||||
solution_printer = SolutionPrinter()
|
||||
status = solver.SolveWithSolutionCallback(model, solution_printer)
|
||||
def main():
|
||||
# Data.
|
||||
num_groups = 10
|
||||
num_items = 100
|
||||
num_colors = 3
|
||||
min_items_of_same_color_per_group = 4
|
||||
|
||||
if status == cp_model.OPTIMAL:
|
||||
all_groups = range(num_groups)
|
||||
all_items = range(num_items)
|
||||
all_colors = range(num_colors)
|
||||
|
||||
# Values for each items.
|
||||
values = [1 + i + (i * i // 200) for i in all_items]
|
||||
# Color for each item (simple modulo).
|
||||
colors = [i % num_colors for i in all_items]
|
||||
|
||||
sum_of_values = sum(values)
|
||||
average_sum_per_group = sum_of_values // num_groups
|
||||
|
||||
num_items_per_group = num_items // num_groups
|
||||
|
||||
# Collect all items in a given color.
|
||||
items_per_color = {}
|
||||
for c in all_colors:
|
||||
items_per_color[c] = []
|
||||
for i in all_items:
|
||||
if colors[i] == c:
|
||||
items_per_color[c].append(i)
|
||||
|
||||
print('Model has %i items, %i groups, and %i colors' % (num_items, num_groups,
|
||||
num_colors))
|
||||
print(' average sum per group = %i' % average_sum_per_group)
|
||||
|
||||
# Model.
|
||||
|
||||
model = cp_model.CpModel()
|
||||
|
||||
item_in_group = {}
|
||||
for i in all_items:
|
||||
for g in all_groups:
|
||||
item_in_group[(i, g)] = model.NewBoolVar('item %d in group %d' % (i, g))
|
||||
|
||||
# Each group must have the same size.
|
||||
for g in all_groups:
|
||||
model.Add(
|
||||
sum(item_in_group[(i, g)] for i in all_items) == num_items_per_group)
|
||||
|
||||
# One item must belong to exactly one group.
|
||||
for i in all_items:
|
||||
model.Add(sum(item_in_group[(i, g)] for g in all_groups) == 1)
|
||||
|
||||
# The deviation of the sum of each items in a group against the average.
|
||||
e = model.NewIntVar(0, 550, 'epsilon')
|
||||
|
||||
# Constrain the sum of values in one group around the average sum per group.
|
||||
for g in all_groups:
|
||||
model.Add(
|
||||
sum(item_in_group[(i, g)] * values[i]
|
||||
for i in all_items) <= average_sum_per_group + e)
|
||||
model.Add(
|
||||
sum(item_in_group[(i, g)] * values[i]
|
||||
for i in all_items) >= average_sum_per_group - e)
|
||||
|
||||
# color_in_group variables.
|
||||
color_in_group = {}
|
||||
for g in all_groups:
|
||||
for c in all_colors:
|
||||
color_in_group[(c,
|
||||
g)] = model.NewBoolVar('color %d is in group %d' % (c, g))
|
||||
|
||||
# Item is in a group implies its color is in that group.
|
||||
for i in all_items:
|
||||
for g in all_groups:
|
||||
model.AddImplication(item_in_group[(i, g)], color_in_group[(colors[i],
|
||||
g)])
|
||||
|
||||
# If a color is in a group, it must contains at least
|
||||
# min_items_of_same_color_per_group items from that color.
|
||||
for c in all_colors:
|
||||
for g in all_groups:
|
||||
literal = color_in_group[(c, g)]
|
||||
model.Add(
|
||||
sum(item_in_group[(i, g)] for i in items_per_color[c]) >=
|
||||
min_items_of_same_color_per_group).OnlyEnforceIf(literal)
|
||||
|
||||
# Compute the maximum number of colors in a group.
|
||||
max_color = num_items_per_group // min_items_of_same_color_per_group
|
||||
# Redundant contraint: The problem does not solve in reasonable time without it.
|
||||
if max_color < num_colors:
|
||||
for g in all_groups:
|
||||
model.Add(sum(color_in_group[(c, g)] for c in all_colors) <= max_color)
|
||||
|
||||
# Minimize epsilon
|
||||
model.Minimize(e)
|
||||
|
||||
solver = cp_model.CpSolver()
|
||||
solution_printer = SolutionPrinter(values, colors, all_groups, all_items,
|
||||
item_in_group)
|
||||
status = solver.SolveWithSolutionCallback(model, solution_printer)
|
||||
|
||||
if status == cp_model.OPTIMAL:
|
||||
print('Optimal epsilon: %i' % solver.ObjectiveValue())
|
||||
print('Statistics')
|
||||
print(' - conflicts : %i' % solver.NumConflicts())
|
||||
print(' - branches : %i' % solver.NumBranches())
|
||||
print(' - wall time : %f s' % solver.WallTime())
|
||||
else:
|
||||
else:
|
||||
print('No solution found')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -88,10 +88,10 @@ def main(sol='CBC'):
|
||||
solver.Sum([CostIngo[i] * ii[i] for i in Ingos]))
|
||||
|
||||
for j in Metals:
|
||||
solver.Add(metal[j] == p[j] +
|
||||
solver.Sum([PercRaw[j][k] * r[k] for k in Raws]) +
|
||||
solver.Sum([PercScrap[j][k] * s[k] for k in Scraps]) +
|
||||
solver.Sum([PercIngo[j][k] * ii[k] for k in Ingos]))
|
||||
solver.Add(
|
||||
metal[j] == p[j] + solver.Sum([PercRaw[j][k] * r[k] for k in Raws]) +
|
||||
solver.Sum([PercScrap[j][k] * s[k] for k in Scraps]) +
|
||||
solver.Sum([PercIngo[j][k] * ii[k] for k in Ingos]))
|
||||
|
||||
solver.Add(solver.Sum(metal) == Alloy)
|
||||
|
||||
|
||||
@@ -20,27 +20,19 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
|
||||
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
||||
import math
|
||||
|
||||
|
||||
# Data
|
||||
|
||||
max_quantities = [ ["N_Total", 1944],
|
||||
["P2O5", 1166.4],
|
||||
["K2O", 1822.5],
|
||||
["CaO", 1458],
|
||||
["MgO", 486],
|
||||
["Fe", 9.7],
|
||||
["B", 2.4] ]
|
||||
max_quantities = [["N_Total", 1944], ["P2O5", 1166.4], ["K2O", 1822.5],
|
||||
["CaO", 1458], ["MgO", 486], ["Fe", 9.7], ["B", 2.4]]
|
||||
|
||||
chemical_set = [ ["A", 0, 0, 510, 540, 0, 0, 0],
|
||||
["B", 110, 0, 0, 0, 160, 0, 0],
|
||||
["C", 61, 149, 384, 0, 30, 1, 0.2],
|
||||
["D", 148, 70, 245, 0, 15, 1, 0.2],
|
||||
["E", 160, 158, 161, 0, 10, 1, 0.2] ]
|
||||
chemical_set = [["A", 0, 0, 510, 540, 0, 0, 0], ["B", 110, 0, 0, 0, 160, 0, 0],
|
||||
["C", 61, 149, 384, 0, 30, 1, 0.2],
|
||||
["D", 148, 70, 245, 0, 15, 1, 0.2],
|
||||
["E", 160, 158, 161, 0, 10, 1, 0.2]]
|
||||
|
||||
num_products = len(max_quantities)
|
||||
all_products = range(num_products)
|
||||
@@ -50,28 +42,32 @@ all_sets = range(num_sets)
|
||||
|
||||
# Model
|
||||
|
||||
max_set = [min(max_quantities[q][1] / chemical_set[s][q + 1]
|
||||
for q in all_products
|
||||
if chemical_set[s][q + 1] != 0.0)
|
||||
for s in all_sets]
|
||||
max_set = [
|
||||
min(max_quantities[q][1] / chemical_set[s][q + 1]
|
||||
for q in all_products
|
||||
if chemical_set[s][q + 1] != 0.0)
|
||||
for s in all_sets
|
||||
]
|
||||
|
||||
solver = pywraplp.Solver('chemical_set_lp',
|
||||
solver = pywraplp.Solver("chemical_set_lp",
|
||||
pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)
|
||||
|
||||
set_vars = [solver.NumVar(0, max_set[s], 'set_%i' % s) for s in all_sets]
|
||||
set_vars = [solver.NumVar(0, max_set[s], "set_%i" % s) for s in all_sets]
|
||||
|
||||
epsilon = solver.NumVar(0, 1000, 'epsilon')
|
||||
epsilon = solver.NumVar(0, 1000, "epsilon")
|
||||
|
||||
for p in all_products:
|
||||
solver.Add(sum(chemical_set[s][p + 1] * set_vars[s] for s in all_sets) <=
|
||||
max_quantities[p][1])
|
||||
solver.Add(sum(chemical_set[s][p + 1] * set_vars[s] for s in all_sets) >=
|
||||
max_quantities[p][1] - epsilon)
|
||||
solver.Add(
|
||||
sum(chemical_set[s][p + 1] * set_vars[s]
|
||||
for s in all_sets) <= max_quantities[p][1])
|
||||
solver.Add(
|
||||
sum(chemical_set[s][p + 1] * set_vars[s]
|
||||
for s in all_sets) >= max_quantities[p][1] - epsilon)
|
||||
|
||||
solver.Minimize(epsilon)
|
||||
|
||||
print(('Number of variables = %d' % solver.NumVariables()))
|
||||
print(('Number of constraints = %d' % solver.NumConstraints()))
|
||||
print(("Number of variables = %d" % solver.NumVariables()))
|
||||
print(("Number of constraints = %d" % solver.NumConstraints()))
|
||||
|
||||
result_status = solver.Solve()
|
||||
|
||||
@@ -80,18 +76,18 @@ assert result_status == pywraplp.Solver.OPTIMAL
|
||||
|
||||
assert solver.VerifySolution(1e-7, True)
|
||||
|
||||
print(('Problem solved in %f milliseconds' % solver.wall_time()))
|
||||
print(("Problem solved in %f milliseconds" % solver.wall_time()))
|
||||
|
||||
# The objective value of the solution.
|
||||
print(('Optimal objective value = %f' % solver.Objective().Value()))
|
||||
print(("Optimal objective value = %f" % solver.Objective().Value()))
|
||||
|
||||
for s in all_sets:
|
||||
print(' %s = %f' % (chemical_set[s][0], set_vars[s].solution_value()),
|
||||
end=' ')
|
||||
print(
|
||||
" %s = %f" % (chemical_set[s][0], set_vars[s].solution_value()), end=" ")
|
||||
print()
|
||||
for p in all_products:
|
||||
name = max_quantities[p][0]
|
||||
max_quantity = max_quantities[p][1]
|
||||
quantity = sum(set_vars[s].solution_value() * chemical_set[s][p + 1]
|
||||
for s in all_sets)
|
||||
print('%s: %f out of %f' % (name, quantity, max_quantity))
|
||||
quantity = sum(
|
||||
set_vars[s].solution_value() * chemical_set[s][p + 1] for s in all_sets)
|
||||
print("%s: %f out of %f" % (name, quantity, max_quantity))
|
||||
|
||||
@@ -20,26 +20,18 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
import math
|
||||
|
||||
|
||||
# Data
|
||||
|
||||
max_quantities = [ ["N_Total", 1944],
|
||||
["P2O5", 1166.4],
|
||||
["K2O", 1822.5],
|
||||
["CaO", 1458],
|
||||
["MgO", 486],
|
||||
["Fe", 9.7],
|
||||
["B", 2.4] ]
|
||||
max_quantities = [["N_Total", 1944], ["P2O5", 1166.4], ["K2O", 1822.5],
|
||||
["CaO", 1458], ["MgO", 486], ["Fe", 9.7], ["B", 2.4]]
|
||||
|
||||
chemical_set = [ ["A", 0, 0, 510, 540, 0, 0, 0],
|
||||
["B", 110, 0, 0, 0, 160, 0, 0],
|
||||
["C", 61, 149, 384, 0, 30, 1, 0.2],
|
||||
["D", 148, 70, 245, 0, 15, 1, 0.2],
|
||||
["E", 160, 158, 161, 0, 10, 1, 0.2] ]
|
||||
chemical_set = [["A", 0, 0, 510, 540, 0, 0, 0], ["B", 110, 0, 0, 0, 160, 0, 0],
|
||||
["C", 61, 149, 384, 0, 30, 1, 0.2],
|
||||
["D", 148, 70, 245, 0, 15, 1, 0.2],
|
||||
["E", 160, 158, 161, 0, 10, 1, 0.2]]
|
||||
|
||||
num_products = len(max_quantities)
|
||||
all_products = range(num_products)
|
||||
@@ -52,38 +44,45 @@ all_sets = range(num_sets)
|
||||
model = cp_model.CpModel()
|
||||
|
||||
# Scale quantities by 100.
|
||||
max_set = [int(math.ceil(min(max_quantities[q][1] * 1000 / chemical_set[s][q + 1]
|
||||
for q in all_products
|
||||
if chemical_set[s][q + 1] != 0)))
|
||||
for s in all_sets]
|
||||
max_set = [
|
||||
int(
|
||||
math.ceil(
|
||||
min(max_quantities[q][1] * 1000 / chemical_set[s][q + 1]
|
||||
for q in all_products
|
||||
if chemical_set[s][q + 1] != 0)))
|
||||
for s in all_sets
|
||||
]
|
||||
|
||||
set_vars = [model.NewIntVar(0, max_set[s], 'set_%i' % s) for s in all_sets]
|
||||
set_vars = [model.NewIntVar(0, max_set[s], "set_%i" % s) for s in all_sets]
|
||||
|
||||
epsilon = model.NewIntVar(0, 10000000, 'epsilon')
|
||||
epsilon = model.NewIntVar(0, 10000000, "epsilon")
|
||||
|
||||
for p in all_products:
|
||||
model.Add(sum(int(chemical_set[s][p + 1] * 10) * set_vars[s]
|
||||
for s in all_sets) <= int(max_quantities[p][1] * 10000))
|
||||
model.Add(sum(int(chemical_set[s][p + 1] * 10) * set_vars[s]
|
||||
for s in all_sets) >= int(max_quantities[p][1] * 10000) -
|
||||
epsilon)
|
||||
model.Add(
|
||||
sum(int(chemical_set[s][p + 1] * 10) * set_vars[s]
|
||||
for s in all_sets) <= int(max_quantities[p][1] * 10000))
|
||||
model.Add(
|
||||
sum(int(chemical_set[s][p + 1] * 10) * set_vars[s]
|
||||
for s in all_sets) >= int(max_quantities[p][1] * 10000) - epsilon)
|
||||
|
||||
model.Minimize(epsilon)
|
||||
|
||||
# Creates a solver and solves.
|
||||
solver = cp_model.CpSolver()
|
||||
status = solver.Solve(model)
|
||||
print('Status = %s' % solver.StatusName(status))
|
||||
print("Status = %s" % solver.StatusName(status))
|
||||
# The objective value of the solution.
|
||||
print('Optimal objective value = %f' % (solver.ObjectiveValue() / 10000.0))
|
||||
print("Optimal objective value = %f" % (solver.ObjectiveValue() / 10000.0))
|
||||
|
||||
for s in all_sets:
|
||||
print(' %s = %f' % (chemical_set[s][0], solver.Value(set_vars[s]) / 1000.0),
|
||||
end=' ')
|
||||
print(
|
||||
" %s = %f" % (chemical_set[s][0], solver.Value(set_vars[s]) / 1000.0),
|
||||
end=" ")
|
||||
print()
|
||||
for p in all_products:
|
||||
name = max_quantities[p][0]
|
||||
max_quantity = max_quantities[p][1]
|
||||
quantity = sum(solver.Value(set_vars[s]) / 1000.0 * chemical_set[s][p + 1]
|
||||
for s in all_sets)
|
||||
print('%s: %f out of %f' % (name, quantity, max_quantity))
|
||||
quantity = sum(
|
||||
solver.Value(set_vars[s]) / 1000.0 * chemical_set[s][p + 1]
|
||||
for s in all_sets)
|
||||
print("%s: %f out of %f" % (name, quantity, max_quantity))
|
||||
|
||||
@@ -366,8 +366,8 @@ def MinimalJobShop():
|
||||
# Add precedence contraints.
|
||||
for job in all_jobs:
|
||||
for index in range(0, len(machines[job]) - 1):
|
||||
model.Add(all_tasks[(job, index + 1)].start >= all_tasks[(job,
|
||||
index)].end)
|
||||
model.Add(
|
||||
all_tasks[(job, index + 1)].start >= all_tasks[(job, index)].end)
|
||||
|
||||
# Makespan objective.
|
||||
obj_var = model.NewIntVar(0, horizon, 'makespan')
|
||||
|
||||
@@ -55,6 +55,7 @@ from __future__ import print_function
|
||||
import sys
|
||||
from ortools.constraint_solver import pywrapcp
|
||||
|
||||
|
||||
def main(n=31, c=14):
|
||||
# Create the solver.
|
||||
solver = pywrapcp.Solver("Coins grid")
|
||||
@@ -104,7 +105,7 @@ def main(n=31, c=14):
|
||||
print("objective:", collector.ObjectiveValue(0))
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
print(collector.Value(0, x[(i, j)]), end=' ')
|
||||
print(collector.Value(0, x[(i, j)]), end=" ")
|
||||
print()
|
||||
print()
|
||||
|
||||
@@ -112,6 +113,7 @@ def main(n=31, c=14):
|
||||
print("branches:", solver.Branches())
|
||||
print("WallTime:", solver.WallTime())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# data
|
||||
n = 31 # the grid size
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
from __future__ import print_function
|
||||
from ortools.linear_solver import pywraplp
|
||||
|
||||
|
||||
def main(unused_argv):
|
||||
# Create the solver.
|
||||
|
||||
@@ -96,5 +97,6 @@ def main(unused_argv):
|
||||
print('walltime :', solver.WallTime(), 'ms')
|
||||
# print 'iterations:', solver.Iterations()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main('coin grids')
|
||||
|
||||
@@ -108,8 +108,8 @@ def regular(x, Q, S, d, q0, F):
|
||||
solver.Add(x[i] <= S)
|
||||
|
||||
# Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
|
||||
solver.Add(a[i + 1] == solver.Element(d2_flatten, (
|
||||
(a[i]) * S) + (x[i] - 1)))
|
||||
solver.Add(
|
||||
a[i + 1] == solver.Element(d2_flatten, ((a[i]) * S) + (x[i] - 1)))
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -76,17 +76,15 @@ def main():
|
||||
|
||||
# Which worker is qualified for each task.
|
||||
# Note: This is 1-based and will be made 0-base below.
|
||||
Qualified = [[1, 9, 19, 22, 25, 28,
|
||||
31], [2, 12, 15, 19, 21, 23, 27, 29, 30, 31,
|
||||
32], [3, 10, 19, 24, 26, 30, 32], [4, 21, 25, 28, 32],
|
||||
[5, 11, 16, 22, 23, 27, 31], [6, 20, 24, 26,
|
||||
30, 32], [7, 12, 17, 25, 30,
|
||||
31], [8, 17, 20, 22, 23],
|
||||
[9, 13, 14, 26, 29, 30,
|
||||
31], [10, 21, 25, 31, 32], [14, 15, 18, 23, 24, 27, 30, 32], [
|
||||
18, 19, 22, 24, 26, 29, 31
|
||||
], [11, 20, 25, 28, 30, 32], [16, 19, 23,
|
||||
31], [9, 18, 26, 28, 31, 32]]
|
||||
Qualified = [[1, 9, 19, 22, 25, 28, 31],
|
||||
[2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32],
|
||||
[3, 10, 19, 24, 26, 30, 32], [4, 21, 25, 28, 32],
|
||||
[5, 11, 16, 22, 23, 27, 31], [6, 20, 24, 26, 30, 32],
|
||||
[7, 12, 17, 25, 30, 31], [8, 17, 20, 22, 23],
|
||||
[9, 13, 14, 26, 29, 30, 31], [10, 21, 25, 31, 32],
|
||||
[14, 15, 18, 23, 24, 27, 30, 32], [18, 19, 22, 24, 26, 29, 31],
|
||||
[11, 20, 25, 28, 30, 32], [16, 19, 23, 31],
|
||||
[9, 18, 26, 28, 31, 32]]
|
||||
|
||||
Cost = [
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
|
||||
|
||||
@@ -158,8 +158,8 @@ def main():
|
||||
# But we must use Element explicitly
|
||||
solver.Add(
|
||||
solver.Element(A_flat, E[overlapping[I][0]] * word_len +
|
||||
overlapping[I][1]) == solver.
|
||||
Element(A_flat, E[overlapping[I][2]] * word_len + overlapping[I][3]))
|
||||
overlapping[I][1]) == solver
|
||||
.Element(A_flat, E[overlapping[I][2]] * word_len + overlapping[I][3]))
|
||||
|
||||
#
|
||||
# solution and search
|
||||
|
||||
@@ -38,8 +38,10 @@ Vehicle = namedtuple('Vehicle', ['capacity'])
|
||||
# City block declaration
|
||||
CityBlock = namedtuple('CityBlock', ['width', 'height'])
|
||||
|
||||
|
||||
class DataProblem():
|
||||
"""Stores the data for the problem"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initializes the data for the problem"""
|
||||
# Locations in block unit
|
||||
@@ -57,7 +59,7 @@ class DataProblem():
|
||||
# Manhattan average block: 750ft x 264ft -> 228m x 80m
|
||||
# here we use: 114m x 80m city block
|
||||
# src: https://nyti.ms/2GDoRIe "NY Times: Know Your distance"
|
||||
city_block = CityBlock(width=228/2, height=80)
|
||||
city_block = CityBlock(width=228 / 2, height=80)
|
||||
self._locations = [(loc[0] * city_block.width, loc[1] * city_block.height)
|
||||
for loc in locations]
|
||||
|
||||
@@ -102,6 +104,7 @@ class DataProblem():
|
||||
"""Gets demands at each location"""
|
||||
return self._demands
|
||||
|
||||
|
||||
#######################
|
||||
# Problem Constraints #
|
||||
#######################
|
||||
@@ -110,8 +113,10 @@ def manhattan_distance(position_1, position_2):
|
||||
return (
|
||||
abs(position_1[0] - position_2[0]) + abs(position_1[1] - position_2[1]))
|
||||
|
||||
|
||||
class CreateDistanceEvaluator(object): # pylint: disable=too-few-public-methods
|
||||
"""Creates callback to return distance between points."""
|
||||
|
||||
def __init__(self, data):
|
||||
"""Initializes the distance matrix."""
|
||||
self._distances = {}
|
||||
@@ -131,6 +136,7 @@ class CreateDistanceEvaluator(object): # pylint: disable=too-few-public-methods
|
||||
"""Returns the manhattan distance between the two nodes"""
|
||||
return self._distances[from_node][to_node]
|
||||
|
||||
|
||||
class CreateDemandEvaluator(object): # pylint: disable=too-few-public-methods
|
||||
"""Creates callback to get demands at each location."""
|
||||
|
||||
@@ -143,6 +149,7 @@ class CreateDemandEvaluator(object): # pylint: disable=too-few-public-methods
|
||||
del to_node
|
||||
return self._demands[from_node]
|
||||
|
||||
|
||||
def add_capacity_constraints(routing, data, demand_evaluator):
|
||||
"""Adds capacity constraint"""
|
||||
capacity = 'Capacity'
|
||||
@@ -153,6 +160,7 @@ def add_capacity_constraints(routing, data, demand_evaluator):
|
||||
True, # start cumul to zero
|
||||
capacity)
|
||||
|
||||
|
||||
###########
|
||||
# Printer #
|
||||
###########
|
||||
@@ -169,15 +177,14 @@ def print_solution(data, routing, assignment):
|
||||
while not routing.IsEnd(index):
|
||||
load_var = capacity_dimension.CumulVar(index)
|
||||
plan_output += ' {} Load({}) -> '.format(
|
||||
routing.IndexToNode(index),
|
||||
assignment.Value(load_var))
|
||||
routing.IndexToNode(index), assignment.Value(load_var))
|
||||
previous_index = index
|
||||
index = assignment.Value(routing.NextVar(index))
|
||||
distance += routing.GetArcCostForVehicle(previous_index, index, vehicle_id)
|
||||
distance += routing.GetArcCostForVehicle(previous_index, index,
|
||||
vehicle_id)
|
||||
load_var = capacity_dimension.CumulVar(index)
|
||||
plan_output += ' {0} Load({1})\n'.format(
|
||||
routing.IndexToNode(index),
|
||||
assignment.Value(load_var))
|
||||
routing.IndexToNode(index), assignment.Value(load_var))
|
||||
plan_output += 'Distance of the route: {}m\n'.format(distance)
|
||||
plan_output += 'Load of the route: {}\n'.format(assignment.Value(load_var))
|
||||
print(plan_output)
|
||||
@@ -186,6 +193,7 @@ def print_solution(data, routing, assignment):
|
||||
print('Total Distance of all routes: {}m'.format(total_distance))
|
||||
print('Total Load of all routes: {}'.format(total_load))
|
||||
|
||||
|
||||
########
|
||||
# Main #
|
||||
########
|
||||
@@ -195,10 +203,8 @@ def main():
|
||||
data = DataProblem()
|
||||
|
||||
# Create Routing Model
|
||||
routing = pywrapcp.RoutingModel(
|
||||
data.num_locations,
|
||||
data.num_vehicles,
|
||||
data.depot)
|
||||
routing = pywrapcp.RoutingModel(data.num_locations, data.num_vehicles,
|
||||
data.depot)
|
||||
|
||||
# Define weight of each edge
|
||||
distance_evaluator = CreateDistanceEvaluator(data).distance_evaluator
|
||||
@@ -210,10 +216,11 @@ def main():
|
||||
# Setting first solution heuristic (cheapest addition).
|
||||
search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()
|
||||
search_parameters.first_solution_strategy = (
|
||||
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member
|
||||
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member
|
||||
# Solve the problem.
|
||||
assignment = routing.SolveWithParameters(search_parameters)
|
||||
print_solution(data, routing, assignment)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user