Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Construct the largest possible rectangle out of line segments of given lengths

Tags:

I recently participated in a competition where I was asked this question. Given an array with lengths what is the area of the biggest rectangle that can be made using ALL the lengths. The lengths can be added but not broken in between.

Example: [ 4,2,4,4,6,8 ] given this array the best we can do is make a rectangle of sides 8 and 6 like this.

enter image description here

giving an area of 8 * 6 = 48.

I am a beginner and even after a long hard think about how to do it I am unable to get anywhere. I am not looking for a solution but any clue to nudge me in the right direction would be appreciated.

TIA

Edit: Somebody pointed out(comment deleted now) that its difficult to explain the solution with just hints and not posting some code. Kindly post code if necessary.

like image 215
johne Avatar asked Sep 03 '11 17:09

johne


1 Answers

The problem is NP-Hard, thus the backtracking solution [or other exponential solution as suggested by @vhallac] will be your best shot, since there is not known [and if P!=NP, there is no existing] polynomial solution for this kind of problem.

NP-Hardness proof:
First, we know that a rectangle consists of 4 edges, that are equal in pairs [e1=e2,e3=e4].
We will show that if there is a polynomial algorithm A to this problem, we can also solve the Partition Problem, by the following algorithm:

input: a group of numbers S=a1,a2,...,an
output: true if and only if the numbers can be partitioned
algorithm:
sum <- a1 + a2 + .. + an
lengths <- a1, a2 , ... , an , (sum*5), (sum*5)
activate A with lengths.
if A answered there is any rectangle [solution is not 0], answer True
else answer False

Correctness:
(1) if there is a partition to S, let it be S1,S2, there is also a rectangle with edges: (sum*5),(sum*5),S1,S2, and the algorithm will yield True.

(2) if the algorithm yields True, there is a rectangle available in lengths, since a1 + a2 + ... + an < sum*5, there are 2 edges with length sum*5, since the 2 other edges must be made using all remaining lengths [as the question specified], each other edge is actually of length (a1 + a2 + ... + an)/2, and thus there is a legal partition to the problem.

Conclusion: There is a reduction PARTITION<=(p) this problem, and thus, this problem is NP-Hard

EDIT:
the backtracking solution is pretty simple, get all possible rectangles, and check each of them to see which is the best.
backtracking solution: pseudo-code:

getAllRectangles(S,e1,e2,e3,e4,sol):
  if S == {}:
     if legalRectangle(e1,e2,e3,e4):
          sol.add((e1,e2,e3,e4))
  else: //S is not empty
     elem <- S[0]
      getAllRectangles(S-elem,e1+elem,e2,e3,e4,sol)
      getAllRectangles(S-elem,e1,e2+elem,e3,e4,sol)
      getAllRectangles(S-elem,e1,e2,e3+elem,e4,sol)
      getAllRectangles(S-elem,e1,e2,e3,e4+elem,sol)

getRectangle(S):
  RECS <- new Set
  getAllRectangles(S,{},{},{},{},RECS)
  getBest(RECS)

EDIT2:
As discussed in the comments, this answer shows not only this is hard to find the BEST rectangle, it is also hard to find ANY rectangle, making this problem hard for heuristic solutions as well.

like image 52
amit Avatar answered Sep 28 '22 05:09

amit