Given an area of specific size I need to find out how many pavement stones to use to completely pave the area. Suppose that I have an empty floor of 100 metre squares and stones with 20x10 cm and 30x10 cm sizes. I must pave the area with minimum usage of stones of both sizes. Anyone knows of an algorithm that calculates this?
(Sorry if my English is bad)
C# is preferred.
This is a category of problem known as a Packing Problem.
This DevX article provides background and outlines approaches without directly solving the homework for you (it also provides code, but you'll have to think a bit to apply it to your situation).
You can solve this in your head (assuming the area to fill is rectangular). If you have to fill an area of N squares, and your tiles are 2x1 and 3x1, you never need more than two 2x1 tiles. This gives the total number of tiles you need to be N/3 (rounded up) except for the case N=1 which is impossible.
Proof:
Suppose your area is A x B and that not both of A and B are 1. Assume without loss of generality that A != 1.
You can tile a rectangular area A x 3 with 3x1 tiles easily. Repeat this pattern to fill up the are as much as possible.
If there are no rows left, you're done (you've tiled the entire area with 3x1 tiles)
If there's one row left, fill with 3x1 tiles until you have either 0, 1 or 2 spaces left. 0 => you're done, 1 => replace the last 3x1 with two 2x1, 2 => fill the last square with a 2x1.
If there's two rows left, do a similar construction. You'll be left with either 0 columns (you're done), 1 column (fill it with a 2x1), or 2 columns (fill it with two 2x1).
Related
Please look at this picture first:
As you can see, blue and red both have a line showing the frontline bases.
Let's assume two players start playing against eachother.
One placing a base at the far left, the other at the far right.
The players continue by expanding and gaining territory.
After a while, the two sides will meet and battle will start.
Question is, in a randomly ordered list of base positions how would one find the two lines that are drawn in the picture?
You could get the distance between enemy bases, where the distance is shorter is the frontline.
Example:
0 1 2 3 4 5 6
0 aa A B bbb
1 aA B bb
2 A B b
3 aA B b
4 aaaA Bb
5 aaaA B
6 aaaA B
If you substract the X positions of the enemy bases in the same row, the ones with the less distance between them are the front lines, B.x - A.x will give you a smaller number that b.x - a.x. Then you can check which ones were the ones that gave you the smaller distance for each row.
Unless I'm getting your question wrong.
area
many games do not draw territory border by polylines
instead they draw a disc with constant radius (or dependent on base strength) at every base position
if the radius is set big enough then these discs/circles will overlap
and create seamless area of single color representing controlled territory
it is easy but inaccurate
perimeter polyline
first cluster all bases and create lists of bases close together
this can be done by grouping bases with distance <= treshold
process each group
find the outer most bases of group
something like perimeter points
this may help with it
also it contains inverse problem of yours which can solve the whole thing more here
now find the perimeter closed loop of area
the algorithm for that is also in the link above
when done then use this list of points as BEZIER cubics poly-curve control points
if borderline too close to the bases then enlarge the points
first compute avg point ap of group
then any point p is computed p=((p-ap)*scale)+ap
it is not exact but for your purposes it is enough
if you want something better then
p=p-ap
l=|p|
p=ap+(p*(l+dl)/l)
where dl is the step at which your border is enlarged
and if you want the accurate thing then you have to compute polygon enlargement
which is not easy task
handle edge cases
for singular base groups draw circle around
this approach has problem in close proximity of bases
one solution is not to count bases too close to any enemy base
per pixel borders
you can process the map image by pixels
something like this: (beware this is not tested)
per each pixel
compute the min distance to any player bases
remember two closest distances of different players
distance0 is closest
distance1 is second closest (but base owns another player)
select territory ownership
the player which has closest base own this
if the distance0 > treshold then this area is uncontrolled
in that case stop processing this pixel
if ((distance0 >= d-w)&&(distance0 <= d+w)&&(distance1>d+w+s)) then set pixel color to border polyline color
d is border line distance from base
w is half-size of borderline thickness
s is min distance between close front lines
edge case
previous step ignore border points that are closer to bases (close enemy bases)
to add them just add
if ((distance0<d)&&(|distance0-distance1|<=s+w)&&(|distance0-distance1|>=s-w)) then set pixel color to player ownership
also this will fail if any two opposing bases are closer then s-w
[Notes]
I think the best way is the per pixel
it is most close to the solution you want
the render can be a bit slower but you need to change it only if any base is conquered
Problem: You are given a set of n types of rectangular 3-D boxes, where the i^th box has height h(i), width w(i) and depth d(i) (all real numbers). You want to create a stack of boxes which is as tall as possible, but you can only stack a box on top of another box if the dimensions of the 2-D base of the lower box are each strictly larger than those of the 2-D base of the higher box. Of course, you can rotate a box so that any side functions as its base. It is also allowable to use multiple instances of the same type of box.
solution: I found the below solution at http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/
1) Generate all 3 rotations of all boxes. The size of rotation array becomes 3 times the size of original array. For simplicity, we consider depth as always smaller than or equal to width.
2) Sort the above generated 3n boxes in decreasing order of base area.
3) After sorting the boxes, the problem is same as LIS with following optimal substructure property.
MSH(i) = Maximum possible Stack Height with box i at top of stack
MSH(i) = { Max ( MSH(j) ) + height(i) } where j < i and width(j) > width(i) and depth(j) > depth(i).
If there is no such j then MSH(i) = height(i)
4) To get overall maximum height, we return max(MSH(i)) where 0 < i < n
I think the solution is wrong as it just considers 3 rotation of all the boxes. To get the correct solution, it should generate 6 possible rotations. So, is the given solution incorrect, or is their any flaw in using 6 rotations?
Note this:
For simplicity, we consider depth as always smaller than or equal to width.
So, if the dimensions of a box are, for example, 3, 4 and 5, we consider the following three ways to put it on the stack:
d=3, w=4, h=5
d=3, w=5, h=4
d=4, w=5, h=3
The other three rotations have depth larger than width, so we do not consider them:
d=4, w=3, h=5
d=5, w=3, h=4
d=5, w=4, h=3
In order to see if one rectangle a x b can be fully covered by another one c x d, it is sufficient to turn them both so that a <= b and c <= d, and then check whether a <= c and b <= d. That's why it works.
No, it's sufficient to consider 3 "rotations" of each box, because the only possibilities to consider are which dimension to make the top and bottom (say) of the box perpendicular to, and there are only 3 of these. It might help to think of the 3 different possibilities for each box in that way, instead of as rotations.
The main point is that, after we have chosen which pair of sides of a box will be top and bottom (which we can do in 3 ways), we don't need to try the 2 different rotations of the box in the plane. We can always just go with (say) the rotation in which the box is wider than it is deep. How do we know that we won't miss any potentially good solutions by doing this? Because in any solution having a box that is deeper than it is wide, there must be a lowest such box b, and that box, plus everything above it, can be safely rotated 90 degrees. (We know it's safe to do this because it's the lowest such box in the solution -- so the box underneath it, if any, must itself be wider than it is deep, meaning that if we rotate b 90 degrees, it must still fit inside this lower box (I recommend verifying this algebraically).) We can keep transforming the lowest deeper-than-it-is-wide box in the solution until none remain, without ever changing the height of the solution. Since we can do this for any solution containing one or more deeper-than-it-is-wide boxes, it means that each one is exactly equivalent in quality to some solution in which every box is wider-than-it-is-deep, so we can totally ignore the former solutions.
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 been struggling with finding a convenient solution for the following problem:
Suppose we have a wall of a given size and 4 types of tiles of sizes 4 x 2, 2 x 2, 2 x 1, 1 x 1. There are certain rectangular regions inside the perimeter of the wall which can not be tiled (i.e. holes). There is also a special type of tile which has a variable dimension A x B with A < 1. This is used to pad the tiling to the margin of the rectangle, if needed.
Find a tiling of the wall which respects the following constraints:
Tiles of the same size can not be placed one below the other, with the same alignment (i.e. tiles appearing on a row below have to be shifted such that there is no gap which looks like a cross between adjoining tiles of the same size)
A minimum number of tiles is used
Tiles which exceed the boundaries of the rectangle will be trimmed to the margin; the incomplete tile thus produced will be broken in smaller tiles; this could possibly involve the use of a special tile which should always sit next to the margin of the rectangle or the margin of a hole, wherever the situation might arise
Here is what I've tried so far:
I've looked into algorithms for solving this using domino tiling but most don't seem to care that the tiling process can not produce gaps which look like a cross where tiles meet. Also, to me the problem seems a bit different as there are more types of tiles and it also seems that the rectangle does not have to be exactly filled (it is possible for small spaces to remain near the margins which will be filled using special tiles)
I've tried to generate all possible tilings using a branch and bound technique with state node pruning so that only those states where tiles which do not break the constraints are added will be explored, but this is definitely not scalable.
I've also looked into packing algorithms but to my knowledge, this might lead to a certain tiling where there are small untiled spaces which can remain inside the premises of the wall.
It might be possible that I've overlooked something, or not had enough insight while exploring the above techniques.
With all these being said, do you guys have any hints or suggestions on a way to approach this which yields results?
This is an example of a tiling which respects constraints 1 and 3, but is not optimal
Do you need the optimal tiling, or are you willing to settle for "pretty good"? Finding the optimal solution is likely exceedingly hard. Intuitively, I would suggest the following heuristic:
1. Pretend there are no holes in the wall, tile with large tiles.
2. Remove all tiles which intersect with holes.
3. current_size = largest
4. For each empty space: tile as much as possible with current_size
5. current_size = the size just below current_size
6. return to 4
Assume an N x M grid. Into this I need to randomly lay out tiles which are sized from 1x1 to I X J grid units. The key problem is to find a way to use each different size around the same number of times and be fairly randomly distributed.
As an example, imagine a floor that's 10 x 20 square feet, You have stacks of 1x1, 1x2 and 2x2 tiles which you want to layout the floor with and you want the design to be random looking and use around the same count of each tile.
You could also think of the problem in reverse, cutting up a floor into pieces of these sizes.
I've seen tree map algorithms but they don't quite match the requirement. If you restrict the pieces to 1 x I then the problem is 1 dimensional and easy. It's the 2D version that seems more difficult. Any ideas or pointers is helpful.
Relaxing the need to be (1) random or (2) similar does make it easier but both are important. I have some ideas on doing it but nothing feels right yet.
An alterative solution is to randomly sort your tiles and use a spatial index to fill the grid. The idea is that a spatial index subdivide the grid into 2 dimension so you can check for quads. Otherwise you want to use a DFS to find the optimal solution.