Problem description: How to put any number of rectangular sets of any size into a closed rectangle with the smallest area without repetition.
AlgorithmThought: (for ease of description, record the closed rectangle to be found as a, record the set of closed rectangles as, record the set of rectangles as RS, and N as the number of rectangles in RS, mark the position of the rectangle that can be inserted as corners)
1. Sort all the rectangles In the rectangle set in descending order of height. In this case, the height of RS [0] is the maximum.
2. initialize A as height = Rs [0]. height, width = Rs [0]. width + Rs [1]. width + ...... + Rs [n-1]. width and corners are initialized to coordinate vertices.
3. Put Rs [0] into a, insert the corner generated by RS [0] into the corners set, and delete the used corner, as shown in:
4. from Rs [1] to Rs [n-1], select the corner with the smallest x value that can be inserted for each insert. After successful insertion, delete the used corner, and insert the new corner. Due to the initialization condition of A, all the rectangles in RS can be inserted into.
5. after all the rectangles are inserted, "slimming" a to make a exactly contain all the Rectangles and record that the width of a is width at this time, the area of A is area (in this case, a is the 'shorged' of all enclosed rectangles that meet the conditions, so as [0] =)
6. decrease. width, add. height, Repeat 3-5. If Area A is reduced, insert a into the as until. width = width of the widest rectangle in RS
7. The last element of the AS set is the closed rectangle with the smallest area of all the rectangles in RS. The algorithm ends.
Algorithm Implementation:
Note the following points in Algorithm Implementation:
1. Calculate the new corner generated by rectangular insertion (many special cases need to be considered)
2. Determine whether a rectangle can be inserted with a corner.
3. Data Structure Design
BelowProgramIs the core method of the algorithm. Insert a rectangle and record the newly generated corner.
Private Boolean Putin (pngrect PNG) {If (pngs = NULL) {pngs = new arraylist <pngrect> (); pngs. add (PNG); PNG. setstartp (new point (0, 0); If (PNG. getheight () <mheight) {rect owner = new rect (0, PNG. getstopp (). gety (), mwidth, mheight); corner = new corner (new point (0, PNG. getheight (), owner); corners. add (Corner);} If (PNG. getwidth () <mwidth) {rect owner = new rect (PNG. getstopp (). getx (), 0, mwidth, mheight); corner = new corner (new point (PNG. getwidth (), 0), owner); corners. add (Corner) ;}return true ;}else {corner; int X; int y; rect owner; For (INT I = 0; I <corners. size (); ++ I) {corner = corners. get (I); X = corner. getpoint (). getx (); y = corner. getpoint (). gety (); owner = corner. getrect (); point startp = corner. getpoint (); int endx = owner. right; int Endy = owner. bottom;/** you can put it into the corner. If there is a coverage problem, you need to determine whether the four sides are used. If yes, return, test the next corner * V0 ----- V1 * | A | * V2 ----- V3 *. To prevent full overlap, you also need to determine an additional vertex, in this example, point A */If (x + PNG. getwidth () <= mwidth & Y + PNG. getheight () <= mheight) {point V0 = startp; point V1 = new point (startp. getx () + PNG. getwidth (), startp. gety (); point V2 = new point (startp. getx (), startp. gety () + PNG. getheight (); point V3 = new point (startp. getx () + PNG. getwidth (), startp. gety () + PNG. getheight (); point A = new point (startp. getx () + PNG. getwidth ()/2, startp. gety () + PNG. getheight ()/2); If (contains (v0, V1, true) | contains (V1, V3, false) | contains (V2, V3, true) | contains (v0, V2, false) | contains (a) {// It may happen to be on the edge of continue;} // If (contains () | contains (v0) | contains (V1) | contains (V2) | contains (V3) {// may fall on the edge right away. // continue; //} If (x + PNG. getwidth () <endx) {corners. add (I + 1, new corner (new point (x + PNG. getwidth (), Y), new rect (x + PNG. getwidth (), y, mwidth, mheight); // The owner may be empty.} If (Y + PNG. getheight () <Endy) {corners. add (I + 1, new corner (new point (X, Y + PNG. getheight (), new rect (X, Y + PNG. getheight (), mwidth, mheight);} corners. remove (I); sortcorners (); PNG. setstartp (Corner. getpoint (); pngs. add (PNG); Return true ;}} return false ;}
The algorithm implementation result is as follows:
If the number of rectangular sets is large and the algorithm execution time is long, there should be some optimizations.