# MAT之GA：遗传算法（GA）解决M-TSP多旅行商问题

+关注继续查看

## 实现代码

% MTSP_GA Multiple Traveling Salesmen Problem (M-TSP) Genetic Algorithm (GA)

%   Finds a (near) optimal solution to the M-TSP by setting up a GA to search

%   for the shortest route (least distance needed for the salesmen to travel

%   to each city exactly once and return to their starting locations)

%

% Summary:

%     1. Each salesman travels to a unique set of cities and completes the

%        route by returning to the city he started from

%     2. Each city is visited by exactly one salesman

%

% Input:

%     XY (float) is an Nx2 matrix of city locations, where N is the number of cities

%     DMAT (float) is an NxN matrix of city-to-city distances or costs

%     NSALESMEN (scalar integer) is the number of salesmen to visit the cities

%     MINTOUR (scalar integer) is the minimum tour length for any of the salesmen

%     POPSIZE (scalar integer) is the size of the population (should be divisible by 8)

%     NUMITER (scalar integer) is the number of desired iterations for the algorithm to run

%     SHOWPROG (scalar logical) shows the GA progress if true

%     SHOWRESULT (scalar logical) shows the GA results if true

%

% Output:

%     OPTROUTE (integer array) is the best route found by the algorithm

%     OPTBREAK (integer array) is the list of route break points (these specify the indices

%         into the route used to obtain the individual salesman routes)

%     MINDIST (scalar float) is the total distance traveled by the salesmen

%

% Route/Breakpoint Details:

%     If there are 10 cities and 3 salesmen, a possible route/break

%     combination might be: rte = [5 6 9 1 4 2 8 10 3 7], brks = [3 7]

%     Taken together, these represent the solution [5 6 9][1 4 2 8][10 3 7],

%     which designates the routes for the 3 salesmen as follows:

%         . Salesman 1 travels from city 5 to 6 to 9 and back to 5

%         . Salesman 2 travels from city 1 to 4 to 2 to 8 and back to 1

%         . Salesman 3 travels from city 10 to 3 to 7 and back to 10

%

% Example:

%     n = 35;

%     xy = 10*rand(n,2);

%     nSalesmen = 5;

%     minTour = 3;

%     popSize = 80;

%     numIter = 5e3;

%     a = meshgrid(1:n);

%     dmat = reshape(sqrt(sum((xy(a,:)-xy(a',:)).^2,2)),n,n);

%     [optRoute,optBreak,minDist] = mtsp_ga(xy,dmat,nSalesmen,minTour, ...

%         popSize,numIter,1,1);

%

% Example:

%     n = 50;

%     phi = (sqrt(5)-1)/2;

%     theta = 2*pi*phi*(0:n-1);

%     rho = (1:n).^phi;

%     [x,y] = pol2cart(theta(:),rho(:));

%     xy = 10*([x y]-min([x;y]))/(max([x;y])-min([x;y]));

%     nSalesmen = 5;

%     minTour = 3;

%     popSize = 80;

%     numIter = 1e4;

%     a = meshgrid(1:n);

%     dmat = reshape(sqrt(sum((xy(a,:)-xy(a',:)).^2,2)),n,n);

%     [optRoute,optBreak,minDist] = mtsp_ga(xy,dmat,nSalesmen,minTour, ...

%         popSize,numIter,1,1);

%

% Example:

%     n = 35;

%     xyz = 10*rand(n,3);

%     nSalesmen = 5;

%     minTour = 3;

%     popSize = 80;

%     numIter = 5e3;

%     a = meshgrid(1:n);

%     dmat = reshape(sqrt(sum((xyz(a,:)-xyz(a',:)).^2,2)),n,n);

%     [optRoute,optBreak,minDist] = mtsp_ga(xyz,dmat,nSalesmen,minTour, ...

%         popSize,numIter,1,1);

%

%

function varargout = mtsp_ga(xy,dmat,nSalesmen,minTour,popSize,numIter,showProg,showResult)

% Process Inputs and Initialize Defaults

nargs = 8;

for k = nargin:nargs-1

switch k

case 0

xy = 10*rand(40,2);

case 1

N = size(xy,1);

a = meshgrid(1:N);

dmat = reshape(sqrt(sum((xy(a,:)-xy(a',:)).^2,2)),N,N);

case 2

nSalesmen = 5;

case 3

minTour = 3;

case 4

popSize = 80;

case 5

numIter = 5e3;

case 6

showProg = 1;

case 7

showResult = 1;

otherwise

end

end

% Verify Inputs

[N,dims] = size(xy);

[nr,nc] = size(dmat);

if N ~= nr || N ~= nc

error('Invalid XY or DMAT inputs!')

end

n = N;

% Sanity Checks

nSalesmen = max(1,min(n,round(real(nSalesmen(1)))));

minTour = max(1,min(floor(n/nSalesmen),round(real(minTour(1)))));

popSize = max(8,8*ceil(popSize(1)/8));

numIter = max(1,round(real(numIter(1))));

showProg = logical(showProg(1));

showResult = logical(showResult(1));

% Initializations for Route Break Point Selection

nBreaks = nSalesmen-1;

dof = n - minTour*nSalesmen;          % degrees of freedom

for k = 2:nBreaks

end

% Initialize the Populations

popRoute = zeros(popSize,n);         % population of routes

popBreak = zeros(popSize,nBreaks);   % population of breaks

popRoute(1,:) = (1:n);

popBreak(1,:) = rand_breaks();

for k = 2:popSize

popRoute(k,:) = randperm(n);

popBreak(k,:) = rand_breaks();

end

% Select the Colors for the Plotted Routes

pclr = ~get(0,'DefaultAxesColor');

clr = [1 0 0; 0 0 1; 0.67 0 1; 0 1 0; 1 0.5 0];

if nSalesmen > 5

clr = hsv(nSalesmen);

end

% Run the GA

globalMin = Inf;

totalDist = zeros(1,popSize);

distHistory = zeros(1,numIter);

tmpPopRoute = zeros(8,n);

tmpPopBreak = zeros(8,nBreaks);

newPopRoute = zeros(popSize,n);

newPopBreak = zeros(popSize,nBreaks);

if showProg

pfig = figure('Name','MTSP_GA | Current Best Solution','Numbertitle','off');

end

for iter = 1:numIter

% Evaluate Members of the Population

for p = 1:popSize

d = 0;

pRoute = popRoute(p,:);

pBreak = popBreak(p,:);

rng = [[1 pBreak+1];[pBreak n]]';

for s = 1:nSalesmen

d = d + dmat(pRoute(rng(s,2)),pRoute(rng(s,1)));

for k = rng(s,1):rng(s,2)-1

d = d + dmat(pRoute(k),pRoute(k+1));

end

end

totalDist(p) = d;

end

% Find the Best Route in the Population

[minDist,index] = min(totalDist);

distHistory(iter) = minDist;

if minDist < globalMin

globalMin = minDist;

optRoute = popRoute(index,:);

optBreak = popBreak(index,:);

rng = [[1 optBreak+1];[optBreak n]]';

if showProg

% Plot the Best Route

figure(pfig);

for s = 1:nSalesmen

rte = optRoute([rng(s,1):rng(s,2) rng(s,1)]);

if dims > 2, plot3(xy(rte,1),xy(rte,2),xy(rte,3),'.-','Color',clr(s,:));

else plot(xy(rte,1),xy(rte,2),'.-','Color',clr(s,:)); end

title(sprintf('Total Distance = %1.4f, Iteration = %d',minDist,iter));

hold on

end

hold off

end

end

% Genetic Algorithm Operators

randomOrder = randperm(popSize);

for p = 8:8:popSize

rtes = popRoute(randomOrder(p-7:p),:);

brks = popBreak(randomOrder(p-7:p),:);

dists = totalDist(randomOrder(p-7:p));

[ignore,idx] = min(dists); %#ok

bestOf8Route = rtes(idx,:);

bestOf8Break = brks(idx,:);

routeInsertionPoints = sort(ceil(n*rand(1,2)));

I = routeInsertionPoints(1);

J = routeInsertionPoints(2);

for k = 1:8 % Generate New Solutions

tmpPopRoute(k,:) = bestOf8Route;

tmpPopBreak(k,:) = bestOf8Break;

switch k

case 2 % Flip

tmpPopRoute(k,I:J) = tmpPopRoute(k,J:-1:I);

case 3 % Swap

tmpPopRoute(k,[I J]) = tmpPopRoute(k,[J I]);

case 4 % Slide

tmpPopRoute(k,I:J) = tmpPopRoute(k,[I+1:J I]);

case 5 % Modify Breaks

tmpPopBreak(k,:) = rand_breaks();

case 6 % Flip, Modify Breaks

tmpPopRoute(k,I:J) = tmpPopRoute(k,J:-1:I);

tmpPopBreak(k,:) = rand_breaks();

case 7 % Swap, Modify Breaks

tmpPopRoute(k,[I J]) = tmpPopRoute(k,[J I]);

tmpPopBreak(k,:) = rand_breaks();

case 8 % Slide, Modify Breaks

tmpPopRoute(k,I:J) = tmpPopRoute(k,[I+1:J I]);

tmpPopBreak(k,:) = rand_breaks();

otherwise % Do Nothing

end

end

newPopRoute(p-7:p,:) = tmpPopRoute;

newPopBreak(p-7:p,:) = tmpPopBreak;

end

popRoute = newPopRoute;

popBreak = newPopBreak;

end

if showResult

% Plots

figure('Name','MTSP_GA | Results','Numbertitle','off');

subplot(2,2,1);

if dims > 2, plot3(xy(:,1),xy(:,2),xy(:,3),'.','Color',pclr);

else plot(xy(:,1),xy(:,2),'.','Color',pclr); end

title('City Locations');

subplot(2,2,2);

imagesc(dmat(optRoute,optRoute));

title('Distance Matrix');

subplot(2,2,3);

rng = [[1 optBreak+1];[optBreak n]]';

for s = 1:nSalesmen

rte = optRoute([rng(s,1):rng(s,2) rng(s,1)]);

if dims > 2, plot3(xy(rte,1),xy(rte,2),xy(rte,3),'.-','Color',clr(s,:));

else plot(xy(rte,1),xy(rte,2),'.-','Color',clr(s,:)); end

title(sprintf('Total Distance = %1.4f',minDist));

hold on;

end

subplot(2,2,4);

plot(distHistory,'b','LineWidth',2);

title('Best Solution History');

set(gca,'XLim',[0 numIter+1],'YLim',[0 1.1*max([1 distHistory])]);

end

% Return Outputs

if nargout

varargout{1} = optRoute;

varargout{2} = optBreak;

varargout{3} = minDist;

end

% Generate Random Set of Break Points

function breaks = rand_breaks()

if minTour == 1 % No Constraints on Breaks

tmpBreaks = randperm(n-1);

breaks = sort(tmpBreaks(1:nBreaks));

else % Force Breaks to be at Least the Minimum Tour Length

for kk = 1:nBreaks

end

end

end

end

JAVA常见算法题(十八)
package com.xiaowu.demo; /** * 两个乒乓球队进行比赛，各出三人。甲队为a，b，c三人，乙队为x，y，z三人，以抽签决定比赛名单。 有人向队员打听比赛的名单：a说他不和x比，c说他不和x、 * z比。
555 0
JAVA常见算法题(十九)
package com.xiaowu.demo; /** * * 有一分数序列：2/1，3/2，5/3，8/5，13/8，21/13...求出这个数列的前20项之和。 * * * @author WQ * */ public class Demo19 { public...
581 0
JAVA常见算法题(十)
package com.xiaowu.demo; /** * 一球从100米高度自由落下，每次落地后反跳回原高度的一半；再落下……求它在第10次落地时，共经过多少米？第10次反弹多高？ * * @author WQ * */ public class Demo10 { pub...
601 0
JAVA常见算法题(十二)
package com.xiaowu.demo; /** * 完全平方即用一个整数乘以自己例如1*1，2*2，3*3等，依此类推。若一个数能表示成某个整数的平方的形式，则称这个数为完全平方数。 * 完全平方数是非负数，而一个完全平方数的项有两个。
635 0
JAVA常见算法题(十五)
package com.xiaowu.demo; /** * * 输入三个整数x，y，z，请把这三个数由小到大输出。 * * @author WQ * */ public class Demo15 { public static void main(String[] ar...
533 0
JAVA常见算法题(十四)
package com.xiaowu.demo; /** * 输入某年某月某日，判断这一天是这一年的第几天？ * * * @author WQ * */ public class Demo14 { public static void main(String[] arg...
703 0
JAVA常见算法题(十一)
package com.xiaowu.demo; /** * 有1、2、3、4个数字，能组成多少个互不相同且无重复数字的三位数？都是多少？ * * * @author WQ * */ public class Demo11 { public static void ma...
548 0
+关注

1701

0

《SaaS模式云原生数据仓库应用场景实践》

《看见新力量：二》电子书