Changeset 15454
- Timestamp:
- 11/07/17 08:24:24 (7 years ago)
- Location:
- branches/2817-BinPackingSpeedup
- Files:
-
- 13 added
- 1 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2817-BinPackingSpeedup/HeuristicLab 3.3.sln
r15178 r15454 2 2 Microsoft Visual Studio Solution File, Format Version 12.00 3 3 # Visual Studio 15 4 VisualStudioVersion = 15.0.26 430.154 VisualStudioVersion = 15.0.26228.9 5 5 MinimumVisualStudioVersion = 10.0.40219.1 6 6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}" … … 462 462 EndProject 463 463 Global 464 GlobalSection(Performance) = preSolution 465 HasPerformanceSessions = true 466 EndGlobalSection 464 467 GlobalSection(SolutionConfigurationPlatforms) = preSolution 465 468 Debug|Any CPU = Debug|Any CPU -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/HeuristicLab.Problems.BinPacking.Views-3.3.csproj
r15233 r15454 167 167 <Name>HeuristicLab.Problems.BinPacking-3.3</Name> 168 168 <Private>False</Private> 169 </ProjectReference> 170 <ProjectReference Include="..\..\HeuristicLab.Problems.Instances.Views\3.3\HeuristicLab.Problems.Instances.Views-3.3.csproj"> 171 <Project>{B1BA398F-953F-4C3A-B07B-1E5E17A27DD9}</Project> 172 <Name>HeuristicLab.Problems.Instances.Views-3.3</Name> 173 </ProjectReference> 174 <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj"> 175 <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project> 176 <Name>HeuristicLab.Problems.Instances-3.3</Name> 169 177 </ProjectReference> 170 178 </ItemGroup> -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs
r15424 r15454 27 27 using HeuristicLab.Common; 28 28 using HeuristicLab.Problems.BinPacking; 29 using HeuristicLab.Problems.BinPacking3D.Geometry; 29 30 30 31 namespace HeuristicLab.Problems.BinPacking3D { … … 38 39 public BinPacking3D(PackingShape binShape) 39 40 : base(binShape) { 40 ResidualSpace = new Dictionary<PackingPosition, Tuple<int, int,int>>();41 ResidualSpace = new Dictionary<PackingPosition, Tuple<int, int, int>>(); 41 42 AddExtremePoint(binShape.Origin); 42 43 InitializeOccupationLayers(); … … 63 64 #endregion 64 65 } 66 67 #region New methods for bin packer class 68 69 public void AddItem(int itemID, PackingItem item, PackingPosition position) { 70 Items[itemID] = item; 71 Positions[itemID] = position; 72 ExtremePoints.Remove(position); 73 ResidualSpace.Remove(position); 74 } 75 76 public void UpdateExtremePoints(PackingItem item, PackingPosition position, bool stackingConstraints) { 77 /*if (stackingConstraints) { 78 AddExtremePoint(new PackingPosition(position.AssignedBin, position.X + item.Width, position.Y, position.Z)); 79 AddExtremePoint(new PackingPosition(position.AssignedBin, position.X, position.Y + item.Height, position.Z)); 80 AddExtremePoint(new PackingPosition(position.AssignedBin, position.X, position.Y, position.Z + item.Depth)); 81 } else {*/ 82 GenerateNewExtremePointsForNewItem(item, position); 83 84 // if an item is fit in below, before, or left of another its extreme points have to be regenerated 85 foreach (var above in GetItemsAbove(position)) { 86 GenerateNewExtremePointsForNewItem(above.Item2, above.Item1); 87 } 88 foreach (var front in GetItemsInfront(position)) { 89 GenerateNewExtremePointsForNewItem(front.Item2, front.Item1); 90 } 91 foreach (var right in GetItemsOnRight(position)) { 92 GenerateNewExtremePointsForNewItem(right.Item2, right.Item1); 93 } 94 //} 95 } 96 97 98 99 /// <summary> 100 /// In this case feasability is defined as following: 101 /// 1. the item fits into the bin-borders; 102 /// 2. the point is supported by something; 103 /// 3. the item does not collide with another already packed item 104 /// 105 /// Unfortunatelly this method does not support item rotation 106 /// </summary> 107 /// <param name="item"></param> 108 /// <param name="position"></param> 109 /// <param name="stackingConstraints"></param> 110 /// <returns></returns> 111 public override bool IsPositionFeasible(PackingItem item, PackingPosition position, bool stackingConstraints) { 112 var b1 = CheckItemDimensions(item); 113 var b2 = ItemCanBePlaced(item, position); 114 var b3 = CheckStackingConstraints(item, position, stackingConstraints); 115 116 return b1 && b2 && b3; 117 } 118 119 /// <summary> 120 /// Compares the dimensions of a given item and the current bin. 121 /// </summary> 122 /// <param name="item"></param> 123 /// <returns>Returns true if the dimensions of an given item are less or equal to the bin.</returns> 124 private bool CheckItemDimensions(PackingItem item) { 125 return BinShape.Width >= item.Width && BinShape.Height >= item.Height && BinShape.Depth >= item.Depth; 126 } 127 128 /// <summary> 129 /// Returns true if a given item can be placed in the current bin 130 /// </summary> 131 /// <param name="givenItem"></param> 132 /// <param name="givenItemPosition"></param> 133 /// <returns></returns> 134 private bool ItemCanBePlaced(PackingItem givenItem, PackingPosition givenItemPosition) { 135 // Check if the boundings of the bin would injured 136 if (givenItemPosition.X + givenItem.Width > BinShape.Width || 137 givenItemPosition.Y + givenItem.Height > BinShape.Height || 138 givenItemPosition.Z + givenItem.Depth > BinShape.Depth) { 139 return false; 140 } 141 142 //if the given item collides with any other item, it can not be placed 143 foreach (var item in Items) { 144 if (ItemsCollides(new Tuple<PackingPosition, PackingItem>(Positions[item.Key], item.Value), 145 new Tuple<PackingPosition, PackingItem>(givenItemPosition, givenItem))) { 146 return false; 147 } 148 } 149 return true; 150 } 151 152 /// <summary> 153 /// Checks if two given items in a space collides 154 /// </summary> 155 /// <param name="t1"></param> 156 /// <param name="t2"></param> 157 /// <returns></returns> 158 bool ItemsCollides(Tuple<PackingPosition, PackingItem> t1, Tuple<PackingPosition, PackingItem> t2) { 159 var position1 = t1.Item1; 160 var item1 = t1.Item2; 161 var position2 = t2.Item1; 162 var item2 = t2.Item2; 163 var cx = (position2.X == position1.X) || (position2.X < position1.X && position2.X + item2.Width > position1.X) || (position2.X > position1.X && position1.X + item1.Width > position2.X); 164 var cy = (position2.Y == position1.Y) || (position2.Y < position1.Y && position2.Y + item2.Height > position1.Y) || (position2.Y > position1.Y && position1.Y + item1.Height > position2.Y); 165 var cz = (position2.Z == position1.Z) || (position2.Z < position1.Z && position2.Z + item2.Depth > position1.Z) || (position2.Z > position1.Z && position1.Z + item1.Depth > position2.Z); 166 return cx && cy && cz; 167 } 168 169 /// <summary> 170 /// Checks the stacking constraints. This method depends that the given item can be placed at this position 171 /// </summary> 172 /// <param name="item"></param> 173 /// <param name="position"></param> 174 /// <param name="stackingConstraints"></param> 175 /// <returns></returns> 176 private bool CheckStackingConstraints(PackingItem item, PackingPosition position, bool stackingConstraints) { 177 if (position.Y == 0 || !stackingConstraints && HasOnePointWithAnItemBelow(item, position)) { 178 return true; 179 } 180 181 return IsStaticStable(item, position) && IsWeightSupported(item, position); 182 } 183 184 185 /// <summary> 186 /// Checks if a given item has any point lieing on another item. 187 /// </summary> 188 /// <param name="item"></param> 189 /// <param name="position"></param> 190 /// <returns></returns> 191 public bool HasOnePointWithAnItemBelow(PackingItem item, PackingPosition position) { 192 bool p1, p2, p3, p4; 193 PointsLiesOnAnItems(item, position, out p1, out p2, out p3, out p4); 194 195 return p1 || p2 || p3 || p4; 196 } 197 198 /// <summary> 199 /// Checks if a given item is static stable. 200 /// A item is static stable if all edges have an object below. 201 /// </summary> 202 /// <param name="item"></param> 203 /// <param name="position"></param> 204 /// <returns></returns> 205 public override bool IsStaticStable(PackingItem item, PackingPosition position) { 206 bool p1, p2, p3, p4; 207 PointsLiesOnAnItems(item, position, out p1, out p2, out p3, out p4); 208 return p1 && p2 && p3 && p4; 209 } 210 211 /// <summary> 212 /// This method sets the out parameters p1 ... p3 if the point lies on another item. 213 /// p1 ... p3 represents one point on the bottom side of an given item. 214 /// +---------+ 215 /// |p1 p2| 216 /// | | 217 /// |p4 p3| 218 /// +---------+ 219 /// </summary> 220 /// <param name="item">Given item</param> 221 /// <param name="position">Given item position</param> 222 /// <param name="p1"></param> 223 /// <param name="p2"></param> 224 /// <param name="p3"></param> 225 /// <param name="p4"></param> 226 public void PointsLiesOnAnItems(PackingItem item, PackingPosition position, out bool p1, out bool p2, out bool p3, out bool p4) { 227 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP1; 228 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP2; 229 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP3; 230 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP4; 231 232 GetItemsUnderItemWithContact(item, position, out itemsP1, out itemsP2, out itemsP3, out itemsP4); 233 234 p1 = itemsP1.Where(x => position.X < x.Item1.X + x.Item2.Width && position.Z < x.Item1.Z + x.Item2.Depth).Any(); 235 p2 = itemsP2.Where(x => position.X + item.Width > x.Item1.X && position.Z < x.Item1.Z + x.Item2.Depth).Any(); 236 p3 = itemsP3.Where(x => position.X + item.Width > x.Item1.X && position.Z + item.Depth > x.Item1.Z).Any(); 237 p4 = itemsP4.Where(x => position.X < x.Item1.X + x.Item2.Width && position.Z + item.Depth > x.Item1.Z).Any(); 238 } 239 240 241 /// <summary> 242 /// 243 /// </summary> 244 /// <param name="item"></param> 245 /// <param name="position"></param> 246 /// <param name="itemsP1"></param> 247 /// <param name="itemsP2"></param> 248 /// <param name="itemsP3"></param> 249 /// <param name="itemsP4"></param> 250 private void GetItemsUnderItemWithContact(PackingItem item, PackingPosition position, 251 out IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP1, 252 out IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP2, 253 out IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP3, 254 out IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP4) { 255 itemsP1 = GetItemsBelowForPosition(new PackingPosition(0, position.X, position.Y, position.Z, false)); 256 itemsP2 = GetItemsBelowForPosition(new PackingPosition(0, position.X + item.Width - 1, position.Y, position.Z, false)); 257 itemsP3 = GetItemsBelowForPosition(new PackingPosition(0, position.X, position.Y, position.Z + item.Depth - 1, false)); 258 itemsP4 = GetItemsBelowForPosition(new PackingPosition(0, position.X + item.Width - 1, position.Y, position.Z + item.Depth - 1, false)); 259 260 } 261 262 /// <summary> 263 /// Returns a collection of items which are below a given point. 264 /// The top side of every item is at the same level as the Y-coordinate of the given position. 265 /// </summary> 266 /// <param name="position"></param> 267 /// <returns></returns> 268 private IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsBelowForPosition(PackingPosition position) { 269 return GetItemsBelow(position).Where(x => (x.Item1.Y + x.Item2.Height) == position.Y); 270 } 271 272 273 /// <summary> 274 /// Checks if a given the weight of an given item is supportet by the items below. 275 /// </summary> 276 /// <param name="item"></param> 277 /// <param name="position"></param> 278 /// <returns></returns> 279 public bool IsWeightSupported(PackingItem item, PackingPosition position) { 280 if (position.Y == 0) { 281 return true; 282 } 283 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP1; 284 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP2; 285 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP3; 286 IEnumerable<Tuple<PackingPosition, PackingItem>> itemsP4; 287 288 GetItemsUnderItemWithContact(item, position, out itemsP1, out itemsP2, out itemsP3, out itemsP4); 289 290 return itemsP1.Where(x => x.Item2.SupportsStacking(item)).Any() && 291 itemsP2.Where(x => x.Item2.SupportsStacking(item)).Any() && 292 itemsP3.Where(x => x.Item2.SupportsStacking(item)).Any() && 293 itemsP4.Where(x => x.Item2.SupportsStacking(item)).Any(); 294 } 295 296 297 298 #endregion 65 299 66 300 public override void PackItem(int itemID, PackingItem item, PackingPosition position) { … … 83 317 } 84 318 319 320 85 321 protected override void GenerateNewExtremePointsForNewItem(PackingItem newItem, PackingPosition position) { 86 322 int newWidth = position.Rotated ? newItem.Depth : newItem.Width; … … 168 404 } 169 405 406 170 407 private bool IsWithinResidualSpaceOfAnotherExtremePoint(Vector3D pos, Tuple<int, int, int> residualSpace) { 171 408 var eps = ExtremePoints.Where(x => !pos.Equals(x) && pos.IsInside(x, ResidualSpace[x])); … … 204 441 205 442 #region Projections 206 443 207 444 private Vector3D ProjectBackward(Vector3D pos) { 208 445 var line = new Line3D(pos, new Vector3D(0, 0, -1)); … … 268 505 #region Get items 269 506 270 507 /// <summary> 508 /// 509 /// </summary> 510 /// <param name="pos"></param> 511 /// <returns></returns> 271 512 private IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsAbove(PackingPosition pos) { 272 513 var line = new Line3D(pos, new Vector3D(0, 1, 0)); … … 298 539 .Select(x => Tuple.Create(x.Position, x.Item)); 299 540 } 541 542 private IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsBelow(PackingPosition pos) { 543 var line = new Line3D(pos, new Vector3D(0, 1, 0)); 544 return Items.Select(x => new { 545 Item = x.Value, 546 Position = Positions[x.Key], 547 Intersection = line.Intersect(new Plane3D(Positions[x.Key], x.Value, Side.Top)) 548 }).Where(x => x.Intersection != null && x.Intersection.Y <= pos.Y) 549 .Select(x => Tuple.Create(x.Position, x.Item)); 550 } 551 552 private IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsBehind(PackingPosition pos) { 553 var line = new Line3D(pos, new Vector3D(0, 0, 1)); 554 return Items.Select(x => new { 555 Item = x.Value, 556 Position = Positions[x.Key], 557 Intersection = line.Intersect(new Plane3D(Positions[x.Key], x.Value, Side.Front)) 558 }).Where(x => x.Intersection != null && x.Intersection.Y >= pos.Y) 559 .Select(x => Tuple.Create(x.Position, x.Item)); 560 } 561 562 private IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsOnLeft(PackingPosition pos) { 563 var line = new Line3D(pos, new Vector3D(1, 0, 0)); 564 return Items.Select(x => new { 565 Item = x.Value, 566 Position = Positions[x.Key], 567 Intersection = line.Intersect(new Plane3D(Positions[x.Key], x.Value, Side.Right)) 568 }).Where(x => x.Intersection != null && x.Intersection.Y >= pos.Y) 569 .Select(x => Tuple.Create(x.Position, x.Item)); 570 } 571 300 572 #endregion 573 574 301 575 302 576 public override PackingPosition FindExtremePointForItem(PackingItem item, bool rotated, bool stackingConstraints) { … … 316 590 } 317 591 318 public override bool IsPositionFeasible(PackingItem item, PackingPosition position, bool stackingConstraints) { 319 var feasible = base.IsPositionFeasible(item, position, stackingConstraints); 320 return feasible 321 && IsSupportedByAtLeastOnePoint(item, position) 322 && (!stackingConstraints || (IsStaticStable(item, position) && IsWeightSupported(item, position))); 323 } 592 324 593 325 594 #region Sliding based packing … … 425 694 return shortestSide; 426 695 } 427 public override bool IsStaticStable(PackingItem item, PackingPosition position) { 428 //Static stability is given, if item is placed on the ground 429 if (position.Y == 0) 430 return true; 431 432 if (IsPointOccupied(new PackingPosition(0, position.X, position.Y - 1, position.Z)) 433 && IsPointOccupied(new PackingPosition(0, position.X + item.Width - 1, position.Y - 1, position.Z)) 434 && IsPointOccupied(new PackingPosition(0, position.X, position.Y - 1, position.Z + item.Depth - 1)) 435 && IsPointOccupied(new PackingPosition(0, position.X + item.Width - 1, position.Y - 1, position.Z + item.Depth - 1))) 436 return true; 437 438 return false; 439 } 440 441 public bool IsSupportedByAtLeastOnePoint(PackingItem item, PackingPosition position) { 442 if (position.Y == 0) 443 return true; 444 445 int y = position.Y - 1; 446 for (int x = position.X; x < position.X + item.Width; x++) 447 for (int z = position.Z; z < position.Z + item.Depth; z++) 448 if (IsPointOccupied(new PackingPosition(0, x, y, z))) 449 return true; 450 451 return false; 452 } 453 public bool IsWeightSupported(PackingItem item, PackingPosition ep) { 454 if (ep.Y == 0) 455 return true; 456 457 if (Items[PointOccupation(new PackingPosition(0, ep.X, ep.Y - 1, ep.Z))].SupportsStacking(item) 458 && Items[PointOccupation(new PackingPosition(0, ep.X + item.Width - 1, ep.Y - 1, ep.Z))].SupportsStacking(item) 459 && Items[PointOccupation(new PackingPosition(0, ep.X, ep.Y - 1, ep.Z + item.Depth - 1))].SupportsStacking(item) 460 && Items[PointOccupation(new PackingPosition(0, ep.X + item.Width - 1, ep.Y - 1, ep.Z + item.Depth - 1))].SupportsStacking(item)) 461 return true; 462 463 return false; 464 } 696 465 697 466 698 protected override void InitializeOccupationLayers() { … … 488 720 return result; 489 721 } 490 722 491 723 public void UpdateResidualSpace(PackingItem item, PackingPosition pos) { 492 724 foreach (var ep in ExtremePoints.ToList()) { … … 509 741 } 510 742 } 511 if (ep.Z <= pos.Z && 743 744 if (ep.Z <= pos.Z && 512 745 ep.Y >= pos.Y && ep.Y < pos.Y + item.Height && 513 746 ep.X >= pos.X && ep.X < pos.X + width) { … … 517 750 changed = true; 518 751 } 752 519 753 if (changed) { 520 754 if (IsNonZero(rs) && !IsWithinResidualSpaceOfAnotherExtremePoint(new Vector3D(ep), rs)) { … … 529 763 } 530 764 531 #region Helper classes for vector math 532 private class Vector3D { 533 public int X; 534 public int Y; 535 public int Z; 536 public Vector3D() { } 537 public Vector3D(int x, int y, int z) { 538 X = x; 539 Y = y; 540 Z = z; 541 } 542 public Vector3D(PackingPosition pos) { 543 X = pos.X; 544 Y = pos.Y; 545 Z = pos.Z; 546 } 547 public static Vector3D AlongX(Vector3D pos, PackingItem item) { 548 return new Vector3D( 549 pos.X + item.Width, 550 pos.Y, 551 pos.Z 552 ); 553 } 554 public static Vector3D AlongY(Vector3D pos, PackingItem item) { 555 return new Vector3D( 556 pos.X, 557 pos.Y + item.Height, 558 pos.Z 559 ); 560 } 561 public static Vector3D AlongZ(Vector3D pos, PackingItem item) { 562 return new Vector3D( 563 pos.X, 564 pos.Y, 565 pos.Z + item.Depth 566 ); 567 } 568 public static Vector3D AlongX(PackingPosition pos, PackingItem item) { 569 return new Vector3D( 570 pos.X + item.Width, 571 pos.Y, 572 pos.Z 573 ); 574 } 575 public static Vector3D AlongY(PackingPosition pos, PackingItem item) { 576 return new Vector3D( 577 pos.X, 578 pos.Y + item.Height, 579 pos.Z 580 ); 581 } 582 public static Vector3D AlongZ(PackingPosition pos, PackingItem item) { 583 return new Vector3D( 584 pos.X, 585 pos.Y, 586 pos.Z + item.Depth 587 ); 588 } 589 590 public Vector3D Cross(Vector3D b) { 591 return new Vector3D( 592 Y * b.Z - Z * b.Y, 593 -X * b.Z + Z * b.X, 594 X * b.Y - Y * b.X 595 ); 596 } 597 598 public bool IsInside(PackingPosition pos, Tuple<int, int, int> rs) { 599 return X >= pos.X && X < pos.X + rs.Item1 600 && Y >= pos.Y && Y < pos.Y + rs.Item2 601 && Z >= pos.Z && Z < pos.Z + rs.Item3; 602 } 603 604 public static int operator *(Vector3D a, Vector3D b) { 605 return a.X * b.X + a.Y * b.Y + a.Z * b.Z; 606 } 607 public static Vector3D operator *(int a, Vector3D b) { 608 return new Vector3D(a * b.X, a * b.Y, a * b.Z); 609 } 610 public static Vector3D operator *(Vector3D a, int b) { 611 return new Vector3D(a.X * b, a.Y * b, a.Z * b); 612 } 613 public static Vector3D operator +(Vector3D a, Vector3D b) { 614 return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z); 615 } 616 public static Vector3D operator -(Vector3D a, Vector3D b) { 617 return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z); 618 } 619 620 public override bool Equals(object obj) { 621 var packPos = obj as PackingPosition; 622 if (packPos != null) { 623 return X == packPos.X && Y == packPos.Y && Z == packPos.Z; 624 } 625 var vec = obj as Vector3D; 626 if (vec != null) { 627 return X == vec.X && Y == vec.Y && Z == vec.Z; 628 } 629 return false; 630 } 631 } 632 633 // A line is given as a point and a directing vector 634 private class Line3D { 635 public Vector3D Point; 636 public Vector3D Direction; 637 638 public Line3D(Vector3D point, Vector3D direction) { 639 Point = point; 640 Direction = direction; 641 } 642 public Line3D(PackingPosition position, Vector3D direction) { 643 Point = new Vector3D(position); 644 Direction = direction; 645 } 646 647 public bool Intersects(Plane3D plane) { 648 return plane.Intersects(this); 649 } 650 651 public Vector3D Intersect(Plane3D plane) { 652 return plane.Intersect(this); 653 } 654 } 655 656 private enum Side { Top, Left, Bottom, Right, Front, Back } 657 // A plane is given as a point and two directing vectors 658 private class Plane3D { 659 public Vector3D Point { get; private set; } 660 public Vector3D Direction1 { get; private set; } 661 public Vector3D Direction2 { get; private set; } 662 public Vector3D Normal { get; private set; } 663 private int rhs; 664 665 public Plane3D(PackingShape bin, Side side) { 666 switch (side) { 667 case Side.Top: // ZX plane 668 Point = new Vector3D(0, bin.Height, 0); 669 Direction1 = new Vector3D(0, 0, bin.Depth); 670 Direction2 = new Vector3D(bin.Width, 0, 0); 671 break; 672 case Side.Left: // ZY plane 673 Point = new Vector3D(0, 0, 0); 674 Direction1 = new Vector3D(0, 0, bin.Depth); 675 Direction2 = new Vector3D(0, bin.Height, 0); 676 break; 677 case Side.Bottom: // XZ plane 678 Point = new Vector3D(0, 0, 0); 679 Direction1 = new Vector3D(bin.Width, 0, 0); 680 Direction2 = new Vector3D(0, 0, bin.Depth); 681 break; 682 case Side.Right: // YZ plane 683 Point = new Vector3D(bin.Width, 0, 0); 684 Direction1 = new Vector3D(0, bin.Height, 0); 685 Direction2 = new Vector3D(0, 0, bin.Depth); 686 break; 687 case Side.Front: // XY plane 688 Point = new Vector3D(0, 0, bin.Depth); 689 Direction1 = new Vector3D(bin.Width, 0, 0); 690 Direction2 = new Vector3D(0, bin.Height, 0); 691 break; 692 case Side.Back: // YX plane 693 Point = new Vector3D(0, 0, 0); 694 Direction1 = new Vector3D(0, bin.Height, 0); 695 Direction2 = new Vector3D(bin.Width, 0, 0); 696 break; 697 } 698 Normal = Direction1.Cross(Direction2); 699 rhs = 0; 700 } 701 702 public Plane3D(PackingPosition pos, PackingItem item, Side side) { 703 // the directing vectors are chosen such that normal always points outside the packing item 704 switch (side) { 705 case Side.Top: // ZX plane 706 Point = new Vector3D(pos.X, pos.Y + item.Height, pos.Z); 707 Direction1 = new Vector3D(0, 0, pos.Rotated ? item.Width : item.Depth); 708 Direction2 = new Vector3D(pos.Rotated ? item.Depth : item.Width, 0, 0); 709 break; 710 case Side.Left: // ZY plane 711 Point = new Vector3D(pos.X, pos.Y, pos.Z); 712 Direction1 = new Vector3D(0, 0, pos.Rotated ? item.Width : item.Depth); 713 Direction2 = new Vector3D(0, item.Height, 0); 714 break; 715 case Side.Bottom: // XZ plane 716 Point = new Vector3D(pos.X, pos.Y, pos.Z); 717 Direction1 = new Vector3D(pos.Rotated ? item.Depth : item.Width, 0, 0); 718 Direction2 = new Vector3D(0, 0, pos.Rotated ? item.Width : item.Depth); 719 break; 720 case Side.Right: // YZ plane 721 Point = new Vector3D(pos.X + (pos.Rotated ? item.Depth : item.Width), pos.Y, pos.Z); 722 Direction1 = new Vector3D(0, item.Height, 0); 723 Direction2 = new Vector3D(0, 0, pos.Rotated ? item.Width : item.Depth); 724 break; 725 case Side.Front: // XY plane 726 Point = new Vector3D(pos.X, pos.Y, pos.Z + (pos.Rotated ? item.Width : item.Depth)); 727 Direction1 = new Vector3D(pos.Rotated ? item.Depth : item.Width, 0, 0); 728 Direction2 = new Vector3D(0, item.Height, 0); 729 break; 730 case Side.Back: // YX plane 731 Point = new Vector3D(pos.X, pos.Y, pos.Z); 732 Direction1 = new Vector3D(0, item.Height, 0); 733 Direction2 = new Vector3D(pos.Rotated ? item.Depth : item.Width, 0, 0); 734 break; 735 } 736 Normal = Direction1.Cross(Direction2); 737 rhs = Normal.X * Point.X + Normal.Y * Point.Y + Normal.Z * Point.Z; 738 } 739 740 public bool IsElementOf(Vector3D point) { 741 return Normal.X * point.X + Normal.Y * point.Y + Normal.Z * point.Z == rhs; 742 } 743 744 public bool Intersects(Line3D line) { 745 return Intersect(line) != null; 746 } 747 748 public Vector3D Intersect(Line3D line) { 749 var denom = Normal * line.Direction; 750 if (denom == 0) { 751 // dir is perpendicular to the normal vector of the plane 752 // this means they intersect if p1 is element of the plane 753 // also the plane does not stretch infinitely, but is bound 754 // to the parallelogram spanned by the point and the two 755 // directing vectors 756 if (IsElementOf(line.Point) && IsWithinDirectionalVectors(line.Point)) 757 return line.Point; 758 else return null; 759 } 760 var intersect = line.Point + ((Normal * (Point - line.Point)) / denom) * line.Direction; 761 if (IsWithinDirectionalVectors(intersect)) return intersect; 762 return null; 763 } 764 765 public bool IsWithinDirectionalVectors(Vector3D point) { 766 return point.X >= Point.X && (Direction1.X + Direction2.X == 0 || (point.X < Point.X + Direction1.X || point.X < Point.X + Direction2.X)) 767 && point.Y >= Point.Y && (Direction1.Y + Direction2.Y == 0 || (point.Y < Point.Y + Direction1.Y || point.Y < Point.Y + Direction2.Y)) 768 && point.Z >= Point.Z && (Direction1.Z + Direction2.Z == 0 || (point.Z < Point.Z + Direction1.Z || point.Z < Point.Z + Direction2.Z)); 769 } 770 } 771 #endregion 765 772 766 } 773 767 } -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/RandomInstanceProvider.cs
r15418 r15454 26 26 using System.IO; 27 27 using System.Linq; 28 using System.Reflection; 28 29 using HeuristicLab.Common; 29 30 using HeuristicLab.Core; 30 31 using HeuristicLab.Problems.Instances; 31 32 using HeuristicLab.Random; 32 33 namespace HeuristicLab.Problems.BinPacking3D { 33 using HeuristicLab.Problems.BinPacking.Random; 34 35 namespace HeuristicLab.Problems.BinPacking3D.Instances { 34 36 // make sure that for each class we have a separate entry in the problem instance providers 37 35 38 public class RandomInstanceClass1Provider : RandomInstanceProvider { 36 public RandomInstanceClass1Provider() : base() { @class = 1; binWidth = binHeight = binDepth = 100; } 37 } 39 public RandomInstanceClass1Provider() : base(new SRand48()) { @class = 1; binWidth = binHeight = binDepth = 100; } 40 41 } 42 38 43 public class RandomInstanceClass2Provider : RandomInstanceProvider { 39 public RandomInstanceClass2Provider() : base() { @class = 2; binWidth = binHeight = binDepth = 100; } 44 public RandomInstanceClass2Provider() : base(new SRand48()) { @class = 2; binWidth = binHeight = binDepth = 100; } 45 40 46 } 41 47 public class RandomInstanceClass3Provider : RandomInstanceProvider { 42 public RandomInstanceClass3Provider() : base() { @class = 3; binWidth = binHeight = binDepth = 100; } 48 public RandomInstanceClass3Provider() : base(new SRand48()) { @class = 3; binWidth = binHeight = binDepth = 100; } 49 43 50 } 44 51 public class RandomInstanceClass4Provider : RandomInstanceProvider { 45 public RandomInstanceClass4Provider() : base() { @class = 4; binWidth = binHeight = binDepth = 100; } 52 public RandomInstanceClass4Provider() : base(new SRand48()) { @class = 4; binWidth = binHeight = binDepth = 100; } 53 46 54 } 47 55 public class RandomInstanceClass5Provider : RandomInstanceProvider { 48 public RandomInstanceClass5Provider() : base() { @class = 5; binWidth = binHeight = binDepth = 100; } 56 public RandomInstanceClass5Provider() : base(new SRand48()) { @class = 5; binWidth = binHeight = binDepth = 100; } 57 49 58 } 50 59 51 60 public class RandomInstanceClass6Provider : RandomInstanceProvider { 52 public RandomInstanceClass6Provider() : base( ) {61 public RandomInstanceClass6Provider() : base(new SRand48()) { 53 62 @class = 6; 54 63 binWidth = binHeight = binDepth = 10; 55 64 } 56 65 protected override void SampleItemParameters(IRandom rand, out int w, out int h, out int d) { 57 w = rand.Next(1, 1 1);58 h = rand.Next(1, 1 1);59 d = rand.Next(1, 1 1);66 w = rand.Next(1, 10); 67 h = rand.Next(1, 10); 68 d = rand.Next(1, 10); 60 69 } 61 70 } 62 71 public class RandomInstanceClass7Provider : RandomInstanceProvider { 63 public RandomInstanceClass7Provider() : base( ) {72 public RandomInstanceClass7Provider() : base(new SRand48()) { 64 73 @class = 7; 65 74 binWidth = binHeight = binDepth = 40; 66 75 } 67 76 protected override void SampleItemParameters(IRandom rand, out int w, out int h, out int d) { 68 w = rand.Next(1, 3 6);69 h = rand.Next(1, 3 6);70 d = rand.Next(1, 3 6);77 w = rand.Next(1, 35); 78 h = rand.Next(1, 35); 79 d = rand.Next(1, 35); 71 80 } 72 81 } 73 82 public class RandomInstanceClass8Provider : RandomInstanceProvider { 74 public RandomInstanceClass8Provider() : base( ) {83 public RandomInstanceClass8Provider() : base(new SRand48()) { 75 84 @class = 8; 76 85 binWidth = binHeight = binDepth = 100; 77 86 } 78 87 protected override void SampleItemParameters(IRandom rand, out int w, out int h, out int d) { 79 w = rand.Next(1, 10 1);80 h = rand.Next(1, 10 1);81 d = rand.Next(1, 10 1);88 w = rand.Next(1, 100); 89 h = rand.Next(1, 100); 90 d = rand.Next(1, 100); 82 91 } 83 92 } … … 88 97 public abstract class RandomInstanceProvider : ProblemInstanceProvider<BPPData>, IProblemInstanceProvider<BPPData> { 89 98 99 /// <summary> 100 /// Number of created test items. This items are used for packing them into the bin 101 /// </summary> 102 private readonly int[] _numberOfGeneratedTestItems = new int[] { 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 150, 200 }; 103 104 /// <summary> 105 /// Number of instance for which should be created for each instance 106 /// </summary> 107 private readonly int _numberOfGeneratedInstances; 108 109 /// <summary> 110 /// Random generator for creating random packing items. 111 /// </summary> 112 private readonly IRandom _randomGenerator; 90 113 91 114 … … 93 116 protected int binWidth, binHeight, binDepth; 94 117 118 #region Common information for displaying on the ui 119 95 120 public override string Name { 96 121 get { return string.Format("Martello, Pisinger, Vigo (class={0})", @class); } … … 109 134 } 110 135 111 public RandomInstanceProvider() : base() { } 112 136 #endregion 137 138 139 public RandomInstanceProvider(IRandom randomGenerator, int numberOfGeneratedInstances = 10, int[] numberOfGeneratedTestItems = null) : base() { 140 _numberOfGeneratedInstances = numberOfGeneratedInstances; 141 if (numberOfGeneratedTestItems != null) { 142 _numberOfGeneratedTestItems = numberOfGeneratedTestItems; 143 } 144 _randomGenerator = randomGenerator; 145 } 146 147 148 /// <summary> 149 /// Returns a collection of data descriptors. Each descriptor contains the seed for the random generator. 150 /// </summary> 151 /// <returns></returns> 113 152 public override IEnumerable<IDataDescriptor> GetDataDescriptors() { 114 153 // 10 classes 115 var rand = new MersenneTwister(1234); // fixed seed to makes sure that instances are always the same 116 foreach (int numItems in new int[] { 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90 }) { 117 // get class parameters 118 // generate 30 different instances for each class 119 foreach (int instance in Enumerable.Range(1, 30)) { 154 foreach (int numItems in _numberOfGeneratedTestItems) { 155 for (int instance = 1; instance <= _numberOfGeneratedInstances; instance++) { 120 156 string name = string.Format("n={0}-id={1:00} (class={2})", numItems, instance, @class); 121 var dd = new RandomDataDescriptor(name, name, numItems, @class, seed: rand.Next()); 122 yield return dd; 157 /* As in the test programm of Silvano Martello, David Pisinger, Daniele Vigo given, 158 * the seed of the instance provider will be calculated by adding the number of generated items and teh instance number. 159 * This guarantees that the instances will always be the same 160 */ 161 yield return new RandomDataDescriptor(name, name, numItems, @class, seed: numItems + instance); 123 162 } 124 163 } 125 164 } 165 126 166 127 167 public override BPPData LoadData(IDataDescriptor dd) { 128 168 var randDd = dd as RandomDataDescriptor; 129 if (randDd == null) 169 if (randDd == null) { 130 170 throw new NotSupportedException("Cannot load data descriptor " + dd); 171 } 131 172 132 173 var data = new BPPData() { … … 134 175 Items = new PackingItem[randDd.NumItems] 135 176 }; 136 var instanceRand = new MersenneTwister((uint)randDd.Seed);177 _randomGenerator.Reset(randDd.Seed); 137 178 for (int i = 0; i < randDd.NumItems; i++) { 138 179 int w, h, d; 139 SampleItemParameters( instanceRand, out w, out h, out d);180 SampleItemParameters(_randomGenerator, out w, out h, out d); 140 181 data.Items[i] = new PackingItem(w, h, d, data.BinShape); 141 182 } … … 143 184 } 144 185 145 // default implementation for class 1 .. 5 186 187 /// <summary> 188 /// Generates the dimensions for a item by using the given random generator 189 /// </summary> 190 /// <param name="rand">Given random generator</param> 191 /// <param name="w">Calculated width of the item</param> 192 /// <param name="h">Calculated height of the item</param> 193 /// <param name="d">Calculated depth of the item</param> 146 194 protected virtual void SampleItemParameters(IRandom rand, out int w, out int h, out int d) { 147 // for classes 1 - 5148 195 Contract.Assert(@class >= 1 && @class <= 5); 149 var weights = new double[] { 0.1, 0.1, 0.1, 0.1, 0.1 };196 /*var weights = new double[] { 0.1, 0.1, 0.1, 0.1, 0.1 }; 150 197 weights[@class - 1] = 0.6; 151 198 var type = Enumerable.Range(1, 5).SampleProportional(rand, 1, weights).First(); 152 153 int minW, maxW; 154 int minH, maxH; 155 int minD, maxD; 156 GetItemParameters(type, rand, binWidth, binHeight, binDepth, 157 out minW, out maxW, out minH, out maxH, out minD, out maxD); 158 159 w = rand.Next(minW, maxW + 1); 160 h = rand.Next(minH, maxH + 1); 161 d = rand.Next(minD, maxD + 1); 162 } 163 164 private void GetItemParameters(int type, IRandom rand, 165 int w, int h, int d, 166 out int minW, out int maxW, out int minH, out int maxH, out int minD, out int maxD) { 199 */ 200 201 // as by Martello and Vigo 202 int type = @class; 203 if (type <= 5) { 204 var t = rand.Next(1, 10); 205 if (t <= 5) { 206 type = t; 207 } 208 } 209 167 210 switch (type) { 168 case 1: { 169 minW = 1; 170 maxW = w / 2; // integer division on purpose (see paper) 171 minH = h * 2 / 3; 172 maxH = h; 173 minD = d * 2 / 3; 174 maxD = d; 175 break; 176 } 177 case 2: { 178 minW = w * 2 / 3; 179 maxW = w; 180 minH = 1; 181 maxH = h / 2; 182 minD = d * 2 / 3; 183 maxD = d; 184 break; 185 } 186 case 3: { 187 minW = w * 2 / 3; 188 maxW = w; 189 minH = h * 2 / 3; 190 maxH = h; 191 minD = 1; 192 maxD = d / 2; 193 break; 194 } 195 case 4: { 196 minW = w / 2; 197 maxW = w; 198 minH = h / 2; 199 maxH = h; 200 minD = d / 2; 201 maxD = d; 202 break; 203 } 204 case 5: { 205 minW = 1; 206 maxW = w / 2; 207 minH = 1; 208 maxH = h / 2; 209 minD = 1; 210 maxD = d / 2; 211 break; 212 } 213 default: { 214 throw new InvalidProgramException(); 215 } 216 } 217 } 211 case 1: 212 CreateInstanceDimensionsType1(rand, out w, out h, out d); 213 break; 214 case 2: 215 CreateInstanceDimensionsType2(rand, out w, out h, out d); 216 break; 217 case 3: 218 CreateInstanceDimensionsType3(rand, out w, out h, out d); 219 break; 220 case 4: 221 CreateInstanceDimensionsType4(rand, out w, out h, out d); 222 break; 223 case 5: 224 CreateInstanceDimensionsType5(rand, out w, out h, out d); 225 break; 226 default: 227 throw new InvalidProgramException(); 228 } 229 } 230 231 232 #region Instance dimensions generators for type 1 - 5 233 private void CreateInstanceDimensionsType1(IRandom rand, out int w, out int h, out int d) { 234 w = rand.Next(1, binWidth / 2); 235 h = rand.Next((binHeight * 2) / 3, binHeight); 236 d = rand.Next((binDepth * 2) / 3, binDepth); 237 } 238 239 private void CreateInstanceDimensionsType2(IRandom rand, out int w, out int h, out int d) { 240 w = rand.Next(((binWidth * 2) / 3), binWidth); 241 h = rand.Next(1, binHeight / 2); 242 d = rand.Next(((binDepth * 2) / 3), binDepth); 243 } 244 245 private void CreateInstanceDimensionsType3(IRandom rand, out int w, out int h, out int d) { 246 w = rand.Next(((binWidth * 2) / 3), binWidth); 247 h = rand.Next(((binHeight * 2) / 3), binHeight); 248 d = rand.Next(1, binDepth / 2); 249 } 250 private void CreateInstanceDimensionsType4(IRandom rand, out int w, out int h, out int d) { 251 w = rand.Next(binWidth / 2, binWidth); 252 h = rand.Next(binHeight / 2, binHeight); 253 d = rand.Next(binDepth / 2, binDepth); 254 } 255 private void CreateInstanceDimensionsType5(IRandom rand, out int w, out int h, out int d) { 256 w = rand.Next(1, binWidth / 2); 257 h = rand.Next(1, binHeight / 2); 258 d = rand.Next(1, binDepth / 2); 259 } 260 261 #endregion 262 263 218 264 219 265 public override bool CanImportData { … … 242 288 else 243 289 writer.WriteLine("{0,-5} {1,-5} {2,-5}", instance.Items[i].Width, instance.Items[i].Height, instance.Items[i].Depth); 244 245 290 } 246 291 writer.Flush(); 247 292 } 248 293 } 249 250 294 } 251 295 } -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs
r15304 r15454 103 103 #region IComparable<PackingPosition> Members 104 104 105 /// <summary> 106 /// Compares two packing positions by their coordinates. 107 /// The order of comparing is z -> x -> y. 108 /// </summary> 109 /// <param name="other"></param> 110 /// <returns></returns> 105 111 public int CompareTo(PackingPosition other) { 106 112 int result = Z.CompareTo(other.Z); -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/Algorithms/3D/ExtremePointAlgorithm.cs
r15229 r15454 32 32 using HeuristicLab.Parameters; 33 33 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 34 using HeuristicLab.Problems.BinPacking3D.Packer; 34 35 35 36 namespace HeuristicLab.Problems.BinPacking3D { 36 37 37 38 public enum SortingMethod { All, Given, VolumeHeight, HeightVolume, AreaHeight, HeightArea, ClusteredAreaHeight, ClusteredHeightArea } 38 39 public enum FittingMethod { All, FirstFit, ResidualSpaceBestFit, FreeVolumeBestFit } … … 86 87 Parameters.Add(fittingMethodParameter = new ValueParameter<EnumValue<FittingMethod>>("FittingMethod", "Which method to fit should be used.", new EnumValue<FittingMethod>(FittingMethod.All))); 87 88 Parameters.Add(deltaParameter = new ValueParameter<PercentValue>("Delta", "[1;100]% Clustered sorting methods use a delta parameter to determine the clusters.", new PercentValue(.1))); 88 89 89 90 Problem = new PermutationProblem(); 90 91 } … … 93 94 return new ExtremePointAlgorithm(this, cloner); 94 95 } 95 96 96 97 [StorableHook(HookType.AfterDeserialization)] 97 98 private void AfterDeserialization() { 98 99 } 99 100 101 /// <summary> 102 /// Runs the extreme point algorithm and adds the results to the property <see cref="Result"/> 103 /// </summary> 104 /// <param name="token"></param> 100 105 protected override void Run(CancellationToken token) { 101 106 var items = Problem.Items; … … 109 114 fitting = Enum.GetValues(typeof(FittingMethod)).Cast<FittingMethod>().Where(x => x != FittingMethod.All).ToArray(); 110 115 } 116 117 // 111 118 var result = GetBest(bin, items, sorting, fitting, token); 112 if (result == null) throw new InvalidOperationException("No result obtained!"); 113 114 Results.Add(new Result("Best Solution", 115 "The best found solution", 116 result.Item1)); 117 Results.Add(new Result("Best Solution Quality", 118 "The quality of the best found solution according to the evaluator", 119 new DoubleValue(result.Item2))); 119 if (result == null) { 120 throw new InvalidOperationException("No result obtained!"); 121 } 122 123 Results.Add(new Result("Best Solution", "The best found solution", result.Item1)); 124 Results.Add(new Result("Best Solution Quality", "The quality of the best found solution according to the evaluator", new DoubleValue(result.Item2))); 120 125 121 126 var binUtil = new BinUtilizationEvaluator(); … … 128 133 new PercentValue(Math.Round(binUtil.Evaluate(result.Item1), 3)))); 129 134 130 if (result.Item3.HasValue && sorting.Length > 1) 135 if (result.Item3.HasValue && sorting.Length > 1) { 131 136 Results.Add(new Result("Best Sorting Method", 132 137 "The sorting method that found the best solution", 133 138 new EnumValue<SortingMethod>(result.Item3.Value))); 134 if (result.Item4.HasValue && fitting.Length > 1) 139 } 140 141 if (result.Item4.HasValue && fitting.Length > 1) { 135 142 Results.Add(new Result("Best Fitting Method", 136 143 "The fitting method that found the best solution", 137 144 new EnumValue<FittingMethod>(result.Item4.Value))); 145 } 138 146 } 139 147 … … 146 154 foreach (var sort in sortings) { 147 155 var result = Optimize(bin, items, sort, fit, DeltaParameter.Value.Value, Problem.UseStackingConstraints, Problem.SolutionEvaluator, token); 148 if (double.IsNaN(result.Item2) || double.IsInfinity(result.Item2)) continue; 149 if (double.IsNaN(best) 150 || Problem.Maximization && result.Item2 > best 151 || !Problem.Maximization && result.Item2 < best) { 156 if (double.IsNaN(result.Item2) || double.IsInfinity(result.Item2)) { 157 continue; 158 } 159 160 if (double.IsNaN(best) || Problem.Maximization && result.Item2 > best || !Problem.Maximization && result.Item2 < best) { 152 161 bestSolution = result.Item1; 153 162 best = result.Item2; … … 155 164 bestFitting = fit; 156 165 } 157 if (token.IsCancellationRequested) return Tuple.Create(bestSolution, best, bestSorting, bestFitting); 166 if (token.IsCancellationRequested) { 167 return Tuple.Create(bestSolution, best, bestSorting, bestFitting); 168 } 158 169 } 159 170 } 160 if (double.IsNaN(best)) return null; 171 if (double.IsNaN(best)) { 172 return null; 173 } 161 174 return Tuple.Create(bestSolution, best, bestSorting, bestFitting); 162 175 } 163 176 164 177 private static Tuple<Solution, double> Optimize(PackingShape bin, IList<PackingItem> items, SortingMethod sorting, FittingMethod fitting, double delta, bool stackingConstraints, IEvaluator evaluator, CancellationToken token) { 178 Permutation sortedItems = SortItemsBySortingMethod(bin, items, sorting, delta); 179 180 if (false) {// alt 181 ExtremePointPermutationDecoderBase decoder = GetDecoderByFittingMethod(fitting); 182 var sol = decoder.Decode(sortedItems, bin, items, stackingConstraints); 183 var fit = evaluator.Evaluate(sol); 184 185 return Tuple.Create(sol, fit); 186 } else { 187 Decoder.ExtremePointPermutationDecoder decoder = new Decoder.ExtremePointPermutationDecoder(GetBinPackerByFittingMethod(fitting, sortedItems, bin, items, stackingConstraints)); 188 189 var sol = decoder.Decode(sortedItems, bin, items, stackingConstraints); 190 var fit = evaluator.Evaluate(sol); 191 192 return Tuple.Create(sol, fit); 193 } 194 195 196 197 } 198 199 200 201 private static BinPacker GetBinPackerByFittingMethod(FittingMethod fittingMethod, Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) { 202 BinPacker binPacker = null; 203 switch (fittingMethod) { 204 case FittingMethod.FirstFit: 205 binPacker = new BinPackerFirstFit(sortedItems, binShape, items, useStackingConstraints); 206 break; 207 case FittingMethod.FreeVolumeBestFit: 208 binPacker = new BinPackerFreeVolumeBestFit(sortedItems, binShape, items, useStackingConstraints); 209 break; 210 case FittingMethod.ResidualSpaceBestFit: 211 binPacker = new BinPackerResidualSpaceBestFit(sortedItems, binShape, items, useStackingConstraints); 212 break; 213 default: 214 throw new ArgumentException("Unknown fitting method: " + fittingMethod); 215 } 216 return binPacker; 217 } 218 219 /// <summary> 220 /// Returns a new permutation of the given items depending on the sorting method 221 /// </summary> 222 /// <param name="bin"></param> 223 /// <param name="items"></param> 224 /// <param name="sortingMethod"></param> 225 /// <param name="delta"></param> 226 /// <returns></returns> 227 private static Permutation SortItemsBySortingMethod(PackingShape bin, IList<PackingItem> items, SortingMethod sortingMethod, double delta) { 165 228 Permutation sorted = null; 166 switch (sorting ) {229 switch (sortingMethod) { 167 230 case SortingMethod.Given: 168 231 sorted = new Permutation(PermutationTypes.Absolute, Enumerable.Range(0, items.Count).ToArray()); … … 216 279 .Select(x => x.Index).ToArray()); 217 280 break; 218 default: throw new ArgumentException("Unknown sorting method: " + sorting); 219 } 220 281 default: 282 throw new ArgumentException("Unknown sorting method: " + sortingMethod); 283 } 284 return sorted; 285 } 286 287 /// <summary> 288 /// Returns a decoder depending on the given fitting method 289 /// </summary> 290 /// <param name="fittingMethod"></param> 291 /// <returns></returns> 292 private static ExtremePointPermutationDecoderBase GetDecoderByFittingMethod(FittingMethod fittingMethod) { 221 293 ExtremePointPermutationDecoderBase decoder = null; 222 switch (fitting ) {294 switch (fittingMethod) { 223 295 case FittingMethod.FirstFit: 224 296 decoder = new ExtremePointPermutationDecoder(); … … 230 302 decoder = new ResidualSpaceBestFitExtremePointPermutationDecoder(); 231 303 break; 232 default: throw new ArgumentException("Unknown fitting method: " + fitting); 233 } 234 235 var sol = decoder.Decode(sorted, bin, items, stackingConstraints); 236 var fit = evaluator.Evaluate(sol); 237 238 return Tuple.Create(sol, fit); 304 default: 305 throw new ArgumentException("Unknown fitting method: " + fittingMethod); 306 } 307 return decoder; 239 308 } 240 309 } -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/BinPacking.cs
r15304 r15454 37 37 #region Properties 38 38 [Storable] 39 40 //key = item id 39 41 public ObservableDictionary<int, TPos> Positions { get; private set; } 40 42 41 43 [Storable] 44 //key = item id 42 45 public ObservableDictionary<int, TItem> Items { get; private set; } 43 46 … … 138 141 return false; 139 142 } 143 144 /// <summary> 145 /// 146 /// </summary> 147 /// <param name="item"></param> 148 /// <param name="position"></param> 149 /// <param name="stackingConstraints"></param> 150 /// <returns></returns> 140 151 public virtual bool IsPositionFeasible(TItem item, TPos position, bool stackingConstraints) { 141 //In this case feasability is defined as following: 1. the item fits into the bin-borders; 2. the point is supported by something; 3. the item does not collide with another already packed item 152 //In this case feasability is defined as following: 153 //1. the item fits into the bin-borders; 154 //2. the point is supported by something; 155 //3. the item does not collide with another already packed item 142 156 if (!BinShape.Encloses(position, item)) 143 157 return false; -
branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/HeuristicLab.Problems.BinPacking-3.3.csproj
r15418 r15454 103 103 <Compile Include="2D\ProblemBase.cs" /> 104 104 <Compile Include="2D\Solution.cs" /> 105 <Compile Include="3D\Packer\BinPacker.cs" /> 106 <Compile Include="3D\Packer\BinPackerFirstFit.cs" /> 105 107 <Compile Include="3D\BinPacking3D.cs" /> 108 <Compile Include="3D\Decoder\ExtremePointPermutationDecoder.cs" /> 106 109 <Compile Include="3D\Evaluators\BinUtilizationEvaluator.cs" /> 107 110 <Compile Include="3D\Evaluators\PackingRatioEvaluator.cs" /> 108 <Compile Include="3D\Instances\RandomInstanceProviderWithSRand.cs" /> 111 <Compile Include="3D\Instances\RandomInstanceProvider.cs" /> 112 <Compile Include="3D\Geometry\Line3D.cs" /> 113 <Compile Include="3D\Geometry\Plane3D.cs" /> 114 <Compile Include="3D\Geometry\Vector3D.cs" /> 115 <Compile Include="3D\Packer\BinPackerFreeVolumeBestFit.cs" /> 116 <Compile Include="3D\Packer\BinPackerResidualSpaceBestFit.cs" /> 109 117 <Compile Include="Algorithms\3D\ExtremePointAlgorithm.cs" /> 110 118 <Compile Include="3D\Instances\ThreeDInstanceDescriptor.cs" /> … … 112 120 <Compile Include="3D\Instances\RandomDataDescriptor.cs" /> 113 121 <Compile Include="3D\Instances\RealWorldContainerPackingInstanceProvider.cs" /> 114 <Compile Include="3D\Instances\RandomInstanceProvider.cs" />115 122 <Compile Include="3D\Instances\ThreeDInstanceParser.cs" /> 116 123 <Compile Include="3D\IntegerVectorEncoding\BottomLeftIntegerVectorDecoder.cs" /> … … 150 157 <Compile Include="Plugin.cs" /> 151 158 <Compile Include="Properties\AssemblyInfo.cs" /> 159 <Compile Include="Random\SRand48.cs" /> 152 160 </ItemGroup> 153 161 <ItemGroup> -
branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/AlgorithmTest.cs
r15424 r15454 3 3 using Microsoft.VisualStudio.TestTools.UnitTesting; 4 4 using HeuristicLab.Problems.BinPacking3D; 5 using HeuristicLab.Problems.BinPacking3D.Instances; 5 6 using System.Collections.Generic; 6 7 using System.Linq; … … 30 31 31 32 var referenceItemLists = ReadReferenceItemLists(); 32 TestRandomInstanceProviderByClass(new RandomInstanceClass1Provider WithSRand(), referenceItemLists);33 TestRandomInstanceProviderByClass(new RandomInstanceClass2Provider WithSRand(), referenceItemLists);34 TestRandomInstanceProviderByClass(new RandomInstanceClass3Provider WithSRand(), referenceItemLists);35 TestRandomInstanceProviderByClass(new RandomInstanceClass4Provider WithSRand(), referenceItemLists);36 TestRandomInstanceProviderByClass(new RandomInstanceClass5Provider WithSRand(), referenceItemLists);37 TestRandomInstanceProviderByClass(new RandomInstanceClass6Provider WithSRand(), referenceItemLists);38 TestRandomInstanceProviderByClass(new RandomInstanceClass7Provider WithSRand(), referenceItemLists);39 TestRandomInstanceProviderByClass(new RandomInstanceClass8Provider WithSRand(), referenceItemLists);33 TestRandomInstanceProviderByClass(new RandomInstanceClass1Provider(), referenceItemLists); 34 TestRandomInstanceProviderByClass(new RandomInstanceClass2Provider(), referenceItemLists); 35 TestRandomInstanceProviderByClass(new RandomInstanceClass3Provider(), referenceItemLists); 36 TestRandomInstanceProviderByClass(new RandomInstanceClass4Provider(), referenceItemLists); 37 TestRandomInstanceProviderByClass(new RandomInstanceClass5Provider(), referenceItemLists); 38 TestRandomInstanceProviderByClass(new RandomInstanceClass6Provider(), referenceItemLists); 39 TestRandomInstanceProviderByClass(new RandomInstanceClass7Provider(), referenceItemLists); 40 TestRandomInstanceProviderByClass(new RandomInstanceClass8Provider(), referenceItemLists); 40 41 41 42 } … … 79 80 } 80 81 81 private void TestRandomInstanceProviderByClass(RandomInstanceProvider WithSRandrandomInstanceProvider, IDictionary<string, List<Dimension>> referenceItems) {82 private void TestRandomInstanceProviderByClass(RandomInstanceProvider randomInstanceProvider, IDictionary<string, List<Dimension>> referenceItems) { 82 83 83 84 var dataDescriptors = randomInstanceProvider.GetDataDescriptors(); … … 111 112 [TestCategory("Problems.BinPacking")] 112 113 public void TestExtremePointAlgorithmClass1() { 113 TestExtremePointAlgorithm(new RandomInstanceClass1Provider WithSRand(), 1);114 TestExtremePointAlgorithm(new RandomInstanceClass1Provider(), 1); 114 115 } 115 116 … … 117 118 [TestCategory("Problems.BinPacking")] 118 119 public void TestExtremePointAlgorithmClass2() { 119 TestExtremePointAlgorithm(new RandomInstanceClass2Provider WithSRand(), 2);120 TestExtremePointAlgorithm(new RandomInstanceClass2Provider(), 2); 120 121 } 121 122 … … 123 124 [TestCategory("Problems.BinPacking")] 124 125 public void TestExtremePointAlgorithmClass3() { 125 TestExtremePointAlgorithm(new RandomInstanceClass3Provider WithSRand(), 3);126 TestExtremePointAlgorithm(new RandomInstanceClass3Provider(), 3); 126 127 } 127 128 … … 129 130 [TestCategory("Problems.BinPacking")] 130 131 public void TestExtremePointAlgorithmClass4() { 131 TestExtremePointAlgorithm(new RandomInstanceClass4Provider WithSRand(), 4);132 TestExtremePointAlgorithm(new RandomInstanceClass4Provider(), 4); 132 133 } 133 134 … … 135 136 [TestCategory("Problems.BinPacking")] 136 137 public void TestExtremePointAlgorithmClass5() { 137 TestExtremePointAlgorithm(new RandomInstanceClass5Provider WithSRand(), 5);138 TestExtremePointAlgorithm(new RandomInstanceClass5Provider(), 5); 138 139 } 139 140 … … 141 142 [TestCategory("Problems.BinPacking")] 142 143 public void TestExtremePointAlgorithmClass6() { 143 TestExtremePointAlgorithm(new RandomInstanceClass6Provider WithSRand(), 6);144 TestExtremePointAlgorithm(new RandomInstanceClass6Provider(), 6); 144 145 } 145 146 … … 147 148 [TestCategory("Problems.BinPacking")] 148 149 public void TestExtremePointAlgorithmClass7() { 149 TestExtremePointAlgorithm(new RandomInstanceClass7Provider WithSRand(), 7);150 TestExtremePointAlgorithm(new RandomInstanceClass7Provider(), 7); 150 151 } 151 152 … … 153 154 [TestCategory("Problems.BinPacking")] 154 155 public void TestExtremePointAlgorithmClass8() { 155 TestExtremePointAlgorithm(new RandomInstanceClass8Provider WithSRand(), 8);156 } 157 158 private void TestExtremePointAlgorithm(RandomInstanceProvider WithSRandrandomInstanceProvider, int @class) {156 TestExtremePointAlgorithm(new RandomInstanceClass8Provider(), 8); 157 } 158 159 private void TestExtremePointAlgorithm(RandomInstanceProvider randomInstanceProvider, int @class) { 159 160 foreach (SortingMethod sortingMethod in Enum.GetValues(typeof(SortingMethod))) { 160 161 //foreach (FittingMethod fittingMethod in Enum.GetValues(typeof(FittingMethod))) { … … 168 169 169 170 170 private void TestExtremePointAlgorithmByParameters(RandomInstanceProvider WithSRandrandomInstanceProvider, int @class, SortingMethod sortingMethod, FittingMethod fittingMethod) {171 private void TestExtremePointAlgorithmByParameters(RandomInstanceProvider randomInstanceProvider, int @class, SortingMethod sortingMethod, FittingMethod fittingMethod) { 171 172 var dataDescriptors = randomInstanceProvider.GetDataDescriptors(); 172 173 var referenceValues = GetReferenceAlgorithmValues();
Note: See TracChangeset
for help on using the changeset viewer.