secnot/rectpack

Weight constraint

WBP20 opened this issue · 5 comments

WBP20 commented

Hi,

Thank you for sharing us this work, this is very helpfull for my needs.

I want to add a weight contraint, that needs to modify your code:

  • add a weight argument to class Rectangle
  • add a maxWeight or remainingWeight argument to Bins
  • Before adding a Rect to a bin check if weight < maxWeight (or > remainingWeight)
  • if Ok add the rect to the bin and modify the maxWeight or remainingWeight arg
  • if not ok continue to the next bin of the second one that fit the best.

But I can't find where I should implant that.. if you can give me some clues I could work on it.

Thank you in advance

Hi

There are two approaches depending on what you are looking for:

1 - Modify a packer to check the bins remaining weight and skip the rectangles that won't fit. The problem with this approach is that if the weigh of a rectangle isn't linked to its area, you could end with bins that have reached the max weight but with a lot of unused space.

2 - Create a new packing algorithm or modify one, so it takes the remaining weight on the bin and the weight of the rectangle in consideration when assigning fitness values. A more complex solution that could give better results with a well chosen fitness function

Hope it helps

WBP20 commented

Hi,

I have already assigned a weight argument to function Rectangle.

I better go with 2nd option, I first though I could made some changes here:

class PackerBBFMixin(object):
    """
    BBF (Bin Best Fit): Pack rectangle in bin that gives best fitness
    """

    # only create this getter once
    first_item = operator.itemgetter(0)

    def add_rect(self, width, height, rid=None):

#iterate for each bins if sum of all rectangle contained in this bin + weight of this rectangle is > maxweight allowed.
# if so remove the bin from open_bins  (assuming in this algo there is no closed bins). stock the removed bins in closed-bins.

    # check if open_bins is not empty , else go to 2nd part of function (while true...)
        # Try packing into open bins
        fit = ((b.fitness(width, height),  b) for b in self._open_bins)
        fit = (b for b in fit if b[0] is not None)
        try:
            _, best_bin = min(fit, key=self.first_item)
            best_bin.add_rect(width, height, rid)
            return True
        except ValueError:
            pass    
 
        # Try packing into one of the empty bins
        while True:
            # can we find an unopened bin that will hold this rect?
            new_bin = self._new_open_bin(width, height, rid=rid)
            if new_bin is None:
                return False

            # _new_open_bin may return a bin that's too small,
            # so we have to double-check
            if new_bin.add_rect(width, height, rid):
                return True

  # add the closed bin to _onpenbins to reset. 

I added comment where I should modify.
But it seems that this is not easy to manipulate these degue objetcts I got error

RuntimeError: deque mutated during iteration

Maybe should I do it in a different way ? modifying direclty in fitness function ? But i need to better understand what are inside open_bins ?

WBP20 commented

Hi, I found out a way to do it ! you can close the issue ! thank you anyway.

Hello WBP20, Do you still have the modified algorithm that takes account weight? Thanks!

same dwag we really need you rn WBP20