matlab中图的表示
顶点集+权值集的形式
s=[1 2 3];
t=[4 1 2];
w=[5 2 6];
G=graph(s,t,w);
plot(G,'EdgeLabel',G.Edges.Weight,'LineWidth',2);
set(gca,'XTick',[],'YTick',[]);%设置x和y的坐标范围
*邻接矩阵转图(常见)
- 无向图
%% matlab中邻接矩阵转无向图
clear;clc;
A = [0 1 0 0 2;%矩阵A必须是对称的,这样直接传入是错误的!!!
1 0 3 0 0;
0 0 0 4 0;
0 0 0 0 5;
0 0 0 5 0];
G = graph(A);%直接转换
plot(G,"EdgeLabel",G.Edges.Weight,'LineWidth',2);
set(gca,'XTick',[],'YTick',[]);%设置x和y的坐标范围
- 有向图
%% matlab中邻接矩阵转有向图
clear;clc;
A = [0 1 0 0 2;
1 0 3 0 0;
0 0 0 4 0;
0 0 0 0 5;
0 0 0 5 0];
G = digraph(A);%直接转换
plot(G,"EdgeLabel",G.Edges.Weight,'LineWidth',2);
set(gca,'XTick',[],'YTick',[]);%设置x和y的坐标范围
最短路算法
dijsktra算法
- 注意负权值不可以使用dijsktra算法
matlab代码
%% dijkstra算法
[P,d]=shortestpath(G,1,4);%路径数组和距离
disp(P);disp(d);
网络最大流
网络最大流问题的概念
- 流量图
- 可行流
- 增广链
Ford Fulkerson算法
matlab代码
%% matlab求解网络最大流问题
clear;clc;
a=zeros(7);
a(1,2)=4;a(1,4)=3;a(1,5)=10;
a(2,3)=1;a(2,4)=3;a(3,7)=7;
a(4,3)=4;a(4,6)=5;a(5,3)=3;
a(5,4)=3;a(5,6)=4;a(6,7)=8;
matrix=digraph(a);
plot(matrix,"EdgeLabel",matrix.Edges.Weight,"LineWidth",2);
mf=maxflow(matrix,1,7)%%不接受邻接矩阵,只接受有向图
最小费用最大流问题
解题思路
Floyd算法
function[path,dis]=Floyd(w)
dis=w;
n=size(w);
path=zeros(n);
for k=1:n
for i=1:n
for j=1:n
if(dis(i,k)+dis(k,j)<dis(i,j))
dis(i,j)=dis(i,k)+dis(k,j);
path(i,j)=k;
end
end
end
end
end
最终代码(详细注释)
cost_all=0;
vector=input("请输入出发点和终点");
while(1)%死循环
[path,dis]=Floyd(w);
i=vector(1);
j=vector(2);
mypath=[j];
%获取路径数组
while path(i,j)~=0
j=path(i,j);
mypath=[mypath j];%matlab中数组拼接操作
end
mypath=[i fliplr(mypath)];
if size(mypath,2)==2%%如果size等于2说明没有最短路了
break;
end
%计算最大流过程
max_x=[+inf];
for i=2:size(mypath,2)%%注意size也是默认对行求长度
max_x=[max_x min(max_x(i-1),c(mypath(i-1),mypath(i))-x(mypath(i-1),mypath(i)))];
end
delta=min(max_x);
%每条边加上流量
for i=2:size(mypath,2)
x(mypath(i-1),mypath(i))=x(mypath(i-1),mypath(i))+delta;
cost_all=cost_all+delta*w(mypath(i-1),mypath(i));%这里是增量乘以权值
end
%添加弧的过程
for i=2:size(mypath,2)
if(x(mypath(i-1),mypath(i)))==c(mypath(i-1),mypath(i))
%只能添加反向弧
w(mypath(i),mypath(i-1))=-w(mypath(i-1),mypath(i));
%删除原弧
c(mypath(i-1),mypath(i))=0;
w(mypath(i-1),mypath(i))=+inf;
end
if x(mypath(i-1),mypath(i))<c(mypath(i-1),mypath(i))&&x(mypath(i-1),mypath(i))>0
w(mypath(i),mypath(i-1))=-w(mypath(i-1),mypath(i));
end
end
%统计费用的过程
end
disp("最小费用最大流的结果是");cost_all
旅行商TSP问题
解题思路
改良圈算法
具体步骤
matlab代码
%% 旅行熵问题
clear;clc;
A = [0 56 21 35;%邻接矩阵
56 0 49 39;
21 49 0 77;
35 39 77 0;]
L=size(A,1);%长度是哈密顿图长度-1
c=[1 2 3 4 1];
res=+inf;
for k=1:L
flag=0;
%暴力模拟选i和j的情况,注意TSP要求i<i+1<j,
for i=1:L-2;
for j=i+2:L
%反转i+1~j的路径
if A(c(i),c(j))+A(c(i+1),c(j+1))<A(c(i),c(i+1))+A(c(j),c(j+1))
c(i+1:j)=c(j:-1:i+1);%反转i+1~j的路径
flag=1;
end
end
end
if flag==1
temp=0;
for i=1:L
temp=temp+A(c(i),c(i+1));
end
res=min(res,temp);
end
end
res
%需要注意的是,这个求法依赖于种子c的取值