### Install Hyperpack using pip Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/installation.md Use this command to install the Hyperpack library from the Python Package Index (PyPI). ```bash pip install hyperpack ``` -------------------------------- ### Interactive Settings Validation Example Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Provides an interactive session demonstrating the process of applying new settings, manually validating changes, and handling invalid settings that raise a SettingsError. ```python >>> # after problem instantiation >>> problem.settings = new_settings # new assignment >>> # on the background problem.validate_settings() was called >>> # doing validation and attributes setting >>> >>> problem.settings["workers_num"] = 3 # no validation happened >>> # workers_num settings hasn't been changed >>> problem.validate_settings() # manually validate and apply settings >>> >>> # in case a wrong settings is given >>> problem.settings["workers_num"] = -3 >>> problem.validate_settings() # manually validate Traceback (most recent call last): ... hyperpack.exceptions.SettingsError: workers_num multi process setting must be positive integer ``` -------------------------------- ### Quick Start: Generate and Solve Random Problem Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Generate a random problem instance with specified container and item dimensions, then create and solve the problem using HyperPack. This is useful for testing and experimentation. ```python from hyperpack import generate_problem_data, HyperPack # Generate random problem data with 2 containers problem_data = generate_problem_data( containers_num=2, containers_width=50, containers_length=50, items_num=30, items_width=5, items_length=3 ) # Create and solve the problem problem = HyperPack(**problem_data) problem.hypersearch() # View the solution problem.log_solution() problem.create_figure(show=True) # Opens in browser (requires plotly) ``` -------------------------------- ### Initialize Hyperpack Logger Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/logging.md Import the logging module and get the 'hyperpack' logger instance. This logger is used throughout the library for user-intended messages. ```python import logging logger = logging.getLogger("hyperpack") ``` -------------------------------- ### Problem Instantiation Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Instantiate your problem with proper arguments for containers, items, and solver settings. ```APIDOC ## Problem Instantiation Instantiate your problem with proper arguments ```python >>> from hyperpack import HyperPack >>> problem = hyperpack.HyperPack( >>> containers=containers, # problem parameter >>> items=items, # problem parameter >>> settings=settings # solver/figure parameters >>> ) ``` According to the arguments given, the corresponding problem will be instantiated, ready to be solved with provided guidelines. ``` -------------------------------- ### Basic Solve Method Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Execute a single-pass construction heuristic for fast, basic packing solutions. ```python from hyperpack import HyperPack containers = {"box": {"W": 50, "L": 40}} items = { "item-1": {"w": 20, "l": 15}, "item-2": {"w": 18, "l": 12}, "item-3": {"w": 10, "l": 8} } problem = HyperPack(containers=containers, items=items) # Single-pass solving problem.solve() # View solution problem.log_solution() ``` -------------------------------- ### Generate Problem Data and Solve Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/README.rst Generates sample problem data for bin packing and then instantiates and solves the problem using HyperPack. Displays the generated containers and opens a visualization of the solution. ```python >>> from hyperpack import generate_problem_data, HyperPack >>> problem_data = hyperpack.generate_problem_data(containers_num=2) Containers number = 2 Containers: { "container-0": { "W": 48, "L": 53 }, "container-1": { "W": 53, "L": 49 } } Items number = 60 >>> problem = HyperPack(**problem_data) >>> problem.hypersearch() >>> problem.create_figure(show=True) >>> # figure opened in default browser >>> >>> # to see parameter explanation do: >>> help(generate_problem_data) ``` -------------------------------- ### Instantiate HyperPack for Strip Packing Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/strip_packing.md Initialize a strip packing problem by providing a strip_pack_width instead of containers. ```python >>> prob = HyperPack(items=items, strip_pack_width=10) >>> # a strip packing width problem is ready to be solved ``` -------------------------------- ### Log solution output Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/extra_methods.md Displays the formatted solution log or a warning if no solution exists. ```python >>> problem.log_solution() SOLUTION LOG: Percent total items stored : 100.0000% Container: container_0 60x30 [util%] : 100.0000% Container: container_1 60x50 [util%] : 91.2000% Remaining items : [] ``` ```python >>> problem.solution {} >>> problem.log_solution() No solving operation has been concluded. ``` -------------------------------- ### Applying New Settings Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Illustrates how to apply a completely new set of settings to an existing HyperPack problem instance. This action automatically triggers validation. ```python >>> problem.settings = new_settings >>> # new settings have been validated and applied ``` -------------------------------- ### Create and display figures Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/extra_methods.md Generates a visualization of the packing solution. The show parameter determines if the figure opens in the system browser. ```python problem.create_figure(show=show) # show in (True, False) ``` ```python >>> problem.create_figure() Can't create figure if a solution hasn't been found ``` -------------------------------- ### Solve 2D Bin Packing Problem Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/simple_solve.md Initializes the HyperPack solver with container, item, and settings data, then executes the solve method. ```python >>> from hyperpack import HyperPack >>> problem_data = { >>> "containers": containers, >>> "items": items, >>> "settings": settings >>> } >>> problem = HyperPack(**problem_data) >>> problem.solve() ``` -------------------------------- ### log_solution Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/extra_methods.md Returns a formatted output of the solution found or a warning if no solution exists. ```APIDOC ## log_solution ### Description Returns a formatted output of the solution found. If a solution has not been found, a warning message is logged. ### Method Method call ### Request Example problem.log_solution() ``` -------------------------------- ### Logging Solution Results Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Generate a formatted summary of the packing results, including utilization percentages and unplaced items. ```python from hyperpack import HyperPack containers = { "container-0": {"W": 60, "L": 30}, "container-1": {"W": 60, "L": 50} } items = {f"item-{i}": {"w": 5 + i % 8, "l": 4 + i % 6} for i in range(25)} problem = HyperPack(containers=containers, items=items) problem.hypersearch() # Get formatted solution log log_output = problem.log_solution() # Output: # Solution Log: # Percent total items stored : 100.0000% # Container: container-0 60x30 # [util%] : 98.5000% # Container: container-1 60x50 # [util%] : 75.2000% # Remaining items : [] ``` -------------------------------- ### String Representation of Containers Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Demonstrates how to obtain a user-friendly string representation of the problem's containers using `str()` or `print()`. ```python >>> print(problem.containers) # or str(problem.containers) Containers - id: container-id-0 width: 100 length: 100 - id: container-id-1 width: 200 length: 200 ``` -------------------------------- ### Create HyperPack Instance with Custom Data Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Instantiate the HyperPack class with custom container and item definitions, along with optional solver settings. This allows for precise problem configuration. ```python from hyperpack import HyperPack # Define containers (bins) with width (W) and length (L) containers = { "bin-A": {"W": 100, "L": 80}, "bin-B": {"W": 120, "L": 100} } # Define items with width (w) and length (l) items = { "item-1": {"w": 30, "l": 20}, "item-2": {"w": 25, "l": 15}, "item-3": {"w": 40, "l": 30}, "item-4": {"w": 15, "l": 10}, "item-5": {"w": 35, "l": 25}, "item-6": {"w": 20, "l": 20}, "item-7": {"w": 45, "l": 35}, "item-8": {"w": 10, "l": 8} } # Optional settings for solver configuration settings = { "rotation": True, # Enable item rotation (default: True) "max_time_in_seconds": 120, # Maximum solving time (default: 60) "workers_num": 4 # Number of parallel processes (default: 1) } # Instantiate the problem problem = HyperPack( containers=containers, items=items, settings=settings ) # Access problem attributes print(problem.containers) # View containers print(problem.items) # View items ``` -------------------------------- ### Check Solution Results Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Access the solution object and utilization metrics directly from the problem instance. ```python print(problem.solution) print(f"Container utilization: {problem.obj_val_per_container}") ``` -------------------------------- ### Accessing Problem Settings Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Demonstrates how to access the 'settings' attribute of a HyperPack problem instance after it has been initialized. ```python >>> problem.settings {"workers_num":2, "rotation": False} ``` -------------------------------- ### Load Benchmark Datasets in Python Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/benchmarks.md Access predefined container and item datasets from the Hopper and Turton 2000 benchmark suite to initialize a HyperPack problem. ```python >>> import hyperpack >>> # C1, C2, C3, C4, C5, C6, C7 >>> C3 = hyperpack.benchmarks.datasets.hopper_and_turton_2000.C3 >>> containers = C3.containers >>> items = C3.items_a # or items_b or items_c >>> problem = hyperpack.HyperPack(containers=containers, items=items) >>> print(len(items_a)) # number of items 28 >>> print(problem.containers) Containers - id: container_0 width: 60 length: 30 >>> problem.local_search() ``` -------------------------------- ### Access Items Instance Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Demonstrates how to access the 'items' attribute after instantiation, showing its content as a dictionary with item IDs and dimensions. ```python >>> problem.items {"item-0-id": {"w": 10, "l": 20}} ``` -------------------------------- ### Run Development Command-Line Tools Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/benchmarks.md Execute the development module to profile local search performance or generate test graphs based on pytest parameters. ```bash >>> python3 -m commands Development tool for various operations. arguments: --create-tests-graphs: Creates all the potential points tests graphs automatically by inspecting the pytests parametrize parameters for every test. --profile: Profile the local search for the corresponding benchmarks. Available choices: C1, C2, ..., C7 -p , --problem: the specific items set for profiling. Defaults to 'a'. Available choices: a, b, c ``` -------------------------------- ### Extra Methods Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/index.md Utility methods for logging, visualization, and item manipulation. ```APIDOC ## Extra Methods ### Description Methods for managing solutions and figures. ### Methods - **log_solution**: Logs the current state of the packing solution. - **create_figure**: Generates a visual representation of the packing solution. - **orient_items**: Adjusts the orientation of items within the packing area. - **sort_items**: Sorts items based on defined criteria. ``` -------------------------------- ### Access and Modify Problem Containers Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Demonstrates accessing the problem's containers after instantiation and how modifications to the `containers` attribute trigger validation and reset the `solution` attribute. ```python >>> problem.containers {"container-0-id": {"W": 100, "L": 200}} ``` ```python # after instantiation >>> problem.solve() # updates self.solution with solution >>> problem.containers = new_containers >>> # validation happened without error >>> assert problem.solution == {} >>> >>> >>> problem.solve() # updates self.solution with solution >>> problem.containers["container-id-0"] = {"W":100, "L":200} >>> assert problem.solution == {} >>> >>> >>> problem.solve() # updates self.solution with solution >>> problem.containers["container-id-0"]["W"] = 200 >>> assert problem.solution == {} ``` ```python # now an invalid containers assignment >>> problem.containers = {"container-id-0": {"W":-100, "L":100}} Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: Width and Length must be positine numbers ``` ```python # now an invalid container key assignment >>> problem.containers["container-id-0"] = {"W": 100 Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: dimensions must (only) contain Width and Length keys ``` ```python # last an invalid Width assignment >>> problem.containers["container-id-0"]["W"] = 100.1 Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: Width and Length must be positine numbers ``` -------------------------------- ### Log Solution with Hyperpack Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/README.rst Use the `log_solution` method to log an already found solution. This method outputs details about the stored items and remaining items. ```python >>> problem.log_solution() Solution Log: Percent total items stored : 100.0000% Container: container-0-id 60x30 [util%] : 100.0000% Container: container-1-id 60x50 [util%] : 91.2000% Remaining items : [] ``` -------------------------------- ### Instantiate HyperPack Problem Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/README.rst Instantiates the HyperPack problem with custom containers, items, and settings. The structure of containers and items is defined, requiring positive integer dimensions. ```python >>> from hyperpack import HyperPack >>> problem = hyperpack.HyperPack( >>> containers=containers, # problem parameter >>> items=items, # problem parameter >>> settings=settings # solver/figure parameters >>> ) ``` ```python containers = { "container-0-id": { "W": int, # > 0 container's width "L": int # > 0 container's length }, "container-1-id": { "W": int, # > 0 container's width "L": int # > 0 container's length }, # ... rest of the containers # minimum 1 container must be provided } items = { "item-0-id": { "w": int, # > 0 item's width "l": int, # > 0 item's length }, "item-1-id": { "w": int, # > 0 item's width "l": int, # > 0 item's length }, # ... rest of the items # minimum 1 item must be provided } ``` -------------------------------- ### Updating Settings Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Demonstrates the two methods for updating the settings of an instantiated HyperPack object. ```APIDOC ## Updating Settings ### Description There are two primary methods for changing the settings of an already instantiated HyperPack object. ### Method A: New Assignment of Settings Assigning a new dictionary to the `settings` attribute automatically validates and applies the new settings. #### Endpoint `problem.settings = new_settings` #### Request Example ```python >>> problem.settings = new_settings ``` ### Method B: Changing a Key/Value and Manual Validation Modifying individual key-value pairs within the `settings` dictionary does not trigger automatic validation. Manual validation is required using `problem.validate_settings()`. #### Endpoint `problem.settings[key] = value` `problem.validate_settings()` #### Request Example ```python >>> problem.settings["workers_num"] = 3 # No validation occurs here >>> problem.validate_settings() # Manually validate and apply settings ``` ### Error Handling Attempting to apply invalid settings through `validate_settings()` will raise a `SettingsError`. #### Request Example ```python >>> problem.settings["workers_num"] = -3 >>> problem.validate_settings() Traceback (most recent call last): ... hyperpack.exceptions.SettingsError: workers_num multi process setting must be positive integer ``` #### NOTE The `solution` attribute will not be reset when settings are reassigned. ``` -------------------------------- ### Settings Structure and Defaults Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Defines the valid structure for the settings dictionary, including default values for various parameters. ```APIDOC ## Settings Structure ### Description Defines the valid structure for the `settings` dictionary, including default values for various parameters. ### Parameters #### Request Body - **workers_num** (int) - Optional - The number of processor threads for hypersearch. Defaults to 1. - **max_time_in_seconds** (int) - Optional - The maximum time in seconds for solving. Defaults to 60. - **rotation** (bool) - Optional - If item rotation is enabled. Defaults to True. - **figure** (object) - Optional - Configuration for figure export and display. - **export** (object) - Optional - Settings for exporting figures. - **type** (str) - Optional - The type of export, either "image" or "html". - **format** (str) - Optional - The format for image export (e.g., "pdf", "png", "jpeg", "webp", "svg"). Unnecessary if exporting as HTML. - **path** (str) - Required if export is enabled - The absolute path to the figure directory. Must be a valid system absolute path. - **file_name** (str) - Optional - The name of the exported figure file. Defaults to "PlotlyGraph". Must match the regex `^[a-zA-Z0-9_-]{1,45}$`. - **width** (int) - Optional - The width of the figure in pixels. Defaults to 1700. - **height** (int) - Optional - The height of the figure in pixels. Defaults to 1700. - **show** (bool) - Optional - If the figure will be shown when `create_figure` is called. Falls back to `create_figure`'s `show` kwarg (default False) if omitted. ### Request Example ```json { "workers_num": 2, "rotation": false, "figure": { "export": { "type": "image", "format": "png", "path": "/abs/path/to/figures", "file_name": "MyPlot" } } } ``` ### Response #### Success Response (200) - **settings** (object) - The applied settings. ### Response Example ```json { "workers_num": 2, "rotation": false, "figure": { "export": { "type": "image", "format": "png", "path": "/abs/path/to/figures", "file_name": "MyPlot" } } } ``` ``` -------------------------------- ### Accessing Solution Structure and Utilization Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt The solution is stored as a nested dictionary mapping containers to placed items, including their position (Xo, Yo) and dimensions (w, l). You can also access utilization values per container. ```python from hyperpack import HyperPack containers = {"main-bin": {"W": 50, "L": 40}} items = { "box-A": {"w": 15, "l": 12}, "box-B": {"w": 20, "l": 10}, "box-C": {"w": 10, "l": 8} } problem = HyperPack(containers=containers, items=items) problem.hypersearch() # Solution structure # { # "main-bin": { # "box-A": [Xo, Yo, w, l], # [0, 0, 15, 12] # "box-B": [Xo, Yo, w, l], # [15, 0, 20, 10] # "box-C": [Xo, Yo, w, l], # [0, 12, 10, 8] # } # } for container_id in problem.solution: print(f"Container: {container_id}") for item_id, placement in problem.solution[container_id].items(): x_origin, y_origin, width, length = placement print(f" {item_id}: placed at ({x_origin}, {y_origin}), size {width}x{length}") # Access utilization values for container_id, util in problem.obj_val_per_container.items(): print(f"{container_id} utilization: {util * 100:.2f}%") ``` -------------------------------- ### Executing a Hypersearch Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/hypersearch.md Initializes a HyperPack problem instance and executes the hypersearch method with specific orientation and sorting configurations. ```python >>> from hyperpack import HyperPack >>> problem_data = { >>> "containers": containers, >>> "items": items, >>> "settings": settings >>> } >>> problem = HyperPack(**problem_data) >>> problem.hypersearch( >>> orientation="wide", >>> sorting_by=("area", True) >>> ) ``` -------------------------------- ### create_figure Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/extra_methods.md Creates and optionally displays a figure representing the solution. ```APIDOC ## create_figure ### Description A figure can be created and shown/exported. If no solving operation has taken place, a warning message will be logged. ### Parameters #### Query Parameters - **show** (bool) - Optional - Controls whether the figure will be opened in the default system browser. Default is not specified. ### Request Example problem.create_figure(show=True) ``` -------------------------------- ### Solve with Local Search Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/localsearch.md Initiates a hill-climbing, 2-opt exchange local search using default potential points. The best solution is stored in the `problem.solution` attribute after completion. ```python from hyperpack import HyperPack problem_data = { "containers": containers, "items": items, "settings": settings } problem = HyperPack(**problem_data) problem.local_search() ``` -------------------------------- ### Load and Use Benchmark Datasets Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt HyperPack includes benchmark datasets from Hopper and Turton (2000) for testing. Load datasets like C3 and access their containers and item sets (items_a, items_b, items_c). ```python import hyperpack from hyperpack import HyperPack # Load benchmark dataset C3 C3 = hyperpack.benchmarks.datasets.hopper_and_turton_2000.C3 # Access containers and different item sets containers = C3.containers # {"container_0": {"W": 60, "L": 30}} items_a = C3.items_a # 16 items items_b = C3.items_b # 17 items items_c = C3.items_c # 16 items # Solve benchmark problem problem = HyperPack(containers=containers, items=items_a) problem.hypersearch(orientation="wide", sorting_by=("area", True)) problem.log_solution() # Available benchmarks: C1, C2, C3, C4, C5, C6, C7 C1 = hyperpack.benchmarks.datasets.hopper_and_turton_2000.C1 C7 = hyperpack.benchmarks.datasets.hopper_and_turton_2000.C7 ``` -------------------------------- ### Local Search with Default Settings Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/README.rst Performs a local search on the HyperPack problem using default settings. The solution is stored in the 'problem.solution' attribute after completion. ```python >>> from hyperpack import HyperPack >>> problem_data = { >>> "containers": containers, >>> "items": items, >>> "settings": settings >>> } >>> problem = HyperPack(**problem_data) >>> problem.local_search() ``` -------------------------------- ### Manually Validating Settings Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Explains how to manually validate and apply settings after changing individual key/value pairs within the settings dictionary. Direct modification does not trigger automatic validation. ```python >>> problem.settings["workers_num"] = 3 # no validation happened >>> # workers_num setting hasn't been changed >>> problem.validate_settings() # manually validate and apply settings >>> # new settings have been validated and applied ``` -------------------------------- ### Define the solution structure Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/solution_structure.md The solution object is a dictionary where keys are container IDs and values are dictionaries of item placements defined by origin coordinates and dimensions. ```python problem.solution = { "container-0-id": { "item_id": [ Xo, # item's X coordinate of the origin's placement Yo, # item's Y coordinate of the origin's placement w, # item's width l, # item's length # item's w, l will be interchanged # if the item was rotated while solving ], "item_id": [Xo, Yo, w, l], # ... }, "container-1-id" : { "item_id": [Xo, Yo, w, l], "item_id": [Xo, Yo, w, l], # ... }, # all the containers } ``` -------------------------------- ### Container and Dimension Types Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Shows the specific class types for `problem.containers` and its elements, highlighting that they are custom dictionary-like objects with predefined behavior. ```python >>> type(problem.containers) >>> type(problem.containers["container-id-0"]) ``` -------------------------------- ### Orient and Sort Items Before Solving Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Manipulate item dimensions and order before solving to potentially improve solution quality. Use 'wide' or 'long' for orientation, and specify sorting criteria like 'area', 'perimeter', or 'longest_side_ratio'. Pass None to skip. ```python from hyperpack import HyperPack containers = {"bin": {"W": 50, "L": 40}} items = { "tall-item": {"w": 5, "l": 20}, # Tall orientation "wide-item": {"w": 25, "l": 8}, # Wide orientation "square-item": {"w": 12, "l": 12} } problem = HyperPack(containers=containers, items=items) # Orient all items to be wider than tall problem.orient_items(orientation="wide") print(problem.items) # tall-item now: {"w": 20, "l": 5} # Or orient to be taller than wide problem.orient_items(orientation="long") # Sort items by different criteria problem.sort_items(sorting_by=("area", True)) # By area, descending problem.sort_items(sorting_by=("perimeter", False)) # By perimeter, ascending problem.sort_items(sorting_by=("longest_side_ratio", True)) # By aspect ratio # Skip orientation/sorting by passing None problem.orient_items(orientation=None) problem.sort_items(sorting_by=None) problem.local_search() ``` -------------------------------- ### Creating and Exporting Figures Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Visualize packing solutions using Plotly and export them to HTML or image formats. ```python from hyperpack import HyperPack containers = {"display-bin": {"W": 80, "L": 60}} items = { "red-box": {"w": 20, "l": 15}, "blue-box": {"w": 25, "l": 20}, "green-box": {"w": 15, "l": 10}, "yellow-box": {"w": 30, "l": 25} } # Settings for figure export (requires plotly >= 5.14.0) settings = { "figure": { "show": True, # Open in browser when create_figure called "export": { "type": "html", # "html" or "image" "path": "/tmp/figures", # Export directory "file_name": "packing_result" } } } problem = HyperPack(containers=containers, items=items, settings=settings) problem.hypersearch() # Create and display figure problem.create_figure(show=True) # Override show setting # For image export (requires kaleido >= 0.2.1) settings_image = { "figure": { "export": { "type": "image", "format": "png", # "pdf", "png", "jpeg", "webp", "svg" "path": "/tmp/figures", "file_name": "solution", "width": 1700, # Pixels "height": 1700 } } } ``` -------------------------------- ### Multiprocessing Entry Point Protection (Windows) Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Provides the necessary code structure for safeguarding the main module when using multiprocessing in Windows environments, as required by the 'workers_num' setting. ```python # in main execution module # safe guarding # only in windows OS systems if __name__ == "__main__": problem.hypersearch() ``` -------------------------------- ### HyperPack Core Components Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/reference.md Overview of the primary classes and mixins provided by the HyperPack library. ```APIDOC ## HyperPack ### Description Core module for the HyperPack project. ## PointGenPack ### Description Module for point generation packing strategies. ## BasePackingProblem ### Description Base class for defining packing problems. ## PointGenerationSolver ### Description Solver implementation for point generation based packing. ## PointGenerationMixin ### Description Mixin providing point generation functionality. ## SolutionFigureMixin ### Description Mixin for handling solution visualization or figure generation. ## DeepcopyMixin ### Description Mixin providing deepcopy capabilities for objects. ## LocalSearchMixin ### Description Mixin providing local search optimization capabilities. ``` -------------------------------- ### HyperPack.local_search Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/index.md Executes a local search algorithm to optimize the packing solution. ```APIDOC ## local_search ### Description Performs a local search to improve the current packing solution. ### Method Method call on HyperPack instance ### Parameters #### Request Body - **args** (various) - Optional - Parameters defining the local search strategy and constraints. ``` -------------------------------- ### Default Settings on Omission Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Shows the default behavior when the 'settings' parameter is omitted during HyperPack instantiation. Default values are assigned to specific attributes. ```python >>> problem = HyperPack(items=items, containers=containers) >>> problem.settings {} ``` -------------------------------- ### Customize Potential Points Strategy Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Control the order in which insertion points are evaluated during the construction heuristic by setting the 'potential_points_strategy' attribute. The default strategy is ('A', 'B', 'C', 'D', 'A_', 'B_', 'B__', 'A__', 'E', 'F'). ```python from hyperpack import HyperPack containers = {"bin": {"W": 40, "L": 30}} items = {f"item-{i}": {"w": 6 + i % 4, "l": 5 + i % 3} for i in range(15)} problem = HyperPack(containers=containers, items=items) # View default strategy print(problem.DEFAULT_POTENTIAL_POINTS_STRATEGY) # ('A', 'B', 'C', 'D', 'A_', 'B_', 'B__', 'A__', 'E', 'F') # Set custom strategy (must be tuple with valid point types) problem.potential_points_strategy = ("B", "A", "D", "C", "B_", "A_", "A__", "B__", "F", "E") # Solve with custom strategy problem.local_search() ``` -------------------------------- ### Reset Container Height Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/strip_packing.md Restore the container height and clear the minimum height constraint after solving. ```python >>> prob = HyperPack(**problem_data) >>> prob.settings["workers_num"] == 1 True >>> prob.container_height 200 >>> prob.container_min_height = 100 >>> prob.hypersearch() >>> prob.container_height < 200 True >>> prob.reset_container_height() >>> prob.container_height 200 >>> prob.container_min_height == None True >>> >>> # now with multiprocessing ------ >>> >>> prob = HyperPack(**problem_data_mp) >>> prob.settings["workers_num"] > 1 True >>> prob.container_height 200 >>> prob.hypersearch() >>> prob.container_height == 200 True ``` -------------------------------- ### Modify Containers and Items After Instantiation Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Containers and items can be modified after instantiation. Changes trigger validation and reset the solution. You can modify existing entries, add new ones, or replace the entire structure. ```python from hyperpack import HyperPack containers = {"bin-1": {"W": 50, "L": 40}} items = {"item-1": {"w": 10, "l": 8}} problem = HyperPack(containers=containers, items=items) problem.solve() # Modify containers (resets solution) problem.containers["bin-1"]["W"] = 60 # Change width problem.containers["bin-2"] = {"W": 80, "L": 60} # Add new container # Modify items (resets solution) problem.items["item-1"]["w"] = 12 # Change width problem.items["item-2"] = {"w": 15, "l": 10} # Add new item # Replace entire structure problem.containers = {"new-bin": {"W": 100, "L": 80}} problem.items = { "new-item-1": {"w": 20, "l": 15}, "new-item-2": {"w": 25, "l": 20} } # Re-solve with new data problem.hypersearch() ``` -------------------------------- ### Strip Packing Mode Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Minimize height for items packed into a fixed-width strip by using the strip_pack_width parameter. ```python from hyperpack import HyperPack items = { "piece-1": {"w": 8, "l": 12}, "piece-2": {"w": 6, "l": 10}, "piece-3": {"w": 10, "l": 8}, "piece-4": {"w": 4, "l": 6}, "piece-5": {"w": 12, "l": 4}, "piece-6": {"w": 5, "l": 9} } # Create strip packing problem with width=20 problem = HyperPack( items=items, strip_pack_width=20, # Fixed width, variable height settings={"max_time_in_seconds": 30} ) # Solve to minimize height problem.hypersearch() # Log solution with height info problem.log_solution() # Optional: Set minimum height constraint problem.container_min_height = 15 problem.reset_container_height() # Reset for new solve problem.hypersearch() # Check current container height print(f"Container height: {problem.container_height}") ``` -------------------------------- ### HyperPack.hypersearch Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/index.md Executes a hyper-heuristic search to find optimal packing configurations. ```APIDOC ## hypersearch ### Description Uses a hyper-heuristic approach to explore the solution space for packing problems. ### Method Method call on HyperPack instance ### Parameters #### Request Body - **args** (various) - Optional - Configuration parameters for the hyper-heuristic search process. ``` -------------------------------- ### Create Figure with Hyperpack Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/README.rst Create a figure using the `create_figure` method. Requires plotly (5.14.0+) and kaleido (0.2.1+) for figure exportation. The figure will open in the default browser. ```python >>> problem.create_figure(show=True) ``` -------------------------------- ### Solve Problem with Local Search Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Execute a hill-climbing local search using `local_search()` for a faster, though potentially suboptimal, solution. This method uses the default potential points strategy and can be throttled for performance. ```python from hyperpack import HyperPack containers = {"bin-1": {"W": 40, "L": 30}} items = { "part-A": {"w": 10, "l": 8}, "part-B": {"w": 12, "l": 6}, "part-C": {"w": 8, "l": 10}, "part-D": {"w": 15, "l": 12}, "part-E": {"w": 6, "l": 4} } problem = HyperPack(containers=containers, items=items) # Run local search problem.local_search(throttle=True) ``` -------------------------------- ### Solve Problem with Hypersearch Source: https://context7.com/alkiviadisaleiferis/hyperpack/llms.txt Utilize the `hypersearch()` method for exhaustive exploration of potential point strategies combined with local search to find optimal solutions. This method can be configured with item orientation and sorting parameters. ```python from hyperpack import HyperPack containers = {"container-0": {"W": 60, "L": 50}} items = { "i_0": {"w": 12, "l": 8}, "i_1": {"w": 15, "l": 10}, "i_2": {"w": 20, "l": 12}, "i_3": {"w": 8, "l": 6}, "i_4": {"w": 25, "l": 15}, "i_5": {"w": 10, "l": 10}, "i_6": {"w": 18, "l": 8}, "i_7": {"w": 14, "l": 12} } problem = HyperPack( containers=containers, items=items, settings={"max_time_in_seconds": 60, "rotation": True} ) # Hypersearch with item orientation and sorting problem.hypersearch( orientation="wide", # Orient items to be wider than tall sorting_by=("area", True), # Sort by area, descending throttle=True # Limit neighbor exploration for speed ) # Access results print(f"Best strategy found: {problem.best_strategy}") print(f"Utilization per container: {problem.obj_val_per_container}") # Solution structure: {container_id: {item_id: [Xo, Yo, w, l], ...}} for container_id, placed_items in problem.solution.items(): print(f"\nContainer: {container_id}") for item_id, coords in placed_items.items(): Xo, Yo, w, l = coords print(f" {item_id}: position=({Xo}, {Yo}), size={w}x{l}") ``` -------------------------------- ### Containers Parameter Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Defines the structure and validation rules for the `containers` parameter. ```APIDOC ## Containers Parameter In figure 1 the container’s (bin’s) coordinate system can be seen. > - **W** is the width of the container (x coordinate). > - **L** is the length of the container (y coordinate). ![container](_static/container.png) This is the `containers` valid structure: ```python containers = { "container-0-id": { "W": int, # > 0 container's width "L": int # > 0 container's length }, "container-1-id": { "W": int, # > 0 container's width "L": int # > 0 container's length }, # ... rest of the containers # minimum 1 container must be provided } ``` A `ContainersError` will be raised at instantiation/validation in case: : - The containers parameter isn’t a dictionary with the above structure specified. - There isn’t at least one container in containers. - A container’s **id** isn’t a string. A `DimensionsError` will be raised at instantiation/validation in case: : - `"W"` or `"L"` values aren’t positive integers. - `"W"` and/or `"L"` are not provided for a given container. - another key beside `"W"` or `"L"` is given for a container. - a deletion of a dimension’s key (“W” or “L”) is attempted. The problem’s containers after instantiation can be found in the `problem.containers` instance attribute: ```python >>> problem.containers {"container-0-id": {"W": 100, "L": 200}} ``` #### NOTE Each **assignement, key value change or deletion** after instantiation of the `containers` attribute, will **trigger** **validation**, and also reset the `solution` attribute of the instance. This reset affects the **figure creation** and the **solution logging**, since they both use the `solution` attribute. In that case if any of the above requirements aren’t met, a `ContainersError` or `DimensionsError` will be raised. ```python >>> # after instantiation >>> problem.solve() # updates self.solution with solution >>> problem.containers = new_containers >>> # validation happened without error >>> assert problem.solution == {} >>> >>> >>> problem.solve() # updates self.solution with solution >>> problem.containers["container-id-0"] = {"W":100, "L":200} >>> assert problem.solution == {} >>> >>> >>> problem.solve() # updates self.solution with solution >>> problem.containers["container-id-0"]["W"] = 200 >>> assert problem.solution == {} >>> >>> >>> # now an invalid containers assignment >>> problem.containers = {"container-id-0": {"W":-100, "L":100}} Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: Width and Length must be positine numbers >>> >>> >>> # now an invalid container key assignment >>> problem.containers["container-id-0"] = {"W": 100 Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: dimensions must (only) contain Width and Length keys >>> >>> >>> # last an invalid Width assignment >>> problem.containers["container-id-0"]["W"] = 100.1 Traceback (most recent call last): ... hyperpack.exceptions.DimensionsError: Width and Length must be positine numbers ``` Must be noted, that `containers` is not of type dict, but an instance of the `hyperpack.structures.Containers` class, that inherits from `hyperpack.structures.AbstractStructureSet`. That is a customized dictionary with predefined behaviour. Also each container’s (and item’s as we ‘ll see later) dimensions are an instance of `hyperpack.structures.Dimensions` class. ```python >>> type(problem.containers) >>> type(problem.containers["container-id-0"]) ``` Also a string representation with `str()` (or implicitly with `print()`) exists: ```python >>> print(problem.containers) # or str(problem.containers) Containers - id: container-id-0 width: 100 length: 100 - id: container-id-1 width: 200 length: 200 ``` ``` -------------------------------- ### HyperPack Settings Structure Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Defines the valid structure for the settings dictionary, including types and default values for various parameters like workers, time limits, rotation, and figure export options. ```python settings = { "workers_num": int, # (> 0) the number of processor threads for hypersearch # defaults to 1 if omitted "max_time_in_seconds": int, # (> 0) the max time for solving # defaults to 60 "rotation": bool , # if item rotation is enabled # defaults to True # figure key can be omitted "figure": { "export": { "type": str, # "image" or "html" "format": str, # "pdf", "png", "jpeg", "webp", "svg" # unecessary if html exportation "path": "abs/path/to/figure/directory", # must be valid system absolute path "file_name": str, # "PlotlyGraph" default value # if file_name given, it must match the # r"^[a-zA-Z0-9_-]{1,45}$" regex "width": int, # (> 1) pixels number (default 1700px) "height": int, # (> 1) pixels number (default 1700px) }, "show": bool, # if the figure will be shown when create_figure is called # if omitted, falls back to create_figure's # 'show' kwarg (default False) } } ``` -------------------------------- ### workers_num Configuration Source: https://github.com/alkiviadisaleiferis/hyperpack/blob/main/docs/source/problem_params.md Details on configuring the `workers_num` setting for multiprocessing and its implications. ```APIDOC ## workers_num Configuration ### Description Configures the number of processor threads for hypersearch. When set to a value greater than 1, multiprocessing is enabled. ### Method Set the `workers_num` key within the `settings` dictionary. ### Endpoint `problem.settings["workers_num"] = value` ### Parameters - **workers_num** (int) - Required/Optional - The number of processor threads for hypersearch. Must be a positive integer. Defaults to 1. ### Behavior - If `workers_num` is greater than 1, a multiprocessing search will be deployed when `hypersearch` is used. - On Windows OS, if `workers_num` is greater than 1, a warning will be logged, reminding the user to implement entry point protection for multiprocessing. - If the value is not a positive integer, a `SettingsError` will be raised upon validation. ### Request Example ```python >>> problem.settings["workers_num"] = 2 >>> problem.validate_settings() ``` ### Warning Example (Windows OS) ``` In Windows OS multiprocessing needs 'Entry point protection' which means adding if '__name__' == '__main__' before multiprocessing depending code execution ``` ### Error Example ```python >>> problem.settings["workers_num"] = -1 >>> problem.validate_settings() Traceback (most recent call last): ... hyperpack.exceptions.SettingsError: workers_num multi process setting must be positive integer ``` ### Multiprocessing Considerations When using multiprocessing (i.e., `workers_num` > 1) on Windows, it is necessary to safeguard the main module by including `if __name__ == "__main__":` before any multiprocessing-dependent code execution, as per the Python standard library documentation. ```