遗传算法/混合粒子群算法求解tsp问题

该博客介绍了使用遗传算法和混合粒子群优化算法解决旅行商问题的实现过程。通过交叉、变异操作改进个体,并记录算法过程。在遗传算法中,按名次选择父母并进行交叉,同时考虑了变异操作;而在混合粒子群优化中,结合全局最优和个人最优进行交叉。最终,算法得到最短路径并进行可视化展示。
摘要由CSDN通过智能技术生成

交叉jiaocha.m

function [t1,t2] = jiaocha(vf,vm,num)
    t = randi(2);
    if t <= 2
        w1 = randi(num);%随机选择交叉点,否则后代太早收敛达不到最小值
        w2 = randi(num);
        if w1==w2
            w2 = w2+1;
            if w2 > num
                w2 = 1;
            end
        end
        if w1>w2
            temp=w1;w1=w2;w2=temp;
        end
        t1 = zeros([1 num]);
        t2 = zeros([1 num]);
        visit1=zeros([1 num]);
        visit2=zeros([1 num]);
        for i = w1+1:w2
            t1(i) = vf(i);
            visit1(t1(i)) = 1;
            t2(i) = vm(i);
            visit2(t2(i)) = 1;
        end
        i1 = w2+1;
        if i1>num
            i1 = 1;
        end
        j1 = w2+1;
        if j1>num
            j1 = 1;
        end
        while t1(i1) == 0
            while visit1(vm(j1))==1
                j1 = j1+1;
                if j1>num
                    j1 = 1;
                end
            end
            t1(i1) = vm(j1);
            visit1(vm(j1)) = 1;
            i1 = i1+1;
            if i1>num
                i1 = 1;
            end
        end
        i1 = w2+1;
        if i1>num
            i1 = 1;
        end
        j1 = w2+1;
        if j1>num
            j1 = 1;
        end
        while t2(j1) == 0
            while visit2(vf(i1))==1
                i1 = i1+1;
                if i1>num
                    i1 = 1;
                end
            end
            t2(j1) = vf(i1);
            visit2(vf(i1)) = 1;
            j1 = j1+1;
            if j1>num
                j1 = 1;
            end
        end
        i1 = i1;
    else
        t1 = vf;
        t2 = vm;
    end
end

按名次选择父母(总权重n^{2}=1+3+5+...+(2n-1))

chooseone.m

function [wh] = chooseone(num)
    sum = num*num;
    R = randi(sum);
    now = 1;
    wh = 1;
    now_sum = 1;
    while now_sum < R
        now = now + 2;
        now_sum = now_sum + now;
        wh = wh + 1;
    end
    wh = num-wh+1;
end

计算路径长度

calc_path_len.m

function [calc_path] = calc_path_len(t)
    global opt_path;
    global opt_len;
    global mm;
    calc_path = 0;
    num = size(t,2);
    for i= 1:num-1
        calc_path = calc_path + norm([mm(t(i),1) mm(t(i),2)]-[mm(t(i+1),1) mm(t(i+1),2)]);
    end
    calc_path = calc_path + norm([mm(t(num),1) mm(t(num),2)]-[mm(t(1),1) mm(t(1),2)]);
    if opt_len > calc_path
        opt_len = calc_path;
        opt_path = t;
    end
end

变异bianyi.m

在tsp问题中作用不大

function [th] = bianyi(ty,num)
    pbianyi = 20; %变异概率
    numbian = 0;
    tb=[];
    numbubian = 0;
    tbb=[];
    for i = 1:num
        w = randi(100);
        if w <= pbianyi
            numbian = numbian+1;
            tb(numbian) = i;
        else
            numbubian = numbubian+1;
            tbb(numbubian) = i;
        end
    end
    th = ty;
    if numbian > 0 && numbian <= numbubian
        randIndex = randperm(numbian);% 生成随机排列
        tb = tb(randIndex); % 随机排列后的矩阵
        randIndex = randperm(numbubian);% 生成随机排列
        tbb = tbb(randIndex); % 随机排列后的矩阵
        numbubian = numbubian;
        for i = 1:numbian
            x = tb(i);
            y = tbb(i);
            temp = th(x); th(x)=th(y); th(y) = temp;
        end
    end
    pbianyi = pbianyi;
end

遗传算法主程序tsp.m

global opt_path;
opt_path = [];
global opt_len;
opt_len = 1e9;
global mm;
mm = [];
%fid = fopen('test.tsp');
fid = fopen('eil51.tsp');
%fid = fopen('book_data.tsp');
tline = fgetl(fid);
while ischar(tline)
    flag = 0;
    for i = 1:size(tline)
        if isletter(tline(i)) == 1
            flag = 1;
            break
        end
    end
    if flag == 0
        %disp(tline);
        li = strsplit(tline);
        l1 = str2num(char(li(1)));
        l2 = str2num(char(li(2)));
        l3 = str2num(char(li(3)));
        mm(l1,1) = l2;
        mm(l1,2) = l3;
    end
    tline = fgetl(fid);
end
fclose(fid);
numcity = size(mm,1);
numgeti = 400; %个体数量
numshidai = 400; %世代数量
fid = fopen('算法过程.txt','w');

a=[]
now_opt=[]
for i= 1:numgeti
    t = randperm(numcity);
    a = [a;t];
    now_opt(i) = calc_path_len(t);
end
%now_opt
[E,I] = sort(now_opt);
father = zeros([1 numgeti]);
mother = zeros([1 numgeti]);
for shidailoop = 1:numshidai    
    fprintf(fid,'世代:%d\n',shidailoop);
    b=[];
    old_opt = now_opt;
    for getiloop = 1:fix(numgeti/2)
        first = getiloop*2-1;
        second = getiloop*2;
        father(first) = chooseone(fix(numgeti*0.6));%只在前50%选(强加强)
        mother(first) = chooseone(fix(numgeti*0.6));
        father(second) = father(first);
        mother(second) = mother(first);
        [t1,t2] = jiaocha(a(I(father(first)),:),a(I(mother(first)),:),numcity);
        t1_length = calc_path_len(t1);
        t2_length = calc_path_len(t2);
        tb1 = bianyi(t1,numcity);
        tb2 = bianyi(t2,numcity);
        tb1_length = calc_path_len(tb1);
        tb2_length = calc_path_len(tb2);
        if t1_length < tb1_length
            b = [b;t1];
            now_opt(first) = t1_length;
        else
            b = [b;tb1];
            now_opt(first) = tb1_length;
            fprintf(fid,'序号:%g\t',first);
            fprintf(fid,'变异前:');
            fprintf(fid,'%g\t',t1);
            fprintf(fid,'变异后:');
            fprintf(fid,'%g\t',tb1);
            fprintf(fid,'\n');
        end
        if t2_length < tb2_length
            b = [b;t2];
            now_opt(second) = t2_length;
        else
            b = [b;tb2];
            now_opt(second) = tb2_length;
            fprintf(fid,'序号:%g\t',second);
            fprintf(fid,'变异前:');
            fprintf(fid,'%g\t',t2);
            fprintf(fid,'变异后:');
            fprintf(fid,'%g\t',tb2);
            fprintf(fid,'\n');
        end
    end
    I_index = zeros(1,numgeti);
    for i = 1:numgeti
        I_index(I(i)) = i;
    end
    fprintf(fid,'原始访问序列:\n');
    for i = 1:numgeti
        fprintf(fid,'序号:%g\t',i);
        fprintf(fid,'顺序:');
        fprintf(fid,'%g\t',a(i,:));
        fprintf(fid,'长度:%g\t',old_opt(i));
        fprintf(fid,'名次:%g\t',I_index(i));
        fprintf(fid,'父母位次:%g,%g\t',father(i),mother(i));
        fprintf(fid,'父母序号:%g,%g\t',I(father(i)),I(mother(i)));
       % fprintf(fid,'父母基因:%g,%g\t',I(father(i)),I(mother(i)));
        fprintf(fid,'\n');
    end
    [E,I] = sort(now_opt);
    fprintf(fid,'交叉变异后访问序列:\n');
    for i = 1:numgeti
        fprintf(fid,'序号:%g\t',i);
        fprintf(fid,'顺序:');
        fprintf(fid,'%g\t',b(i,:));
        fprintf(fid,'长度:%g\t',now_opt(i));
        fprintf(fid,'\n');
    end
    fprintf(fid,'\n');
    a=b;
end


fclose(fid);


%绘图
hold on
clear line;
for i = 1:numcity-1
    plot(mm(opt_path(i),1),mm(opt_path(i),2),'r*');  
    line([mm(opt_path(i),1) mm(opt_path(i+1),1)],[mm(opt_path(i),2) mm(opt_path(i+1),2)]);  %只连线当前城市和下家城市    
end
plot(mm(opt_path(numcity),1),mm(opt_path(numcity),2),'r*');  
line([mm(opt_path(numcity),1) mm(opt_path(1),1)],[mm(opt_path(numcity),2) mm(opt_path(1),2)]);
opt_len

混合粒子群主程序tsp_multipso.m

global opt_path;
opt_path = [];
global opt_len;
opt_len = 1e9;
global mm;
mm = [];
%fid = fopen('test.tsp');
fid = fopen('eil101.tsp');
%fid = fopen('book_data.tsp');
tline = fgetl(fid);
while ischar(tline)
    flag = 0;
    for i = 1:size(tline)
        if isletter(tline(i)) == 1
            flag = 1;
            break
        end
    end
    if flag == 0
        %disp(tline);
        li = strsplit(tline);
        l1 = str2num(char(li(1)));
        l2 = str2num(char(li(2)));
        l3 = str2num(char(li(3)));
        mm(l1,1) = l2;
        mm(l1,2) = l3;
    end
    tline = fgetl(fid);
end
fclose(fid);
numcity = size(mm,1);
numgeti = 500; %个体数量
numshidai = 500; %世代数量
fid = fopen('算法过程.txt','w');

a=[]
now_opt=[]
for i= 1:numgeti
    t = randperm(numcity);
    a = [a;t];
    now_opt(i) = calc_path_len(t);
end
best_geti = zeros(numgeti,numcity);
best_geti_value = zeros(numgeti);
best_zhongqun = zeros(numcity);
best_zhongqun_value = Inf;
for i = 1:numgeti
    best_geti(i,:) = a(i,:);
    best_geti_value(i) = now_opt(i);
    if best_zhongqun_value > best_geti_value(i)
         best_zhongqun_value = best_geti_value(i);
         best_zhongqun = best_geti(i,:);
    end
end
[E,I] = sort(now_opt);
for shidailoop = 1:numshidai    
    old_opt = now_opt;
    fprintf(fid,'世代:%d\n',shidailoop);
    b=[];
    for getiloop = 1:numgeti
        [t1,t2] = jiaocha(a(getiloop,:),best_geti(getiloop,:),numcity);
        t1_length = calc_path_len(t1);
        t2_length = calc_path_len(t2);
        if t1_length > t2_length
            t1 = t2;
        end
        [t1,t2] = jiaocha(t1,best_zhongqun,numcity);
        t1_length = calc_path_len(t1);
        t2_length = calc_path_len(t2);
        if t1_length > t2_length
            t1 = t2;
            t1_length = t2_length;
        end
        b = [b;t1];
        now_opt(getiloop) = t1_length;
        if best_geti_value(getiloop) > t1_length
            best_geti_value(getiloop) = t1_length;
            best_geti(getiloop,:) = t1;
        end
        if best_zhongqun_value > t1_length
            best_zhongqun_value = t1_length;
            best_zhongqun = t1;
        end
    end
    I_index = zeros(1,numgeti);
    for i = 1:numgeti
        I_index(I(i)) = i;
    end
    fprintf(fid,'原始访问序列:\n');
    for i = 1:numgeti
        fprintf(fid,'序号:%g\t',i);
        fprintf(fid,'顺序:');
        fprintf(fid,'%g\t',a(i,:));
        fprintf(fid,'长度:%g\t',old_opt(i));
        fprintf(fid,'名次:%g\t',I_index(i));
        fprintf(fid,'\n');
    end
    [E,I] = sort(now_opt);
    fprintf(fid,'交叉后访问序列:\n');
    for i = 1:numgeti
        fprintf(fid,'序号:%g\t',i);
        fprintf(fid,'顺序:');
        fprintf(fid,'%g\t',b(i,:));
        fprintf(fid,'长度:%g\t',now_opt(i));
        fprintf(fid,'\n');
    end
    fprintf(fid,'\n');
    a=b;
end


fclose(fid);


%绘图
hold on
clear line;
for i = 1:numcity-1
    plot(mm(opt_path(i),1),mm(opt_path(i),2),'r*');  
    line([mm(opt_path(i),1) mm(opt_path(i+1),1)],[mm(opt_path(i),2) mm(opt_path(i+1),2)]);  %只连线当前城市和下家城市    
end
plot(mm(opt_path(numcity),1),mm(opt_path(numcity),2),'r*');  
line([mm(opt_path(numcity),1) mm(opt_path(1),1)],[mm(opt_path(numcity),2) mm(opt_path(1),2)]);
opt_len
best_geti
best_geti_value
best_zhongqun
best_zhongqun_value

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值