Rectangular Bin-Packing Problem: a computational evaluation of 4 heuristics algorithms

The Rectangular Bin-packing Problem, also known as The Two-dimensional Binpacking Problem (2DBPP), is a well-known combinatorial optimization problem which is the problem of orthogonally packing a given set of rectangles into a minimum number of two-dimensional rectangular bins. In this article we benchmark four heuristics: constructive, based on a First Fit Decreasing strategy, local search using a greedy packing First-Fit algorithm, Simulated Annealing with multiple cooling values and Genetic Algorithm. All implementations are written in Python, run using the Pypy environment and the new multiprocessing module. All implementations were tested using the Berkey and Wang and Martelo and Vigo Benchmark Instances. Subject Headings. Optimization, computer programming, operational research. Author

− We can set a fixed maximum number of bins or set a group of different sized bins (Alvarez-Valdés, Parreño, and Tamarit 2013;Wei et al. 2013); − We can limit the orientation of the items or enable a 90º rotation (Blum and Schmid 2013;Sarabian and Lee 2010); − We can force a guillotine cut 1 ; − We can impose a cost on each item (Pisinger and Sigurd 2005). − Lodi et al. (1999)introduce four possible BPP subtypes based on the orientation and guillotine cut constraints: − 2DBPP|R|F: Items may be rotated by 90º (R), guillotine cut constraint not imposed (F); − 2DBPP|R|G: Items may be rotated by 90º (R), guillotine cut constraint is imposed (G); − 2DBPP|O|F: Orientation of items is fixed (O), guillotine cut constraint not imposed (F); − 2DBPP|O|G: Orientation of items is fixed (O), guillotine cut constraint is imposed (G).
In this article, on section 2, we will start by introducing the type of two-dimensional bin packing problem we are going to study. On section 3 we will present the algorithms we are going to implement and on section 4 we will present the benchmark instances that are used throughout the literature related to this problem. On section 5 we will discuss our results, comparing the number of bins and execution times of all algorithms. On section 6 we will do a brief conclusion of the work and present some future work.

Problem Description
In this article we are going to study the Rectangular Bin-packing Problem as stated in the following description (Pisinger and Sigurd 2007): Assume that a set ℜ = {1,..., n} of rectangles is given, rectangle ı having width wı, and height hı. We can use an infinite number of bins to pack the items, each bin has a width W and a height H. The objective is to minimize the number of bins used to pack all rectangles in ℜ such that they do not overlap. Following the Lodi et al. (1999) subtypes we are going to focus on the 2DBPP|O|F, fixed orientation and no guillotine cut. For the sake of simplicity from now on, when we refer to 2DBPP in the article, we are referring to this definition.

Solution Approaches
The implementations done in this study follows each heuristic and meta-heuristic implementation basic ideas from the description of the papers in the literature (Bays 1977;Kirkpatrick, Gelatt, and Vecchi 1983;Osogami and Okano 2003;Wei et al. 2013). Nevertheless these implementations are our own work and will most likely give different results concerning execution time and efficiency, from the ones already found in the literature, due to using different programming and testing platforms. The implementations are going to be described in the subsection of each heuristic and meta-heuristic. For this article we are going to test the implementation of four heuristics to solve the 2DBPP problem: a constructive heuristic, a local search, a simulated annealing and a Genetic algorithm meta-heuristic. The solutions are represented by the list of items that was used as input to the packing algorithm. Also all metaheuristics used the same packing algorithm, based on a First-Fit Strategy.

Tables
Our constructive heuristic is based on the First-Fit-Decreasing (FFD) Heuristic (Bays 1977). As we can see on the Algorithm 1, first the list of pieces is ordered in a non-increasing order and each piece is set on the first bin it fits. In our implementation we only visit each bin once. We run through the list of pieces and try to fit each piece in the current bin if the piece fits, we look for a new piece in the remaining list, to fit in the remaining free space. If there is no piece on the list that fits, we close the current bin and open a new one, going back to the start of the piece's list and repeating the process.

Local Search
Our Local Search meta-heuristic (Osogami and Okano 2003) which can be seen in the Algorithm 2, starts with an initial solution since we do not have a limit in the number of bins and we can state that each piece fits completely inside one bin. As we will see in the section 4, any list of pieces is a feasible solution, the worst case being having one bin for each piece. The possible initial solution is then tested using a greedy algorithm to position the pieces inside the bins, a Fit-First packing method. After, we test the neighborhood of the initial solution for a better solution. If we find a better neighbor, we use it as a starting point for a new neighborhood and restart the search for a better neighbor until we cannot find a better neighbor. The neighborhood is defined by switching two random pieces position with each other and a better neighbor is one that can be packed in a smaller number of bins. A better neighborhood can also have the same number of bins but the bin that is less filled has a smaller occupied area than the less filled bin of the current solution. If the less filled bin has a smaller occupied area than the other, the remaining bins are better packed and we are probably closer to a solution with less bins.
xn is the initial solution Algorithm 2: Local Search

Simulated Annealing
The Simulated Annealing (Kirkpatrick, Gelatt, and Vecchi 1983) implementation is the second meta-heuristics we are going to implement. It consists of a random global search for a better solution, enabling the selection of a temporary worst solution in the quest to find a better one. The description of the algorithm can be seen on the Algorithm 3. Using, as a metaphor, a pan of boiling water, initially the selection of a next solution is chaotic and so, we can select almost any neighbor to be the center of our new neighborhood, being it better or worse than the one we have. As time goes by and we iterate through the outer while loop, we readjust the temperature applying a freezing rate (α) to reduce the chaos in the selection of the new neighborhood center and narrow our selection. Eventually the temperature would be so low that the environment would be static and the water would freeze. When we reach the limit of iterations without change, or in our case, we reach the execution time limit, we stop the algorithm. The neighborhood implementation is the same as with the local search: we swap two pieces with each other.
xn is the initial solution Algorithm 3: Simulated Annealing

Genetic Algorithm
The Genetic Algorithm is a meta-heuristic based on the theory of evolution of species by Darwin (Chu and Beasley 1998). The base of the algorithm is that we have a population of solutions, in this context called chromosomes, which can evolve into better solutions by using the same processes that affect every chromosome inside every organism in nature, survival of the fittest, crossovers and mutations. Through this evolutionary process, the population evolves towards an optimum solution. The evolutionary process works through three methods: survival of the fittest; mutations; and crossover of chromosomes.
Survival of the fittest means that the better solution in a population has a higher probability of survival so it has a higher chance of being in the next generation. Crossover is a process of reproduction where two chromosomes swap part of their components with each other and create two new chromosomes, each with parts from both parents. The idea is that by joining two already good solutions we can create a better one. However, with only this process the population would evolve into a homogeneous population. This is a bad thing because homogeneous populations are very weak against changes in the environment. Mutations can help keep the population more heterogeneous. Mutations create changes in a chromosome, in our case, this can create chromosomes that are different from the ones already in the population and expand the population with new solutions, better or worse than the current ones. Thus, this is a mechanism to escape local optima.
g is the total of generations we will test t = 0 Pt is the Population at time t (generation) Algorithm 4: Genetic Algorithm

Benchmark Instances
For this 2DBPP problem there are two benchmark instances or data set generation techniques that appear the most in literature: Berkey and Wang (1987); and Martello and Vigo(1998 As before, W and H are the width and the height of the bins and wı and hı the width and height of a piece ı. For each item of an instance of Class k (k ∈ {I, II, III, IV }) the probability of an item being of type k is 70%, and 10% of being of any other type (Martello and Vigo 1998). These datasets are also composed of 5 instances with n pieces (n = 20, 40, 60, 80, 100) and W = H = 100 (Lodi et al., 2002b).

Computational Results
For our study we implemented the four algorithms and tested them against the benchmark instances from section 4. The tests were made in an Intel Core i7-3517U CPU with 4GB of ram, using Pypy 32bits runtime 2 in Windows 8.1. The runs had a soft limit of 60 seconds, so all instances could be run in a sensible time frame. The FFD never hit the time limit but all the others end up reaching the time limit in some of the instances. Without this time limit the results would have been better but this limit gave enough time to be able to compare the performance of each heuristic in a feasible time frame.
To take into account the overhead of the JIT 3 , the Class 1 should have been run for all algorithms 3 times before running the full experiment and collecting the results. This would enable the JIT to compile the source code before collecting data. As it was implemented, running the instances of Class 1 took more time than it should, at least for the FFD implementation.
The results were computed and compared to one representation of each heuristic and metaheuristic, the results are shown in Table 1 and Table 2. In those tables we compare the FFD, the Local Search with the starting solution in a decreasing order(LSearchD), a Simulated annealing implementation with an α of 95% and a Genetic algorithm with random initial population. Looking at tables 3, 4, 7 and 10 we can compare the differences in execution time between the implementations and is very clear the difference in the results. The LSearchD execution time greatly increases with the number of pieces as opposed to the FFD where we see a slower increase. This difference comes from the fact that in LSearchD we are basically packing every solution in the neighborhood until we find a better neighbor whereas in the FFD we are only packing one list of items. A similar rule applies to the simulated annealing and genetic algorithm implementations where we also pack more than one solution. We do not see a higher impact because of the soft limit on the running time and number of generations. Another thing we can clearly see in the results is that the LSearchD results are always the same or better than the FFD ones, which is due to fact that the packing algorithm and the initial solution order are the same. So, the initial solution for the LSearchD is the solution for the FFD with the same instance of the problem. The results of the simulated annealing should have been the same or better than the Local Search, and in most cases are. In the cases where that is not the case, for example, Class 3 instance 80 or Class 5 instance 100, if we increase the soft limit we will see at least a solution as good as the one in local search. The Genetic algorithm results are also generally better than the local search yet they are most of the time worse than the simulated annealing. An increase in the number of generations could improve these results.

Constructive Heuristic
The constructive heuristic is fast. When comparing the constructive heuristic with the metaheuristics used in this study, the FFD is blazing fast. Our implementation of the FFD ranges from just under nine milliseconds on a Class 1 instance with 60 pieces to 5 seconds in a Class 6 instance with 100 pieces, with most of the runs taking less than 100 milliseconds. Our implementation is faster in runs where we have big boxes when compared to the size of the pieces, as seen in Class 2, Class 4 and Class 10.

Local Search
For our study we tested the local search algorithm with three different initial solutions, a) order the given piece's list in a non-increasing order (LSearchD); b) order the given piece's list in a non-decreasing order (LSearchA); and c) randomize the given list (LSearchR).
For each instance class we compare the average number of bins used and the average wasted space. The result are shown in Table 5 for the Berkey and Wang benchmark set and Table 6 for the Martelo and Vigo benchmark set. The Avg. Waste field shows the average empty area in the bins and the Time field shows the average time per instance in milliseconds.
As we can see in Table 5 and Table 6 the initial solution really influences the results of the heuristic. An initial solution in non-increasing order generates the result at least as good as the FFD heuristic. The average times of this heuristic are higher than the FFD one and as we can see in Table 4, they go from 5 milliseconds to a little over 12 seconds, still none of the instances broke the soft limit of 300 seconds.

Simulated Annealing
As we can see in Table 1 and Table 2, the results for the Simulated Annealing were better than the FFD and the Local Search but these results come at the cost of time. As shown in Table 7, the average time of each SA is higher than either of the previous ones. The time goes from 1,3 seconds to 74 seconds, hitting the soft limit of 150 seconds per run in 31 out of 50 instance type.
Since Simulated Annealing is heavily based on a stochastic method to get a new neighbor we have to run more than once and get the best result. Usually between 10 and 20 random seeds should be used to get better results. In our case we used 10 random seeds.
The tables 8 and 9 show the comparison in results from 3 different values of α: 90%; 95% and 99%. As explained in section 3 the α is the freezing rate such as a rate of 90% freezes faster than a rate of 99% where the temperature only decreases 1%. The freezing rate also influences the time the implementation runs, since it freezes faster, an implementation with α=90% will end faster than an implementation with α=95%. In our results α=95% is always better or equal to the results of α=90%. This is due to the fact that since we freeze slower we can accept worse solutions for longer time. Our results show that the implementation with α=99% sometimes gives worse results than the implementation with α=95. This happens because the soft time limit of 300 seconds is probably too small for an α this high. Given enough time, a better solution than the α=95% would have been found.

Genetic Algorithm
As shown in Table 1 and Table 2, Genetic algorithm has generally better results than the FFD and LSearchD. But when compared to SA the results are a bit worse. The Class 9 problems give exactly the same results and Class 6, 7 and 8 instances with 100 pieces have on average a better result with GA, the difference is very small but GA takes almost 10 seconds more, on average, than the SA algorithm. Looking at Table 10, we can see that the average time is higher than the remaining heuristics. We did not impose a time limit as with the SA implementation. The tables 11 and 12 show the comparison in results from 3 different configurations: a) a mutation and survivability rates of 10%; b) a mutation rate of 75% and survivability rate of 10%; c) and a mutation rate of 10% and survivability rate of 75%. We used a fixed number of generations and population size for all configurations, 25 generations and 50 chromosomes per population. The survivability rate is the probability that a chromosome will be destroyed to create new chromosomes through crossover or will pass unchanged into the next generation. The mutation rate is the probability of a mutation occurring in a chromosome. The algorithm we implemented for a mutation was the same we implemented on the neighborhood function in simulated annealing and local search, we swap the position of two pieces. All chromosomes can suffer a mutation. The average generation field is the generation in which the best solution was found.
The results for the GA are very similar in all configurations although the configuration with a higher mutation rate has, most of the time, a better result than the one with a lower mutation rate.

Conclusion
We implemented one heuristic and three meta-heuristic, a constructive, a local search, a simulated annealing and genetic algorithm to solve the Rectangular Bin Packing Problem. We analyzed them using the most common Benchmark Sets in the literature for the problem defined on section 2: Berkey and Wang; and from Martello and Vigo. One conclusion we can take from the results is that the way we pick the neighborhood in the local search heuristic is very prone to local optimal so starting with a good solution for our packing algorithm improves the chances of our heuristic finding a good solution.
In future tests, we could change the formula for the neighborhood and make it less prone to local optima, either by increasing the neighborhood size or by picking the best neighbor or a random best instead of picking the first best. In Simulated Annealing we could also increase the soft limit to 300 seconds and compare the different α's again, doing so would probably find a better solution with α=99%. In the case of the Genetic algorithm we could increase the population size and the generation number to give more time for the population to evolve and check how it affects the results. As a final note, the comparison between these heuristics also shows that finding a solution can be very fast using a constructive heuristic like the First-Fit Decreasing. Improving on the other hand, can be very resource consuming as in the case of Local Search, Simulated Annealing and Genetic algorithm, where we already start with one or more feasible solutions.