I have different dimension of small rectangles (1cm x 2xm, 2cmx3cm, 4cm*6cm etc). The number of different type rectangles may vary depending on case. Each type of different rectangles may have different number of counts.
I need to create a big rectangle with all these small rectangles which these small rectangles can only be placed on the edges. no rotations. The final outer rectangle should ideally be smiliar to a square shape. X ~Y. Not all edges need to be filled up. There can be gaps in between smaller rectangles. Picture Example:
http://i.stack.imgur.com/GqI5z.png
I am trying to write a code that finds out the minimum possible area that can be formed.
I have an algorithm that loop through all possible placement to find out the minimum area possible. But that takes a long run time as number of different type rectangles and number of rectangles increase. i.e. 2 type of rectangles, each has 100 + rectangles. 8 for loops. That will be ~100^8 iterations
Any ideas on better and faster algorithm to calculate the minimum possible area? code is in python, but any algorithm concept is fine.
for rectange_1_top_count in (range(0,all_rectangles[1]["count"]+1)):
for rectange_1_bottom_count in range(0,all_rectangles[1]["count"]-rectange_1_top_count+1):
for rectange_1_left_count in (range(0,all_rectangles[1]["count"]-rectange_1_top_count-rectange_1_bottom_count+1)):
for rectange_1_right_count in ([all_rectangles[1]["count"]-rectange_1_top_count-rectange_1_bottom_count-rectange_1_left_count]):
for rectange_2_top_count in (range(0,all_rectangles[2]["count"]+1)):
for rectange_2_bottom_count in (range(0,all_rectangles[2]["count"]-rectange_2_top_count+1)):
for rectange_2_left_count in (range(0,all_rectangles[2]["count"]-rectange_2_bottom_count-rectange_2_top_count+1)):
for rectange_2_right_count in [(all_rectangles[2]["count"]-rectange_2_bottom_count-rectange_2_left_count-rectange_2_top_count)]:
area=calculate_minimum_area()
if area< minimum_area:
minimum_area=area
This looks like an NP-hard problem, so there exists no simple and efficient algorithm. It doesn't mean that there is no good heuristic that you can use, but if you have many small rectangles, you won't find the optimal solution fast.
Why is it NP-hard? Let's assume all your rectangles have height 1 and you have on rectangle of height 2, then it would make sense to look for a solution with total height 2 (basically, you try to form two horizontal lines of height-1 rectangles with the same length). To figure out if such a solution exists, you would have to form two subsets of your small rectangles, both adding up to the same total width. This is called the partition problem and it is NP-complete. Even if there may be gaps and the total widths are not required to be the same, this is still an NP-hard problem. You can reduce the partition problem to your rectangle problem by converting the elements to partition into rectangles of height 1 as outlined above.
I'll wait for the answer to the questions I posted in the comments to your question and then think about it again.
Related
I'm looking for a general algorithm for creating an evenly spaced grid, and I've been surprised how difficult it is to find!
Is this a well solved problem whose name I don't know?
Or is this an unsolved problem that is best done by self organising map?
More specifically, I'm attempting to make a grid on a 2D Cartesian plane in which the Euclidean distance between each point and 4 bounding lines (or "walls" to make a bounding box) are equal or nearly equal.
For a square number, this is as simple as making a grid with sqrt(n) rows and sqrt(n) columns with equal spacing positioned in the center of the bounding box. For 5 points, the pattern would presumably either be circular or 4 points with a point in the middle.
I didn't find a very good solution, so I've sadly left the problem alone and settled with a quick function that produces the following grid:
There is no simple general solution to this problem. A self-organizing map is probably one of the best choices.
Another way to approach this problem is to imagine the points as particles that repel each others and that are also repelled by the walls. As an initial arrangement, you could already evenly distribute the points up to the next smaller square number - for this you already have a solution. Then randomly add the remaining points.
Iteratively modify the locations to minimize the energy function based on the total force between the particles and walls. The result will of course depend on the force law, i.e. how the force depends on the distance.
To solve this, you can use numerical methods like FEM.
A simplified and less efficient method that is based on the same principle is to first set up an estimated minimal distance, based on the square number case which you can calculate. Then iterate through all points a number of times and for each one calculate the distance to its closest neighbor. If this is smaller than the estimated distance, move your point into the opposite direction by a certain fraction of the difference.
This method will generally not lead to a stable minimum but should find an acceptable solution after a number ot iterations. You will have to experiment with the stepsize and the number of iterations.
To summarize, you have three options:
FEM method: Efficient but difficult to implement
Self organizing map: Slightly less efficient, medium complexity of implementation.
Iteration described in last section: Less efficient but easy to implement.
Unfortunately your problem is still not very clearly specified. You say you want the points to be "equidistant" yet in your example, some pairs of points are far apart (eg top left and bottom right) and the points are all different distances from the walls.
Perhaps you want the points to have equal minimum distance? In which case a simple solution is to draw a cross shape, with one point in the centre and the remainder forming a vertical and horizontal crossed line. The gap between the walls and the points, and the points in the lines can all be equal and this can work with any number of points.
For example we have two rectangles and they overlap. I want to get the exact range of the union of them. What is a good way to compute this?
These are the two overlapping rectangles. Suppose the cords of vertices are all known:
How can I compute the cords of the vertices of their union polygon? And what if I have more than two rectangles?
There exists a Line Sweep Algorithm to calculate area of union of n rectangles. Refer the link for details of the algorithm.
As said in article, there exist a boolean array implementation in O(N^2) time. Using the right data structure (balanced binary search tree), it can be reduced to O(NlogN) time.
Above algorithm can be extended to determine vertices as well.
Details:
Modify the event handling as follows:
When you add/remove the edge to the active set, note the starting point and ending point of the edge. If any point lies inside the already existing active set, then it doesn't constitute a vertex, otherwise it does.
This way you are able to find all the vertices of resultant polygon.
Note that above method can be extended to general polygon but it is more involved.
For a relatively simple and reliable way, you can work as follows:
sort all abscissas (of the vertical sides) and ordinates (of the horizontal sides) independently, and discard any duplicate.
this establishes mappings between the coordinates and integer indexes.
create a binary image of size NxN, filled with black.
for every rectangle, fill the image in white between the corresponding indexes.
then scan the image to find the corners, by contour tracing, and revert to the original coordinates.
This process isn't efficient as it takes time proportional to N² plus the sum of the (logical) areas of the rectangles, but it can be useful for a moderate amount of rectangles. It easily deals with coincidences.
In the case of two rectangles, there aren't so many different configurations possible and you can precompute all vertex sequences for the possible configuration (a small subset of the 2^9 possible images).
There is no need to explicitly create the image, just associate vertex sequences to the possible permutations of the input X and Y.
Look into binary space partitioning (BSP).
https://en.wikipedia.org/wiki/Binary_space_partitioning
If you had just two rectangles then a bit of hacking could yield some result, but for finding intersections and unions of multiple polygons you'll want to implement BSP.
Chapter 13 of Geometric Tools for Computer Graphics by Schneider and Eberly covers BSP. Be sure to download the errata for the book!
Eberly, one of the co-authors, has a wonderful website with PDFs and code samples for individual topics:
https://www.geometrictools.com/
http://www.geometrictools.com/Books/Books.html
Personally I believe this problem should be solved just as all other geometry problems are solved in engineering programs/languages, meshing.
So first convert your vertices into rectangular grids of fixed size, using for example:
MatLab meshgrid
Then go through all of your grid elements and remove any with duplicate edge elements. Now sum the number of remaining meshes and times it by the area of the mesh you have chosen.
I've got a binary matrix and I'm trying to find all the largest rectangles that can be formed by adjoining elements in the matrix. By largest rectangles I mean, all the rectangles which are unique, non subsets of any other rectangles. For example, the following matrix contains six such rectangles.
This is related to the set cover problem, though here I'm interested in the maximum number of rectangles, not the minimum. An approach I've tried is to find all the rectangles regardless of size, then compare rectangles and remove them if they are a subset of another rectangle. This is not an optimal approach. It seems like this case of the set cover problem shouldn't be too hard.
I've had a look and not found anything similar to this problem. There is this paper, which has some good ideas, but still wide of the mark. Is there another name for this particular problem? Are there any existing algorithms for finding all possible rectangles in a set cover problem?
After a bit more work, I've realised this is not really related to the set cover problem. It's actually the 'finding the unique rectangles that are not contained within in any other rectangle in a binary matrix problem'.
I have come up with something that works well, but I have no idea about it's complexity.
Basically, line sweep across the matrix horizontally and vertically. In each case, look for contiguous groups of 1's that can form rectangles with the next line. This results in a number of rectangles, some of which are duplicates or sub rectangles of others. These rectangles are reduced to a unique set where no rectangle is a sub rectangle of another. Then you have all the rectangles.
Here is a diagram that relates to the image in the original post:
i dont speek english very wheel but, maximal rectangles overlapping is a problem that resolve many pb, if you somme maximal rectangles, geometrique sommation you find optimal volume that you derive to find queleton etc
I'm not sure if there's an algorithm that can solve this.
A given number of rectangles are placed side by side horizontally from left to right to form a shape. You are given the width and height of each.
How would you determine the minimum number of rectangles needed to cover the whole shape?
i.e How would you redraw this shape using as few rectangles as possible?
I've can only think about trying to squeeze as many big rectangles as i can but that seems inefficient.
Any ideas?
Edit:
You are given a number n , and then n sizes:
2
1 3
2 5
The above would have two rectangles of sizes 1x3 and 2x5 next to each other.
I'm wondering how many rectangles would i least need to recreate that shape given rectangles cannot overlap.
Since your rectangles are well aligned, it makes the problem easier. You can simply create rectangles from the bottom up. Each time you do that, it creates new shapes to check. The good thing is, all your new shapes will also be base-aligned, and you can just repeat as necessary.
First, you want to find the minimum height rectangle. Make a rectangle that height, with the width as total width for the shape. Cut that much off the bottom of the shape.
You'll be left with multiple shapes. For each one, do the same thing.
Finding the minimum height rectangle should be O(n). Since you do that for each group, worst case is all different heights. Totals out to O(n2).
For example:
In the image, the minimum for each shape is highlighted green. The resulting rectangle is blue, to the right. The total number of rectangles needed is the total number of blue ones in the image, 7.
Note that I'm explaining this as if these were physical rectangles. In code, you can completely do away with the width, since it doesn't matter in the least unless you want to output the rectangles rather than just counting how many it takes.
You can also reduce the "make a rectangle and cut it from the shape" to simply subtracting the height from each rectangle that makes up that shape/subshape. Each contiguous section of shapes with +ve height after doing so will make up a new subshape.
If you look for an overview on algorithms for the general problem, Rectangular Decomposition of Binary Images (article by Tomas Suk, Cyril Höschl, and Jan Flusser) might be helpful. It compares different approaches: row methods, quadtree, largest inscribed block, transformation- and graph-based methods.
A juicy figure (from page 11) as an appetizer:
Figure 5: (a) The binary convolution kernel used in the experiment. (b) Its 10 blocks of GBD decomposition.
I have a set of N positive numbers, and a rectangle of dimensions X and Y that I need to partition into N smaller rectangles such that:
the surface area of each smaller rectangle is proportional to its corresponding number in the given set
all space of big rectangle is occupied and there is no leftover space between smaller rectangles
each small rectangle should be shaped as close to square as feasible
the execution time should be reasonably small
I need directions on this. Do you know of such an algorithm described on the web? Do you have any ideas (pseudo-code is fine)?
Thanks.
What you describe sounds like a treemap:
Treemaps display hierarchical (tree-structured) data as a set of nested rectangles. Each branch of the tree is given a rectangle, which is then tiled with smaller rectangles representing sub-branches. A leaf node's rectangle has an area proportional to a specified dimension on the data.
That Wikipedia page links to a page by Ben Shneiderman, which gives a nice overview and links to Java implementations:
Then while puzzling about this in the faculty lounge, I had the Aha! experience of splitting the screen into rectangles in alternating horizontal and vertical directions as you traverse down the levels. This recursive algorithm seemed attractive, but it took me a few days to convince myself that it would always work and to write a six line algorithm.
Wikipedia also to "Squarified Treemaps" by Mark Bruls, Kees Huizing and Jarke J. van Wijk (PDF) that presents one possible algorithm:
How can we tesselate a rectangle recursively into rectangles, such that their aspect-ratios (e.g. max(height/width, width/height)) approach 1 as close as possible? The number of all possible tesselations is very large. This problem falls in the category of NP-hard problems. However, for our application we do not need the optimal solution, a good solution
that can be computed in short time is required.
You do not mention any recursion in the question, so your situation might be just one level of the treemap; but since the algorithms work on one level at a time, this should be no problem.
I have been working on something similar. I'm prioritizing simplicity over getting as similar aspect ratios as possible. This should (in theory) work. Tested it on paper for some values of N between 1 and 10.
N = total number of rects to create,
Q = max(width, height) / min(width, height),
R = N / Q
If Q > N/2, split the rect in N parts along its longest side.
If Q <= N/2, split the rect in R (rounded int) parts along its shortest side.
Then split the subrects in N/R (rounded down int) parts along its shortest side.
Subtract the rounded down value from the result of the next subrects division. Repeat for all subrects or until the required number of rects are created.