遗传算法(三)解TSP问题
来源:互联网 发布:上海东方网络金融 编辑:程序博客网 时间:2024/05/20 11:24
巡回旅行商问题TSP
TSP问题:给定一个图
问题抽象:例如一条城市顺序表
基于这样的思想,只需要对遗传算法的编码部分作出改动:
function parent = InitGroup(GroupNum, Dist) parent.fitness = []; parent.chrom = []; NumCity= size(Dist, 2); for i = 1:GroupNum city = 1 : NumCity; order = randperm(NumCity);%随机生成城市顺序 item = []; for j = 1 : NumCity - 1 item = [item, find(city == order(j))]; city(find(city == order(j))) = []; end %按照上文规则,根据顺序生成染色体item item = [item, 1]; item = num2str(item); item(find(item==' ')) = []; parent.chrom = [parent.chrom; item]; %其实没必要转化成字符串 %若城市数大于9(出现两位数三位数时) %采取单字节的字符串编码在交叉时就会出现问题 %直接用double数组就好 end parent.fitness = CalcFit(parent.chrom, Dist);end
上段代码中本来为了节省空间,将编码转为字符串。但在调试的过程中发现当城市数大于9后两位数的城市代码会破坏原先字符串的单字节特性,使交叉操作出现错误。故应该直接采取double数字编码。
采用随机生成的数据,照样是当某解重复出现十次以上时认为算法收敛。应用自适应的交叉变异概率的遗传算法,可以得到某一次代码运行时,随机生成的TSP解的示意图:
贴出本代码之前,还有一些说明:
1. 本次计算中,由于TSP问题的特殊性,还加入了精英原则,即在选择操作时,保留当前适应度最高的个体。
2. 本代码中适应度计算(行走的总距离)时的解码Decode过程没有使用向量运算,而是直接循环嵌套。导致代码效率较低。有朋友想出如何用向量运算的话可以显著提高算法的运行速度。
3. 遗传算法得出的是较优解,不保证每次最优。
%%%缂栫爜鏂瑰紡锟?鍩烘湰浜岃繘鍒剁紪锟?%Input: FitFunc: Any function% pCrossover: probability of crossover, default 0.5% pMutation: probability of mutation, default 0.04% GroupNum: number of individuals of the virtual group, default 30% MaxIter: maximum iterations% MaxRepeat: (optional)determine the convergence standard 鍒ゆ柇鏀舵暃%parent.fitness%parent.chromfunction iter = GA_TSP(pCrossover, pMutation, GroupNum, MaxIter, MaxRepeat) % Default parameters if nargin < 6 MaxRepeat = 10; if nargin < 5 MaxIter = 1000; if nargin < 4 GroupNum = 10; if nargin < 3 pMutation = 0.03; if nargin < 2 pCrossover = 0.45; end end end end end NumCity = 9; CityPos = 10 * rand(NumCity, 2) + 10; Dist = zeros(NumCity, NumCity) for i = 1:NumCity for j = i+1:NumCity Dist(i, j) = sqrt((CityPos(i, 1) - CityPos(j, 1))^2 + (CityPos(i, 2) - CityPos(j, 2))^2); Dist(j, i) = Dist(i, j); end end Result = []; epsilon = 1e-4; iter = 0; iRepeat = 1; thisMax = 0; parent = InitGroup(GroupNum, Dist); %Generate initial population while iter < MaxIter%% Heredity children1 = Crossover(parent, pCrossover/iter^0.1); %Return crossovered chromes children.chrom = []; children.fitness = []; children.chrom = Mutation([parent.chrom; children1], pMutation/iter^0.1); children.fitness = CalcFit(children.chrom, Dist); children = select(children, GroupNum); parent = children; iter = iter + 1; %parent.chrom; %[m, I] = max(parent.fitness) if abs((thisMax-max(parent.fitness))/max(parent.fitness)) < epsilon (thisMax-max(parent.fitness))/max(parent.fitness); iRepeat = iRepeat + 1; if iRepeat == 10 break end else iRepeat = 1; end [thisMax, I] = max(parent.fitness);%% Decode axis([0 22 0 22]) order = []; city = 1 : NumCity; for j = 1 : NumCity order = [order, city( 1 + rem(str2num(parent.chrom(I(1), j))-1, length(city)) )]; city(1 + rem(str2num(parent.chrom(I(1), j))-1, length(city))) = []; end disp(200 - thisMax); Result = [Result; thisMax]; end %% Draw scatter(CityPos(:,1), CityPos(:,2)); hold on order for j = 1 : NumCity plot([CityPos(order(j),1) CityPos(order(rem(j, NumCity)+1),1)], [CityPos(order(j),2) CityPos(order(rem(j, NumCity)+1),2)],'r'); end hold offend%Encoding method: function parent = InitGroup(GroupNum, Dist) parent.fitness = []; parent.chrom = []; NumCity= size(Dist, 2); for i = 1:GroupNum city = 1 : NumCity; order = randperm(NumCity); %order = num2str(order); %order(find(b-' '==0)) = []; item = []; for j = 1 : NumCity - 1 item = [item, find(city == order(j))]; city(find(city == order(j))) = []; end item = [item, 1]; item = num2str(item); item(find(item==' ')) = []; parent.chrom = [parent.chrom; item]; end parent.fitness = CalcFit(parent.chrom, Dist);end%Population = ['12345';% '23451';]%Calculate Fitnessfunction Fitness = CalcFit(Population, Dist) NumCity = size(Dist, 2); PopNum = size(Population, 1); Fitness = zeros(PopNum, 1); %Decode: %city = 1 : NumCity; %city = repmat(city, GroupNum, 1); %Population for i = 1 : PopNum order = []; city = 1 : NumCity; for j = 1 : NumCity order = [order, city( 1 + rem(str2num(Population(i, j))-1, length(city)) )]; city(1 + rem(str2num(Population(i, j))-1, length(city))) = []; end end for i = 1 : NumCity city1 = order(i); city2 = order(1 + rem(i, NumCity)); Fitness = Fitness + Dist((city1-1)*NumCity + city2); end Fitness = 200 - Fitness;end%roulette selcting method. The samefunction newPop = select(parent, PopNum) %Add: The best survive? cumFit = cumsum(parent.fitness)/sum(parent.fitness); [M, I] = max(parent.fitness); newPop.chrom(1,:) = parent.chrom(I, :); newPop.fitness(1) = parent.fitness(I); for i = 2 : PopNum index = find (cumFit - rand > 0); newPop.chrom(i,:) = parent.chrom(index(1),:); newPop.fitness(i) = parent.fitness(index(1)); endendfunction childrenChrom = Crossover(parent, pCrossover) [PopNum, CityNum] = size(parent.chrom); childrenChrom = []; [M, I] = max(parent.fitness); childrenChrom = parent.chrom(I, :); %Parent with highest fitness for i = 1 : PopNum/2 RandCross = rand(1); if RandCross < pCrossover i = fix(rand(1)*PopNum + 1); j = fix(rand(1)*PopNum + 1); while i == j i = fix(rand(1)*PopNum + 1); j = fix(rand(1)*PopNum + 1); end BreakPoint = fix(rand(1)*CityNum + 1); temp = parent.chrom(i, 1:BreakPoint); parent.chrom(i, 1:BreakPoint) = parent.chrom(j, 1:BreakPoint); parent.chrom(j, 1:BreakPoint) = temp; childrenChrom = [childrenChrom; parent.chrom(i, :); parent.chrom(j, :)]; end endendfunction childrenChrom = Mutation(chrom, pMutation) [PopNum, CityNum] = size(chrom); childrenChrom = chrom; for i = 1:PopNum for j = 1:CityNum if rand < pMutation childrenChrom(i, j) = num2str(floor(rand*CityNum)+1); end end end end
- 遗传算法(三)解TSP问题
- 遗传算法 TSP问题 C++实现 (三)
- 遗传算法解TSP问题 python实现
- 遗传算法解决TSP问题
- 遗传算法解决tsp问题
- 遗传算法求解TSP问题
- 遗传算法解决TSP问题
- 遗传算法解决TSP问题
- 遗传算法解决TSP问题
- 遗传算法解决tsp问题
- 遗传算法求解TSP问题
- 遗传算法解决TSP问题
- 遗传算法及TSP问题
- 遗传算法解决TSP问题
- 遗传算法求解TSP问题
- 算法笔记(XII) 遗传算法与TSP问题
- 遗传算法解TSP问题的C++源码
- 遗传算法实现 但货郎问题(tsp)
- Machine Works UVALive
- JavaScript编写验证码
- Windows下Anaconda的安装和简单使用
- 1566:逆反质数
- 容器
- 遗传算法(三)解TSP问题
- 题目19:擅长排列的小明
- Tyvj1079
- 实验一 集合的定义与运算
- 写一个不能被继承的类
- git pull 出现错误
- Linux下Redis的安装和部署
- dubbo 使用学习八(异步调用
- 问题 A: 二哈学A+B