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