Da ich im Rahmen der mathematischen Modellierung ein dreidimensionales Crating-Problem lösen muss, habe ich nach der Suche die Arbeit „Hybrid Simulated Annealing Algorithm for Solving Three-Dimensional Crating Problems“, die von Prof. Zhang Defu et al. im Journal of Computing veröffentlicht wurde, als theoretische Grundlage des Problems ausgewählt.
Die Zusammenfassung des Artikels lautet wie folgt:
Es wird ein hybrider Simulated Annealing-Algorithmus zur effizienten Lösung des dreidimensionalen Containerladeproblems 3D-CLP vorgeschlagen. Das dreidimensionale Containerladeproblem (3D-CLP) verlangt, eine Teilmenge einer gegebenen Menge von Kisten so in einen Container zu laden, dass das Gesamtvolumen der geladenen Kisten maximiert wird. Der in diesem Papier vorgestellte hybride Simulationsglüh-Algorithmus basiert auf drei wichtigen Algorithmen: (1) dem Algorithmus zur Erzeugung von Verbundblöcken, der sich von den traditionellen Algorithmen dadurch unterscheidet, dass der in diesem Papier vorgeschlagene Verbundblock nicht nur eine einzige Art von Kisten enthält, sondern unter bestimmten Einschränkungen jede Art von Kisten enthalten kann. (2) Grundlegender heuristischer Algorithmus, der auf dem Laden von Blöcken basiert und ein Platzierungsschema gemäß einer bestimmten Ladesequenz generieren kann. (3) Der Algorithmus des simulierten Annealing, der auf der Erzeugung von zusammengesetzten Blöcken und dem grundlegenden heuristischen Algorithmus basiert, kodiert die Ladesequenzen als machbare Platzierungsschemata und durchsucht den Kodierungsraum mit dem Algorithmus des simulierten Annealing, um die annähernd optimale Lösung des Problems zu finden. Der Algorithmus wird mit 1.500 schwach und stark heterogenen Daten für das Packproblem getestet. Die experimentellen Ergebnisse zeigen, dass die Füllrate des hybriden simulierten Annealing-Algorithmus die der besten bekannten Algorithmen übertrifft.
DOI-Nummer :10.3724/ SP .J.1016 .2009.02147
Der Algorithmus in diesem Papier implementiert seine Berechnungsergebnisse
MATLAB-Code für die Kernfunktion dieser Implementierung
function [solution, newPlan, rate] = container_packeting(bcon, plan, blockTable, blockNeed) %UNTITLED2 Berechnet den Packplan auf der Grundlage der Angaben zu den großen und kleinen Containern und der Information über die Anzahl der kleinen Container % bigContainer Spezifikationsvektor des bigContainers [L B H] % smallContainers Spezifikationsmatrix der kleinen Behälter [L W H;]. % smallContainersNumber Vektor der Anzahl der kleinen Container [n]. solution = {}; newPlan = [] ; searchDeep = 40960; clf. draw_container([0,0,0], bcon); % Verbleibender Platzstapel lspace_s = get_stack(); % leerer Stapel iterval_s = get_stack(); % leerer Stapel itervalSpace_s = get_stack(); % Restlichen Platz als großen Containerplatz initialisieren lspace_s = stack_push(lspace_s, get_space([0,0,0], bcon)); % ItervalSpace_s = get_stack(); % Initialisieren Sie den verbleibenden Platz als großen Containerplatz. psCount = 0; while lspace_s.count > 0 psZahl = psZahl + 1; % Holen Sie den verfügbaren Restplatz aus dem Restplatzstapel lspace = stack_top(lspace_s); lspace_s = stack_pop(lspace_s); lspace_size = lspace.size. lspace_base = lspace.base_point; lspace_s = stack_pop(lspace_s); if_input = 0; theBlockNeed = NaN; find_idx = 1; lspace_size(1, lspace_size(2), lspace_size(3)) find_idx = 1; if Größe(blockListe, 1) wenn Größe(blockList, 1) == 0 find_avaliable = 0; sonst if size(blockList, 1) == 0 find_avaliable = 0; sonst find_avaliable = 1; wenn plan(psCount) <= Größe(blockList, 1) if plan(psCount) <= Größe(blockListNeed, 1) theBlockNeed = blockListNeed(plan(psCount),:); find_idx = plan(psCount); find_idx = plan(psCount); sonst theBlockNeed = blockListNeed(size(blockListNeed, 1),:); find_idx = size(block(psCount),:); sonst find_idx = Größe(blockListNeed, 1); sonst theBlockNeed = blockListNeed(Größe(blockListNeed, 1),:); find_idx = Größe(blockListNeed, 1); find_idx = Plan(psCount) end newPlan = [newPlan, find_idx]; end end %% Container lokalisieren if find_avaliable == 1 newLocatedBlock = {lspace_base, blockList(find_idx, :), theBlockNeed {1}, theBlockNeed {2}}; Lösung(Größe(Lösung, 1) + 1, :) = newLocatedBlock; spaceInfo = newLocatedBlock {4}; spaceLastInfo = spaceInfo(size(spaceInfo,1), :) ; locateInfo = newLocatedBlock {2}; hold on ; draw_container(lspace_base, locateInfo(1:3)) ; itervalSpace_s = stack_push(itervalSpace_s, (1-spaceLastInfo(1)) * prod(locateInfo(1:3))); if_input = 1; % Berechnung des verbleibenden Platzes % Verbleibender Platz in H-Richtung location = lspace_base; location(2) = location(2) + locateInfo(2); iterval_space = get_space(location, [locateInfo(1) , lspace_size(2) - locateInfo(2), locateInfo(3)]); lspace_s = stack_push(lspace_s, iterval_space); % Verbleibender Platz in L-Richtung location = lspace_base; location(1) = location(1) + locateInfo(1); % In L-Richtung verbleibender Platz. left_space = get_space(location, [lspace_size(1) - locateInfo(1), lspace_size(2), lspace_size(3)]); lspace_s = stack_push(lspace_s, left_space); % verbleibender Platz in W-Richtung location = lspace_base. location(3) = location(3) + locateInfo(3); % verbleibender Platz in W-Richtung; iterval_space = get_space(3) iterval_space = get_space(location, [locateInfo(1) , lspace_size(2), lspace_size(3) - locateInfo(3)]); lspace_s = stack_push(lspace_s, iterval_space); Ende if_input == 1 end if if_input == 1 % In den Lückenstapel schieben iterval_s = stack_push(iterval_s, lspace); % lspace_s = stack_push(lspace_s, lspace); Ende Ende rate = space_used_rate(bcon, lösung); end function rate = space_used_rate(container, lösung) spaceHasTotal = 0.0; for i = 1:1:size(Lösung, 1); end function for i = 1:1:Größe(Lösung, 1) mergeMessage = Lösung{i, 4}; for k = 1:1:Größe(Lösung, 1) for k = 1:1:Größe(zusammenfassenMitteilung,1) spaceHasTotal = spaceHasTotal + prod(mergeMessage(k, 3:5)); end end rate = spaceHasTotal / prod(container); end
Funktionen zur Erzeugung von Boxen
function [blockTable, boxNeedTable] = simple_block_generate_indepent(container, box, num) simBlockCount = 0; simple_block_generate_indepent(container, box, num); simBlockCount = 0; simBlockTable = zeros(256, 8); for type = 1:1:size(box, 1) for nx = 1:1:num(Typ) für ny = 1:1:num(Typ)/nx für nz = 1:1:num(typ)/ny/nx if box(typ,3) * nx < container(3) && box(typ, 1) * ny < container(1) && box(typ, 2) * nz < container(2) newSimBlock = [box(type, :), nx, ny, nz, type, prod(box(type, :)) * nx * ny * nz]; simBlockTable(simBlockCount + 1, :)) = newSimBlock; simBlockCount = simBlockCount + 1; end end end end end simBlockTable = simBlockTable(1:simBlockCount, :); simBlockTable = sortrows(simBlockTable, 8); simBlockTable = simBlockTable(:, 1:7); % Verarbeitung in ein Format, das der heuristische Algorithmus verarbeiten kann simBlockTable(:, 13) = ones(size(simBlockTable, 1), 1); % In ein Format verarbeiten, das vom heuristischen Algorithmus verarbeitet werden kann. simBlockTable(:, 11) = simBlockTable(:,4) .* . simBlockTable(:,3); . simBlockTable(:, 12) = simBlockTable(:,5) .* . simBlockTable(:,1); % ly = ay simBlockTable(:, 8) = simBlockTable(:, 12); % ly = ay % lx = ax simBlockTable(:, 10) = simBlockTable(:, 11); % lz = lz0 * nz0; % ly = ay % lz = lz0 * nz simBlockTable(:, 9) = simBlockTable(:, 2) .* simBlockTable(:, 6); . boxNeedTable = cell(size(simBlockTable, 1), 2); for i = 1:1:size(simBlockTable, 1) boxNeedTable{i, 1} = nullen(1, size(box ,1)); boxBedarfTabelle{i, 1}(simBlockTabelle(i, 7)) = simBlockTabelle(i, 4) * simBlockTabelle(i, 5) * simBlockTabelle(i, 6); boxNeedTable{i, 2} = [simBlockTable(i, 7), 0, simBlockTable(i, 8:10)]; end blockTable = simBlockTable(:, 8:13); blockTable(:, 7); blockTable(:, 7); blockTable(:, 7) blockTable(:, 7) = blockTable(:, 1) .* blockTable(:, 2) .* blockTable(:, 3); [blockTable, idx] = sortrows(blockTable, [ 7 ]); . boxNeedTable = boxNeedTable(idx, :); end
BoxNeedTable(idx, :); boxNeedTable(idx, :); end
function [blockTable, boxNeedTable] = complex_block_genrate(container, box, num, level) simBlockTable = simple_block_generate(container, box, num); simBlockTable(:, 13) = ones(size(simBlockTable, 1), 1); simBlockTable(:, 11) = simBlockTable(:,4) .* . simBlockTable(:,3); . simBlockTable(:, 12) = simBlockTable(:,5) .* . simBlockTable(:,1); spaceUsedRateMin = 0.90; . % ly = ay simBlockTable(:, 8) = simBlockTable(:, 12); % ly = ax % lx = ax simBlockTable(:, 10) = simBlockTable(:, 11); % lz = lz0 * lz0 * lz0; % lz = lz0 * lz0 * lz0 % lz = lz0 * nz simBlockTable(:, 9) = simBlockTable(:, 2) .* simBlockTable(:, 6); . boxNeedTable = cell(size(simBlockTable, 1), 2); for i = 1:1:size(simBlockTable, 1) boxNeedTable{i, 1} = nullen(1, size(box ,1)); boxBedarfTabelle{i, 1}(simBlockTabelle(i, 7)) = simBlockTabelle(i, 4) * simBlockTabelle(i, 5) * simBlockTabelle(i, 6); boxNeedTable{i, 2} = [simBlockTable(i, 7), 0, simBlockTable(i, 8:10)]; end blockTable = simBlockTable(:, 8:13); for level = 1:1:level for level = 1:1:level newBlockTable = nullen(128,6); newBlockCount = 1; for level = 1:1:level; for level = 1:1:level newBlockCount = 1; boxNeedCount = size(box) boxNeedCount = size(boxNeedTable, 1); for a = 1:1:size(boxNeedTable, 1); for level = 1:1:level für a = 1:1:Größe(blockTable,1) für b = a:1:Größe(blockTable, 1) wenn b == a weiter; end wenn b == a weiter; end if blockTable(a, 6) == blockTable(b, 6) % x Richtung Zusammenführen if blockTable(a, 1) == blockTable(a, 5) && blockTable(a, 3) == blockTable(a, 4) && blockTable(a, 2) == blockTable(b, 2) tempBlockMerged = [max(blockTable(a,1), blockTable(b,1)), max(blockTable(a,2), blockTable(b, 2)), blockTable(a,3) + blockTable(b,3), blockTable(a,4)) blockTable(a,4) + blockTable(b,4), min(blockTable(a,5), blockTable(b,5)), max(blockTable(a, 6), blockTable(b, 6)) + 1]; rate = space_used_rate(tempBlockMerged(1:3), blockTable(a,1:3), blockTable(b,1:3)); if rate > spaceUsedRate(tempBlockMerged(1:3)) wenn Rate > spaceUsedRateMin newBlockTable(newBlockCount, :)) = tempBlockMerged; boxNeedCount = boxNeedCount; boxNeedCount = boxNeedCount boxNeedCount = boxNeedCount + 1; newBlockCount = newBlockCount; if rate > spaceUsedRateMin boxNeedCount = boxNeedCount + 1; newBlockCount = newBlockCount + 1; boxNeedTable{boxNeedCount, 1} = boxNeedTable {a,1} + boxNeedTable {b,1}; boxNeedTable{boxNeedCount, 2} = [boxNeedTable{a, 2}; rate, 1, blockTable(b, 1:3)]; Ende end % Zusammenführung in y-Richtung if blockTable(a, 5) == blockTable(a, 1) && blockTable(b, 5) == blockTable(b, 1) && blockTable(a, 2) == blockTable(b, 2) tempBlockMerged = [blockTable(a,1) + blockTable(b,1), max(blockTable(a, 2), blockTable(b, 2)), max(blockTable(a, 3), blockTable(b, 3)), min( blockTable(a, 4), blockTable(b, 4)), blockTable(a, 5) + blockTable(b, 5), max(blockTable(a, 6), blockTable(b, 6)) + 1]; rate = space_used_rate(tempBlockMerged(1:3), blockTable(a, 1:3), blockTable(b, 1:3)); if rate > spaceUsedRate wenn Rate > spaceUsedRateMin newBlockTable(newBlockCount, :)) = tempBlockMerged; newBlockCount = newBlockCount, :)) newBlockCount = newBlockCount + 1; boxNeedCount = boxNeedCount; if rate > spaceUsedRateMin newBlockCount = newBlockCount + 1; boxNeedCount = boxNeedCount + 1; boxNeedTable{boxNeedCount, 1} = boxNeedTable {a,1} + boxNeedTable {b,1}; end end % Zusammenführung in z-Richtung if blockTable(a,4) >= blockTable(b,3) && blockTable(a, 5) >= blockTable(b, 1) tempBlockMerged = [max(blockTable(a,1), blockTable(b, 1)), blockTable(a, 2) + blockTable(b, 2), max(blockTable(a, 3), blockTable(b, 3)), blockTable(b, 4), blockTable(b, 4)), blockTable(b, 4)) blockTable(a, 2) + blockTable(b, 2), max(blockTable(a, 3), blockTable(b, 3)), blockTable(b, 4), blockTable(b, 5), max(blockTable(a, 6), blockTable(b, 6)) + 1]; rate = space_used_rate(tempBlockMerged(1:3), blockTable(a, 1:3), blockTable(b, 1:3)); if rate > spaceUsedRate wenn Rate > spaceUsedRateMin newBlockTable(newBlockCount, :)) = tempBlockMerged; newBlockCount = newBlockCount, :)) newBlockCount = newBlockCount + 1; boxNeedCount = boxNeedCount; if rate > spaceUsedRateMin newBlockCount = newBlockCount + 1; boxNeedCount = boxNeedCount + 1; boxNeedTable{boxNeedCount, 1} = boxNeedTable {a,1} + boxNeedTable {b,1}; end end end end end end blockTable = cat(1, blockTable, newBlockTable(1:newBlockCount-1, :)); % Äquivalente komplexe Blöcke eliminieren blockTableTemp = blockTable(:, 1:5); [~, ia] = unique(blockTableTemp, 'stable', 'rows'); blockTable = blockTable(ia, :); boxNeedTable = boxNeedTable(ia, :); end blockTable(:, 7) = blockTable(:, 1) .* blockTable(:, 2) .* blockTable(:, 3); [blockTable, idx] = sortrows(blockTable, [ 7 ]); . boxNeedTable = boxNeedTable(idx, :); end function [rate] = space_used_rate(container, box1, box2) rate = (prod(box1) + prod(box2)) /prod(container); end function [rate] = space_used_rate(container, box2, box1) end
Hauptfunktion
ts = 1; tf = 0,005; end tf = 0,005; dt = 0,98; dt = 0,98; tf = 0,005 dt = 0.98; dt = 0.98; length = 50; dt = 0.98 Länge = 50; maxSeq = 64; maxSeq = 0; maxSeq = 0 maxSeq = 64; maxChoice = 1024; maxChoice = 1024 maxAuswahl = 1024. Klick = 1; tempRate = []; numList = [64,64,64,64,64,64,64,64,64,64,64,128,128,128]; container = StandardISOContainer; % [blockTable, blockNeed] = complex_block_genrate(StandardISOContainer, Packets, numList, 1); ps = ones(1, maxSeq); ps(1) = 1; [Lösung, Plan, Rate] = container_packeting(container, ps, blockTable, blockNeed); best = plan; best_rate = rate. beste_Lösung = Lösung; t = ts; t = ps; ps, blockTable, blockNeed best = plan; best_rate = rate; best_solution = solution; t = ts. while t > tf for i = 1:1:length k = randi(size(ps)); nps = ps; nps = ps; nps = Lösung nps = ps; nps(k) = randi(maxChoice); nps(k) nps(k) = randi(maxAuswahl); nps = ps; nps(k) = randi(maxAuswahl) [Lösung, nplan, nrate] = container_packeting(container, nps, blockTable, blockNeed); % disp(['TempPlan: ', mat2str(nplan)]); % fprintf("TempRate: %f\n",nrate); Klick = Klick + 1; if nrate > rate if nrate > rate ps = nps; plan = nplan; if nrate > rate plan = nplan; rate = nrate; if nrate > rate rate = nrate; wenn nrate > rate ps = nps; plan = nplan; rate = nrate tempRateX = [tempRateX, Klick]; tempRate = [tempRateX, nrate]; if nrate > rate tempRate = [tempRate, nrate]; elseif rand(0, 1 > exp(nrate)) elseif rand(0, 1) > exp((nrate - rate) * 10 / t) ps = nps; plan = nplan; rate = nrate; elseif rand(0, 1) rate = nrate; end ps = nps; plan = nplan; rate = nrate; end wenn nrate > best_rate best = nplan; best_rate = nrate; end if nrate > best_rate best_rate = nrate. best_solution = solution. disp(['BestPlan: ', mat2str(best)]); fprintf("BestRate: %f\n",best_rate); fprintf("BesteRate: \n",best_rate); end end t = (1 - t * dt) * t; end end disp(['BesterPlan: ', mat2str(best)]); fprintf("BestRate: %f\n",best_rate); figure(1) draw_solution(container, best_solution); abbildung(2) plot(tempRateX, tempRate); figure(2) save Lösung best_solution best_rate tempRateX tempRate