/// <summary> /// AFTER PACKING OF EACH BOX, 100% PACKING CONDITION IS CHECKED /// </summary> private void VolumeCheck(int cboxi, int cboxx, int cboxy, int cboxz, bool packingbest , ref bool hundredpercent) { BoxInfo bi = boxList[cboxi]; bi.SetPacked(cboxx, cboxy, cboxz); packedvolume += bi.Vol; packednumbox++; if (packingbest) { bi.Write(cboxi); 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(int hmx, int hy, int hmy, int hz, int hmz, ref int cboxi, ref int cboxx, ref int cboxy, ref int cboxz) { int boxi = 0, boxx = 0, boxy = 0, boxz = 0; int bboxi = 0, bboxx = 0, bboxy = 0, bboxz = 0; int bfx = int.MaxValue, bfy = int.MaxValue, bfz = int.MaxValue; int bbfx = int.MaxValue, bbfy = int.MaxValue, bbfz = int.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; } BoxInfo 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(int thickness, PalletInfo p) { int exdim = 0, dimdif = 0, dimen2 = 0, dimen3 = 0; int layereval = 0, eval = int.MaxValue; layerThickness = 0; for (int x = 0; x < boxList.Count; x++) { BoxInfo 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 }; int 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 *** int lenx = smallestz.Cumx; int 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; } BoxInfo bi = boxList[cboxi]; boxList[cboxi].Cox = 0; boxList[cboxi].Coy = packedy; boxList[cboxi].Coz = smallestz.Cumz; if (cboxx == smallestz.Cumx) { smallestz.Cumz = smallestz.Cumz + cboxz; } else { smallestz.next = new Scrappad(); smallestz.next.prev = smallestz; smallestz.next.Cumx = smallestz.Cumx; smallestz.next.Cumz = smallestz.Cumz; smallestz.Cumx = cboxx; smallestz.Cumz = smallestz.Cumz + cboxz; } VolumeCheck(cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else if (null == smallestz.prev) { //*** SITUATION-2: NO BOXES ON THE LEFT SIDE *** int lenx = smallestz.Cumx; int lenz = smallestz.next.Cumz - smallestz.Cumz; int 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; } BoxInfo bi = boxList[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[cboxi]; bi.Cox = smallestz.Cumx - cboxx; if (smallestz.Cumz + cboxz == smallestz.next.Cumz) { smallestz.Cumx = smallestz.Cumx - cboxx; } else { smallestz.next.prev = new Scrappad(); smallestz.next.prev.next = smallestz.next; smallestz.next.prev.prev = smallestz; smallestz.next = smallestz.next.prev; smallestz.next.Cumx = smallestz.Cumx; smallestz.Cumx = smallestz.Cumx - cboxx; smallestz.next.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck(cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } else if (null == smallestz.next) { //*** SITUATION-3: NO BOXES ON THE RIGHT SIDE *** int lenx = smallestz.Cumx - smallestz.prev.Cumx; int lenz = smallestz.prev.Cumz - smallestz.Cumz; int 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; } BoxInfo bi = boxList[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(); smallestz.prev.next.prev = smallestz.prev; smallestz.prev.next.next = smallestz; smallestz.prev = smallestz.prev.next; smallestz.prev.Cumx = smallestz.prev.prev.Cumx + cboxx; smallestz.prev.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck(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 *** int lenx = smallestz.Cumx - smallestz.prev.Cumx; int lenz = smallestz.prev.Cumz - smallestz.Cumz; int 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[cboxi].Coy = packedy; boxList[cboxi].Coz = smallestz.Cumz; if (cboxx == smallestz.Cumx - smallestz.prev.Cumx) { boxList[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[cboxi].Cox = smallestz.Cumx - cboxx; } else { boxList[cboxi].Cox = smallestz.prev.Cumx; smallestz.prev.next = new Scrappad(); smallestz.prev.next.prev = smallestz.prev; smallestz.prev.next.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[cboxi].Cox = smallestz.prev.Cumx; } else { boxList[cboxi].Cox = smallestz.Cumx - cboxx; smallestz.next.prev = new Scrappad(); smallestz.next.prev.next = smallestz.next; smallestz.next.prev.prev = smallestz; smallestz.next = smallestz.next.prev; smallestz.next.Cumx = smallestz.Cumx; smallestz.next.Cumz = smallestz.Cumz + cboxz; smallestz.Cumx = smallestz.Cumx - cboxx; } } VolumeCheck(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 *** int lenx = smallestz.Cumx - smallestz.prev.Cumx; int lenz = smallestz.prev.Cumz - smallestz.Cumz; int 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[cboxi].Coy = packedy; boxList[cboxi].Coz = smallestz.Cumz; boxList[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[cboxi].Cox = smallestz.Cumx - cboxx; smallestz.Cumx = smallestz.Cumx - cboxx; } else { smallestz.prev.next = new Scrappad(); smallestz.prev.next.prev = smallestz.prev; smallestz.prev.next.next = smallestz; smallestz.prev = smallestz.prev.next; smallestz.prev.Cumx = smallestz.prev.prev.Cumx + cboxx; smallestz.prev.Cumz = smallestz.Cumz + cboxz; } } VolumeCheck(cboxi, cboxx, cboxy, cboxz, packingbest, ref hundredpercent); } } return(true); }