@jetta/blocks-allocator 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -2
- package/package.json +67 -5
- package/src/Allocation_Attempt.js +135 -0
- package/src/Allocation_Error_Handler.js +69 -0
- package/src/Allocation_Flow.js +162 -0
- package/src/Allocation_Optimization/Allocation_LP.js +150 -0
- package/src/Allocation_Optimization/Block_Allocator.js +129 -0
- package/src/Allocation_Optimization/Block_Layer_Order.js +50 -0
- package/src/Allocation_Optimization/Block_Potential_Weight.js +54 -0
- package/src/Allocation_Optimization/Chosen_Blocks_Stock_Cap.js +82 -0
- package/src/Allocation_Optimization/block_builder/Allocation_Item_Creator.js +37 -0
- package/src/Allocation_Optimization/block_builder/Block_Item_List_Validator.js +18 -0
- package/src/Allocation_Optimization/block_builder/Block_Wall_Builder.js +303 -0
- package/src/Allocation_Optimization/block_builder/Blocks_Builder.js +40 -0
- package/src/Allocation_Optimization/block_builder/Next_Block_Position.js +33 -0
- package/src/Allocation_Optimization/block_builder/Slot_Item_Assigner.js +45 -0
- package/src/Allocation_Optimization/block_builder/Stacking_Validation.js +30 -0
- package/src/Allocation_Optimization/block_builder/assert_tie_ratio_block_matches_orientation_below.js +44 -0
- package/src/Allocation_Optimization/block_builder/block_shape_stock.js +129 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Empty_Block_Item_List_Exception.js +21 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception.js +14 -0
- package/src/Allocation_Optimization/block_builder/exceptions/No_Suitable_Item_Exception.js +16 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception.js +21 -0
- package/src/Allocation_Optimization/block_builder/should_omit_block_group_id.js +29 -0
- package/src/Allocation_Optimization/block_builder/snap_elevated_block_wall_items.js +34 -0
- package/src/Allocation_Optimization/block_builder/stacking_rules_input.js +52 -0
- package/src/Allocation_Optimization/cap_chosen_blocks_by_shape_stock.js +110 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Preparer.js +21 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Selector.js +55 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Threshold_Resolver.js +28 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Thresholds.js +23 -0
- package/src/Allocation_Optimization/density_groups/Container_Utilization.js +67 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Partitioner.js +74 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Scheduler.js +168 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Stock.js +49 -0
- package/src/Allocation_Optimization/density_groups/Density_Groups_Strategy.js +26 -0
- package/src/Allocation_Optimization/density_groups/Item_Density_Calculator.js +20 -0
- package/src/Allocation_Optimization/density_groups/Lock_Weight_Ahead_Release.js +75 -0
- package/src/Allocation_Optimization/exceptions/Invalid_Item_Amount_Exception.js +17 -0
- package/src/Allocation_Optimization/exceptions/No_Valid_Allocation_Exception.js +14 -0
- package/src/Allocation_Optimization/exceptions/Optimization_Infeasible_Exception.js +14 -0
- package/src/Allocation_Optimization/functions/Measure_Reader.js +20 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Mode.js +25 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Strategies.js +8 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js +70 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Translation.js +22 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Variable_Weight_Getter.js +85 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/constants.js +16 -0
- package/src/Allocation_Optimization/functions/measure_to_optimize.js +6 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Capacity_Bias_Item_Order.js +76 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js +63 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Item_Chooser.js +159 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Item_For_Slot_Chooser.js +49 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Slot_Compatible_Items_Finder.js +88 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Slots_Items_Assigner.js +182 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Stack_Slot_Calculator.js +87 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Weight_Slot_Distribution.js +72 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Empty_Slot_Exception.js +17 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Item_Taller_Than_Limit_Exception.js +21 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Available_Items_Exception.js +14 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Slots_For_Items_Exception.js +14 -0
- package/src/Allocation_Optimization/lp_model/Block_Weight_Calculator.js +31 -0
- package/src/Allocation_Optimization/lp_model/LP_Data_Processor.js +42 -0
- package/src/Allocation_Optimization/lp_model/LP_Item_Slot_Assignment.js +93 -0
- package/src/Allocation_Optimization/lp_model/LP_Result_Mapper.js +47 -0
- package/src/Allocation_Optimization/lp_model/model_builder/Dimension_Range_Helper.js +49 -0
- package/src/Allocation_Optimization/lp_model/model_builder/Item_Assignment_Variables.js +133 -0
- package/src/Allocation_Optimization/lp_model/model_builder/LP_Model_Builder.js +132 -0
- package/src/Allocation_Optimization/lp_model/model_builder/exceptions/Missing_Item_Stock_Exception.js +18 -0
- package/src/Allocation_Optimization/lp_model/model_builder/goal_function/Goal_Function_Creator.js +83 -0
- package/src/Allocation_Optimization/lp_model/model_builder/item_dimension_hashes.js +31 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Block_Item_Amount_Restriction.js +53 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Coherence_Restriction.js +65 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Container_Supported_Weight_Restriction.js +42 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Exact_Pass_Amount_Restriction.js +62 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Group_Restriction.js +97 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Single_Item_Type_Restriction.js +79 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Space_Restriction.js +47 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Unavailable_Block_Restriction.js +27 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Uniform_Block_Measure_Restriction.js +92 -0
- package/src/Allocation_Optimization/next_group_id_after_preloaded.js +30 -0
- package/src/Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier.js +74 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/Key_Item_Mapper.js +49 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Almost_Unique_Item.js +31 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Cant_Stack_It_Self.js +68 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Rule_Interface.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Intercalation_State.js +49 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter.js +33 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter.js +20 -0
- package/src/Allocation_Optimization/tie_ratio/collect_tie_ratio_orientations_below_footprint.js +64 -0
- package/src/Allocation_Optimization/tie_ratio/filter_blocks_by_orientation.js +17 -0
- package/src/Allocation_Optimization/tie_ratio/find_orientation_below_space.js +77 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/allocated_item_penetrates_any.js +31 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item.js +94 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/axis_overlap_length.js +16 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/block_local_origin.js +18 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/box_fits_inside_container.js +39 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_allocated_item_at_placement.js +18 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_placement_on_generic_supporter.js +64 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_slot_grid_from_cluster.js +66 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/compare_group_ids.js +20 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/container_with_pending_wall_items.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/empty_space_is_on_floor.js +16 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/finalize_loose_item_placement.js +58 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_best_generic_supporter_placement.js +58 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_next_free_slot_index.js +119 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_supporter_directly_below.js +51 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_tie_ratio_supporter_cluster.js +57 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/footprint_xz_overlap_area.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/item_fits_supporter_slot.js +22 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_footprint_region_from_options.js +24 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_fits_inside_container.js +21 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_has_geometric_support.js +21 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_on_block_slot_state.js +88 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/placement_coords_fit_inside_container.js +34 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/read_empilhar_area_igual_from_allocation_item.js +12 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/realigned_loose_geometry_gates.js +25 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_on_generic_supporter.js +65 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_placement_position.js +68 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_placement_y_at_slot.js +45 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_without_tie_ratio_cluster.js +79 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/select_tie_ratio_slot_placement.js +84 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/slot_footprint_collision.js +105 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_cluster_selection.js +119 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_footprint_overlap.js +56 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_placement_plane.js +109 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_supporter_predicate.js +23 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/try_tie_ratio_slot_placement.js +62 -0
- package/src/Allocation_Optimization/tie_ratio/snap_stacked_items_to_floor_footprints.js +138 -0
- package/src/Allocation_Optimization/tie_ratio/supporters_by_top_y_index.js +78 -0
- package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space.js +89 -0
- package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_from_group.js +48 -0
- package/src/Block_Management.js +34 -0
- package/src/Blocks_Preparation/Cube_Map_Function.js +27 -0
- package/src/Blocks_Wall_Allocation.js +3 -0
- package/src/IO/Answer_Status.js +4 -0
- package/src/IO/Output_Builder.js +35 -0
- package/src/IO/count_allocated_items.js +31 -0
- package/src/IO/create_error_response.js +62 -0
- package/src/IO/format_allocation_error_message.js +25 -0
- package/src/Item_Continuation_Lock.js +129 -0
- package/src/Item_Picking_Continuity.js +41 -0
- package/src/allocation_flow/chooser_session_state.js +21 -0
- package/src/allocation_flow/compound_probe_fallback.js +17 -0
- package/src/allocation_flow/container_remaining_capacity.js +23 -0
- package/src/allocation_flow/density_group_item_filter.js +31 -0
- package/src/allocation_flow/effective_item_fingerprint.js +14 -0
- package/src/allocation_flow/item_continuation_lock_gate.js +38 -0
- package/src/allocation_flow/no_space_left_recovery.js +48 -0
- package/src/allocation_flow/run_allocation_iteration.js +155 -0
- package/src/allocation_flow/space_skip_state.js +91 -0
- package/src/allocation_flow/try_no_space_left_recovery.js +50 -0
- package/src/exceptions/Invalid_Parameter_Exception.js +17 -0
- package/src/exceptions/Relational_Allocation_Incomplete_Exception.js +24 -0
- package/src/exceptions/Relational_Colocation_Violation_Exception.js +23 -0
- package/src/exceptions/Relational_Config_Mismatch_Exception.js +17 -0
- package/src/exceptions/There_Is_No_Block_Options_To_Allocate_Exception.js +14 -0
- package/src/index.js +6 -0
- package/src/input_preparation/Block_Formatter.js +179 -0
- package/src/input_preparation/Input_Creator.js +76 -0
- package/src/input_preparation/Input_State_Preparation.js +47 -0
- package/src/input_preparation/State_Builder.js +27 -0
- package/src/input_preparation/block_formatter/align_flush_axis_config.js +36 -0
- package/src/input_preparation/block_formatter/align_flush_axis_single_round.js +112 -0
- package/src/input_preparation/block_formatter/align_flush_stacked_slots.js +67 -0
- package/src/input_preparation/block_formatter/overlapped_slots.js +24 -0
- package/src/input_preparation/block_formatter/parallelepiped_shell.js +38 -0
- package/src/input_preparation/block_formatter/rectangle_coverage.js +112 -0
- package/src/input_preparation/block_formatter/shell_face_coverage.js +64 -0
- package/src/input_preparation/block_formatter/shell_snap_convergence.js +104 -0
- package/src/input_preparation/block_preparation/Block_Data_To_Object_Transformer.js +57 -0
- package/src/input_preparation/block_preparation/Block_Module_Name.js +17 -0
- package/src/input_preparation/block_preparation/Blocks_Creator.js +101 -0
- package/src/input_preparation/block_preparation/Blocksmith.js +19 -0
- package/src/input_preparation/block_preparation/block_modules/create_block_candidates.js +41 -0
- package/src/input_preparation/block_preparation/block_modules/manual_blocks.js +10 -0
- package/src/input_preparation/block_preparation/block_modules/module_registry.js +20 -0
- package/src/input_preparation/block_preparation/block_modules/run_creator.js +34 -0
- package/src/input_preparation/block_preparation/block_modules/single_item_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/spiral_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/tie_ratio_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/tower_blocks.js +12 -0
- package/src/input_preparation/block_preparation/exceptions/Failed_To_Create_Block_Exception.js +14 -0
- package/src/input_preparation/block_preparation/exceptions/Failed_To_Retrieve_Block_Exception.js +17 -0
- package/src/input_preparation/block_preparation/exceptions/Missing_Object_Store_Exception.js +10 -0
- package/src/input_preparation/block_preparation/exceptions/No_Blocks_Were_Created_Exception.js +14 -0
- package/src/input_preparation/block_preparation/input/Input_Creator.js +96 -0
- package/src/input_preparation/block_preparation/manual_blocks/Manual_Blocks.js +95 -0
- package/src/input_preparation/build_empty_space_finder_options.js +43 -0
- package/src/input_preparation/item_preparation/Items_Reader.js +27 -0
- package/src/input_preparation/min_extents_from_items.js +29 -0
- package/src/input_preparation/stackability_index/Blocks_Stackability_Index_Calculator.js +58 -0
- package/src/input_preparation/stackability_index/Slots_Stackability_index_Calculator.js +28 -0
- package/src/input_preparation/stackability_index/Stackability_Input_Creator.js +27 -0
- package/src/input_preparation/stackability_index/stackability_index_pop_stack.js +81 -0
- package/src/input_preparation/stacking_constraints/Weight_Stacking_Validation.js +15 -0
- package/src/lp_optimizer_result_status.js +20 -0
- package/src/messages/Allocator_Message.js +42 -0
- package/src/messages/resolve_error_message_entry.js +57 -0
- package/src/models/Allocated_Item.js +136 -0
- package/src/models/Allocation_Item.js +219 -0
- package/src/models/Block.js +198 -0
- package/src/models/Cargo_Profile.js +418 -0
- package/src/models/Preloaded_Allocated_Item.js +132 -0
- package/src/models/Slot.js +67 -0
- package/src/models/Stacking_Rules.js +58 -0
- package/src/models/auxiliaryFunctions/Available_Block_Module_List_Creator.js +9 -0
- package/src/models/auxiliaryFunctions/Measure_Translator.js +24 -0
- package/src/models/auxiliaryFunctions/item_json_reader.js +44 -0
- package/src/models/item_json_reader.js +71 -0
- package/src/models/placed_item_record.js +70 -0
- package/src/models/preloaded_rotation_helpers.js +38 -0
- package/src/models/slots_have_same_measure.js +45 -0
- package/src/models/transport/Container.js +162 -0
- package/src/models/transport/Transport.js +62 -0
- package/src/models/transport/build_stacking_feasibility_checker.js +64 -0
- package/src/models/transport/container_stacking_checkpoint.js +42 -0
- package/src/models/transport/factory/Container_Factory.js +46 -0
- package/src/models/transport/factory/Corner_Casting_Factory.js +62 -0
- package/src/models/transport/factory/Previously_Allocated_Item_Factory.js +28 -0
- package/src/models/transport/factory/Transport_Factory.js +13 -0
- package/src/models/transport/items_for_empty_space_finder.js +91 -0
- package/src/models/transport/resolve_container_stacking_inputs.js +23 -0
- package/src/models/transport/stacking_input_from_wire.js +58 -0
- package/src/optimizer_connection_errors.js +50 -0
- package/src/relational/Relational_Error_Codes.js +7 -0
- package/src/relational/finalize_relational_allocation.js +20 -0
- package/src/relational/has_relational_items.js +11 -0
- package/src/relational/is_relational_error_code.js +15 -0
- package/src/relational/resolve_relational_container_sequences.js +29 -0
- package/src/run_core_allocation.js +118 -0
- package/src/space_and_block_chooser/Space_And_Blocks_Chooser.js +115 -0
- package/src/space_and_block_chooser/blocks_filters/Block_Filter_Interface.js +19 -0
- package/src/space_and_block_chooser/blocks_filters/Filter_Runner.js +46 -0
- package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Block_With_Overlapped_Slots_Filter.js +14 -0
- package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Initial_Blocks_Filter_List.js +19 -0
- package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Blocks_Bigger_Than_Space_Filter.js +17 -0
- package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Post_Selection_Filter_List.js +9 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Insuficient_Items_Filter.js +81 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Pre_Selection_Filter_List.js +8 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Blocks_Lower_Than_Max_Tower_Height.js +23 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Max_Tower_Height.js +82 -0
- package/src/space_and_block_chooser/build_allocated_item_snapshots.js +19 -0
- package/src/space_and_block_chooser/compound_first_empty_space_branch.js +61 -0
- package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +142 -0
- package/src/space_and_block_chooser/compound_first_without_leftover_fill.js +56 -0
- package/src/space_and_block_chooser/empty_spaces_where_post_selection_keeps_blocks.js +83 -0
- package/src/space_and_block_chooser/exceptions/Invalid_Space_To_Allocate_Exception.js +14 -0
- package/src/space_and_block_chooser/leftover_space_memory.js +113 -0
- package/src/space_and_block_chooser/leftover_unitary_blocks.js +153 -0
- package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +135 -0
- package/src/space_and_block_chooser/probe_set_pool.js +35 -0
- package/src/space_and_block_chooser/run_space_and_block_selection_attempt.js +88 -0
- package/src/tools/Array_Validator.js +6 -0
- package/src/tools/Clone.js +27 -0
- package/src/tools/Hash.js +8 -0
- package/src/tools/Rounder.js +5 -0
- package/src/tools/String_To_Boolean.js +12 -0
- package/src/tools/cargo_profile/Cargo_Profile_Field_Value_Resolver.js +44 -0
- package/src/tools/compact_items_with_stock.js +9 -0
- package/src/tools/mm_to_allocation_domain.js +14 -0
- package/src/tracing/Allocation_Tracer.js +52 -0
- package/src/tracing/Trace_Context.js +18 -0
- package/src/tracing/trace_outcome.js +18 -0
- package/src/tracing/traced_step.js +57 -0
- package/src/validation/Item_Continuation_Lock_Flag.js +52 -0
- package/src/validation/Item_Validation.js +29 -0
- package/src/validation/Relational_Colocation_Validator.js +60 -0
- package/src/validation/Relational_Completeness_Validator.js +146 -0
- package/src/validation/Relational_Continuation_Lock_Validation.js +37 -0
- package/src/validation/Relational_Proportional_Normalizer.js +194 -0
- package/src/validation/Validation.js +9 -0
- package/src/validation/Validation_Runner.js +20 -0
- package/src/validation/exceptions/Invalid_Block_Module_Config_Exception.js +14 -0
- package/src/validation/exceptions/Invalid_Input_Exception.js +14 -0
- package/src/validation/exceptions/Invalid_Input_Type_Exception.js +14 -0
- package/src/validation/schemas/allocated_item_schema.js +18 -0
- package/src/validation/schemas/allocation_request_schema.js +178 -0
- package/src/validation/schemas/container_row_schema.js +16 -0
- package/src/validation/schemas/item_schema.js +60 -0
- package/src/validation/schemas/transport_env_schema.js +19 -0
- package/src/validation/validate_block_module_config.js +147 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the density group index that contains the given item id.
|
|
3
|
+
* @param {Map<number, Set<string>>} groups - Group index to item id set.
|
|
4
|
+
* @param {number} group_count - Total number of groups.
|
|
5
|
+
* @param {string} item_id - Item identifier.
|
|
6
|
+
* @returns {number|null}
|
|
7
|
+
*/
|
|
8
|
+
function find_group_index_for_item_id(groups, group_count, item_id)
|
|
9
|
+
{
|
|
10
|
+
for (let group_index = 0; group_index < group_count; group_index++)
|
|
11
|
+
{
|
|
12
|
+
const group_ids = groups.get(group_index)
|
|
13
|
+
if (group_ids && group_ids.has(item_id))
|
|
14
|
+
{
|
|
15
|
+
return group_index
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns density group indices that still have at least one item with stock.
|
|
24
|
+
* @param {Map<number, Set<string>>} groups - Group index to item id set.
|
|
25
|
+
* @param {number} group_count - Total number of groups.
|
|
26
|
+
* @param {object[]} item_list - Master item list.
|
|
27
|
+
* @returns {number[]}
|
|
28
|
+
*/
|
|
29
|
+
function get_groups_with_stock(groups, group_count, item_list)
|
|
30
|
+
{
|
|
31
|
+
const groups_with_stock = []
|
|
32
|
+
|
|
33
|
+
for (let group_index = 0; group_index < group_count; group_index++)
|
|
34
|
+
{
|
|
35
|
+
const group_ids = groups.get(group_index)
|
|
36
|
+
const has_stock = item_list.some(
|
|
37
|
+
item => group_ids.has(item.get_id()) && item.get_amount() > 0
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if (has_stock)
|
|
41
|
+
{
|
|
42
|
+
groups_with_stock.push(group_index)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return groups_with_stock
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = { find_group_index_for_item_id, get_groups_with_stock }
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const DENSITY_GROUPS_STRATEGY = Object.freeze({
|
|
2
|
+
ROUND_ROBIN: 'round_robin',
|
|
3
|
+
ADAPTIVE: 'adaptive',
|
|
4
|
+
})
|
|
5
|
+
|
|
6
|
+
const VALID_DENSITY_GROUP_STRATEGIES = Object.freeze(Object.values(DENSITY_GROUPS_STRATEGY))
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Maps raw config input to a density group strategy constant.
|
|
10
|
+
* @param {unknown} raw - Raw strategy value from cargo profile config.
|
|
11
|
+
* @returns {typeof DENSITY_GROUPS_STRATEGY.ROUND_ROBIN | typeof DENSITY_GROUPS_STRATEGY.ADAPTIVE}
|
|
12
|
+
*/
|
|
13
|
+
function normalize_density_groups_strategy(raw)
|
|
14
|
+
{
|
|
15
|
+
if (raw === DENSITY_GROUPS_STRATEGY.ADAPTIVE)
|
|
16
|
+
{
|
|
17
|
+
return DENSITY_GROUPS_STRATEGY.ADAPTIVE
|
|
18
|
+
}
|
|
19
|
+
return DENSITY_GROUPS_STRATEGY.ROUND_ROBIN
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
DENSITY_GROUPS_STRATEGY,
|
|
24
|
+
VALID_DENSITY_GROUP_STRATEGIES,
|
|
25
|
+
normalize_density_groups_strategy,
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes item density (weight / volume) for SKU-level grouping.
|
|
3
|
+
* @param {object} item - Item with get_weight, get_width, get_height, get_length, get_id.
|
|
4
|
+
* @returns {{ item_id: string, density: number }}
|
|
5
|
+
*/
|
|
6
|
+
function calculate_item_density(item)
|
|
7
|
+
{
|
|
8
|
+
const weight = item.get_weight()
|
|
9
|
+
const volume = item.get_width() * item.get_height() * item.get_length()
|
|
10
|
+
const item_id = item.get_id()
|
|
11
|
+
|
|
12
|
+
if (!Number.isFinite(weight) || weight < 0 || volume <= 0)
|
|
13
|
+
{
|
|
14
|
+
return { item_id, density: Number.POSITIVE_INFINITY }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return { item_id, density: weight / volume }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = { calculate_item_density }
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const Cargo_Profile = require('../../models/Cargo_Profile')
|
|
2
|
+
const { DENSITY_GROUPS_STRATEGY } = require('./Density_Groups_Strategy')
|
|
3
|
+
const { get_weight_ahead_threshold } = require('./Adaptive_Density_Group_Threshold_Resolver')
|
|
4
|
+
const { get_weight_utilization, get_space_utilization } = require('./Container_Utilization')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns whether the continuation lock should release so adaptive density groups can expose lighter SKUs.
|
|
8
|
+
* @param {object} container - Current container.
|
|
9
|
+
* @param {object} density_scheduler - Density group scheduler.
|
|
10
|
+
* @param {object[]} item_list - Master item list.
|
|
11
|
+
* @param {object} locked_item - Locked item instance.
|
|
12
|
+
* @returns {boolean}
|
|
13
|
+
*/
|
|
14
|
+
function should_release_lock_for_weight_ahead(container, density_scheduler, item_list, locked_item)
|
|
15
|
+
{
|
|
16
|
+
const gap = get_weight_utilization(container) - get_space_utilization(container)
|
|
17
|
+
if (gap <= get_weight_ahead_threshold())
|
|
18
|
+
{
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const groups_with_stock = density_scheduler.get_groups_with_stock(item_list)
|
|
23
|
+
if (groups_with_stock.length === 0)
|
|
24
|
+
{
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const lowest_density_group = Math.min(...groups_with_stock)
|
|
29
|
+
const locked_group = density_scheduler.find_group_index_for_item_id(locked_item.get_id())
|
|
30
|
+
if (locked_group === null)
|
|
31
|
+
{
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return locked_group > lowest_density_group
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Releases the lock when weight is ahead and the locked SKU is not in the lightest density band.
|
|
40
|
+
* @param {object} container - Current container.
|
|
41
|
+
* @param {object|null} density_scheduler - Density group scheduler, if enabled.
|
|
42
|
+
* @param {object} item_lock - Item continuation lock instance.
|
|
43
|
+
* @param {object[]} item_list - Master item list.
|
|
44
|
+
* @param {object|null} locked_item - Currently locked item, if any.
|
|
45
|
+
* @returns {object|null} Locked item after optional release.
|
|
46
|
+
*/
|
|
47
|
+
function apply_weight_ahead_lock_release(container, density_scheduler, item_lock, item_list, locked_item)
|
|
48
|
+
{
|
|
49
|
+
if (!locked_item || !density_scheduler)
|
|
50
|
+
{
|
|
51
|
+
return locked_item
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (Cargo_Profile.density_groups_strategy() !== DENSITY_GROUPS_STRATEGY.ADAPTIVE)
|
|
55
|
+
{
|
|
56
|
+
return locked_item
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const should_release = should_release_lock_for_weight_ahead(
|
|
60
|
+
container,
|
|
61
|
+
density_scheduler,
|
|
62
|
+
item_list,
|
|
63
|
+
locked_item
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if (!should_release)
|
|
67
|
+
{
|
|
68
|
+
return locked_item
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
item_lock.release_for_density_balance()
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = { apply_weight_ahead_lock_release }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { build_message_entry } = require('../../messages/resolve_error_message_entry')
|
|
2
|
+
const { ALLOCATOR_MESSAGE } = require('../../messages/Allocator_Message')
|
|
3
|
+
|
|
4
|
+
class Invalid_Item_Amount_Exception extends Error
|
|
5
|
+
{
|
|
6
|
+
/**
|
|
7
|
+
* @param {string|number} item
|
|
8
|
+
*/
|
|
9
|
+
constructor(item)
|
|
10
|
+
{
|
|
11
|
+
const message_key = ALLOCATOR_MESSAGE.INVALID_ITEM_AMOUNT
|
|
12
|
+
super(message_key)
|
|
13
|
+
this.message_entry = build_message_entry(message_key, [String(item)])
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = Invalid_Item_Amount_Exception
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const { build_message_entry } = require('../../messages/resolve_error_message_entry')
|
|
2
|
+
const { ALLOCATOR_MESSAGE } = require('../../messages/Allocator_Message')
|
|
3
|
+
|
|
4
|
+
class No_Valid_Allocation_Exception extends Error
|
|
5
|
+
{
|
|
6
|
+
constructor()
|
|
7
|
+
{
|
|
8
|
+
const message_key = ALLOCATOR_MESSAGE.NO_VALID_ALLOCATION
|
|
9
|
+
super(message_key)
|
|
10
|
+
this.message_entry = build_message_entry(message_key)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = No_Valid_Allocation_Exception
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const { build_message_entry } = require('../../messages/resolve_error_message_entry')
|
|
2
|
+
const { ALLOCATOR_MESSAGE } = require('../../messages/Allocator_Message')
|
|
3
|
+
|
|
4
|
+
class Optimization_Infeasible_Exception extends Error
|
|
5
|
+
{
|
|
6
|
+
constructor()
|
|
7
|
+
{
|
|
8
|
+
const message_key = ALLOCATOR_MESSAGE.OPTIMIZATION_INFEASIBLE
|
|
9
|
+
super(message_key)
|
|
10
|
+
this.message_entry = build_message_entry(message_key)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = Optimization_Infeasible_Exception
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const Cargo_Profile = require('../../models/Cargo_Profile')
|
|
2
|
+
const measure_to_optimize = require('./measure_to_optimize')
|
|
3
|
+
|
|
4
|
+
function read_measure_to_be_optimized()
|
|
5
|
+
{
|
|
6
|
+
const config = Cargo_Profile.measure_to_optimize()
|
|
7
|
+
switch (config.toLowerCase())
|
|
8
|
+
{
|
|
9
|
+
case measure_to_optimize.LENGTH:
|
|
10
|
+
return measure_to_optimize.LENGTH
|
|
11
|
+
case measure_to_optimize.WIDTH:
|
|
12
|
+
return measure_to_optimize.WIDTH
|
|
13
|
+
default:
|
|
14
|
+
return measure_to_optimize.WIDTH
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
read_measure_to_be_optimized
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
const Cargo_Profile = require('../../../models/Cargo_Profile')
|
|
3
|
+
const { mode_checks } = require('./Measure_Combination_Mode_Checkers')
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* Determines the computation mode based on the block variable weight configuration.
|
|
7
|
+
* @returns {string} The computation mode.
|
|
8
|
+
*/
|
|
9
|
+
function get_mode()
|
|
10
|
+
{
|
|
11
|
+
const config = Cargo_Profile.block_variable_weight_config()
|
|
12
|
+
|
|
13
|
+
const default_value = 'volume'
|
|
14
|
+
|
|
15
|
+
if (!config || config.length <= 1)
|
|
16
|
+
{
|
|
17
|
+
return default_value
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const found = mode_checks.find(item => item.check(config))
|
|
21
|
+
|
|
22
|
+
return found ? found.mode : default_value
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = get_mode
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const strategies = {
|
|
2
|
+
volume: block => block.get_volume(),
|
|
3
|
+
height_length: block => block.get_length() * block.get_height(),
|
|
4
|
+
length_width: block => block.get_length() * block.get_width(),
|
|
5
|
+
height_width: block => block.get_height() * block.get_width(),
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
module.exports = strategies
|
package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const { DIMENSIONS } = require('./constants')
|
|
2
|
+
const { includes_key_or_translation } = require('./Translation')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a configuration array contains all the given keys, considering translations.
|
|
6
|
+
* @param {string[]} config - The configuration array from Cargo Profile.
|
|
7
|
+
* @param {...string} keys - The dimension keys to check for.
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
const has = (config, ...keys) => keys.every( key => includes_key_or_translation(config, key) )
|
|
11
|
+
|
|
12
|
+
const { HEIGHT, LENGTH, WIDTH } = DIMENSIONS
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @constant {object} volume_check
|
|
16
|
+
* @property {function(string[]): boolean} check - Function to check if the config includes HEIGHT, LENGTH, and WIDTH.
|
|
17
|
+
* @property {string} mode - The mode name for volume.
|
|
18
|
+
* @augments ModeCheck
|
|
19
|
+
*/
|
|
20
|
+
const volume_check = {
|
|
21
|
+
check: config => has(config, HEIGHT, LENGTH, WIDTH),
|
|
22
|
+
mode: 'volume',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @constant {object} height_length_check
|
|
27
|
+
* @property {function(string[]): boolean} check - Function to check if the config includes HEIGHT and LENGTH, but not WIDTH.
|
|
28
|
+
* @property {string} mode - The mode name for height and length.
|
|
29
|
+
* @augments ModeCheck
|
|
30
|
+
*/
|
|
31
|
+
const height_length_check = {
|
|
32
|
+
check: config => has(config, HEIGHT, LENGTH) && !has(config, WIDTH),
|
|
33
|
+
mode: 'height_length',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @constant {object} length_width_check
|
|
38
|
+
* @property {function(string[]): boolean} check - Function to check if the config includes LENGTH and WIDTH, but not HEIGHT.
|
|
39
|
+
* @property {string} mode - The mode name for length and width.
|
|
40
|
+
* @augments ModeCheck
|
|
41
|
+
*/
|
|
42
|
+
const length_width_check = {
|
|
43
|
+
check: config => has(config, LENGTH, WIDTH) && !has(config, HEIGHT),
|
|
44
|
+
mode: 'length_width',
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @constant {object} height_width_check
|
|
49
|
+
* @property {function(string[]): boolean} check - Function to check if the config includes HEIGHT and WIDTH, but not LENGTH.
|
|
50
|
+
* @property {string} mode - The mode name for height and width.
|
|
51
|
+
* @augments ModeCheck
|
|
52
|
+
*/
|
|
53
|
+
const height_width_check = {
|
|
54
|
+
check: config => has(config, HEIGHT, WIDTH) && !has(config, LENGTH),
|
|
55
|
+
mode: 'height_width',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @typedef {object} ModeCheck
|
|
60
|
+
* @property {function(string[]): boolean} check - A function that takes a configuration array and returns true if the configuration matches this mode.
|
|
61
|
+
* @property {string} mode - The string identifier for the mode.
|
|
62
|
+
*/
|
|
63
|
+
const mode_checks = [
|
|
64
|
+
volume_check,
|
|
65
|
+
height_length_check,
|
|
66
|
+
length_width_check,
|
|
67
|
+
height_width_check
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
module.exports = { mode_checks }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const {TRANSLATIONS} = require('./constants')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Translates a given key using predefined translations.
|
|
5
|
+
* If no translation is found, the original key is returned.
|
|
6
|
+
* @param {string} key - The key to translate.
|
|
7
|
+
* @returns {string} The translated key or the original key if no translation exists.
|
|
8
|
+
*/
|
|
9
|
+
const translate = key => (TRANSLATIONS[key] || key)
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a configuration array includes a specific key or its translation.
|
|
13
|
+
* @param {string[]} config - The configuration array.
|
|
14
|
+
* @param {string} key - The key to check for.
|
|
15
|
+
* @returns {boolean} True if the key or its translation is found, false otherwise.
|
|
16
|
+
*/
|
|
17
|
+
const includes_key_or_translation = (config, key) =>
|
|
18
|
+
{
|
|
19
|
+
return config.includes(key) || config.includes(translate(key))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {includes_key_or_translation}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const Cargo_Profile = require('../../../models/Cargo_Profile')
|
|
2
|
+
const round = require('../../../tools/Rounder')
|
|
3
|
+
const get_mode = require('./Measure_Cobination_Mode')
|
|
4
|
+
|
|
5
|
+
const should_prefer_same_measure_items_block = () => Cargo_Profile.prefer_same_measure_slot_blocks()
|
|
6
|
+
|
|
7
|
+
const compute_weight = {
|
|
8
|
+
volume: block => block.get_volume(),
|
|
9
|
+
height_length: block => block.get_height() * block.get_length(),
|
|
10
|
+
length_width: block => block.get_length() * block.get_width(),
|
|
11
|
+
height_width: block => block.get_height() * block.get_width(),
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const get_item_amount_untie = block => block.get_slot_list().length * Cargo_Profile.untie_by_quantity_multiplier()
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Calculates a bonus weight based on the measure combination mode.
|
|
18
|
+
* The specific calculation depends on the mode returned by `get_mode()`.
|
|
19
|
+
* @param {Block} block - The block object for which to calculate the bonus.
|
|
20
|
+
* @returns {number} The measure combination bonus weight.
|
|
21
|
+
*/
|
|
22
|
+
const get_measure_combination_bonus = (block) =>
|
|
23
|
+
{
|
|
24
|
+
const mode = get_mode()
|
|
25
|
+
const computer = compute_weight[mode]
|
|
26
|
+
if (computer)
|
|
27
|
+
{
|
|
28
|
+
return computer(block) / 10
|
|
29
|
+
}
|
|
30
|
+
return 0
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculates a bonus weight based on the block's stackability index.
|
|
35
|
+
* @param {Block} block - The block object for which to calculate the bonus.
|
|
36
|
+
* @returns {number} The stackability bonus weight.
|
|
37
|
+
*/
|
|
38
|
+
const get_stackability_bonus = block => block.get_stackability_index()
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Calculates a bonus weight if the block is marked as a "preference" block.
|
|
42
|
+
* Returns preferential_blocks_bonus(default 5) if preferred, otherwise 0.
|
|
43
|
+
* @param {Block} block - The block object for which to calculate the bonus.
|
|
44
|
+
* @returns {number} The preference bonus weight.
|
|
45
|
+
*/
|
|
46
|
+
const get_preference_bonus = block => (block.is_preference() ? Cargo_Profile.preferential_blocks_bonus() : 0)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Calculates a bonus weight if the block's slots have the same measures and
|
|
50
|
+
* either same-measure preference flag is true.
|
|
51
|
+
* @param {Block} block - The block object for which to calculate the bonus.
|
|
52
|
+
* @returns {number} The same item measures bonus weight.
|
|
53
|
+
*/
|
|
54
|
+
function get_same_item_measures_bonus (block)
|
|
55
|
+
{
|
|
56
|
+
const has_same_measures = block.is_slots_of_same_measure()
|
|
57
|
+
const same_item_measures_bonus = Cargo_Profile.same_item_measures_bonus()
|
|
58
|
+
return should_prefer_same_measure_items_block() && has_same_measures ? same_item_measures_bonus : 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
// --- Main Exported Function ---
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Calculates a custom weight for a block based on various factors.
|
|
66
|
+
* @param {object} block - The block to be evaluated.
|
|
67
|
+
* @returns {number} The calculated custom weight.
|
|
68
|
+
*/
|
|
69
|
+
function get_custom_weight(block)
|
|
70
|
+
{
|
|
71
|
+
|
|
72
|
+
const weight_components = [
|
|
73
|
+
get_measure_combination_bonus(block),
|
|
74
|
+
get_stackability_bonus(block),
|
|
75
|
+
get_same_item_measures_bonus(block),
|
|
76
|
+
get_preference_bonus(block),
|
|
77
|
+
get_item_amount_untie(block)
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
const total_weight = weight_components.reduce((sum, value) => sum + value, 0)
|
|
81
|
+
|
|
82
|
+
return round(total_weight)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = get_custom_weight
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const DIMENSIONS = {
|
|
2
|
+
HEIGHT: 'height',
|
|
3
|
+
LENGTH: 'length',
|
|
4
|
+
WIDTH: 'width',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const TRANSLATIONS = {
|
|
8
|
+
[DIMENSIONS.HEIGHT]: 'altura',
|
|
9
|
+
[DIMENSIONS.LENGTH]: 'comprimento',
|
|
10
|
+
[DIMENSIONS.WIDTH]: 'largura',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
DIMENSIONS,
|
|
15
|
+
TRANSLATIONS,
|
|
16
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const { get_weight_utilization, get_space_utilization } = require('../density_groups/Container_Utilization')
|
|
2
|
+
const { calculate_item_density } = require('../density_groups/Item_Density_Calculator')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Compares two items by density for stable sorting.
|
|
6
|
+
* @param {object} left_item
|
|
7
|
+
* @param {object} right_item
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
function compare_by_density_ascending(left_item, right_item)
|
|
11
|
+
{
|
|
12
|
+
const left_density = calculate_item_density(left_item).density
|
|
13
|
+
const right_density = calculate_item_density(right_item).density
|
|
14
|
+
if (left_density !== right_density)
|
|
15
|
+
{
|
|
16
|
+
return left_density - right_density
|
|
17
|
+
}
|
|
18
|
+
return String(left_item.get_id()).localeCompare(String(right_item.get_id()))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether the container exposes the accessors needed for utilization metrics.
|
|
23
|
+
* @param {object} container
|
|
24
|
+
* @returns {boolean}
|
|
25
|
+
*/
|
|
26
|
+
function container_supports_utilization(container)
|
|
27
|
+
{
|
|
28
|
+
const required_methods = [
|
|
29
|
+
'get_allocated_items',
|
|
30
|
+
'get_width',
|
|
31
|
+
'get_height',
|
|
32
|
+
'get_length'
|
|
33
|
+
]
|
|
34
|
+
return required_methods.every((method_name) =>
|
|
35
|
+
typeof container[method_name] === 'function'
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reorders compatible items using container weight vs space utilization.
|
|
41
|
+
* @param {object[]} item_list - Candidate items.
|
|
42
|
+
* @param {object|null|undefined} container - Container with allocated items.
|
|
43
|
+
* @returns {object[]} Same items, possibly reordered.
|
|
44
|
+
*/
|
|
45
|
+
function order_items_by_capacity_bias(item_list, container)
|
|
46
|
+
{
|
|
47
|
+
if (!container || item_list.length <= 1)
|
|
48
|
+
{
|
|
49
|
+
return item_list
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!container_supports_utilization(container))
|
|
53
|
+
{
|
|
54
|
+
return item_list
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const gap = get_weight_utilization(container) - get_space_utilization(container)
|
|
58
|
+
if (gap === 0)
|
|
59
|
+
{
|
|
60
|
+
return item_list
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const sorted_items = item_list.slice()
|
|
64
|
+
if (gap > 0)
|
|
65
|
+
{
|
|
66
|
+
sorted_items.sort(compare_by_density_ascending)
|
|
67
|
+
return sorted_items
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
sorted_items.sort((left_item, right_item) =>
|
|
71
|
+
compare_by_density_ascending(right_item, left_item)
|
|
72
|
+
)
|
|
73
|
+
return sorted_items
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { order_items_by_capacity_bias }
|
package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a container stub for tests and legacy callers that only pass height_limit.
|
|
3
|
+
* @param {number} height_limit - Stack height cap.
|
|
4
|
+
* @returns {object} Minimal container with get_height and permissive is_a_valid_stacking.
|
|
5
|
+
*/
|
|
6
|
+
function create_height_limit_container_stub(height_limit)
|
|
7
|
+
{
|
|
8
|
+
return {
|
|
9
|
+
get_height: () => height_limit,
|
|
10
|
+
is_a_valid_stacking: () => true
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolves slot, container, and item_position for choose_item heuristic path.
|
|
16
|
+
* @param {object} data - Same bag as choose_item.
|
|
17
|
+
* @returns {{ slot: object, container: object, item_position: { x: number, y: number, z: number } }}
|
|
18
|
+
*/
|
|
19
|
+
function resolve_choose_item_heuristic_context(data)
|
|
20
|
+
{
|
|
21
|
+
const slot = data.slot ?? data.block_slot
|
|
22
|
+
if (!slot)
|
|
23
|
+
{
|
|
24
|
+
throw new Error('choose_item heuristic requires data.slot or data.block_slot')
|
|
25
|
+
}
|
|
26
|
+
let container = data.container
|
|
27
|
+
if (!container && data.height_limit != null)
|
|
28
|
+
{
|
|
29
|
+
container = create_height_limit_container_stub(data.height_limit)
|
|
30
|
+
}
|
|
31
|
+
if (!container)
|
|
32
|
+
{
|
|
33
|
+
throw new Error('choose_item heuristic requires data.container or data.height_limit')
|
|
34
|
+
}
|
|
35
|
+
const item_position = data.item_position
|
|
36
|
+
return { slot, container, item_position }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Human-readable slot label for exception messages.
|
|
41
|
+
* @param {object} slot - Slot with optional to_string or get_x/get_y/get_z.
|
|
42
|
+
* @returns {string}
|
|
43
|
+
*/
|
|
44
|
+
function format_slot_label_for_exception(slot)
|
|
45
|
+
{
|
|
46
|
+
if (typeof slot.to_string === 'function')
|
|
47
|
+
{
|
|
48
|
+
return slot.to_string()
|
|
49
|
+
}
|
|
50
|
+
const x = slot.get_x?.()
|
|
51
|
+
const y = slot.get_y?.()
|
|
52
|
+
const z = slot.get_z?.()
|
|
53
|
+
if (x !== undefined && y !== undefined && z !== undefined)
|
|
54
|
+
{
|
|
55
|
+
return `${x};${y};${z}`
|
|
56
|
+
}
|
|
57
|
+
return 'slot'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = {
|
|
61
|
+
resolve_choose_item_heuristic_context,
|
|
62
|
+
format_slot_label_for_exception
|
|
63
|
+
}
|