6

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
Charles Tang
  • 177
  • 1
  • 15
  • So the size of the outer rectangle is given and you want to minimize the white area in the middle? – M Oehm Jan 22 '16 at 06:24
  • The condition that makes it hard is rectangle can only be placed on the edges/sides. They cannot be stacked – Charles Tang Jan 22 '16 at 06:26
  • The size of outer rectangle is not given. Only small rectangle diemsions are given. The dimension of the outer rectangle will change as placement changes. But I want the optimal small rectangle placement on the edge that will give the smallest outer rectangle area. – Charles Tang Jan 22 '16 at 06:27
  • Okay, thanks. Do you have to use all tiles? – M Oehm Jan 22 '16 at 06:28
  • Yes, all tiles need to be used. For example, I have 10 tiles. All 10 tiles can only be placed on the edge and all need to be placed. Thanks – Charles Tang Jan 22 '16 at 06:31
  • 1
    Is it required that every segment of an edge is adjacent to a rectangle, or can there be gaps? Obviously rectangles in the corners are part of two edges. But may a big rectangle also be part of let's say the bottom and the top edge? – lex82 Jan 22 '16 at 07:34
  • Do opposing sides need to be equal or they can have different rectangles? – Juan Lopes Jan 22 '16 at 10:40
  • May the solution have height or width 1? – lex82 Jan 22 '16 at 10:44
  • The solution should have the height and width as close as possible, so that the bigger rectangle can be in square shape. Opposing sides do not need to be equal, they can have different number of rectangles. – Charles Tang Jan 22 '16 at 16:36
  • @lex82 @juan Lopes I have thought of one way to reduce the complexity. Since we know the outer rectangle wants to be as close to square shape as possible. Instead of starting from 0 to # of type 1 rectangles, I can try to find out a smaller range, `for rectange_1_top_count in (range(5,all_rectangles[1]["count"]+1)):` If we start from 5, instead of 0, 3^8 less iterations. I can do the same for the other loops. But I am wondering if thre will be a even better solution, – Charles Tang Jan 22 '16 at 16:37
  • I have to admit I don't understand how your code works. And where does the number five come from in your improvement? – lex82 Jan 22 '16 at 16:51
  • @lex82 The code was looping through all possible placements on each side, from 0 to the total count of each rectangles. And then find out the minimum possible area. Now given that the final bigger rectangle wants to as similar to square as possible, we know each side will get some rectangles, it will not be 0 . To reduce the number of iterations, we will not start from 0, but start with a number. 5 is just an example. The number will be based on a formula that depends on the dimensions and number of rectangles. I still have not come up with that formula. – Charles Tang Jan 22 '16 at 17:41
  • But if we can reduce the number of iterations for each loop.each reduction will make run time decrease exponentially. This is not the optimal solution, but is something that will reduce the run time dramatically. For your answer, what do you mean by partitioning the problem? Appreciate if you can give me a bit more hint on this. Thanks! – Charles Tang Jan 22 '16 at 17:41
  • I didn't mean to partition the problem but that your problem is related to the "[partition problem](https://en.wikipedia.org/wiki/Partition_problem)" which is hard. So your problem is also very hard to solve, at least if you need the optimal solution. – lex82 Jan 22 '16 at 18:03

1 Answers1

0

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.

lex82
  • 10,346
  • 2
  • 37
  • 63
  • I think your proof sketch is too informal. Your argument basically says that you can reduce one particular instance of the problem to the partition problem, that doesn't prove NP-completeness. You should prove the inverse: that any instance of an NP-complete problem can be reduced (in polynomial time) to this problem, then it will be considered NP-hard. It cannot be proved NP-complete, because this isn't a decision problem, i.e. it isn't in NP. – Juan Lopes Jan 22 '16 at 10:31
  • @juan-lopes, thanks for pointing this out. I mixed up NP-hard and NP-complete. I tried to improve the answer. – lex82 Jan 22 '16 at 10:48