Background:
Hello, so I've been working on this function for a bit and I'm stumbling. Ultimately, what I'm trying to accomplish is to have an application where a user inputs larger boxes, and also inputs a list of smaller boxes. (All 2 dimensional, by the way). The program then processes this, and tries to fill as completely as possible the larger boxes with the smaller ones. For those curious, this is for a theater platform application.
Code stuff:
I have this function here that takes "box", which is a table of larger boxes created by the user, and "platforms", which is a table of smaller boxes. As seen in the comments, I've already written the part where if a platform fits perfectly into a box, then it does so. It then reduces the quantity of the given size of that platform, and marks that box as filled.
Problem:
The problem I can't figure out is how to programmatically fit two platforms into one larger box in the most efficient manner. I considered using the x side of the box and filling that up with the x values of a given set of platforms, and then interplacing different platforms with the same x values in that set, but with different y values but there's several problems there.
Any pointers on where I should go from here?
userInterfaceCall()
squares[#squares+1] = {x1=x, y1=y, x2 = nil, y2 = nil, f=false}
--x1,y1 and x2,y2 are coordinates for two opposite points in a square
--f is the boolean that is marked true when a square (box) is completely filled
end
platforms[1] = {x=4, y=4, q=2} --example user data
platforms[2] = {x=4, y=6, q=2} --x and y are platform dimensions
platforms[3] = {x=6, y=2, q=1} --q is quantity
platforms[4] = {x=8, y=4, q=1}
process(squares,platforms) --this is called by a UI element
function process(box,platforms)
for i,box in ipairs(box) do --for every square do
if box.f == false then --if the box already has a given platform, don't do shit
for i,platform in ipairs(platforms) do --for each platform for each box
boxX = math.abs(box.x1-box.x2)/scale --Ignore this, this is working with scaling from-
boxY = math.abs(box.y1-box.y2)/scale --pixel size to feet to compare to list of platforms
if boxX == platform.x and boxY == platform.y and platform.q > 0 then --Test if any platform fits directly in the box
placements[#placements+1] = {x1 = box.x1, y1 = box.y1, x2 = box.x2, y2 = box.y2, s = ''} --Creates a new placement of a given platform, which is then drawn
platform.q = platform.q - 1 --we reduce the quantity, cause we used one
box.f = true --yes, we just filled the box completely
elseif boxY == platform.x and boxX == platform.y and platform.q > 0 then --Test for switched x and y
placements[#placements+1] = {x1 = box.x1, y1 = box.y1, x2 = box.x2, y2 = box.y2, s = ''}
platform.q = platform.q - 1
box.f = true
elseif
--put multiple platforms in one box, Help
else
setPrompt('Could not find for box: '..boxX..','..boxY)
end
end
end
end
end
You found a variant of the Multi-dimensional Knapsack Problem, which is known to be NP-complete. So no, there is no simple "best" solution, however, a number of strategies have been found to yield acceptable results in acceptable time. Please see the linked article for further explanation.