Ignore:
Timestamp:
01/24/18 13:17:00 (3 years ago)
Author:
rhanghof
Message:

#2817:

  • Dealing with stackable items
  • Enhanced the Evaluator
  • Added parameters some paramters to the packing items
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerMinRSLeft.cs

    r15618 r15646  
    4545    #endregion
    4646
     47
     48
    4749    public BinPackerMinRSLeft() : base() { }
    4850
     51    /// <summary>
     52    /// This proportion of the residual space left to the item height is used for deciding if a not stackable item should be placed.
     53    /// </summary>
     54    private const double NOT_STACKABLE_RS_LEFT_TO_ITEM_HEIGHT_PROPORTION = 1.1;
    4955
    5056    public override IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, ExtremePointPruningMethod epPruningMethod, bool useStackingConstraints) {
     
    5763          BinPacking3D packingBin = new BinPacking3D(binShape);
    5864          PackRemainingItems(ref remainingIds, ref packingBin, workingItems, epCreationMethod, useStackingConstraints);
    59           packingList.Add(packingBin);
    60         }
    61       } catch(BinPacking3DException e) {
    62       }
    63      
     65          packingList.Add(packingBin);         
     66        }
     67      } catch (BinPacking3DException e) {
     68      }
     69
    6470      ExtremePointPruningFactory.CreatePruning().PruneExtremePoints(epPruningMethod, packingList);
     71
    6572      return packingList;
    6673    }
     
    7683    protected void PackRemainingItems(ref IList<int> remainingIds, ref BinPacking3D packingBin, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, bool useStackingConstraints) {
    7784      IExtremePointCreator extremePointCreator = ExtremePointCreatorFactory.CreateExtremePointCreator(epCreationMethod, useStackingConstraints);
     85      var remainingNotStackableItems = new List<int>();
    7886      foreach (var itemId in new List<int>(remainingIds)) {
    7987        var item = items[itemId];
    80         PackingPosition position = FindPackingPositionForItem(packingBin, item, useStackingConstraints);
    81         // if a valid packing position could be found, the current item can be added to the given bin
    82         if (position != null) {
    83           PackItem(packingBin, itemId, item, position, extremePointCreator, useStackingConstraints);
    84           remainingIds.Remove(itemId);
    85         }
    86       }
    87     }
    88 
    89    
     88
     89        // If an item is not stackable it should have a minimum waste of the residual space.
     90        // As long as there are stackable items left, put the non stackable items into a collection
     91        // and try to find positions where they don't waste too much space.
     92        // If there are no stackable items left the non stackable have to be treated as a stackable one.
     93        if (!item.IsStackabel && useStackingConstraints && remainingIds.Where(x => items[x].IsStackabel).Any()) {
     94          remainingNotStackableItems.Add(itemId);         
     95        } else {
     96          PackingPosition position = FindPackingPositionForItem(packingBin, item, useStackingConstraints);
     97          // if a valid packing position could be found, the current item can be added to the given bin
     98          if (position != null) {           
     99            PackItem(packingBin, itemId, item, position, extremePointCreator, useStackingConstraints);
     100            remainingIds.Remove(itemId);
     101          }
     102        }
     103
     104        // try to find a valid position for a non stackable item
     105        var stackableLeft = remainingIds.Where(x => items[x].IsStackabel).Any();
     106        foreach (var saId in new List<int>(remainingNotStackableItems)) {
     107          item = items[saId];
     108          PackingPosition position = null;
     109          if (stackableLeft) {
     110            position  = FindPackingPositionForNotStackableItem(packingBin, item, useStackingConstraints);
     111          } else {
     112            position = FindPackingPositionForItem(packingBin, item, useStackingConstraints);
     113          }
     114         
     115          if (position != null) {           
     116            PackItem(packingBin, saId, item, position, extremePointCreator, useStackingConstraints);
     117            remainingIds.Remove(saId);
     118            remainingNotStackableItems.Remove(saId);
     119          }
     120        }
     121       
     122      }
     123    }
     124
     125    /// <summary>
     126    /// Tries to find a valid position for a non stackable item.
     127    /// Positions will only be valid if the height difference of its residual space is smaller then the hight of the item.
     128    /// </summary>
     129    /// <param name="packingBin"></param>
     130    /// <param name="packingItem"></param>
     131    /// <param name="useStackingConstraints"></param>
     132    /// <returns></returns>
     133    private PackingPosition FindPackingPositionForNotStackableItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) {
     134      if (!CheckItemDimensions(packingBin, packingItem)) {
     135        throw new BinPacking3DException($"The dimensions of the given item exceeds the bin dimensions. " +
     136          $"Bin: ({packingBin.BinShape.Width} {packingBin.BinShape.Depth} {packingBin.BinShape.Height})" +
     137          $"Item: ({packingItem.Width} {packingItem.Depth} {packingItem.Height})");
     138      }
     139      var rsds = CalculateResidalSpaceDifferences(packingBin, packingItem, useStackingConstraints).ToList();
     140      var rsd = rsds.Where(x => x != null && (x.Y / (double)x.Item.Height) < NOT_STACKABLE_RS_LEFT_TO_ITEM_HEIGHT_PROPORTION).OrderByDescending(x => x.Y % x.Item.Height).FirstOrDefault();
     141
     142      if (rsd == null) {
     143        return null;
     144      }
     145
     146      packingItem.Rotated = rsd.Item.Rotated;
     147      packingItem.Tilted = rsd.Item.Tilted;
     148      return rsd.Position;
     149    }
     150
    90151    protected override PackingPosition FindPackingPositionForItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) {
    91152      if (!CheckItemDimensions(packingBin, packingItem)) {
     
    95156      }
    96157
    97       var rsds = new SortedSet<ResidualSpaceDifference>();
    98 
    99       rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: false, tilted: false));
    100 
    101       if (packingItem.TiltEnabled) {
    102         rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: false, tilted: true));
    103       }
    104       if (packingItem.RotateEnabled) {
    105         rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: true, tilted: false));
    106       }
    107       if (packingItem.RotateEnabled && packingItem.TiltEnabled) {
    108         rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: true, tilted: true));
    109       }
    110 
    111       var rsd = rsds.Where(x => x != null).FirstOrDefault();
    112      
     158      var rsd = CalculateResidalSpaceDifferences(packingBin, packingItem, useStackingConstraints).Where(x => x != null).FirstOrDefault();
     159
    113160      if (rsd == null) {
    114161        return null;
     
    120167    }
    121168
     169    /// <summary>
     170    ///
     171    /// </summary>
     172    /// <param name="packingBin"></param>
     173    /// <param name="packingItem"></param>
     174    /// <param name="useStackingConstraints"></param>
     175    /// <returns></returns>
     176    private SortedSet<ResidualSpaceDifference> CalculateResidalSpaceDifferences(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) {
     177      var rsds = new SortedSet<ResidualSpaceDifference>();
     178
     179      rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: false, tilted: false));
     180
     181      if (packingItem.TiltEnabled) {
     182        rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: false, tilted: true));
     183      }
     184      if (packingItem.RotateEnabled) {
     185        rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: true, tilted: false));
     186      }
     187      if (packingItem.RotateEnabled && packingItem.TiltEnabled) {
     188        rsds.Add(FindResidualSpaceDifferenceForItem(packingBin, packingItem, useStackingConstraints, rotated: true, tilted: true));
     189      }
     190      return rsds;
     191    }
     192
     193    /// <summary>
     194    ///
     195    /// </summary>
     196    /// <param name="packingBin"></param>
     197    /// <param name="packingItem"></param>
     198    /// <param name="useStackingConstraints"></param>
     199    /// <param name="rotated"></param>
     200    /// <param name="tilted"></param>
     201    /// <returns></returns>
    122202    protected ResidualSpaceDifference FindResidualSpaceDifferenceForItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints, bool rotated, bool tilted) {
    123203      PackingItem newItem = new PackingItem(packingItem) {
     
    125205        Tilted = tilted
    126206      };
    127 
     207     
    128208      var rsds = new SortedSet<ResidualSpaceDifference>();
    129 
    130209      foreach (var ep in packingBin.ExtremePoints) {
    131210        var position = ep.Key;
    132         if (packingBin.IsPositionFeasible(newItem, position, useStackingConstraints)) {
    133           foreach (var rs in ep.Value) {
    134             var rsd = ResidualSpaceDifference.Create(position, newItem, rs);
    135             if (rsd != null) {
    136               rsds.Add(rsd);
    137             }
     211        foreach (var rs in ep.Value) {
     212          var rsd = ResidualSpaceDifference.Create(position, newItem, rs);
     213          if (rsd != null) {
     214            rsds.Add(rsd);
    138215          }
    139216        }
    140217      }
    141       return rsds.FirstOrDefault();
    142     }
    143 
     218      return rsds.Where(rsd => packingBin.IsPositionFeasible(rsd.Item, rsd.Position, useStackingConstraints)).FirstOrDefault();
     219    }
     220       
    144221    protected override bool CheckItemDimensions(BinPacking3D packingBin, PackingItem item) {
    145222      bool ok = false;
     
    167244        OriginalWidth = width,
    168245        OriginalHeight = height,
    169         OriginalDepth =  depth
     246        OriginalDepth = depth
    170247      });
    171248    }
     
    212289        if (x != 0) {
    213290          return x;
    214         } else if (y != 0 ) {
     291        } else if (y != 0) {
    215292          return y;
    216293        } else if (z != 0) {
Note: See TracChangeset for help on using the changeset viewer.