@jetta/blocks-allocator 0.0.0-stage → 0.1.0-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.
Files changed (282) hide show
  1. package/README.md +103 -2
  2. package/package.json +67 -5
  3. package/src/Allocation_Attempt.js +135 -0
  4. package/src/Allocation_Error_Handler.js +69 -0
  5. package/src/Allocation_Flow.js +162 -0
  6. package/src/Allocation_Optimization/Allocation_LP.js +150 -0
  7. package/src/Allocation_Optimization/Block_Allocator.js +129 -0
  8. package/src/Allocation_Optimization/Block_Layer_Order.js +50 -0
  9. package/src/Allocation_Optimization/Block_Potential_Weight.js +54 -0
  10. package/src/Allocation_Optimization/Chosen_Blocks_Stock_Cap.js +82 -0
  11. package/src/Allocation_Optimization/block_builder/Allocation_Item_Creator.js +37 -0
  12. package/src/Allocation_Optimization/block_builder/Block_Item_List_Validator.js +18 -0
  13. package/src/Allocation_Optimization/block_builder/Block_Wall_Builder.js +303 -0
  14. package/src/Allocation_Optimization/block_builder/Blocks_Builder.js +40 -0
  15. package/src/Allocation_Optimization/block_builder/Next_Block_Position.js +33 -0
  16. package/src/Allocation_Optimization/block_builder/Slot_Item_Assigner.js +45 -0
  17. package/src/Allocation_Optimization/block_builder/Stacking_Validation.js +30 -0
  18. package/src/Allocation_Optimization/block_builder/assert_tie_ratio_block_matches_orientation_below.js +44 -0
  19. package/src/Allocation_Optimization/block_builder/block_shape_stock.js +129 -0
  20. package/src/Allocation_Optimization/block_builder/exceptions/Empty_Block_Item_List_Exception.js +21 -0
  21. package/src/Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception.js +14 -0
  22. package/src/Allocation_Optimization/block_builder/exceptions/No_Suitable_Item_Exception.js +16 -0
  23. package/src/Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception.js +21 -0
  24. package/src/Allocation_Optimization/block_builder/should_omit_block_group_id.js +29 -0
  25. package/src/Allocation_Optimization/block_builder/snap_elevated_block_wall_items.js +34 -0
  26. package/src/Allocation_Optimization/block_builder/stacking_rules_input.js +52 -0
  27. package/src/Allocation_Optimization/cap_chosen_blocks_by_shape_stock.js +110 -0
  28. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Preparer.js +21 -0
  29. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Selector.js +55 -0
  30. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Threshold_Resolver.js +28 -0
  31. package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Thresholds.js +23 -0
  32. package/src/Allocation_Optimization/density_groups/Container_Utilization.js +67 -0
  33. package/src/Allocation_Optimization/density_groups/Density_Group_Partitioner.js +74 -0
  34. package/src/Allocation_Optimization/density_groups/Density_Group_Scheduler.js +168 -0
  35. package/src/Allocation_Optimization/density_groups/Density_Group_Stock.js +49 -0
  36. package/src/Allocation_Optimization/density_groups/Density_Groups_Strategy.js +26 -0
  37. package/src/Allocation_Optimization/density_groups/Item_Density_Calculator.js +20 -0
  38. package/src/Allocation_Optimization/density_groups/Lock_Weight_Ahead_Release.js +75 -0
  39. package/src/Allocation_Optimization/exceptions/Invalid_Item_Amount_Exception.js +17 -0
  40. package/src/Allocation_Optimization/exceptions/No_Valid_Allocation_Exception.js +14 -0
  41. package/src/Allocation_Optimization/exceptions/Optimization_Infeasible_Exception.js +14 -0
  42. package/src/Allocation_Optimization/functions/Measure_Reader.js +20 -0
  43. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Mode.js +25 -0
  44. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Strategies.js +8 -0
  45. package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js +70 -0
  46. package/src/Allocation_Optimization/functions/Weight_Getter/Translation.js +22 -0
  47. package/src/Allocation_Optimization/functions/Weight_Getter/Variable_Weight_Getter.js +85 -0
  48. package/src/Allocation_Optimization/functions/Weight_Getter/constants.js +16 -0
  49. package/src/Allocation_Optimization/functions/measure_to_optimize.js +6 -0
  50. package/src/Allocation_Optimization/item_consumption_heuristic/Capacity_Bias_Item_Order.js +76 -0
  51. package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js +63 -0
  52. package/src/Allocation_Optimization/item_consumption_heuristic/Item_Chooser.js +159 -0
  53. package/src/Allocation_Optimization/item_consumption_heuristic/Item_For_Slot_Chooser.js +49 -0
  54. package/src/Allocation_Optimization/item_consumption_heuristic/Slot_Compatible_Items_Finder.js +88 -0
  55. package/src/Allocation_Optimization/item_consumption_heuristic/Slots_Items_Assigner.js +182 -0
  56. package/src/Allocation_Optimization/item_consumption_heuristic/Stack_Slot_Calculator.js +87 -0
  57. package/src/Allocation_Optimization/item_consumption_heuristic/Weight_Slot_Distribution.js +72 -0
  58. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Empty_Slot_Exception.js +17 -0
  59. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Item_Taller_Than_Limit_Exception.js +21 -0
  60. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Available_Items_Exception.js +14 -0
  61. package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Slots_For_Items_Exception.js +14 -0
  62. package/src/Allocation_Optimization/lp_model/Block_Weight_Calculator.js +31 -0
  63. package/src/Allocation_Optimization/lp_model/LP_Data_Processor.js +42 -0
  64. package/src/Allocation_Optimization/lp_model/LP_Item_Slot_Assignment.js +93 -0
  65. package/src/Allocation_Optimization/lp_model/LP_Result_Mapper.js +47 -0
  66. package/src/Allocation_Optimization/lp_model/model_builder/Dimension_Range_Helper.js +49 -0
  67. package/src/Allocation_Optimization/lp_model/model_builder/Item_Assignment_Variables.js +133 -0
  68. package/src/Allocation_Optimization/lp_model/model_builder/LP_Model_Builder.js +132 -0
  69. package/src/Allocation_Optimization/lp_model/model_builder/exceptions/Missing_Item_Stock_Exception.js +18 -0
  70. package/src/Allocation_Optimization/lp_model/model_builder/goal_function/Goal_Function_Creator.js +83 -0
  71. package/src/Allocation_Optimization/lp_model/model_builder/item_dimension_hashes.js +31 -0
  72. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Block_Item_Amount_Restriction.js +53 -0
  73. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Coherence_Restriction.js +65 -0
  74. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Container_Supported_Weight_Restriction.js +42 -0
  75. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Exact_Pass_Amount_Restriction.js +62 -0
  76. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Group_Restriction.js +97 -0
  77. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Single_Item_Type_Restriction.js +79 -0
  78. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Space_Restriction.js +47 -0
  79. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Unavailable_Block_Restriction.js +27 -0
  80. package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Uniform_Block_Measure_Restriction.js +92 -0
  81. package/src/Allocation_Optimization/next_group_id_after_preloaded.js +30 -0
  82. package/src/Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier.js +74 -0
  83. package/src/Allocation_Optimization/preferential_blocks/key_item/Key_Item_Mapper.js +49 -0
  84. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Almost_Unique_Item.js +31 -0
  85. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Cant_Stack_It_Self.js +68 -0
  86. package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Rule_Interface.js +26 -0
  87. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Intercalation_State.js +49 -0
  88. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter.js +33 -0
  89. package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter.js +20 -0
  90. package/src/Allocation_Optimization/tie_ratio/collect_tie_ratio_orientations_below_footprint.js +64 -0
  91. package/src/Allocation_Optimization/tie_ratio/filter_blocks_by_orientation.js +17 -0
  92. package/src/Allocation_Optimization/tie_ratio/find_orientation_below_space.js +77 -0
  93. package/src/Allocation_Optimization/tie_ratio/loose_on_block/allocated_item_penetrates_any.js +31 -0
  94. package/src/Allocation_Optimization/tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item.js +94 -0
  95. package/src/Allocation_Optimization/tie_ratio/loose_on_block/axis_overlap_length.js +16 -0
  96. package/src/Allocation_Optimization/tie_ratio/loose_on_block/block_local_origin.js +18 -0
  97. package/src/Allocation_Optimization/tie_ratio/loose_on_block/box_fits_inside_container.js +39 -0
  98. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_allocated_item_at_placement.js +18 -0
  99. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_placement_on_generic_supporter.js +64 -0
  100. package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_slot_grid_from_cluster.js +66 -0
  101. package/src/Allocation_Optimization/tie_ratio/loose_on_block/compare_group_ids.js +20 -0
  102. package/src/Allocation_Optimization/tie_ratio/loose_on_block/container_with_pending_wall_items.js +26 -0
  103. package/src/Allocation_Optimization/tie_ratio/loose_on_block/empty_space_is_on_floor.js +16 -0
  104. package/src/Allocation_Optimization/tie_ratio/loose_on_block/finalize_loose_item_placement.js +58 -0
  105. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_best_generic_supporter_placement.js +58 -0
  106. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_next_free_slot_index.js +119 -0
  107. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_supporter_directly_below.js +51 -0
  108. package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_tie_ratio_supporter_cluster.js +57 -0
  109. package/src/Allocation_Optimization/tie_ratio/loose_on_block/footprint_xz_overlap_area.js +26 -0
  110. package/src/Allocation_Optimization/tie_ratio/loose_on_block/item_fits_supporter_slot.js +22 -0
  111. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_footprint_region_from_options.js +24 -0
  112. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_fits_inside_container.js +21 -0
  113. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_has_geometric_support.js +21 -0
  114. package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_on_block_slot_state.js +88 -0
  115. package/src/Allocation_Optimization/tie_ratio/loose_on_block/placement_coords_fit_inside_container.js +34 -0
  116. package/src/Allocation_Optimization/tie_ratio/loose_on_block/read_empilhar_area_igual_from_allocation_item.js +12 -0
  117. package/src/Allocation_Optimization/tie_ratio/loose_on_block/realigned_loose_geometry_gates.js +25 -0
  118. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_on_generic_supporter.js +65 -0
  119. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_placement_position.js +68 -0
  120. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_placement_y_at_slot.js +45 -0
  121. package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_without_tie_ratio_cluster.js +79 -0
  122. package/src/Allocation_Optimization/tie_ratio/loose_on_block/select_tie_ratio_slot_placement.js +84 -0
  123. package/src/Allocation_Optimization/tie_ratio/loose_on_block/slot_footprint_collision.js +105 -0
  124. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_cluster_selection.js +119 -0
  125. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_footprint_overlap.js +56 -0
  126. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_placement_plane.js +109 -0
  127. package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_supporter_predicate.js +23 -0
  128. package/src/Allocation_Optimization/tie_ratio/loose_on_block/try_tie_ratio_slot_placement.js +62 -0
  129. package/src/Allocation_Optimization/tie_ratio/snap_stacked_items_to_floor_footprints.js +138 -0
  130. package/src/Allocation_Optimization/tie_ratio/supporters_by_top_y_index.js +78 -0
  131. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space.js +89 -0
  132. package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_from_group.js +48 -0
  133. package/src/Block_Management.js +34 -0
  134. package/src/Blocks_Preparation/Cube_Map_Function.js +27 -0
  135. package/src/Blocks_Wall_Allocation.js +3 -0
  136. package/src/IO/Answer_Status.js +4 -0
  137. package/src/IO/Output_Builder.js +35 -0
  138. package/src/IO/count_allocated_items.js +31 -0
  139. package/src/IO/create_error_response.js +62 -0
  140. package/src/IO/format_allocation_error_message.js +25 -0
  141. package/src/Item_Continuation_Lock.js +129 -0
  142. package/src/Item_Picking_Continuity.js +41 -0
  143. package/src/allocation_flow/chooser_session_state.js +21 -0
  144. package/src/allocation_flow/compound_probe_fallback.js +17 -0
  145. package/src/allocation_flow/container_remaining_capacity.js +23 -0
  146. package/src/allocation_flow/density_group_item_filter.js +31 -0
  147. package/src/allocation_flow/effective_item_fingerprint.js +14 -0
  148. package/src/allocation_flow/item_continuation_lock_gate.js +38 -0
  149. package/src/allocation_flow/no_space_left_recovery.js +48 -0
  150. package/src/allocation_flow/run_allocation_iteration.js +155 -0
  151. package/src/allocation_flow/space_skip_state.js +91 -0
  152. package/src/allocation_flow/try_no_space_left_recovery.js +50 -0
  153. package/src/exceptions/Invalid_Parameter_Exception.js +17 -0
  154. package/src/exceptions/Relational_Allocation_Incomplete_Exception.js +24 -0
  155. package/src/exceptions/Relational_Colocation_Violation_Exception.js +23 -0
  156. package/src/exceptions/Relational_Config_Mismatch_Exception.js +17 -0
  157. package/src/exceptions/There_Is_No_Block_Options_To_Allocate_Exception.js +14 -0
  158. package/src/index.js +6 -0
  159. package/src/input_preparation/Block_Formatter.js +179 -0
  160. package/src/input_preparation/Input_Creator.js +76 -0
  161. package/src/input_preparation/Input_State_Preparation.js +47 -0
  162. package/src/input_preparation/State_Builder.js +27 -0
  163. package/src/input_preparation/block_formatter/align_flush_axis_config.js +36 -0
  164. package/src/input_preparation/block_formatter/align_flush_axis_single_round.js +112 -0
  165. package/src/input_preparation/block_formatter/align_flush_stacked_slots.js +67 -0
  166. package/src/input_preparation/block_formatter/overlapped_slots.js +24 -0
  167. package/src/input_preparation/block_formatter/parallelepiped_shell.js +38 -0
  168. package/src/input_preparation/block_formatter/rectangle_coverage.js +112 -0
  169. package/src/input_preparation/block_formatter/shell_face_coverage.js +64 -0
  170. package/src/input_preparation/block_formatter/shell_snap_convergence.js +104 -0
  171. package/src/input_preparation/block_preparation/Block_Data_To_Object_Transformer.js +57 -0
  172. package/src/input_preparation/block_preparation/Block_Module_Name.js +17 -0
  173. package/src/input_preparation/block_preparation/Blocks_Creator.js +101 -0
  174. package/src/input_preparation/block_preparation/Blocksmith.js +19 -0
  175. package/src/input_preparation/block_preparation/block_modules/create_block_candidates.js +41 -0
  176. package/src/input_preparation/block_preparation/block_modules/manual_blocks.js +10 -0
  177. package/src/input_preparation/block_preparation/block_modules/module_registry.js +20 -0
  178. package/src/input_preparation/block_preparation/block_modules/run_creator.js +34 -0
  179. package/src/input_preparation/block_preparation/block_modules/single_item_blocks.js +12 -0
  180. package/src/input_preparation/block_preparation/block_modules/spiral_blocks.js +12 -0
  181. package/src/input_preparation/block_preparation/block_modules/tie_ratio_blocks.js +12 -0
  182. package/src/input_preparation/block_preparation/block_modules/tower_blocks.js +12 -0
  183. package/src/input_preparation/block_preparation/exceptions/Failed_To_Create_Block_Exception.js +14 -0
  184. package/src/input_preparation/block_preparation/exceptions/Failed_To_Retrieve_Block_Exception.js +17 -0
  185. package/src/input_preparation/block_preparation/exceptions/Missing_Object_Store_Exception.js +10 -0
  186. package/src/input_preparation/block_preparation/exceptions/No_Blocks_Were_Created_Exception.js +14 -0
  187. package/src/input_preparation/block_preparation/input/Input_Creator.js +96 -0
  188. package/src/input_preparation/block_preparation/manual_blocks/Manual_Blocks.js +95 -0
  189. package/src/input_preparation/build_empty_space_finder_options.js +43 -0
  190. package/src/input_preparation/item_preparation/Items_Reader.js +27 -0
  191. package/src/input_preparation/min_extents_from_items.js +29 -0
  192. package/src/input_preparation/stackability_index/Blocks_Stackability_Index_Calculator.js +58 -0
  193. package/src/input_preparation/stackability_index/Slots_Stackability_index_Calculator.js +28 -0
  194. package/src/input_preparation/stackability_index/Stackability_Input_Creator.js +27 -0
  195. package/src/input_preparation/stackability_index/stackability_index_pop_stack.js +81 -0
  196. package/src/input_preparation/stacking_constraints/Weight_Stacking_Validation.js +15 -0
  197. package/src/lp_optimizer_result_status.js +20 -0
  198. package/src/messages/Allocator_Message.js +42 -0
  199. package/src/messages/resolve_error_message_entry.js +57 -0
  200. package/src/models/Allocated_Item.js +136 -0
  201. package/src/models/Allocation_Item.js +219 -0
  202. package/src/models/Block.js +198 -0
  203. package/src/models/Cargo_Profile.js +418 -0
  204. package/src/models/Preloaded_Allocated_Item.js +132 -0
  205. package/src/models/Slot.js +67 -0
  206. package/src/models/Stacking_Rules.js +58 -0
  207. package/src/models/auxiliaryFunctions/Available_Block_Module_List_Creator.js +9 -0
  208. package/src/models/auxiliaryFunctions/Measure_Translator.js +24 -0
  209. package/src/models/auxiliaryFunctions/item_json_reader.js +44 -0
  210. package/src/models/item_json_reader.js +71 -0
  211. package/src/models/placed_item_record.js +70 -0
  212. package/src/models/preloaded_rotation_helpers.js +38 -0
  213. package/src/models/slots_have_same_measure.js +45 -0
  214. package/src/models/transport/Container.js +162 -0
  215. package/src/models/transport/Transport.js +62 -0
  216. package/src/models/transport/build_stacking_feasibility_checker.js +64 -0
  217. package/src/models/transport/container_stacking_checkpoint.js +42 -0
  218. package/src/models/transport/factory/Container_Factory.js +46 -0
  219. package/src/models/transport/factory/Corner_Casting_Factory.js +62 -0
  220. package/src/models/transport/factory/Previously_Allocated_Item_Factory.js +28 -0
  221. package/src/models/transport/factory/Transport_Factory.js +13 -0
  222. package/src/models/transport/items_for_empty_space_finder.js +91 -0
  223. package/src/models/transport/resolve_container_stacking_inputs.js +23 -0
  224. package/src/models/transport/stacking_input_from_wire.js +58 -0
  225. package/src/optimizer_connection_errors.js +50 -0
  226. package/src/relational/Relational_Error_Codes.js +7 -0
  227. package/src/relational/finalize_relational_allocation.js +20 -0
  228. package/src/relational/has_relational_items.js +11 -0
  229. package/src/relational/is_relational_error_code.js +15 -0
  230. package/src/relational/resolve_relational_container_sequences.js +29 -0
  231. package/src/run_core_allocation.js +118 -0
  232. package/src/space_and_block_chooser/Space_And_Blocks_Chooser.js +115 -0
  233. package/src/space_and_block_chooser/blocks_filters/Block_Filter_Interface.js +19 -0
  234. package/src/space_and_block_chooser/blocks_filters/Filter_Runner.js +46 -0
  235. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Block_With_Overlapped_Slots_Filter.js +14 -0
  236. package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Initial_Blocks_Filter_List.js +19 -0
  237. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Blocks_Bigger_Than_Space_Filter.js +17 -0
  238. package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Post_Selection_Filter_List.js +9 -0
  239. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Insuficient_Items_Filter.js +81 -0
  240. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Pre_Selection_Filter_List.js +8 -0
  241. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Blocks_Lower_Than_Max_Tower_Height.js +23 -0
  242. package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Max_Tower_Height.js +82 -0
  243. package/src/space_and_block_chooser/build_allocated_item_snapshots.js +19 -0
  244. package/src/space_and_block_chooser/compound_first_empty_space_branch.js +61 -0
  245. package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +142 -0
  246. package/src/space_and_block_chooser/compound_first_without_leftover_fill.js +56 -0
  247. package/src/space_and_block_chooser/empty_spaces_where_post_selection_keeps_blocks.js +83 -0
  248. package/src/space_and_block_chooser/exceptions/Invalid_Space_To_Allocate_Exception.js +14 -0
  249. package/src/space_and_block_chooser/leftover_space_memory.js +113 -0
  250. package/src/space_and_block_chooser/leftover_unitary_blocks.js +153 -0
  251. package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +135 -0
  252. package/src/space_and_block_chooser/probe_set_pool.js +35 -0
  253. package/src/space_and_block_chooser/run_space_and_block_selection_attempt.js +88 -0
  254. package/src/tools/Array_Validator.js +6 -0
  255. package/src/tools/Clone.js +27 -0
  256. package/src/tools/Hash.js +8 -0
  257. package/src/tools/Rounder.js +5 -0
  258. package/src/tools/String_To_Boolean.js +12 -0
  259. package/src/tools/cargo_profile/Cargo_Profile_Field_Value_Resolver.js +44 -0
  260. package/src/tools/compact_items_with_stock.js +9 -0
  261. package/src/tools/mm_to_allocation_domain.js +14 -0
  262. package/src/tracing/Allocation_Tracer.js +52 -0
  263. package/src/tracing/Trace_Context.js +18 -0
  264. package/src/tracing/trace_outcome.js +18 -0
  265. package/src/tracing/traced_step.js +57 -0
  266. package/src/validation/Item_Continuation_Lock_Flag.js +52 -0
  267. package/src/validation/Item_Validation.js +29 -0
  268. package/src/validation/Relational_Colocation_Validator.js +60 -0
  269. package/src/validation/Relational_Completeness_Validator.js +146 -0
  270. package/src/validation/Relational_Continuation_Lock_Validation.js +37 -0
  271. package/src/validation/Relational_Proportional_Normalizer.js +194 -0
  272. package/src/validation/Validation.js +9 -0
  273. package/src/validation/Validation_Runner.js +20 -0
  274. package/src/validation/exceptions/Invalid_Block_Module_Config_Exception.js +14 -0
  275. package/src/validation/exceptions/Invalid_Input_Exception.js +14 -0
  276. package/src/validation/exceptions/Invalid_Input_Type_Exception.js +14 -0
  277. package/src/validation/schemas/allocated_item_schema.js +18 -0
  278. package/src/validation/schemas/allocation_request_schema.js +178 -0
  279. package/src/validation/schemas/container_row_schema.js +16 -0
  280. package/src/validation/schemas/item_schema.js +60 -0
  281. package/src/validation/schemas/transport_env_schema.js +19 -0
  282. package/src/validation/validate_block_module_config.js +147 -0
@@ -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_Slots_For_Items_Exception extends Error
5
+ {
6
+ constructor()
7
+ {
8
+ const message_key = ALLOCATOR_MESSAGE.NO_SLOTS_FOR_ITEMS
9
+ super(message_key)
10
+ this.message_entry = build_message_entry(message_key)
11
+ }
12
+ }
13
+
14
+ module.exports = No_Slots_For_Items_Exception
@@ -0,0 +1,31 @@
1
+ const Cargo_Profile = require('../../models/Cargo_Profile')
2
+ const Measure_Reader = require('../functions/Measure_Reader')
3
+ const measure_to_optimize = require('../functions/measure_to_optimize')
4
+ const get_custom_weight = require('../functions/Weight_Getter/Variable_Weight_Getter')
5
+
6
+ function get_measure(obj)
7
+ {
8
+ switch (Measure_Reader.read_measure_to_be_optimized())
9
+ {
10
+ case measure_to_optimize.LENGTH:
11
+ return obj.length !== undefined ? obj.length : obj.get_length()
12
+ case measure_to_optimize.WIDTH:
13
+ return obj.width !== undefined ? obj.width : obj.get_width()
14
+ default:
15
+ throw new Error('invalid measure identifier')
16
+ }
17
+ }
18
+
19
+ function buff_block(block)
20
+ {
21
+ return Cargo_Profile.enable_blocks_extra_score() ? (1 + (block.is_block() ? 1 : 0)) / 1.5 : 1
22
+ }
23
+
24
+ module.exports = function calculate_block_var_weight(block)
25
+ {
26
+ const measure = Number(get_measure(block))
27
+ const custom_additional_weight = get_custom_weight(block)
28
+ const base_weight = (measure * 10) + Number(custom_additional_weight)
29
+ const buff_blocks = buff_block(block)
30
+ return base_weight * buff_blocks
31
+ }
@@ -0,0 +1,42 @@
1
+
2
+ class LP_Data_Processor
3
+ {
4
+ /**
5
+ * Sanitizes available usable blocks based on restricted blocks.
6
+ * Filters out fully restricted blocks and identifies multi-slot blocks.
7
+ * @param {Array<Object>} available_block_list - A list of available usable block objects.
8
+ * @param {Object} restricted_block_map - An object mapping block IDs to their restricted status.
9
+ * @returns {Array<Object>} A filtered list of usable block objects, prioritizing multi-slot blocks if available.
10
+ */
11
+ sanitize(available_block_list, restricted_block_map = {})
12
+ {
13
+ const fully_restricted_ids = new Set()
14
+ for (const block_id of Object.keys(restricted_block_map))
15
+ {
16
+ if (restricted_block_map[block_id] == 0)
17
+ {
18
+ fully_restricted_ids.add(block_id)
19
+ }
20
+ }
21
+ if (fully_restricted_ids.size === 0)
22
+ {
23
+ return available_block_list
24
+ }
25
+ return available_block_list.filter(block => !fully_restricted_ids.has(block.get_id()))
26
+ }
27
+
28
+ /**
29
+ * Removes duplicate blocks from a list based on their IDs.
30
+ * If multiple blocks have the same ID, only the last occurrence is kept.
31
+ * @param {Array<Object>} blocks - A list of block objects.
32
+ * @returns {Array<Object>} A new list of blocks with duplicates removed.
33
+ */
34
+ remove_duplicates(blocks)
35
+ {
36
+ const map = {}
37
+ blocks.forEach(block => map[block.get_id()] = block)
38
+ return Object.values(map)
39
+ }
40
+ }
41
+
42
+ module.exports = LP_Data_Processor
@@ -0,0 +1,93 @@
1
+ const round = require('../../tools/Rounder')
2
+
3
+ /**
4
+ * Builds per-block-instance item id queues from LP block_item_amount variables.
5
+ * @param {object} result - Optimizer result with variables().
6
+ * @param {{ slot_demand_list: object[] }} item_assignment_context
7
+ * @returns {Map<string, string[]>} block_id -> ordered item ids (one per block instance)
8
+ */
9
+ function build_block_instance_item_queues(result, item_assignment_context)
10
+ {
11
+ const variable_values = index_variable_values(result)
12
+ const queues = new Map()
13
+
14
+ for (const slot_demand of item_assignment_context.slot_demand_list)
15
+ {
16
+ merge_slot_demand_into_queues(slot_demand, variable_values, queues)
17
+ }
18
+
19
+ return queues
20
+ }
21
+
22
+ function index_variable_values(result)
23
+ {
24
+ const values = new Map()
25
+
26
+ for (const variable of result.variables())
27
+ {
28
+ if (!variable.name.startsWith('block_item_amount_'))
29
+ {
30
+ continue
31
+ }
32
+
33
+ const amount = round(variable.value)
34
+ if (amount > 0)
35
+ {
36
+ values.set(variable.name, amount)
37
+ }
38
+ }
39
+
40
+ return values
41
+ }
42
+
43
+ function merge_slot_demand_into_queues(slot_demand, variable_values, queues)
44
+ {
45
+ const { block_id, required_amount, compatibility_list } = slot_demand
46
+ const item_ids_for_slot_shape = expand_item_counts(compatibility_list, variable_values)
47
+
48
+ if (item_ids_for_slot_shape.length === 0)
49
+ {
50
+ return
51
+ }
52
+
53
+ if (required_amount !== 1)
54
+ {
55
+ return
56
+ }
57
+
58
+ const block_instances = item_ids_for_slot_shape.length
59
+ if (!queues.has(block_id))
60
+ {
61
+ queues.set(block_id, new Array(block_instances))
62
+ }
63
+
64
+ const block_queue = queues.get(block_id)
65
+ for (let index = 0; index < block_instances; index++)
66
+ {
67
+ if (!block_queue[index])
68
+ {
69
+ block_queue[index] = []
70
+ }
71
+ block_queue[index].push(item_ids_for_slot_shape[index])
72
+ }
73
+ }
74
+
75
+ function expand_item_counts(compatibility_list, variable_values)
76
+ {
77
+ const item_ids = []
78
+
79
+ for (const entry of compatibility_list)
80
+ {
81
+ const count = variable_values.get(entry.variable_name) || 0
82
+ for (let index = 0; index < count; index++)
83
+ {
84
+ item_ids.push(entry.item_id)
85
+ }
86
+ }
87
+
88
+ return item_ids
89
+ }
90
+
91
+ module.exports = {
92
+ build_block_instance_item_queues
93
+ }
@@ -0,0 +1,47 @@
1
+
2
+ const round = require('../../tools/Rounder')
3
+ const { read_measure_to_be_optimized } = require('../functions/Measure_Reader')
4
+ const { build_block_instance_item_queues } = require('./LP_Item_Slot_Assignment')
5
+
6
+ class LP_Result_Mapper
7
+ {
8
+ constructor(block_map)
9
+ {
10
+ this.block_map = block_map
11
+ }
12
+
13
+ map_result(result, item_assignment_context = null)
14
+ {
15
+ const allocated_blocks = {
16
+ optimized_measure: read_measure_to_be_optimized(),
17
+ chosen_blocks: [],
18
+ block_instance_item_queues: new Map()
19
+ }
20
+
21
+ for (const variable of result.variables())
22
+ {
23
+ const is_block_var = (variable) => this.block_map[variable.name]
24
+ if (is_block_var(variable))
25
+ {
26
+ const block_object = this.block_map[variable.name]
27
+ const chosen_block = { block: block_object, amount: round(variable.value) }
28
+ if (chosen_block.amount > 0)
29
+ {
30
+ allocated_blocks.chosen_blocks.push(chosen_block)
31
+ }
32
+ }
33
+ }
34
+
35
+ if (item_assignment_context)
36
+ {
37
+ allocated_blocks.block_instance_item_queues = build_block_instance_item_queues(
38
+ result,
39
+ item_assignment_context
40
+ )
41
+ }
42
+
43
+ return allocated_blocks
44
+ }
45
+ }
46
+
47
+ module.exports = LP_Result_Mapper
@@ -0,0 +1,49 @@
1
+ const Cargo_Profile = require('../../../models/Cargo_Profile')
2
+ const { read_measure_to_be_optimized } = require('../../functions/Measure_Reader')
3
+ const measure_to_optimize = require('../../functions/measure_to_optimize')
4
+
5
+ /**
6
+ * Shared helpers for block dimension ranges used by the uniformity penalty and coherence restrictions.
7
+ * @module Dimension_Range_Helper
8
+ */
9
+
10
+ /**
11
+ * Returns the perpendicular measure used for block equalization (width when optimizing length, length when optimizing width).
12
+ * @param {object} obj - Object with width/length or get_width/get_length.
13
+ * @returns {number} The penalty measure value.
14
+ */
15
+ function get_penalty_measure(obj)
16
+ {
17
+ switch (read_measure_to_be_optimized())
18
+ {
19
+ case measure_to_optimize.LENGTH:
20
+ return obj.width !== undefined ? obj.width : obj.get_width()
21
+ case measure_to_optimize.WIDTH:
22
+ return obj.length !== undefined ? obj.length : obj.get_length()
23
+ default:
24
+ throw new Error('invalid measure identifier')
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Returns the dimension range id for a block, used for uniformity penalty and coherence restrictions.
30
+ * @param {object} block - The block object.
31
+ * @returns {number} The range id (same as used in penalty variable names).
32
+ */
33
+ function get_dimension_range(block)
34
+ {
35
+ const tolerance = Cargo_Profile.block_equalization_tolerance()
36
+ if (tolerance <= 0)
37
+ {
38
+ return get_penalty_measure(block)
39
+ }
40
+
41
+ const penalty_measure = get_penalty_measure(block)
42
+ const range_id = Math.ceil(penalty_measure / tolerance) * tolerance
43
+ return range_id
44
+ }
45
+
46
+ module.exports = {
47
+ get_penalty_measure,
48
+ get_dimension_range
49
+ }
@@ -0,0 +1,133 @@
1
+ const create_hash = require('../../../tools/Hash')
2
+ const {
3
+ get_dimension_hash,
4
+ collect_rotation_dimension_hashes
5
+ } = require('./item_dimension_hashes')
6
+ const Missing_Item_Stock_Exception = require('./exceptions/Missing_Item_Stock_Exception')
7
+
8
+ /**
9
+ * Builds the LP assignment graph between blocks, slot shapes, and compatible items.
10
+ * Single source of truth for the `block_item_amount_<hash>` variable naming used by
11
+ * Block_Item_Amount_Restriction and Single_Item_Type_Restriction.
12
+ * @param {object[]} block_list - Block objects (must expose get_id and get_slot_list).
13
+ * @param {object[]} item_list - Item objects (must expose get_id, get_amount and get_all_rotated_options).
14
+ * @returns {{
15
+ * slot_demand_list: Array<{block_id: string, slot_hash: string, required_amount: number, compatibility_list: Array<{item_id: string, variable_name: string}>}>,
16
+ * variables_by_item: Map<string, string[]>,
17
+ * id_to_stock_map: Map<string, number>
18
+ * }}
19
+ */
20
+ function create_item_assignment_variables(block_list, item_list)
21
+ {
22
+ const { dim_to_id_map, id_to_stock_map } = build_item_dimension_and_stock_maps(item_list)
23
+ const slot_demand_list = build_block_slot_demand_list(block_list, dim_to_id_map)
24
+ const variables_by_item = group_variable_names_by_item(slot_demand_list)
25
+ return { slot_demand_list, variables_by_item, id_to_stock_map }
26
+ }
27
+
28
+ /**
29
+ * Reads stock for an item id from the map built with create_item_assignment_variables.
30
+ * @param {Map<string, number>} id_to_stock_map - Item id to available amount.
31
+ * @param {string} item_id - Item id to resolve.
32
+ * @returns {number} Stock amount for the item.
33
+ * @throws {Missing_Item_Stock_Exception} When the item id is missing from the map.
34
+ */
35
+ function read_stock(id_to_stock_map, item_id)
36
+ {
37
+ const amount = id_to_stock_map.get(item_id)
38
+ if (amount === undefined)
39
+ {
40
+ throw new Missing_Item_Stock_Exception(item_id)
41
+ }
42
+ return amount
43
+ }
44
+
45
+ module.exports = create_item_assignment_variables
46
+ module.exports.read_stock = read_stock
47
+
48
+ function build_item_dimension_and_stock_maps(item_list)
49
+ {
50
+ const dim_to_id_map = new Map()
51
+ const id_to_stock_map = new Map()
52
+ for (const item of item_list)
53
+ {
54
+ const item_id = item.get_id()
55
+ index_item_rotations(dim_to_id_map, item)
56
+ if (!id_to_stock_map.has(item_id))
57
+ {
58
+ id_to_stock_map.set(item_id, item.get_amount())
59
+ }
60
+ }
61
+ return { dim_to_id_map, id_to_stock_map }
62
+ }
63
+
64
+ function index_item_rotations(dim_to_id_map, item)
65
+ {
66
+ const item_id = item.get_id()
67
+ for (const hash of collect_rotation_dimension_hashes(item))
68
+ {
69
+ if (!dim_to_id_map.has(hash))
70
+ {
71
+ dim_to_id_map.set(hash, new Set())
72
+ }
73
+ dim_to_id_map.get(hash).add(item_id)
74
+ }
75
+ }
76
+
77
+ function build_block_slot_demand_list(block_list, dim_to_id_map)
78
+ {
79
+ const slot_demand_list = []
80
+ for (const block of block_list)
81
+ {
82
+ const block_id = block.get_id()
83
+ const demand_by_slot_hash = get_block_slot_demand(block)
84
+ for (const [slot_hash, required_amount] of demand_by_slot_hash.entries())
85
+ {
86
+ slot_demand_list.push({
87
+ block_id,
88
+ slot_hash,
89
+ required_amount,
90
+ compatibility_list: build_compatibility_list(block_id, slot_hash, dim_to_id_map)
91
+ })
92
+ }
93
+ }
94
+ return slot_demand_list
95
+ }
96
+
97
+ function get_block_slot_demand(block)
98
+ {
99
+ const demand_by_slot_hash = new Map()
100
+ for (const slot of block.get_slot_list())
101
+ {
102
+ const slot_hash = get_dimension_hash(slot)
103
+ const current_count = demand_by_slot_hash.get(slot_hash) || 0
104
+ demand_by_slot_hash.set(slot_hash, current_count + 1)
105
+ }
106
+ return demand_by_slot_hash
107
+ }
108
+
109
+ function build_compatibility_list(block_id, slot_hash, dim_to_id_map)
110
+ {
111
+ const compatible_id_set = dim_to_id_map.get(slot_hash) || new Set()
112
+ return [...compatible_id_set].map(item_id => ({
113
+ item_id,
114
+ variable_name: `block_item_amount_${create_hash(`${block_id};${slot_hash};${item_id}`)}`
115
+ }))
116
+ }
117
+
118
+ function group_variable_names_by_item(slot_demand_list)
119
+ {
120
+ const variables_by_item = new Map()
121
+ for (const slot_demand of slot_demand_list)
122
+ {
123
+ for (const entry of slot_demand.compatibility_list)
124
+ {
125
+ if (!variables_by_item.has(entry.item_id))
126
+ {
127
+ variables_by_item.set(entry.item_id, [])
128
+ }
129
+ variables_by_item.get(entry.item_id).push(entry.variable_name)
130
+ }
131
+ }
132
+ return variables_by_item
133
+ }
@@ -0,0 +1,132 @@
1
+ const create_coherence_restrictions = require('./restrictions/Coherence_Restriction')
2
+ const create_item_assignment_variables = require('./Item_Assignment_Variables')
3
+ const create_block_item_amount_restriction = require('./restrictions/Block_Item_Amount_Restriction')
4
+ const create_container_supported_weight_restriction = require('./restrictions/Container_Supported_Weight_Restriction')
5
+ const create_block_restricted_to_0_restriction = require('./restrictions/Unavailable_Block_Restriction')
6
+ const create_single_item_type_restriction = require('./restrictions/Single_Item_Type_Restriction')
7
+ const create_uniform_block_measure_restriction = require('./restrictions/Uniform_Block_Measure_Restriction')
8
+ const create_relational_group_restriction = require('./restrictions/Relational_Group_Restriction')
9
+ const create_relational_exact_pass_amount_restriction = require('./restrictions/Relational_Exact_Pass_Amount_Restriction')
10
+ const create_space_restriction = require('./restrictions/Space_Restriction')
11
+ const Goal_Function_Creator = require('./goal_function/Goal_Function_Creator')
12
+
13
+ function validate_data(data)
14
+ {
15
+ if (data == null || typeof data !== 'object')
16
+ {
17
+ throw new Error('LP_Model_Builder: data is required and must be an object')
18
+ }
19
+ const required = ['optimizer', 'container', 'empty_space', 'block_list', 'item_list']
20
+ for (const key of required)
21
+ {
22
+ if (data[key] === undefined)
23
+ {
24
+ throw new Error(`LP_Model_Builder: data.${key} is required`)
25
+ }
26
+ }
27
+ if (!Array.isArray(data.block_list) || !Array.isArray(data.item_list))
28
+ {
29
+ throw new Error('LP_Model_Builder: data.block_list and data.item_list must be arrays')
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Assembles the full LP model: goal function and all restrictions (space, block-item, container weight,
35
+ * coherence, unavailable blocks, and single-item-type caps where applicable).
36
+ */
37
+ class LP_Model_Builder
38
+ {
39
+ #goal_function
40
+ #optimizer
41
+ #container
42
+ #empty_space
43
+ #block_list
44
+ #item_list
45
+ #block_amount_map
46
+ #enable_uniformity_penalty
47
+ #item_assignment_context = null
48
+
49
+ /**
50
+ * @param {object} data - Builder configuration.
51
+ * @param {object} data.optimizer - LP optimizer instance to receive goal and restrictions.
52
+ * @param {object} data.container - Container (e.g. supported_weight).
53
+ * @param {object} data.empty_space - Space to allocate (measure used for space restriction).
54
+ * @param {Array<object>} data.block_list - Available blocks.
55
+ * @param {Array<object>} data.item_list - Items for block-item constraints.
56
+ * @param {object} data.block_amount_map - Map of block id to max amount (unavailable-block restrictions).
57
+ * @param {boolean} [data.enable_uniformity_penalty=true] - Whether to add uniformity penalty in the goal.
58
+ */
59
+ constructor(data)
60
+ {
61
+ validate_data(data)
62
+ const {
63
+ optimizer,
64
+ container,
65
+ empty_space,
66
+ block_list,
67
+ item_list,
68
+ block_amount_map,
69
+ enable_uniformity_penalty = true
70
+ } = data
71
+ this.#optimizer = optimizer
72
+ this.#container = container
73
+ this.#empty_space = empty_space
74
+ this.#block_list = block_list
75
+ this.#item_list = item_list
76
+ this.#block_amount_map = block_amount_map
77
+ this.#enable_uniformity_penalty = enable_uniformity_penalty
78
+ }
79
+
80
+ /**
81
+ * Builds the LP model: goal function and all restrictions, and registers them with the optimizer.
82
+ * @returns {void}
83
+ */
84
+ build_model()
85
+ {
86
+ const penalty_vars = this.#build_goal_function()
87
+ this.#optimizer.set_goal_function(this.#goal_function)
88
+ this.#build_restrictions(penalty_vars)
89
+ }
90
+
91
+ /**
92
+ * Returns the item assignment context built during the last build_model() call.
93
+ * @returns {{slot_demand_list: Array, variables_by_item: Map<string, string[]>, id_to_stock_map: Map<string, number>}|null}
94
+ */
95
+ get_item_assignment_context()
96
+ {
97
+ return this.#item_assignment_context
98
+ }
99
+
100
+ #build_goal_function()
101
+ {
102
+ const goal_function_creator = new Goal_Function_Creator(this.#block_list, this.#enable_uniformity_penalty)
103
+ const {goal_function, penalty_vars} = goal_function_creator.create_goal_function()
104
+ this.#goal_function = goal_function
105
+ return penalty_vars
106
+ }
107
+
108
+ #build_restrictions(penalty_var_list)
109
+ {
110
+ this.#item_assignment_context = create_item_assignment_variables(this.#block_list, this.#item_list)
111
+ const restriction_list = [
112
+ ...create_space_restriction(this.#empty_space, this.#block_list),
113
+ ...create_block_item_amount_restriction(this.#block_list, this.#item_list, this.#item_assignment_context),
114
+ ...create_container_supported_weight_restriction(this.#container, this.#block_list, this.#item_list),
115
+ ...create_coherence_restrictions(penalty_var_list, this.#block_list),
116
+ ...create_uniform_block_measure_restriction(this.#block_list, this.#item_list),
117
+ ...create_block_restricted_to_0_restriction(this.#block_list, this.#block_amount_map ?? {}),
118
+ ...create_single_item_type_restriction(this.#block_list, this.#item_list, this.#item_assignment_context),
119
+ ...create_relational_group_restriction(this.#block_list, this.#item_list, this.#item_assignment_context),
120
+ ...create_relational_exact_pass_amount_restriction(this.#block_list, this.#item_list, this.#item_assignment_context)
121
+ ]
122
+
123
+ this.#add_restriction_list(restriction_list)
124
+ }
125
+
126
+ #add_restriction_list(restriction_list)
127
+ {
128
+ restriction_list.forEach(restriction => this.#optimizer.add_restriction(restriction))
129
+ }
130
+ }
131
+
132
+ module.exports = LP_Model_Builder
@@ -0,0 +1,18 @@
1
+ const { build_message_entry } = require('../../../../messages/resolve_error_message_entry')
2
+ const { ALLOCATOR_MESSAGE } = require('../../../../messages/Allocator_Message')
3
+
4
+ class Missing_Item_Stock_Exception extends Error
5
+ {
6
+ /**
7
+ * @param {string|number} item_id
8
+ */
9
+ constructor(item_id)
10
+ {
11
+ const message_key = ALLOCATOR_MESSAGE.MISSING_ITEM_STOCK
12
+ super(message_key)
13
+ this.message_entry = build_message_entry(message_key, [String(item_id)])
14
+ this.item_id = item_id
15
+ }
16
+ }
17
+
18
+ module.exports = Missing_Item_Stock_Exception
@@ -0,0 +1,83 @@
1
+ const {
2
+ GoalFunction,
3
+ OptimizationCriteria,
4
+ VariableType,
5
+ create_variable
6
+ } = require('@jetta/lp-framework')
7
+ const Cargo_Profile = require('../../../../models/Cargo_Profile')
8
+ const { get_dimension_range } = require('../Dimension_Range_Helper')
9
+ const calculate_block_var_weight = require('../../Block_Weight_Calculator')
10
+
11
+ /**
12
+ * Builds the LP goal function (objective) and optional uniformity penalty variables for block equalization.
13
+ */
14
+ module.exports = class Goal_Function_Creator
15
+ {
16
+ #goal_function
17
+ #block_list
18
+ #enable_uniformity_penalty
19
+ #penalty_vars = []
20
+ /**
21
+ * @param {Array<object>} block_list - List of blocks; each must have get_id().
22
+ * @param {boolean} enable_uniformity_penalty - Whether to add uniformity penalty variables when equalization is enabled.
23
+ */
24
+ constructor(block_list, enable_uniformity_penalty)
25
+ {
26
+ this.#block_list = block_list
27
+ this.#enable_uniformity_penalty = enable_uniformity_penalty
28
+ this.#goal_function = new GoalFunction(OptimizationCriteria.MAX)
29
+ }
30
+
31
+ /**
32
+ * Builds the goal function with block variables and, when enabled, uniformity penalty variables.
33
+ * @returns {{ goal_function: import('@jetta/lp-framework').GoalFunction, penalty_vars: Array<object> }} The goal function and list of penalty variables for coherence restrictions.
34
+ */
35
+ create_goal_function()
36
+ {
37
+ this.#add_block_variables_to_goal(this.#block_list)
38
+ const enabled = Cargo_Profile.enable_block_equalization()
39
+ if (enabled && this.#enable_uniformity_penalty)
40
+ {
41
+ this.#add_uniformity_penalty_to_goal()
42
+ }
43
+
44
+ return {
45
+ goal_function: this.#goal_function,
46
+ penalty_vars: this.#penalty_vars
47
+ }
48
+ }
49
+
50
+ #add_block_variables_to_goal(block_list)
51
+ {
52
+ for (const block of block_list)
53
+ {
54
+ const var_name = block.get_id()
55
+ const weight = calculate_block_var_weight(block)
56
+ const variable = create_variable(var_name, weight, VariableType.INTEGER)
57
+ this.#goal_function.set_variable(variable)
58
+ }
59
+ }
60
+
61
+ #add_uniformity_penalty_to_goal()
62
+ {
63
+ const unique_ranges = [...new Set(this.#block_list.map(b => get_dimension_range(b)))]
64
+
65
+ for (const range_id of unique_ranges)
66
+ {
67
+ const penalty_var_name = `used_penalty_range_${range_id}`
68
+ const penalty_variable = this.#create_penalty_variable(penalty_var_name)
69
+ this.#goal_function.set_variable(penalty_variable)
70
+ this.#penalty_vars.push(penalty_variable)
71
+ }
72
+ }
73
+
74
+ #create_penalty_variable(name)
75
+ {
76
+ const penalty_coefficient = parseInt(Cargo_Profile.block_equalization_penalty_coefficient())
77
+ const penalty_variable = create_variable(name, penalty_coefficient, VariableType.INTEGER)
78
+ return penalty_variable
79
+ }
80
+ }
81
+
82
+
83
+
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Builds the same dimension string key used across LP restrictions (width;height;length).
3
+ * @param {object} cube - Object with get_width, get_height, and get_length methods.
4
+ * @returns {string} Semicolon-separated dimensions.
5
+ */
6
+ function get_dimension_hash(cube)
7
+ {
8
+ return `${cube.get_width()};${cube.get_height()};${cube.get_length()}`
9
+ }
10
+
11
+ /**
12
+ * Collects dimension hashes for every rotation of an item (matches Block_Item indexing).
13
+ * @param {object} item - Item with get_all_rotated_options().
14
+ * @returns {Set<string>} Unique dimension hashes for all rotated orientations.
15
+ */
16
+ function collect_rotation_dimension_hashes(item)
17
+ {
18
+ const hash_set = new Set()
19
+
20
+ for (const rotated_item of item.get_all_rotated_options())
21
+ {
22
+ hash_set.add(get_dimension_hash(rotated_item))
23
+ }
24
+
25
+ return hash_set
26
+ }
27
+
28
+ module.exports = {
29
+ get_dimension_hash,
30
+ collect_rotation_dimension_hashes
31
+ }