small polish
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""Solves the Stell Mill Slab problem with 4 different techniques."""
|
||||
|
||||
from __future__ import print_function
|
||||
import argparse
|
||||
@@ -291,22 +292,6 @@ class SteelMillSlabSolutionPrinter(cp_model.CpSolverSolutionCallback):
|
||||
print(line)
|
||||
|
||||
|
||||
class SolutionPrinterWithObjective(cp_model.CpSolverSolutionCallback):
|
||||
"""Print intermediate solutions."""
|
||||
|
||||
def __init__(self):
|
||||
cp_model.CpSolverSolutionCallback.__init__(self)
|
||||
self.__solution_count = 0
|
||||
self.__start_time = time.time()
|
||||
|
||||
def on_solution_callback(self):
|
||||
current_time = time.time()
|
||||
print('Solution %i, time = %f s, objective = %i' %
|
||||
(self.__solution_count, current_time - self.__start_time,
|
||||
self.ObjectiveValue()))
|
||||
self.__solution_count += 1
|
||||
|
||||
|
||||
def steel_mill_slab(problem, break_symmetries, output_proto):
|
||||
"""Solves the Steel Mill Slab Problem."""
|
||||
### Load problem.
|
||||
@@ -347,12 +332,14 @@ def steel_mill_slab(problem, break_symmetries, output_proto):
|
||||
for s in all_slabs
|
||||
]
|
||||
color_is_in_slab = [[
|
||||
model.NewBoolVar('color_%i_in_slab_%i' % (c + 1, s)) for c in all_colors
|
||||
model.NewBoolVar('color_%i_in_slab_%i' % (c + 1, s))
|
||||
for c in all_colors
|
||||
] for s in all_slabs]
|
||||
|
||||
# Compute load of all slabs.
|
||||
for s in all_slabs:
|
||||
model.Add(sum(assign[o][s] * widths[o] for o in all_orders) == loads[s])
|
||||
model.Add(
|
||||
sum(assign[o][s] * widths[o] for o in all_orders) == loads[s])
|
||||
|
||||
# Orders are assigned to one slab.
|
||||
for o in all_orders:
|
||||
@@ -438,13 +425,14 @@ def steel_mill_slab(problem, break_symmetries, output_proto):
|
||||
|
||||
### Solve model.
|
||||
solver = cp_model.CpSolver()
|
||||
status = solver.Solve(model)
|
||||
solver.parameters.num_search_workers = 8
|
||||
objective_printer = cp_model.ObjectiveSolutionPrinter()
|
||||
status = solver.SolveWithSolutionCallback(model, objective_printer)
|
||||
|
||||
### Output the solution.
|
||||
if status == cp_model.OPTIMAL:
|
||||
print('Loss = %i, time = %f s, %i conflicts' %
|
||||
(solver.ObjectiveValue(), solver.WallTime(),
|
||||
solver.NumConflicts()))
|
||||
print('Loss = %i, time = %f s, %i conflicts' % (
|
||||
solver.ObjectiveValue(), solver.WallTime(), solver.NumConflicts()))
|
||||
else:
|
||||
print('No solution')
|
||||
|
||||
@@ -476,7 +464,9 @@ def collect_valid_slabs(capacities, colors, widths, loss_array, all_colors):
|
||||
assign = [model.NewBoolVar('assign_%i' % o) for o in all_orders]
|
||||
load = model.NewIntVar(0, max_capacity, 'load')
|
||||
|
||||
color_in_slab = [model.NewBoolVar('color_%i' % (c + 1)) for c in all_colors]
|
||||
color_in_slab = [
|
||||
model.NewBoolVar('color_%i' % (c + 1)) for c in all_colors
|
||||
]
|
||||
|
||||
# Compute load.
|
||||
model.Add(sum(assign[o] * widths[o] for o in all_orders) == load)
|
||||
@@ -496,12 +486,24 @@ def collect_valid_slabs(capacities, colors, widths, loss_array, all_colors):
|
||||
loss = model.NewIntVar(0, max(loss_array), 'loss')
|
||||
model.AddElement(load, loss_array, loss)
|
||||
|
||||
model.AddDecisionStrategy(assign, cp_model.CHOOSE_FIRST,
|
||||
cp_model.SELECT_MAX_VALUE)
|
||||
|
||||
### Solve model and collect columns.
|
||||
print('Collect Valid Slabs...DONE')
|
||||
print('Collect Valid Slabs...START')
|
||||
start_time = time.time()
|
||||
|
||||
solver = cp_model.CpSolver()
|
||||
|
||||
# Add solution callback to store all possible slab templates.
|
||||
collector = AllSolutionsCollector(assign + [loss, load])
|
||||
|
||||
# Force solver to follow the decision strategy exactly.
|
||||
solver.parameters.search_branching = cp_model.FIXED_SEARCH
|
||||
|
||||
solver.SearchForAllSolutions(model, collector)
|
||||
print('Collect Valid Slabs...DONE')
|
||||
run_time = time.time() - start_time
|
||||
print('Collect Valid Slabs...DONE in %.2f s' % run_time)
|
||||
return collector.all_solutions()
|
||||
|
||||
|
||||
@@ -535,7 +537,9 @@ def steel_mill_slab_with_valid_slabs(problem, break_symmetries, output_proto):
|
||||
assign = [[
|
||||
model.NewBoolVar('assign_%i_to_slab_%i' % (o, s)) for s in all_slabs
|
||||
] for o in all_orders]
|
||||
loads = [model.NewIntVar(0, max_capacity, 'load_%i' % s) for s in all_slabs]
|
||||
loads = [
|
||||
model.NewIntVar(0, max_capacity, 'load_%i' % s) for s in all_slabs
|
||||
]
|
||||
losses = [model.NewIntVar(0, max_loss, 'loss_%i' % s) for s in all_slabs]
|
||||
|
||||
unsorted_valid_slabs = collect_valid_slabs(capacities, colors, widths,
|
||||
@@ -548,8 +552,8 @@ def steel_mill_slab_with_valid_slabs(problem, break_symmetries, output_proto):
|
||||
|
||||
for s in all_slabs:
|
||||
model.AddAllowedAssignments(
|
||||
[assign[o][s]
|
||||
for o in all_orders] + [losses[s], loads[s]], valid_slabs)
|
||||
[assign[o][s] for o in all_orders] + [losses[s], loads[s]],
|
||||
valid_slabs)
|
||||
|
||||
# Orders are assigned to one slab.
|
||||
for o in all_orders:
|
||||
@@ -590,7 +594,8 @@ def steel_mill_slab_with_valid_slabs(problem, break_symmetries, output_proto):
|
||||
for w, os in local_width_to_order.items():
|
||||
if len(os) > 1:
|
||||
for p in range(len(os) - 1):
|
||||
ordered_equivalent_orders.append((os[p], os[p + 1]))
|
||||
ordered_equivalent_orders.append((os[p],
|
||||
os[p + 1]))
|
||||
for w, os in width_to_unique_color_order.items():
|
||||
if len(os) > 1:
|
||||
for p in range(len(os) - 1):
|
||||
@@ -628,15 +633,15 @@ def steel_mill_slab_with_valid_slabs(problem, break_symmetries, output_proto):
|
||||
|
||||
### Solve model.
|
||||
solver = cp_model.CpSolver()
|
||||
solver.num_search_workers = 8
|
||||
solution_printer = SteelMillSlabSolutionPrinter(orders, assign, loads,
|
||||
losses)
|
||||
status = solver.SolveWithSolutionCallback(model, solution_printer)
|
||||
|
||||
### Output the solution.
|
||||
if status == cp_model.OPTIMAL:
|
||||
print('Loss = %i, time = %f s, %i conflicts' %
|
||||
(solver.ObjectiveValue(), solver.WallTime(),
|
||||
solver.NumConflicts()))
|
||||
print('Loss = %i, time = %.2f s, %i conflicts' % (
|
||||
solver.ObjectiveValue(), solver.WallTime(), solver.NumConflicts()))
|
||||
else:
|
||||
print('No solution')
|
||||
|
||||
@@ -680,7 +685,8 @@ def steel_mill_slab_with_column_generation(problem, output_proto):
|
||||
|
||||
for o in all_orders:
|
||||
model.Add(
|
||||
sum(selected[i] for i in all_valid_slabs if valid_slabs[i][o]) == 1)
|
||||
sum(selected[i] for i in all_valid_slabs
|
||||
if valid_slabs[i][o]) == 1)
|
||||
|
||||
# Redundant constraint (sum of loads == sum of widths).
|
||||
model.Add(
|
||||
@@ -690,8 +696,8 @@ def steel_mill_slab_with_column_generation(problem, output_proto):
|
||||
# Objective.
|
||||
max_loss = max(valid_slabs[i][-2] for i in all_valid_slabs)
|
||||
obj = model.NewIntVar(0, num_slabs * max_loss, 'obj')
|
||||
model.Add(
|
||||
obj == sum(selected[i] * valid_slabs[i][-2] for i in all_valid_slabs))
|
||||
model.Add(obj == sum(
|
||||
selected[i] * valid_slabs[i][-2] for i in all_valid_slabs))
|
||||
model.Minimize(obj)
|
||||
|
||||
print('Model created')
|
||||
@@ -704,14 +710,14 @@ def steel_mill_slab_with_column_generation(problem, output_proto):
|
||||
|
||||
### Solve model.
|
||||
solver = cp_model.CpSolver()
|
||||
solution_printer = SolutionPrinterWithObjective()
|
||||
solver.parameters.num_search_workers = 8
|
||||
solution_printer = cp_model.ObjectiveSolutionPrinter()
|
||||
status = solver.SolveWithSolutionCallback(model, solution_printer)
|
||||
|
||||
### Output the solution.
|
||||
if status == cp_model.OPTIMAL:
|
||||
print('Loss = %i, time = %f s, %i conflicts' %
|
||||
(solver.ObjectiveValue(), solver.WallTime(),
|
||||
solver.NumConflicts()))
|
||||
if status in (cp_model.OPTIMAL, cp_model.FEASIBLE):
|
||||
print('Loss = %i, time = %.2f s, %i conflicts' % (
|
||||
solver.ObjectiveValue(), solver.WallTime(), solver.NumConflicts()))
|
||||
else:
|
||||
print('No solution')
|
||||
|
||||
@@ -753,7 +759,8 @@ def steel_mill_slab_with_mip_column_generation(problem):
|
||||
(num_valid_slabs, generate - start))
|
||||
|
||||
# create model and decision variables.
|
||||
solver = pywraplp.Solver('Steel', pywraplp.Solver.BOP_INTEGER_PROGRAMMING)
|
||||
solver = pywraplp.Solver('Steel',
|
||||
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
|
||||
selected = [
|
||||
solver.IntVar(0.0, 1.0, 'selected_%i' % i) for i in all_valid_slabs
|
||||
]
|
||||
@@ -776,7 +783,7 @@ def steel_mill_slab_with_mip_column_generation(problem):
|
||||
|
||||
### Output the solution.
|
||||
if status == pywraplp.Solver.OPTIMAL:
|
||||
print('Objective value = %f found in %f s' %
|
||||
print('Objective value = %f found in %.2f s' %
|
||||
(solver.Objective().Value(), time.time() - generate))
|
||||
else:
|
||||
print('No solution')
|
||||
|
||||
Reference in New Issue
Block a user