def test_is_inside(self) -> None: item_0 = Rectangle(6, 6) instance = BinPacking2D(Rectangle(100, 100), [item_0]) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) self.assertTrue(instance.is_inside(sol[0], item_0)) sol[0] = Coordinate(100, 0) self.assertFalse(instance.is_inside(sol[0], item_0)) sol[0] = Coordinate(99, 99) self.assertFalse(instance.is_inside(sol[0], item_0)) sol[0] = Coordinate(93, 93) self.assertTrue(instance.is_inside(sol[0], item_0)) # Rotation test item_a = Rectangle(6, 2) item_b = Rectangle(6, 2) instance = BinPacking2D(Rectangle(6, 4), [item_a, item_b]) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(0, 2) sol[0].rotate() self.assertFalse(instance.is_inside(sol[0], item_a)) self.assertTrue(instance.is_inside(sol[1], item_b))
def __init__(self, instance: BinPacking2D, sol: Solution): self.capacity = instance.get_capacity() self.rectangles_with_coordinates: List[Tuple[int, int, bool, Rectangle]] = [] for i, coordinate in enumerate(sol): if coordinate.is_valid(): item = instance.get_item(i) self.rectangles_with_coordinates.append( (coordinate.x, coordinate.y, coordinate.is_rotated, item))
def test_evaluate(self) -> None: ################### instance = BinPacking2D( Rectangle(100, 100), [Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1)], ) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(1, 1) sol[2] = Coordinate(2, 2) sol[3] = Coordinate(3, 3) instance.evaluate(sol) fitness = sol.get_fitness() self.assertEqual(fitness, 4.0) ################### instance = BinPacking2D( Rectangle(100, 100), [ Rectangle(30, 40), Rectangle(70, 30), Rectangle(30, 30), Rectangle(40, 70), Rectangle(30, 20), Rectangle(30, 70), ], ) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(0, 70) sol[2] = Coordinate(0, 40) sol[3] = Coordinate(30, 0) sol[4] = Coordinate(70, 0) sol[5] = Coordinate(70, 30) instance.evaluate(sol) fitness = sol.get_fitness() self.assertEqual(fitness, 6.0) ################### sol[0] = Coordinate(0, 0) sol[1] = Coordinate(0, 40) sol[2] = Coordinate(0, 70) sol[3] = Coordinate(30, 0) sol[3].rotate() sol[4] = Coordinate(30, 70) sol[5] = Coordinate(30, 93) sol[5].rotate() instance.evaluate(sol) fitness = sol.get_fitness() self.assertEqual(fitness, -1.0)
def test_has_collision(self) -> None: item_a = Rectangle(6, 6) item_b = Rectangle(2, 2) instance = BinPacking2D(Rectangle(10, 10), [item_a, item_b]) sol = Solution(instance.get_instance_size()) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(4, 4) sol[1] = Coordinate(2, 2) self.assertFalse(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(4, 4) sol[1] = Coordinate(4, 4) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(6, 6) self.assertFalse(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(0, 6) self.assertFalse(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(5, 2) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(2, 5) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(2, 0) sol[1] = Coordinate(1, 2) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) sol[0] = Coordinate(2, 0) sol[1] = Coordinate(0, 2) self.assertFalse(instance.has_collision(sol[1], item_b, sol[0], item_a)) sol[0] = Coordinate(2, 0) sol[1] = Coordinate(0, 2) self.assertFalse(instance.has_collision(sol[0], item_a, sol[1], item_b)) # Rotation test item_a = Rectangle(6, 2) item_b = Rectangle(6, 2) instance = BinPacking2D(Rectangle(10, 10), [item_a, item_b]) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(0, 2) sol[0].rotate() self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b))
def test_run_big_instance(self) -> None: instance = BinPacking2D( Rectangle(100, 100), [ Rectangle(30, 40), Rectangle(70, 30), Rectangle(30, 30), Rectangle(40, 70), Rectangle(30, 20), Rectangle(30, 70), ], ) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(-1, -1) sol[1] = Coordinate(-1, -1) sol[2] = Coordinate(-1, -1) sol[3] = Coordinate(-1, -1) sol[4] = Coordinate(-1, -1) sol[5] = Coordinate(-1, -1) statistics = Statistics() statistics.add_statistic(StatisticIteration()) statistics.add_statistic(StatisticFitness()) statistics.add_statistic(StatisticSolution()) stop_criteria = StopCriteria() stop_criteria.add_criterion(CriterionBudget(500)) backtracking = Backtracking(instance, statistics, stop_criteria) backtracking.run(sol)
def get_bin_packing(cls, file_path: str) -> BinPacking2D: loaded_instance = cls.load_json(file_path) # not super nice to cast but JSON doesn't have tuples capacity = Rectangle(*loaded_instance['capacity']) items = [Rectangle(*item) for item in loaded_instance['items']] b = BinPacking2D(capacity, items) return b
def test_backtracking(self) -> None: instance = BinPacking2D( Rectangle(2, 2), [Rectangle(2, 1), Rectangle(1, 1), Rectangle(1, 1)], ) domains = Domains(instance) statistics = Statistics() stop_criteria = StopCriteria() backtracking = Backtracking(instance, statistics, stop_criteria) valid_solutions = backtracking.run(domains) self.assertEqual(len(valid_solutions), 49) for valid_solution in valid_solutions: instance.evaluate(valid_solution) self.assertTrue(valid_solution.get_fitness() >= 0) self.assertTrue( any(valid_solution.get_fitness() == instance.get_instance_size() for valid_solution in valid_solutions)) number_of_solutions = 0 for valid_solution in valid_solutions: if valid_solution.get_fitness() == instance.get_instance_size(): number_of_solutions += 1 self.assertEqual(number_of_solutions, 8)
def test_has_collision_with_overlapping_rectangles(self) -> None: item_a = Rectangle(6, 2) item_b = Rectangle(2, 6) instance = BinPacking2D(Rectangle(10, 10), [item_a, item_b]) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(2, 3) sol[1] = Coordinate(4, 1) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) self.assertTrue(instance.has_collision(sol[1], item_b, sol[0], item_a)) item_a = Rectangle(2, 4) item_b = Rectangle(4, 2) instance = BinPacking2D(Rectangle(10, 10), [item_a, item_b]) sol[0] = Coordinate(2, 2) sol[1] = Coordinate(1, 3) self.assertTrue(instance.has_collision(sol[0], item_a, sol[1], item_b)) self.assertTrue(instance.has_collision(sol[1], item_a, sol[0], item_b))
def test_ac3_with_all_fitting_inputs(self) -> None: instance = BinPacking2D( Rectangle(100, 100), [Rectangle(10, 10), Rectangle(20, 20), Rectangle(10, 30)], ) ac3 = AC3(instance) domains = Domains(instance) ac3.run(domains) self.assertEqual( sum(len(sub_domain) for sub_domain in domains.values()), 27767)
def test_ac3_without_all_fitting_inputs(self) -> None: instance = BinPacking2D( Rectangle(10, 10), [Rectangle(1, 1), Rectangle(8, 8), Rectangle(3, 3)], ) ac3 = AC3(instance) domains = Domains(instance) ac3.run(domains) self.assertEqual( sum(len(sub_domain) for sub_domain in domains.values()), 127)
def test_run_small_instance(self) -> None: instance = BinPacking2D( Rectangle(2, 2), [Rectangle(1, 2), Rectangle(1, 2)], ) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(-1, -1) sol[1] = Coordinate(-1, -1) statistics = Statistics() stop_criteria = StopCriteria() backtracking = Backtracking(instance, statistics, stop_criteria) valid_solutions = backtracking.run(sol) self.assertEqual( str(valid_solutions), str([ [(0, 0, 0), (1, 0, 0)], [(0, 0, 90), (0, 1, 90)], [(0, 1, 90), (0, 0, 90)], [(1, 0, 0), (0, 0, 0)], ]), )
from binpacking.solver.bin_packing_2d import BinPacking2D, Rectangle from binpacking.solver.data_structure.solution import Solution, Coordinate from binpacking.plot.plot_handler import PlotHandler if __name__ == '__main__': print('Processing and printing to file...') instance = BinPacking2D( Rectangle(5, 5), [Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1)]) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(1, 1) sol[2] = Coordinate(2, 2) sol[3] = Coordinate(3, 3) plot_handler = PlotHandler(instance, sol) results_filepath = plot_handler.save_to_file('test1_plt.png') instance = BinPacking2D( Rectangle(5, 5), [Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1), Rectangle(1, 1)]) sol = Solution(instance.get_instance_size()) sol[0] = Coordinate(0, 0) sol[1] = Coordinate(1, 0)