@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,150 @@
|
|
|
1
|
+
const { Optimizer } = require('@jetta/lp-framework')
|
|
2
|
+
const Optimization_Infeasible_Exception = require('./exceptions/Optimization_Infeasible_Exception')
|
|
3
|
+
const LP_Data_Processor = require('./lp_model/LP_Data_Processor')
|
|
4
|
+
const LP_Model_Builder = require('./lp_model/model_builder/LP_Model_Builder')
|
|
5
|
+
const LP_Result_Mapper = require('./lp_model/LP_Result_Mapper')
|
|
6
|
+
const has_relational_items = require('../relational/has_relational_items')
|
|
7
|
+
const Cargo_Profile = require('../models/Cargo_Profile')
|
|
8
|
+
const { enrich_optimizer_http_error } = require('../optimizer_connection_errors')
|
|
9
|
+
const { is_lp_optimizer_result_success } = require('../lp_optimizer_result_status')
|
|
10
|
+
const { traced_step } = require('../tracing/traced_step')
|
|
11
|
+
const { TRACE_CONTEXT } = require('../tracing/Trace_Context')
|
|
12
|
+
/**
|
|
13
|
+
* @class Allocation_LP
|
|
14
|
+
* @description Orchestrates the Linear Programming model for block allocation; see `<root_project>/doc/LP`.
|
|
15
|
+
*/
|
|
16
|
+
class Allocation_LP
|
|
17
|
+
{
|
|
18
|
+
#container
|
|
19
|
+
#space_to_allocate
|
|
20
|
+
#block_list
|
|
21
|
+
#block_amount_map
|
|
22
|
+
#item_list
|
|
23
|
+
#block_map = {}
|
|
24
|
+
constructor(
|
|
25
|
+
container,
|
|
26
|
+
space_to_allocate,
|
|
27
|
+
block_list,
|
|
28
|
+
block_amount_map,
|
|
29
|
+
item_list
|
|
30
|
+
)
|
|
31
|
+
{
|
|
32
|
+
this.#container = container
|
|
33
|
+
this.#space_to_allocate = space_to_allocate
|
|
34
|
+
this.#block_amount_map = block_amount_map
|
|
35
|
+
this.#item_list = item_list
|
|
36
|
+
this.#block_list = this.#unique_blocks(block_list)
|
|
37
|
+
this.#block_list.forEach(block => this.#block_map[block.get_id()] = block)
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Orchestrates the Linear Programming model for block allocation,
|
|
41
|
+
* attempting to find an optimal solution first with a uniformity penalty,
|
|
42
|
+
* and falling back to an allocation without the uniformity penalty if the first attempt fails.
|
|
43
|
+
* @returns {Promise<object>} The mapped result of the optimization.
|
|
44
|
+
* @throws {Optimization_Infeasible_Exception} If no feasible solution can be found in either attempt.
|
|
45
|
+
*/
|
|
46
|
+
async optimize()
|
|
47
|
+
{
|
|
48
|
+
return traced_step(TRACE_CONTEXT.LP_OPTIMIZE, async () => this.#optimize_without_trace())
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async #optimize_without_trace()
|
|
52
|
+
{
|
|
53
|
+
// Attempt 1: Optimize with uniformity penalty (skipped when single-item-type or uniform
|
|
54
|
+
// block measure is enforced, since those caps already collapse dimensional variety).
|
|
55
|
+
if (
|
|
56
|
+
Cargo_Profile.enable_block_equalization()
|
|
57
|
+
&& !Cargo_Profile.enforce_single_item_type()
|
|
58
|
+
&& !Cargo_Profile.enforce_uniform_block_measure()
|
|
59
|
+
)
|
|
60
|
+
{
|
|
61
|
+
const result_with_uniformity = await this.#run_optimization_attempt(true)
|
|
62
|
+
if (this.#is_optimization_feasible(result_with_uniformity))
|
|
63
|
+
{
|
|
64
|
+
return result_with_uniformity
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Attempt 2: Optimize without uniformity penalty (fallback)
|
|
68
|
+
const result_without_uniformity = await this.#run_optimization_attempt(false)
|
|
69
|
+
if (this.#is_optimization_feasible(result_without_uniformity))
|
|
70
|
+
{
|
|
71
|
+
return result_without_uniformity
|
|
72
|
+
}
|
|
73
|
+
throw new Optimization_Infeasible_Exception()
|
|
74
|
+
}
|
|
75
|
+
#is_optimization_feasible(result)
|
|
76
|
+
{
|
|
77
|
+
return result && result.chosen_blocks.length > 0
|
|
78
|
+
}
|
|
79
|
+
#build_model(enable_uniformity_penalty)
|
|
80
|
+
{
|
|
81
|
+
const optimizer = new Optimizer(undefined, true)
|
|
82
|
+
const model_builder = new LP_Model_Builder({
|
|
83
|
+
optimizer,
|
|
84
|
+
container: this.#container,
|
|
85
|
+
empty_space: this.#space_to_allocate,
|
|
86
|
+
block_list: this.#block_list,
|
|
87
|
+
item_list: this.#item_list,
|
|
88
|
+
block_amount_map: this.#block_amount_map,
|
|
89
|
+
enable_uniformity_penalty
|
|
90
|
+
})
|
|
91
|
+
model_builder.build_model()
|
|
92
|
+
return {
|
|
93
|
+
optimizer,
|
|
94
|
+
item_assignment_context: model_builder.get_item_assignment_context()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async #run_optimization_attempt(enable_uniformity_penalty)
|
|
98
|
+
{
|
|
99
|
+
const { optimizer, item_assignment_context } = this.#build_model(enable_uniformity_penalty)
|
|
100
|
+
const optimization_start_ms = Date.now()
|
|
101
|
+
let result
|
|
102
|
+
try
|
|
103
|
+
{
|
|
104
|
+
result = await optimizer.optimize()
|
|
105
|
+
}
|
|
106
|
+
catch (error)
|
|
107
|
+
{
|
|
108
|
+
throw enrich_optimizer_http_error(
|
|
109
|
+
error,
|
|
110
|
+
Date.now() - optimization_start_ms,
|
|
111
|
+
this.#block_list.length,
|
|
112
|
+
optimizer.restriction_list?.length ?? -1
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
const status = result.status()
|
|
116
|
+
if (is_lp_optimizer_result_success(status))
|
|
117
|
+
{
|
|
118
|
+
const context_for_mapper = should_use_lp_item_assignment(this.#item_list)
|
|
119
|
+
? item_assignment_context
|
|
120
|
+
: null
|
|
121
|
+
const result_mapper = new LP_Result_Mapper(this.#block_map)
|
|
122
|
+
return result_mapper.map_result(result, context_for_mapper)
|
|
123
|
+
}
|
|
124
|
+
return null
|
|
125
|
+
}
|
|
126
|
+
#unique_blocks(to_clean)
|
|
127
|
+
{
|
|
128
|
+
const data_processor = new LP_Data_Processor()
|
|
129
|
+
const sanitized_blocks = data_processor.sanitize(to_clean, this.#block_amount_map)
|
|
130
|
+
const unique_blocks = data_processor.remove_duplicates(sanitized_blocks)
|
|
131
|
+
return unique_blocks
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function should_use_lp_item_assignment(item_list)
|
|
136
|
+
{
|
|
137
|
+
if (Cargo_Profile.relational_lp_require_exact_pass_amount() && has_relational_items(item_list))
|
|
138
|
+
{
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!Cargo_Profile.enforce_relational_group_co_location())
|
|
143
|
+
{
|
|
144
|
+
return false
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return has_relational_items(item_list)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
module.exports = Allocation_LP
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const Allocation_LP = require('./Allocation_LP')
|
|
2
|
+
const cap_chosen_blocks_by_stock_budget = require('./Chosen_Blocks_Stock_Cap')
|
|
3
|
+
const cap_chosen_blocks_by_shape_stock = require('./cap_chosen_blocks_by_shape_stock')
|
|
4
|
+
const No_Valid_Allocation_Exception = require('./exceptions/No_Valid_Allocation_Exception')
|
|
5
|
+
const Block_Builder = require('./block_builder/Blocks_Builder')
|
|
6
|
+
const { order_chosen_blocks_for_layer } = require('./Block_Layer_Order')
|
|
7
|
+
const resolve_next_group_id = require('./next_group_id_after_preloaded')
|
|
8
|
+
|
|
9
|
+
class Block_Allocator
|
|
10
|
+
{
|
|
11
|
+
#next_group_id = 0
|
|
12
|
+
|
|
13
|
+
async optimize_and_allocate
|
|
14
|
+
(
|
|
15
|
+
container,
|
|
16
|
+
space_to_allocate,
|
|
17
|
+
block_list,
|
|
18
|
+
item_amount_map,
|
|
19
|
+
item_list,
|
|
20
|
+
block_amount_map,
|
|
21
|
+
effective_item_list,
|
|
22
|
+
picking_continuity_seed
|
|
23
|
+
)
|
|
24
|
+
{
|
|
25
|
+
this.#next_group_id = resolve_next_group_id(container, this.#next_group_id)
|
|
26
|
+
const lp_item_list = effective_item_list ?? item_list
|
|
27
|
+
const optimized_blocks = await this.#optimize_block_layer(
|
|
28
|
+
container,
|
|
29
|
+
space_to_allocate,
|
|
30
|
+
block_list,
|
|
31
|
+
block_amount_map,
|
|
32
|
+
lp_item_list
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const ordered_blocks = order_chosen_blocks_for_layer(
|
|
36
|
+
optimized_blocks.chosen_blocks,
|
|
37
|
+
container,
|
|
38
|
+
lp_item_list
|
|
39
|
+
)
|
|
40
|
+
const capped_by_budget = cap_chosen_blocks_by_stock_budget(ordered_blocks, item_list, container)
|
|
41
|
+
const capped_blocks = cap_chosen_blocks_by_shape_stock(capped_by_budget, item_list)
|
|
42
|
+
|
|
43
|
+
const block_builder_output = this.#build_blocks(
|
|
44
|
+
space_to_allocate,
|
|
45
|
+
{ chosen_blocks: capped_blocks },
|
|
46
|
+
item_list,
|
|
47
|
+
item_amount_map,
|
|
48
|
+
container,
|
|
49
|
+
picking_continuity_seed,
|
|
50
|
+
optimized_blocks.block_instance_item_queues
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if (block_builder_output.allocated_item_list.length === 0)
|
|
54
|
+
{
|
|
55
|
+
throw new No_Valid_Allocation_Exception()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return block_builder_output
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async #optimize_block_layer(
|
|
63
|
+
container,
|
|
64
|
+
space_to_allocate,
|
|
65
|
+
block_list,
|
|
66
|
+
block_amount_map,
|
|
67
|
+
items_to_allocate
|
|
68
|
+
)
|
|
69
|
+
{
|
|
70
|
+
const LP = new Allocation_LP(
|
|
71
|
+
container,
|
|
72
|
+
space_to_allocate,
|
|
73
|
+
block_list,
|
|
74
|
+
block_amount_map,
|
|
75
|
+
items_to_allocate
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return await LP.optimize()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#build_blocks(
|
|
82
|
+
space_to_allocate,
|
|
83
|
+
optimized_block_layer,
|
|
84
|
+
item_list,
|
|
85
|
+
item_amount_map,
|
|
86
|
+
container,
|
|
87
|
+
picking_continuity_seed,
|
|
88
|
+
block_instance_item_queues
|
|
89
|
+
)
|
|
90
|
+
{
|
|
91
|
+
const block_builder_data = this.#create_blocks_builder_data(
|
|
92
|
+
space_to_allocate,
|
|
93
|
+
optimized_block_layer,
|
|
94
|
+
item_list,
|
|
95
|
+
item_amount_map,
|
|
96
|
+
container,
|
|
97
|
+
picking_continuity_seed
|
|
98
|
+
)
|
|
99
|
+
block_builder_data.block_instance_item_queues = block_instance_item_queues ?? new Map()
|
|
100
|
+
const block_builder = new Block_Builder(block_builder_data)
|
|
101
|
+
const block_builder_output = block_builder.get_allocated_item_list()
|
|
102
|
+
this.#next_group_id = block_builder_output.next_group_id
|
|
103
|
+
return block_builder_output
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#create_blocks_builder_data(
|
|
107
|
+
space_to_allocate,
|
|
108
|
+
optimized_block_layer,
|
|
109
|
+
item_list,
|
|
110
|
+
item_amount_map,
|
|
111
|
+
container,
|
|
112
|
+
picking_continuity_seed
|
|
113
|
+
)
|
|
114
|
+
{
|
|
115
|
+
return {
|
|
116
|
+
space_to_allocate: space_to_allocate,
|
|
117
|
+
optimized_block_layer: optimized_block_layer,
|
|
118
|
+
item_list: item_list,
|
|
119
|
+
item_amount_map: item_amount_map,
|
|
120
|
+
container: container,
|
|
121
|
+
picking_continuity_seed: picking_continuity_seed,
|
|
122
|
+
next_group_id: this.#next_group_id
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = Block_Allocator
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const { get_weight_utilization, get_space_utilization } = require('./density_groups/Container_Utilization')
|
|
2
|
+
const { calculate_block_potential_weight, get_dimension_to_max_weight_map } = require('./Block_Potential_Weight')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sorts chosen LP blocks for block builder consumption.
|
|
6
|
+
* @param {{ block: object, amount: number }[]} chosen_blocks - LP output.
|
|
7
|
+
* @param {object} container - Current container.
|
|
8
|
+
* @param {object[]} item_list - Items available for weight estimation.
|
|
9
|
+
* @returns {{ block: object, amount: number }[]}
|
|
10
|
+
*/
|
|
11
|
+
function order_chosen_blocks_for_layer(chosen_blocks, container, item_list)
|
|
12
|
+
{
|
|
13
|
+
const block_choices = Array.from(chosen_blocks)
|
|
14
|
+
if (block_choices.length <= 1)
|
|
15
|
+
{
|
|
16
|
+
return block_choices
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const weight_utilization = get_weight_utilization(container)
|
|
20
|
+
const space_utilization = get_space_utilization(container)
|
|
21
|
+
if (weight_utilization <= space_utilization)
|
|
22
|
+
{
|
|
23
|
+
return block_choices.sort((block_b, block_a) => block_b.block.get_volume() - block_a.block.get_volume())
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const dimension_to_max_weight_map = get_dimension_to_max_weight_map(item_list)
|
|
27
|
+
return block_choices.sort((block_b, block_a) =>
|
|
28
|
+
{
|
|
29
|
+
const ratio_b = get_volume_to_weight_ratio(block_b.block, dimension_to_max_weight_map)
|
|
30
|
+
const ratio_a = get_volume_to_weight_ratio(block_a.block, dimension_to_max_weight_map)
|
|
31
|
+
return ratio_a - ratio_b
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {object} block
|
|
37
|
+
* @param {Map<string, number>} dimension_to_max_weight_map
|
|
38
|
+
* @returns {number}
|
|
39
|
+
*/
|
|
40
|
+
function get_volume_to_weight_ratio(block, dimension_to_max_weight_map)
|
|
41
|
+
{
|
|
42
|
+
const potential_weight = calculate_block_potential_weight(block, dimension_to_max_weight_map)
|
|
43
|
+
if (potential_weight <= 0)
|
|
44
|
+
{
|
|
45
|
+
return block.get_volume()
|
|
46
|
+
}
|
|
47
|
+
return block.get_volume() / potential_weight
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = { order_chosen_blocks_for_layer }
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const {
|
|
2
|
+
get_dimension_hash,
|
|
3
|
+
collect_rotation_dimension_hashes
|
|
4
|
+
} = require('./lp_model/model_builder/item_dimension_hashes')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Maps each dimension hash to the max item weight for that hash.
|
|
8
|
+
* @param {object[]} item_list - An array of Item objects.
|
|
9
|
+
* @returns {Map<string, number>} Hash to max weight.
|
|
10
|
+
*/
|
|
11
|
+
function get_dimension_to_max_weight_map(item_list)
|
|
12
|
+
{
|
|
13
|
+
const dimension_to_max_weight_map = new Map()
|
|
14
|
+
|
|
15
|
+
for (const item of item_list)
|
|
16
|
+
{
|
|
17
|
+
const weight = item.get_weight()
|
|
18
|
+
const rotation_hashes = collect_rotation_dimension_hashes(item)
|
|
19
|
+
|
|
20
|
+
for (const hash of rotation_hashes)
|
|
21
|
+
{
|
|
22
|
+
const current_max_weight = dimension_to_max_weight_map.get(hash) || 0
|
|
23
|
+
|
|
24
|
+
if (weight > current_max_weight)
|
|
25
|
+
{
|
|
26
|
+
dimension_to_max_weight_map.set(hash, weight)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return dimension_to_max_weight_map
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculates the maximum potential weight of a block by summing slot max weights.
|
|
35
|
+
* @param {object} block - The block to analyze.
|
|
36
|
+
* @param {Map<string, number>} dimension_to_max_weight_map - Hash to max weight.
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
function calculate_block_potential_weight(block, dimension_to_max_weight_map)
|
|
40
|
+
{
|
|
41
|
+
let block_potential_weight = 0
|
|
42
|
+
for (const slot of block.get_slot_list())
|
|
43
|
+
{
|
|
44
|
+
const slot_hash = get_dimension_hash(slot)
|
|
45
|
+
const max_weight_for_slot = dimension_to_max_weight_map.get(slot_hash) || 0
|
|
46
|
+
block_potential_weight += max_weight_for_slot
|
|
47
|
+
}
|
|
48
|
+
return block_potential_weight
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
get_dimension_to_max_weight_map,
|
|
53
|
+
calculate_block_potential_weight
|
|
54
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sums remaining allocatable units across items.
|
|
3
|
+
* @param {object[]} item_list - Items with get_amount().
|
|
4
|
+
* @returns {number}
|
|
5
|
+
*/
|
|
6
|
+
function sum_item_amounts(item_list)
|
|
7
|
+
{
|
|
8
|
+
return item_list.reduce(
|
|
9
|
+
(running_sum, item) => running_sum + Math.max(0, Math.floor(Number(item.get_amount()) || 0)),
|
|
10
|
+
0,
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Minimum item weight among SKUs with positive amount (pessimistic load per slot).
|
|
16
|
+
* @param {object[]} item_list - Items with get_amount() and get_weight().
|
|
17
|
+
* @returns {number} Zero when no stock (weight cap skipped).
|
|
18
|
+
*/
|
|
19
|
+
function minimum_weight_among_available_items(item_list)
|
|
20
|
+
{
|
|
21
|
+
let minimum_weight = null
|
|
22
|
+
for (let i = 0; i < item_list.length; i += 1)
|
|
23
|
+
{
|
|
24
|
+
const item = item_list[i]
|
|
25
|
+
if (item.get_amount() <= 0)
|
|
26
|
+
{
|
|
27
|
+
continue
|
|
28
|
+
}
|
|
29
|
+
const item_weight = item.get_weight()
|
|
30
|
+
if (minimum_weight === null || item_weight < minimum_weight)
|
|
31
|
+
{
|
|
32
|
+
minimum_weight = item_weight
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return minimum_weight === null ? 0 : minimum_weight
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Trims chosen block instance counts using item stock and container supported weight
|
|
40
|
+
* (pessimistic: each slot carries at least the lightest in-stock SKU). Preserves caller order.
|
|
41
|
+
*
|
|
42
|
+
* @param {{ block: object, amount: number }[]} chosen_blocks - Block choices in execution order.
|
|
43
|
+
* @param {object[]} item_list - Current items with amounts.
|
|
44
|
+
* @param {object} container - Container with supported_weight().
|
|
45
|
+
* @returns {{ block: object, amount: number }[]}
|
|
46
|
+
*/
|
|
47
|
+
module.exports = function cap_chosen_blocks_by_stock_budget(chosen_blocks, item_list, container)
|
|
48
|
+
{
|
|
49
|
+
let slot_budget = sum_item_amounts(item_list)
|
|
50
|
+
const minimum_weight = minimum_weight_among_available_items(item_list)
|
|
51
|
+
let weight_budget = typeof container.supported_weight === 'function'
|
|
52
|
+
? container.supported_weight()
|
|
53
|
+
: container.supported_weight
|
|
54
|
+
const capped_block_choices = []
|
|
55
|
+
|
|
56
|
+
for (const choice of chosen_blocks)
|
|
57
|
+
{
|
|
58
|
+
const slots_per_block = choice.block.get_slot_list().length
|
|
59
|
+
const requested = Math.floor(Number(choice.amount) || 0)
|
|
60
|
+
if (slots_per_block === 0 || requested === 0)
|
|
61
|
+
{
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
const maximum_by_stock = Math.floor(slot_budget / slots_per_block)
|
|
65
|
+
const load_per_instance = minimum_weight > 0 ? slots_per_block * minimum_weight : 0
|
|
66
|
+
const maximum_by_weight = load_per_instance > 0
|
|
67
|
+
? Math.floor(weight_budget / load_per_instance)
|
|
68
|
+
: Number.POSITIVE_INFINITY
|
|
69
|
+
const allowed_instance_count = Math.min(requested, maximum_by_stock, maximum_by_weight)
|
|
70
|
+
if (allowed_instance_count > 0)
|
|
71
|
+
{
|
|
72
|
+
capped_block_choices.push({ block: choice.block, amount: allowed_instance_count })
|
|
73
|
+
slot_budget -= allowed_instance_count * slots_per_block
|
|
74
|
+
if (load_per_instance > 0)
|
|
75
|
+
{
|
|
76
|
+
weight_budget -= allowed_instance_count * load_per_instance
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return capped_block_choices
|
|
82
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const Allocation_Item = require('../../models/Allocation_Item')
|
|
2
|
+
|
|
3
|
+
function assign_block_metadata_to_items(group_id, tie_ratio_orientation, items_in_block)
|
|
4
|
+
{
|
|
5
|
+
items_in_block.forEach(item =>
|
|
6
|
+
{
|
|
7
|
+
if (group_id !== undefined)
|
|
8
|
+
{
|
|
9
|
+
item.set_group_id(group_id)
|
|
10
|
+
}
|
|
11
|
+
if (tie_ratio_orientation !== undefined)
|
|
12
|
+
{
|
|
13
|
+
item.set_tie_ratio_orientation(tie_ratio_orientation)
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = function create_allocated_item(group_id, block, items_in_block, block_position)
|
|
19
|
+
{
|
|
20
|
+
const tie_ratio_orientation = block.get_tie_ratio_orientation()
|
|
21
|
+
assign_block_metadata_to_items(group_id, tie_ratio_orientation, items_in_block)
|
|
22
|
+
const block_weight = items_in_block.reduce((sum, item) => sum + item.get_weight(), 0)
|
|
23
|
+
const block_json = block.get_json()
|
|
24
|
+
block_json['weight'] = block_weight
|
|
25
|
+
if (group_id !== undefined)
|
|
26
|
+
{
|
|
27
|
+
block_json['groupId'] = group_id
|
|
28
|
+
}
|
|
29
|
+
if (tie_ratio_orientation !== undefined)
|
|
30
|
+
{
|
|
31
|
+
block_json['tie_ratio_orientation'] = tie_ratio_orientation
|
|
32
|
+
}
|
|
33
|
+
const allocation_item = new Allocation_Item(block_json)
|
|
34
|
+
allocation_item.sum_position_vector(block_position)
|
|
35
|
+
const allocated_item = allocation_item.get_item_as_positioned_cube()
|
|
36
|
+
return allocated_item
|
|
37
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const Empty_Block_Item_List_Exception = require('./exceptions/Empty_Block_Item_List_Exception')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Ensures a block build produced at least one allocated item before side effects run.
|
|
5
|
+
* @param {object} block - Block whose slots were assigned.
|
|
6
|
+
* @param {object[]} item_in_block_list - Items assigned to the block slots.
|
|
7
|
+
* @throws {Empty_Block_Item_List_Exception} When no items were allocated.
|
|
8
|
+
*/
|
|
9
|
+
function assert_non_empty_item_list(block, item_in_block_list)
|
|
10
|
+
{
|
|
11
|
+
if (item_in_block_list.length === 0)
|
|
12
|
+
{
|
|
13
|
+
const slot_count = block.get_slot_list().length
|
|
14
|
+
throw new Empty_Block_Item_List_Exception(block.get_id(), slot_count)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = { assert_non_empty_item_list }
|