/// <summary> /// AFTER PACKING OF EACH BOX, 100% PACKING CONDITION IS CHECKED /// </summary> private void VolumeCheck(int cboxi, decimal cboxx, decimal cboxy, decimal cboxz, bool packingbest , ref bool hundredpercent) { Cuboid bi = boxList[cboxi]; bi.SetPacked(cboxx, cboxy, cboxz); packedvolume += bi.Vol; packednumbox++; if (packingbest) { bi.WriteToFile(fso, best_variant, 0); } else if (packedvolume == pallet.Vol || packedvolume == total_box_volume) { packing = false; hundredpercent = true; } }
/// <summary> /// FINDS THE MOST PROPER BOXES BY LOOKING AT ALL SIX POSSIBLE ORIENTATIONS, /// EMPTY SPACE GIVEN, ADJACENT BOXES, AND PALLET LIMITS /// </summary> private void Find_box(decimal hmx, decimal hy, decimal hmy, decimal hz, decimal hmz, ref decimal cboxi, ref decimal cboxx, ref decimal cboxy, ref decimal cboxz) { decimal boxi = 0; decimal boxx = 0, boxy = 0, boxz = 0; decimal bboxi = 0; decimal bboxx = 0, bboxy = 0, bboxz = 0; decimal bfx = decimal.MaxValue, bfy = decimal.MaxValue, bfz = decimal.MaxValue; decimal bbfx = decimal.MaxValue, bbfy = decimal.MaxValue, bbfz = decimal.MaxValue; boxi = 0; bboxi = 0; for (int y = 0; y < boxList.Count; y += boxList[y].N) { int x = y; for (x = y; x < y + boxList[y].N - 1; x++) { if (!boxList[x].Is_packed) { break; } } if (boxList[x].Is_packed) { continue; } if (x >= boxList.Count) { return; } Cuboid bi = boxList[x]; // 1 2 3 Analyse_box(x, hmx, hy, hmy, hz, hmz, bi.Dim1, bi.Dim2, bi.Dim3 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); if ((bi.Dim1 == bi.Dim3) && (bi.Dim3 == bi.Dim2)) { continue; } // 1 3 2 Analyse_box(x, hmx, hy, hmy, hz, hmz , bi.Dim1, bi.Dim3, bi.Dim2 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); // 2 1 3 Analyse_box(x, hmx, hy, hmy, hz, hmz , bi.Dim2, bi.Dim1, bi.Dim3 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); // 2 3 1 Analyse_box(x, hmx, hy, hmy, hz, hmz , bi.Dim2, bi.Dim3, bi.Dim1 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); // 3 1 2 Analyse_box(x, hmx, hy, hmy, hz, hmz , bi.Dim3, bi.Dim1, bi.Dim2 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); // 3 2 1 Analyse_box(x, hmx, hy, hmy, hz, hmz , bi.Dim3, bi.Dim2, bi.Dim1 , ref bfx, ref bfy, ref bfz , ref bbfx, ref bbfy, ref bbfz , ref boxi, ref boxx, ref boxy, ref boxz , ref bboxi, ref bboxx, ref bboxy, ref bboxz); } CheckFound(ref cboxi, ref cboxx, ref cboxy, ref cboxz , boxi, boxx, boxy, boxz , bboxi, bboxx, bboxy, bboxz); }
///---------------------------------------------------------------------------- /// FINDS THE MOST PROPER LAYER HEIGHT BY LOOKING AT THE UNPACKED BOXES AND THE /// REMAINING EMPTY SPACE AVAILABLE ///---------------------------------------------------------------------------- private int Find_layer(decimal thickness, PalletInfo p) { decimal exdim = 0, dimdif = 0, dimen2 = 0, dimen3 = 0; decimal layereval = 0, eval = decimal.MaxValue; layerThickness = 0; for (int x = 0; x < boxList.Count; x++) { Cuboid bi = boxList[x]; if (bi.Is_packed) { continue; } for (int y = 1; y <= 3; y++) { switch (y) { case 1: exdim = bi.Dim1; dimen2 = bi.Dim2; dimen3 = bi.Dim3; break; case 2: exdim = bi.Dim2; dimen2 = bi.Dim1; dimen3 = bi.Dim3; break; case 3: exdim = bi.Dim3; dimen2 = bi.Dim1; dimen3 = bi.Dim2; break; default: break; } layereval = 0; if ((exdim <= thickness) && (((dimen2 <= p.Pallet_x) && (dimen3 <= p.Pallet_z)) || ((dimen3 <= p.Pallet_x) && (dimen2 <= p.Pallet_z)))) { for (int z = 0; z < boxList.Count; z++) { if (!(x == z) && !(boxList[z].Is_packed)) { dimdif = Math.Abs(exdim - boxList[z].Dim1); if (Math.Abs(exdim - boxList[z].Dim2) < dimdif) { dimdif = Math.Abs(exdim - boxList[z].Dim2); } if (Math.Abs(exdim - boxList[z].Dim3) < dimdif) { dimdif = Math.Abs(exdim - boxList[z].Dim3); } layereval = layereval + dimdif; } } if (layereval < eval) { eval = layereval; layerThickness = exdim; } } } } if (layerThickness == 0 || layerThickness > remainpy) { packing = false; } return(0); }
///---------------------------------------------------------------------------- /// PACKS THE BOXES FOUND AND ARRANGES ALL VARIABLES AND RECORDS PROPERLY ///---------------------------------------------------------------------------- private bool Pack_layer(bool packingbest, ref bool hundredpercent) { if (0 == layerThickness) { packing = false; return(false); } scrapfirst = new Scrappad() { Cumx = pallet.Pallet_x, Cumz = 0 }; decimal cboxi = 0, cboxx = 0, cboxy = 0, cboxz = 0; while (true) { smallestz = Find_smallest_z(); if (null == smallestz.prev && null == smallestz.next) { //*** SITUATION-1: NO BOXES ON THE RIGHT AND LEFT SIDES *** decimal lenx = smallestz.Cumx; decimal lpz = remainpz - smallestz.Cumz; Find_box(lenx, layerThickness, remainpy, lpz, lpz, ref cboxi, ref cboxx, ref cboxy, ref cboxz); if (layerdone) { break; } if (evened) { continue; } Cuboid bi = boxList[(int)cboxi]; boxList[(int)cboxi].Cox = 0; boxList[(int)cboxi].Coy = packedy; boxList[(int)cboxi].Coz = smallestz.Cumz; if (cboxx == smallestz.Cumx) { smallestz.Cumz = smallestz.Cumz + cboxz; } else { smallestz.next = new Scrappad { prev = smallestz, Cumx = smallestz.Cumx, Cumz = smallestz.Cumz }; smallestz.Cumx = cboxx; smallestz.Cumz = smallestz.Cumz + cboxz; } VolumeCheck((int)cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else if (null == smallestz.prev) { //*** SITUATION-2: NO BOXES ON THE LEFT SIDE *** decimal lenx = smallestz.Cumx; decimal lenz = smallestz.next.Cumz - smallestz.Cumz; decimal lpz = remainpz - smallestz.Cumz; Find_box(lenx, layerThickness, remainpy, lenz, lpz , ref cboxi, ref cboxx, ref cboxy, ref cboxz); if (layerdone) { break; } if (evened) { continue; } Cuboid bi = boxList[(int)cboxi]; bi.Coy = packedy; bi.Coz = smallestz.Cumz; if (cboxx == smallestz.Cumx) { bi.Cox = 0; if (smallestz.Cumz + cboxz == smallestz.next.Cumz) { smallestz.Cumz = smallestz.next.Cumz; smallestz.Cumx = smallestz.next.Cumx; trash = smallestz.next; smallestz.next = smallestz.next.next; if (null != smallestz.next) { smallestz.next.prev = smallestz; } } else { smallestz.Cumz = smallestz.Cumz + cboxz; } } else { bi = boxList[(int)cboxi]; bi.Cox = smallestz.Cumx - cboxx; if (smallestz.Cumz + cboxz == smallestz.next.Cumz) { smallestz.Cumx = smallestz.Cumx - cboxx; } else { smallestz.next.prev = new Scrappad { next = smallestz.next, prev = smallestz }; smallestz.next = smallestz.next.prev; smallestz.next.Cumx = smallestz.Cumx; smallestz.Cumx = smallestz.Cumx - cboxx; smallestz.next.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck((int)cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else if (null == smallestz.next) { //*** SITUATION-3: NO BOXES ON THE RIGHT SIDE *** decimal lenx = smallestz.Cumx - smallestz.prev.Cumx; decimal lenz = smallestz.prev.Cumz - smallestz.Cumz; decimal lpz = remainpz - smallestz.Cumz; Find_box(lenx, layerThickness, remainpy, lenz, lpz , ref cboxi, ref cboxx, ref cboxy, ref cboxz); if (layerdone) { break; } if (evened) { continue; } Cuboid bi = boxList[(int)cboxi]; bi.Coy = packedy; bi.Coz = smallestz.Cumz; bi.Cox = smallestz.prev.Cumx; if (cboxx == smallestz.Cumx - smallestz.prev.Cumx) { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.prev.Cumx = smallestz.Cumx; smallestz.prev.next = null; } else { smallestz.Cumz = smallestz.Cumz + cboxz; } } else { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.prev.Cumx = smallestz.prev.Cumx + cboxx; } else { smallestz.prev.next = new Scrappad { prev = smallestz.prev, next = smallestz }; smallestz.prev = smallestz.prev.next; smallestz.prev.Cumx = smallestz.prev.prev.Cumx + cboxx; smallestz.prev.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck((int)cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else if (smallestz.prev.Cumz == smallestz.next.Cumz) { //*** SITUATION-4: THERE ARE BOXES ON BOTH OF THE SIDES *** //*** SUBSITUATION-4A: SIDES ARE EQUAL TO EACH OTHER *** decimal lenx = smallestz.Cumx - smallestz.prev.Cumx; decimal lenz = smallestz.prev.Cumz - smallestz.Cumz; decimal lpz = remainpz - smallestz.Cumz; Find_box(lenx, layerThickness, remainpy, lenz, lpz , ref cboxi, ref cboxx, ref cboxy, ref cboxz); if (layerdone) { break; } if (evened) { continue; } boxList[(int)cboxi].Coy = packedy; boxList[(int)cboxi].Coz = smallestz.Cumz; if (cboxx == smallestz.Cumx - smallestz.prev.Cumx) { boxList[(int)cboxi].Cox = smallestz.prev.Cumx; if (smallestz.Cumz + cboxz == smallestz.next.Cumz) { smallestz.prev.Cumx = smallestz.next.Cumx; if (null != smallestz.next.next) { smallestz.prev.next = smallestz.next.next; smallestz.next.next.prev = smallestz.prev; } else { smallestz.prev.next = null; } } else { smallestz.Cumz = smallestz.Cumz + cboxz; } } else if (smallestz.prev.Cumx < pallet.Pallet_x - smallestz.Cumx) { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.Cumx = smallestz.Cumx - cboxx; boxList[(int)cboxi].Cox = smallestz.Cumx - cboxx; } else { boxList[(int)cboxi].Cox = smallestz.prev.Cumx; smallestz.prev.next = new Scrappad { prev = smallestz.prev, next = smallestz }; smallestz.prev = smallestz.prev.next; smallestz.prev.Cumx = smallestz.prev.prev.Cumx + cboxx; smallestz.prev.Cumz = smallestz.Cumz + cboxz; } } else { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.prev.Cumx = smallestz.prev.Cumx + cboxx; boxList[(int)cboxi].Cox = smallestz.prev.Cumx; } else { boxList[(int)cboxi].Cox = smallestz.Cumx - cboxx; smallestz.next.prev = new Scrappad { next = smallestz.next, prev = smallestz }; smallestz.next = smallestz.next.prev; smallestz.next.Cumx = smallestz.Cumx; smallestz.next.Cumz = smallestz.Cumz + cboxz; smallestz.Cumx = smallestz.Cumx - cboxx; } } VolumeCheck((int)cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else { //*** SUBSITUATION-4B: SIDES ARE NOT EQUAL TO EACH OTHER *** //*** SUBSITUATION-4B: SIDES ARE NOT EQUAL TO EACH OTHER *** decimal lenx = smallestz.Cumx - smallestz.prev.Cumx; decimal lenz = smallestz.prev.Cumz - smallestz.Cumz; decimal lpz = remainpz - smallestz.Cumz; Find_box(lenx, layerThickness, remainpy, lenz, lpz , ref cboxi, ref cboxx, ref cboxy, ref cboxz); if (layerdone) { break; } if (evened) { continue; } boxList[(int)cboxi].Coy = packedy; boxList[(int)cboxi].Coz = smallestz.Cumz; boxList[(int)cboxi].Cox = smallestz.prev.Cumx; if (cboxx == smallestz.Cumx - smallestz.prev.Cumx) { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.prev.Cumx = smallestz.Cumx; smallestz.prev.next = smallestz.next; smallestz.next.prev = smallestz.prev; } else { smallestz.Cumz = smallestz.Cumz + cboxz; } } else { if (smallestz.Cumz + cboxz == smallestz.prev.Cumz) { smallestz.prev.Cumx = smallestz.prev.Cumx + cboxx; } else if (smallestz.Cumz + cboxz == smallestz.next.Cumz) { boxList[(int)cboxi].Cox = smallestz.Cumx - cboxx; smallestz.Cumx = smallestz.Cumx - cboxx; } else { smallestz.prev.next = new Scrappad { prev = smallestz.prev, next = smallestz }; smallestz.prev = smallestz.prev.next; smallestz.prev.Cumx = smallestz.prev.prev.Cumx + cboxx; smallestz.prev.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck((int)cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } } return(true); }