Skip to content

Instantly share code, notes, and snippets.

@munificent
Created February 19, 2018 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save munificent/89197013a4079c30a559567876aa26bd to your computer and use it in GitHub Desktop.
Save munificent/89197013a4079c30a559567876aa26bd to your computer and use it in GitHub Desktop.
Bin-packing-esque

This is in response to: https://gist.github.com/derek-knox/2aee55a146276b0514581f36b36b3f54

Here's some thoughts:

1.

As long as even distribution is a soft goal and not a hard constraint, and you've got that specific set of small box sizes, it seems pretty tractable. It would be harder if your box sizes were weird and large like 4x19, etc. But with 1x1 in there, you can always find some solution that fills the region even if it ends up using more 1x1 boxes than you want.

There are probably a number of algorithms that would work. With those specific box sizes, I might try:

  1. Keep a running count of the number of boxes of each size.

  2. Fill the whole region with 1x1 boxes.

  3. Until the box counts are uniformly distributed or some maximum number of attempts is made:

    1. Pick the box size that is least represented.
    2. Pick a random point. Try to collapse it with neighboring boxes to produce a box with the desired size. So, if you're trying to make a 2x1 box and you landed on a 1x1 box, see if the box to the left or right is 1x1 and, if so, merge them.

This probably won't give you a very close uniform distribution, but it's simple and might be good enough for something like a game.

Here's another:

  1. Keep a running count of the number of boxes of each size.

  2. As long as there are open cells that don't contain a box.

    1. Choose the least represented box size that is still selectable.
    2. Iterate over every location in the container where the box could be placed.
    3. If you find a place where it doesn't overlap any existing boxes, add that location to a list.
    4. If the list is empty, then mark that box size as no longer selectable.
    5. Otherwise, place the box at a randomly chosen location from that list.

This will probably end up biased towards smaller boxes because they'll stay selectable longer. You could tweak that by preferring larger boxes earlier on.

2.

I think you can extend the second algorith to handle this. When checking to see if a location is valid, just add padding to box when checking for overlap.

3.

I think it handles this too. When choosing the "least represented box size", just adjust the desired weights accordingly.

I hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment