- Timestamp:
- 01/24/18 13:17:00 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerMinRSLeft.cs
r15618 r15646 45 45 #endregion 46 46 47 48 47 49 public BinPackerMinRSLeft() : base() { } 48 50 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; 49 55 50 56 public override IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, ExtremePointPruningMethod epPruningMethod, bool useStackingConstraints) { … … 57 63 BinPacking3D packingBin = new BinPacking3D(binShape); 58 64 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 64 70 ExtremePointPruningFactory.CreatePruning().PruneExtremePoints(epPruningMethod, packingList); 71 65 72 return packingList; 66 73 } … … 76 83 protected void PackRemainingItems(ref IList<int> remainingIds, ref BinPacking3D packingBin, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, bool useStackingConstraints) { 77 84 IExtremePointCreator extremePointCreator = ExtremePointCreatorFactory.CreateExtremePointCreator(epCreationMethod, useStackingConstraints); 85 var remainingNotStackableItems = new List<int>(); 78 86 foreach (var itemId in new List<int>(remainingIds)) { 79 87 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 90 151 protected override PackingPosition FindPackingPositionForItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) { 91 152 if (!CheckItemDimensions(packingBin, packingItem)) { … … 95 156 } 96 157 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 113 160 if (rsd == null) { 114 161 return null; … … 120 167 } 121 168 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> 122 202 protected ResidualSpaceDifference FindResidualSpaceDifferenceForItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints, bool rotated, bool tilted) { 123 203 PackingItem newItem = new PackingItem(packingItem) { … … 125 205 Tilted = tilted 126 206 }; 127 207 128 208 var rsds = new SortedSet<ResidualSpaceDifference>(); 129 130 209 foreach (var ep in packingBin.ExtremePoints) { 131 210 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); 138 215 } 139 216 } 140 217 } 141 return rsds. FirstOrDefault();142 } 143 218 return rsds.Where(rsd => packingBin.IsPositionFeasible(rsd.Item, rsd.Position, useStackingConstraints)).FirstOrDefault(); 219 } 220 144 221 protected override bool CheckItemDimensions(BinPacking3D packingBin, PackingItem item) { 145 222 bool ok = false; … … 167 244 OriginalWidth = width, 168 245 OriginalHeight = height, 169 OriginalDepth = 246 OriginalDepth = depth 170 247 }); 171 248 } … … 212 289 if (x != 0) { 213 290 return x; 214 } else if (y != 0 291 } else if (y != 0) { 215 292 return y; 216 293 } else if (z != 0) {
Note: See TracChangeset
for help on using the changeset viewer.