- Timestamp:
- 02/01/18 12:21:34 (7 years ago)
- Location:
- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPacker.cs
r15652 r15705 94 94 packingItem.Height, 95 95 packingItem.Depth, 96 packingItem.TargetBin, packingItem.Weight, packingItem. Material);96 packingItem.TargetBin, packingItem.Weight, packingItem.Layer); 97 97 98 98 // The extremepoints are sortet by Y / Z / X -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerMinRSLeft.cs
r15652 r15705 63 63 BinPacking3D packingBin = new BinPacking3D(binShape); 64 64 PackRemainingItems(ref remainingIds, ref packingBin, workingItems, epCreationMethod, useStackingConstraints); 65 packingList.Add(packingBin); 65 packingList.Add(packingBin); 66 66 } 67 67 } catch (BinPacking3DException e) { … … 105 105 protected void PackRemainingItems(ref IList<int> remainingIds, ref BinPacking3D packingBin, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, bool useStackingConstraints) { 106 106 IExtremePointCreator extremePointCreator = ExtremePointCreatorFactory.CreateExtremePointCreator(epCreationMethod, useStackingConstraints); 107 var remainingNot StackableItems = new List<int>();107 var remainingNotWeightSupportedItems = new List<int>(); 108 108 foreach (var itemId in new List<int>(remainingIds)) { 109 109 var item = items[itemId]; 110 110 111 // If an item is not stackableit should have a minimum waste of the residual space.112 // As long as there are stackable items left, put the non stackableitems into a collection111 // If an item doesn't support any weight it should have a minimum waste of the residual space. 112 // As long as there are weight supporting items left, put the non supporting items into a collection 113 113 // and try to find positions where they don't waste too much space. 114 // If there are no stackable items left the non stackable have to be treated as a stackable one. 115 if (!item.IsStackabel && useStackingConstraints && remainingIds.Where(x => items[x].IsStackabel).Any()) { 116 remainingNotStackableItems.Add(itemId); 117 } else { 114 // If there are no weight supporting items left the non supporting ones have to be treated as a supporting one. 115 if (item.SupportedWeight <= 0 && useStackingConstraints && remainingIds.Any(x => items[x].SupportedWeight > 0)) { 116 remainingNotWeightSupportedItems.Add(itemId); 117 } else if (!item.IsStackabel) { 118 PackingPosition position = FindPackingPositionForNotStackableItem(packingBin, item, useStackingConstraints); 119 // if a valid packing position could be found, the current item can be added to the given bin 120 if (position != null) { 121 PackItem(packingBin, itemId, item, position, extremePointCreator, useStackingConstraints); 122 remainingIds.Remove(itemId); 123 } 124 } else { 118 125 PackingPosition position = FindPackingPositionForItem(packingBin, item, useStackingConstraints); 119 126 // if a valid packing position could be found, the current item can be added to the given bin 120 if (position != null) { 127 if (position != null) { 121 128 PackItem(packingBin, itemId, item, position, extremePointCreator, useStackingConstraints); 122 129 remainingIds.Remove(itemId); … … 124 131 } 125 132 126 // try to find a valid position for a non stackableitem127 var stackableLeft = remainingIds.Where(x => items[x].IsStackabel).Any();128 foreach (var saId in new List<int>(remainingNot StackableItems)) {133 // try to find a valid position for a non weight supporting item 134 var weightSupportedLeft = remainingIds.Any(x => items[x].SupportedWeight > 0); 135 foreach (var saId in new List<int>(remainingNotWeightSupportedItems)) { 129 136 item = items[saId]; 130 137 PackingPosition position = null; 131 if ( stackableLeft) {132 position = FindPackingPositionForNotStackableItem(packingBin, item, useStackingConstraints);138 if (weightSupportedLeft) { 139 position = FindPackingPositionForWeightUnsupportedItem(packingBin, item, useStackingConstraints); 133 140 } else { 134 141 position = FindPackingPositionForItem(packingBin, item, useStackingConstraints); 135 142 } 136 137 if (position != null) { 143 144 if (position != null) { 138 145 PackItem(packingBin, saId, item, position, extremePointCreator, useStackingConstraints); 139 146 remainingIds.Remove(saId); 140 remainingNotStackableItems.Remove(saId); 141 } 142 } 143 144 } 147 remainingNotWeightSupportedItems.Remove(saId); 148 } 149 } 150 151 } 152 } 153 154 /// <summary> 155 /// Finds a valid packing position for a not stackable item. 156 /// Not stackable means that an item can't be placed on another one and no other item can be placed on it. 157 /// The item will be rotated and tilted so it needs the minimum area. 158 /// </summary> 159 /// <param name="packingBin"></param> 160 /// <param name="packingItem"></param> 161 /// <param name="useStackingConstraints"></param> 162 /// <returns></returns> 163 private PackingPosition FindPackingPositionForNotStackableItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) { 164 if (!useStackingConstraints) { 165 return FindPackingPositionForItem(packingBin, packingItem, useStackingConstraints); 166 } 167 var areas = new List<Tuple<double, bool, bool>>(); 168 areas.Add(CalculateArea(packingItem, false, false)); 169 if (packingItem.TiltEnabled) { 170 areas.Add(CalculateArea(packingItem, false, true)); 171 } 172 if (packingItem.RotateEnabled) { 173 areas.Add(CalculateArea(packingItem, true, false)); 174 } 175 if (packingItem.RotateEnabled && packingItem.TiltEnabled) { 176 areas.Add(CalculateArea(packingItem, true, true)); 177 } 178 179 areas.Sort((x1, x2) => (int)(x1.Item1 - x2.Item1)); 180 var orientation = areas.FirstOrDefault(); 181 if (orientation == null) { 182 return null; 183 } 184 185 186 PackingItem newItem = new PackingItem(packingItem) { 187 Rotated = orientation.Item2, 188 Tilted = orientation.Item3 189 }; 190 191 var rsds = new SortedSet<ResidualSpaceDifference>(); 192 foreach (var ep in packingBin.ExtremePoints.Where(x => x.Key.Y == 0)) { 193 var position = ep.Key; 194 foreach (var rs in ep.Value) { 195 var rsd = ResidualSpaceDifference.Create(position, newItem, rs); 196 if (rsd != null) { 197 rsds.Add(rsd); 198 } 199 } 200 } 201 var d = rsds.Where(x => packingBin.IsPositionFeasible(x.Item, x.Position, useStackingConstraints)).FirstOrDefault(); 202 203 if (d == null) { 204 return null; 205 } 206 207 packingItem.Rotated = orientation.Item2; 208 packingItem.Tilted = orientation.Item3; 209 return d.Position; 210 } 211 212 Tuple<double, bool, bool> CalculateArea(PackingItem packingItem, bool rotated, bool tilted) { 213 var item = new PackingItem(packingItem) { 214 Rotated = rotated, 215 Tilted = tilted 216 }; 217 return Tuple.Create<double, bool, bool>(item.Width * item.Depth, rotated, tilted); 145 218 } 146 219 … … 153 226 /// <param name="useStackingConstraints"></param> 154 227 /// <returns></returns> 155 private PackingPosition FindPackingPositionFor NotStackableItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) {228 private PackingPosition FindPackingPositionForWeightUnsupportedItem(BinPacking3D packingBin, PackingItem packingItem, bool useStackingConstraints) { 156 229 if (!CheckItemDimensions(packingBin, packingItem)) { 157 230 throw new BinPacking3DException($"The dimensions of the given item exceeds the bin dimensions. " + … … 227 300 Tilted = tilted 228 301 }; 229 302 230 303 var rsds = new SortedSet<ResidualSpaceDifference>(); 231 304 foreach (var ep in packingBin.ExtremePoints) { … … 240 313 return rsds.Where(rsd => packingBin.IsPositionFeasible(rsd.Item, rsd.Position, useStackingConstraints)).FirstOrDefault(); 241 314 } 242 315 243 316 protected override bool CheckItemDimensions(BinPacking3D packingBin, PackingItem item) { 244 317 bool ok = false; … … 270 343 } 271 344 272 345 273 346 protected class ResidualSpaceDifference : IComparable { 274 347 public static ResidualSpaceDifference Create(PackingPosition position, PackingItem item, ResidualSpace rs) { … … 307 380 308 381 var x = this.X - rsd.X; 309 var y = rsd.Y - this.Y;382 var y = this.Y - rsd.Y; 310 383 var z = this.Z - rsd.Z; 311 384
Note: See TracChangeset
for help on using the changeset viewer.