Packing rectangles for compact representation

做~自己de王妃 提交于 2019-11-30 21:23:06

Your problem is a simpler variant, but you might get some tips reading about heuristics developed for the "binpacking" problem. There has been a lot written about this, but this page is a good start.

Topcoder had a competition to solve the 3D version of this problem. The winner discussed his approach here, it might be an interesting read for you.

Are the rectangles all of the same height? If they are, and the problem is just which row to put each rectangle in, then the problem boils down to a series of constraints over all pairs of rectangles (X,Y) of the form "rectangle X cannot be in the same row as rectangle Y" when rectangle X overlaps in the x-direction with rectangle Y.

A 'greedy' algorithm for this sorts the rectangles from left to right, then assigns each rectangle in turn to the lowest-numbered row in which it fits. Because the rectangles are being processed from left to right, one only needs to worry about whether the left hand edge of the current rectangle will overlap any other rectangles, which simplifies the overlap detection algorithm somewhat.

I can't prove that this is gives the optimal solution, but on the other hand can't think of any counterexamples offhand either. Anyone?

Jasper

Something like this?

  • Sort your collection of rectangles by x-position
  • write a method that checks which rectangles are present on a certain interval of the x-axis

    Collection<Rectangle> overlaps (int startx, int endx, Collection<Rectangle> rects){
    ...
    }
    
  • loop over the collection of rectangles

    Collection<Rectangle> toDraw;
    Collection<Rectangle> drawn;
    foreach (Rectangle r in toDraw){
    Collection<Rectangle> overlapping = overlaps (r.x, r.x+r.width, drawn);
    int y = 0;
    foreach(Rectangle overlapRect in overlapping){
    y += overlapRect.height;
    }
    drawRectangle(y, Rectangle);
    drawn.add(r);
    }
    

Put a tetris-like game into you website. Generate the blocks that fall and the size of the play area based on your paramters. Award points to players based on the compactness (less free space = more points) of their design. Get your website visitors to perform the work for you.

I had worked on a problem like this before. The most intuitive picture is probably one where the large rectangles are on the bottom, and the smaller ones are on top, kinda like putting them all in a container and shaking it so the heavy ones fall to the bottom. So to accomplish this, first sort your array in order of decreasing area (or width) -- we will process the large items first and build the picture ground up.

Now the problem is to assign y-coordinates to a set of rectangles whose x-coordinates are given, if I understand you correctly.

Iterate over your array of rectangles. For each rectangle, initialize the rectangle's y-coordinate to 0. Then loop by increasing this rectangle's y-coordinate until it does not intersect with any of the previously placed rectangles (you need to keep track of which rectangles have been previously placed). Commit to the y-coordinate you just found, and continue on to process the next rectangle.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!