天天看點

模拟退火背包問題求解

clear;
clc;
%物品價值
earn=[;;;;;;;;;;;];
earn=-earn;%模拟退火算法求解最小值,故取負數
cost=[;;;;;;;;;;;];
num=;
restriction=;%包最大允許品質
sol_new=ones(,num);
sol_current=sol_new;
sol_best=sol_new;
E_current=inf;
E_best=inf;
t0=;
tf=;
t=t0;
p=;
a=;
while t>tf
    for i=:
        %産生随機擾動
        temp=ceil(rand*);
        sol_new(:temp)=~sol_new(:temp);
        %限制條件判斷
        while sol_new*cost>restriction
            %随機找到一個1逆轉為0
            temp=find(sol_new==);
            %if p
            %    sol_new(1,temp(1))=0;
            %   p=~p;
            %else
             %   sol_new(1,temp(end))=0;
              %  p=~p;
            %end
            temp1=ceil(rand*size(temp));
            sol_new(,temp(temp1))=;
        end

        E_new=sol_new*earn;
        if E_new<E_current
            E_current=E_new;
            sol_current=sol_new;
            if E_new<E_best
                E_best=E_new;
                sol_best=sol_new;
            end
        else
            if rand<exp(-(E_new-E_current)/t)
                E_current=E_new;
                sol_current=sol_new;
            else
                sol_new=sol_current;
            end
        end
    end
    t=t*a;
end

disp('最優解為:')
disp(sol_best);
disp('物品總價值')
val=-E_best;
disp(val);
disp('背包重量物品總重量')
disp(sol_best*cost)

           

繼續閱讀