/// <summary> /// Load a new empty container with the supplied list of boxes. /// </summary> /// <param name="boxes">The boxes to be loaded into the container</param> /// <param name="sw">The output log file</param> private static void LoadContainer(List<Box> boxes, StreamWriter sw) { // Setup an empty container with the desired size. Container container = new Container(ContainerWidthX, ContainerHeightY, ContainerDepthZ); LargestAreaFirstFit laff = new LargestAreaFirstFit(boxes, container); container = laff.Calculate(); // Show where the boxes are now located in the container ShowContainer(container, sw); }
/// <summary> /// Try to fit the box inside the container. /// </summary> /// <param name="box">The box to fit into the container</param> /// <param name="container">The container</param> /// <returns>true if it has been fitted; false if no space for the box</returns> private bool TryToFitBoxInsideContainer(Box box, Container container) { int originX, originY, originZ; bool boxFitted = false; // Scan the floor of the container first. for (originY = 0; originY < container.HeightY; originY++) { for (originZ = 0; originZ < container.DepthZ; originZ++) { for (originX = 0; originX < container.WidthX; originX++) { if (container.Occupied[originX, originY, originZ] == '.') { // This point (cell) in the container is empty so // see if the whole box would fit within the bounds of // the container at this position. if (originX + box.WidthX > container.WidthX || originZ + box.DepthZ > container.DepthZ || originY + box.HeightY > container.HeightY) { break; } // OK, so the box doesn't extend beyond the bounds of the // container but are any of the cells it would occupy // already taken by another box? If there are, this box // won't fit here. int yScan = 0, xScan = 0, zScan = 0; bool fits = true; // assume it fits unless we find otherwise for (yScan = originY; yScan < originY + box.HeightY; yScan++) { for (zScan = originZ; zScan < originZ + box.DepthZ; zScan++) { for (xScan = originX; xScan < originX + box.WidthX; xScan++) { if (container.Occupied[xScan, yScan, zScan] != '.') { fits = false; break; } } if (!fits) break; } if (!fits) break; } // If the box fits here, add it to the container. if (fits) { for (yScan = originY; yScan < originY + box.HeightY; yScan++) { for (zScan = originZ; zScan < originZ + box.DepthZ; zScan++) { for (xScan = originX; xScan < originX + box.WidthX; xScan++) { container.Occupied[xScan, yScan, zScan] = box.Identifier; } } } boxFitted = true; } if (boxFitted) break; } } if (boxFitted) break; } if (boxFitted) break; } // If the box couldn't be fitted, add it to a list so we can show the caller // which boxes have been left out. if (!boxFitted) { container.BoxesNotFitted.Add(box); } // The caller might want to know if the box fitted into the container or not. return boxFitted; }
/// <summary> /// Display and write out to a text file how the boxes have been loaded into /// the container. /// </summary> /// <param name="container">The loaded container</param> /// <param name="sw">The output log file</param> private static void ShowContainer(Container container, StreamWriter sw) { // Show how the boxes have fitted into the container. int occupiedCellCount = 0; int totalCellCount = container.WidthX * container.HeightY * container.DepthZ; for (int y = 0; y < container.HeightY; y++) { Console.WriteLine("Plane Y={0}", y); sw.WriteLine("Plane Y={0}", y); for (int z = 0; z < container.DepthZ; z++) { for (int x = 0; x < container.WidthX; x++) { if (container.Occupied[x, y, z] == '.') { Console.Write(". "); sw.Write(". "); } else { occupiedCellCount++; Console.Write("{0} ", container.Occupied[x, y, z]); sw.Write("{0} ", container.Occupied[x, y, z]); } } Console.WriteLine(); sw.WriteLine(); } Console.WriteLine(); sw.WriteLine(); } // Show whether any boxes couldn't be fitted into the container. if (container.BoxesNotFitted.Count > 0) { string notFitted = string.Empty; for (int i = 0; i < container.BoxesNotFitted.Count; i++) { if (i == 0) { notFitted += container.BoxesNotFitted[i].Identifier.ToString(); } else { notFitted += string.Format(", {0}", container.BoxesNotFitted[i].Identifier); } } Console.WriteLine("Boxes that couldn't be fitted are : {0}", notFitted); Console.WriteLine(); sw.WriteLine("Boxes that couldn't be fitted are : {0}", notFitted); sw.WriteLine(); } // Show how much of the container is filled / empty double fillRate = occupiedCellCount * 100 / totalCellCount; Console.WriteLine("Percentage full = {0:0.0}%", fillRate); sw.WriteLine("Percentage full = {0:0.0}%", fillRate); Console.WriteLine(); sw.WriteLine(); // Leave a blank line between tests. Console.WriteLine(string.Empty.PadRight(80, '=')); sw.WriteLine(string.Empty.PadRight(80, '=')); }
/// <summary> /// Constructs an instance of the object with the list of boxes /// and the container they should fit into. /// </summary> /// <param name="boxes">The boxes to fit into the container</param> /// <param name="container">The container</param> public LargestAreaFirstFit(List<Box> boxes, Container container) { this.boxes = boxes; this.container = container; }