Implementierung eines hybriden simulierten Annealing-Algorithmus zur Lösung des dreidimensionalen Boxproblems MATLAB

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