new example: pell equation
This commit is contained in:
@@ -58,6 +58,8 @@ code_sample_py("maze_escape_sat")
|
||||
|
||||
code_sample_py("no_wait_baking_scheduling_sat")
|
||||
|
||||
code_sample_py("pell_equation_sat")
|
||||
|
||||
code_sample_py("pentominoes_sat")
|
||||
|
||||
code_sample_py("prize_collecting_tsp_sat")
|
||||
@@ -96,6 +98,8 @@ code_sample_py("task_allocation_sat")
|
||||
|
||||
code_sample_py("tasks_and_workers_assignment_sat")
|
||||
|
||||
code_sample_py("test_scheduling_sat")
|
||||
|
||||
code_sample_py("tsp_sat")
|
||||
|
||||
code_sample_py("vendor_scheduling_sat")
|
||||
|
||||
@@ -23,11 +23,8 @@ of the rule.
|
||||
"""
|
||||
|
||||
from absl import app
|
||||
from absl import flags
|
||||
from ortools.constraint_solver import pywrapcp
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
|
||||
# We disable the following warning because it is a false positive on constraints
|
||||
# like: solver.Add(x == 0)
|
||||
# pylint: disable=g-explicit-bool-comparison
|
||||
|
||||
@@ -47,7 +47,7 @@ _MODEL = flags.DEFINE_string(
|
||||
)
|
||||
|
||||
|
||||
class SectionInfo(object):
|
||||
class SectionInfo:
|
||||
"""Store model information for each section of the input file."""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -50,7 +50,7 @@ DECORATING = "decorating"
|
||||
DISPLAY = "display"
|
||||
|
||||
|
||||
class Task(object):
|
||||
class Task:
|
||||
"""A unit baking task.
|
||||
|
||||
- Simple baking tasks have a fixed duration. They are performed by workers.
|
||||
@@ -64,7 +64,7 @@ class Task(object):
|
||||
self.max_duration = max_duration
|
||||
|
||||
|
||||
class Skill(object):
|
||||
class Skill:
|
||||
"""The skill of a worker or the capability of a machine."""
|
||||
|
||||
def __init__(self, name, efficiency):
|
||||
@@ -73,7 +73,7 @@ class Skill(object):
|
||||
self.efficiency = efficiency
|
||||
|
||||
|
||||
class Recipe(object):
|
||||
class Recipe:
|
||||
"""A recipe is a sequence of cooking tasks."""
|
||||
|
||||
def __init__(self, name):
|
||||
@@ -85,7 +85,7 @@ class Recipe(object):
|
||||
return self
|
||||
|
||||
|
||||
class Resource(object):
|
||||
class Resource:
|
||||
"""A resource is a worker, a machine, or just some space for cakes to rest.
|
||||
|
||||
- Workers have a capacity of 1 and can have variable efficiency.
|
||||
@@ -106,7 +106,7 @@ class Resource(object):
|
||||
return self
|
||||
|
||||
|
||||
class Order(object):
|
||||
class Order:
|
||||
"""An order is a recipe that should be delivered at a given due date."""
|
||||
|
||||
def __init__(self, unique_id, recipe_name, due_date, quantity):
|
||||
|
||||
@@ -20,6 +20,9 @@ as a linear boolean problem.
|
||||
|
||||
This problem comes from the game Katamino:
|
||||
http://boardgamegeek.com/boardgame/6931/katamino
|
||||
|
||||
This example also includes suggestions from
|
||||
https://web.ma.utexas.edu/users/smmg/archive/1997/radin.html
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
@@ -42,6 +45,8 @@ _PIECES = flags.DEFINE_string(
|
||||
"pieces", "FILNPTUVWXYZ", "The subset of pieces to consider."
|
||||
)
|
||||
|
||||
_HEIGHT = flags.DEFINE_integer("height", 5, "The height of the box.")
|
||||
|
||||
|
||||
def is_one(mask: List[List[int]], x: int, y: int, orientation: int) -> bool:
|
||||
"""Returns true if the oriented piece is 1 at position [i][j].
|
||||
@@ -104,8 +109,9 @@ def orientation_is_redundant(mask: List[List[int]], orientation: int) -> bool:
|
||||
|
||||
def generate_and_solve_problem(pieces: Dict[str, List[List[int]]]) -> None:
|
||||
"""Solves the pentominoes problem."""
|
||||
box_width = len(pieces)
|
||||
box_height = 5
|
||||
box_height = _HEIGHT.value
|
||||
box_width = 5 * len(pieces) // box_height
|
||||
print(f"Box has dimension {box_height} * {box_width}")
|
||||
|
||||
model = cp_model.CpModel()
|
||||
position_to_variables: List[List[List[cp_model.IntVar]]] = [
|
||||
@@ -142,8 +148,8 @@ def generate_and_solve_problem(pieces: Dict[str, List[List[int]]]) -> None:
|
||||
status = solver.solve(model)
|
||||
|
||||
print(
|
||||
f"Problem {_PIECES.value} solved in {solver.wall_time}s with status"
|
||||
f" {solver.status_name(status)}"
|
||||
f"Problem {_PIECES.value} box {box_height}*{box_width} solved in"
|
||||
f" {solver.wall_time}s with status {solver.status_name(status)}"
|
||||
)
|
||||
|
||||
# Print the solution.
|
||||
@@ -183,6 +189,16 @@ def main(argv: Sequence[str]) -> None:
|
||||
print(f"Piece {p} not found in the list of pieces")
|
||||
return
|
||||
selected_pieces[p] = pieces[p]
|
||||
if (len(selected_pieces) * 5) % _HEIGHT.value != 0:
|
||||
print(
|
||||
f"The height {_HEIGHT.value} does not divide the total area"
|
||||
f" {5 * len(selected_pieces)}"
|
||||
)
|
||||
return
|
||||
if _HEIGHT.value < 3 or 5 * len(selected_pieces) // _HEIGHT.value < 3:
|
||||
print(f"The height {_HEIGHT.value} is not compatible with the pieces.")
|
||||
return
|
||||
|
||||
generate_and_solve_problem(selected_pieces)
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ _OUTPUT_PROTO = flags.DEFINE_string(
|
||||
)
|
||||
_PARAMS = flags.DEFINE_string(
|
||||
"params",
|
||||
"num_search_workers:16,log_search_progress:false,max_time_in_seconds:45",
|
||||
"num_search_workers:16,log_search_progress:true,max_time_in_seconds:45",
|
||||
"Sat solver parameters.",
|
||||
)
|
||||
_PREPROCESS = flags.DEFINE_bool(
|
||||
|
||||
Reference in New Issue
Block a user