判别无向图g中指定的两个顶点之间是否存在一条长度为k的简单路径_图与网络 | 最短路径问题与MATLAB实现...

2dbdb135f16454b1a0a42cb9be1c9d1e.png

点击蓝字关注我们

图与网络是运筹学(Operations Research)中的一个经典和重要的分支,所研究的问题涉及经济管理、工业工程、交通运输、计算机科学与信息技术、通讯与网络技术等诸多领域。下面将要讨论的最短路问题、最大流问题、最小费用流问题和匹配问题等都是图与网络的基本问题。

网络优化问题举例

例 1

最短路问题(SPP-shortest path problem)

一名货柜车司机奉命在最短的时间内将一车货物从甲地运往乙地。从甲地到乙地的公路网纵横交错,因此有多种行车路线,这名司机应选择哪条线路呢?假设货柜车的运行速度是恒定的,那么这一问题相当于需要找到一条从甲地到乙地的最短路。

例 2

公路连接问题

某一地区有若干个主要城市,现准备修建高速公路把这些城市连接起来,使得从其中任何一个城市都可以经高速公路直接或间接到达另一个城市。假定已经知道了任意两个城市之间修建高速公路的成本,那么应如何决定在哪些城市间修建高速公路,使得总成本最小?

例 3  

指派问题(assignment problem)

一家公司经理准备安排 N 名员工去完成 N 项任务,每人一项。由于各员工的特点不同,不同的员工去完成同一项任务时所获得的回报是不同的。如何分配工作方案可以使总回报最大?

例 4  

中国邮递员问题(CPP-chinese postman problem)

一名邮递员负责投递某个街区的邮件。如何为他(她)设计一条最短的投递路线(从邮局出发,经过投递区内每条街道至少一次,最后返回邮局)?由于这一问题是我国管梅谷教授 1960 年首先提出的,所以国际上称之为中国邮递员问题。

例 5 

旅行商问题(TSP-traveling salesman problem)

一名推销员准备前往若干城市推销产品。如何为他(她)设计一条最短的旅行路线(从驻地出发,经过每个城市恰好一次,最后返回驻地)?这一问题的研究历史十分悠久,通常称之为旅行商问题。

例 6 

运输问题(transportation problem)

某种原材料有 M 个产地,现在需要将原材料从产地运往 N 个使用这些原材料的工厂。假定 M 个产地的产量和 N 家工厂的需要量已知,单位产品从任一产地到任一工厂的运费已知,那么如何安排运输方案可以使总运输成本最低?

上面例子中介绍的问题都是网络优化问题。上述问题有两个共同的特点

一是它们的目的都是从若干可能的安排或方案中寻求某种意义下的最优安排或方案,数学上把这种问题称为最优化或优化(optimization)问题

二是它们都易于用图形的形式直观地描述和表达,数学上把这种与图相关的结构称为网络(network)。与图和网络相关的最优化问题就是网络最优化或称网络优化(netwok optimization)问题。

应用—最短路问题

两个指定顶点之间的最短路径

问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,找一条最短铁路线。

以各城镇为图 G 的顶点,两城镇间的直通铁路为图 G 相应两顶点间的边,得图 G 。

对 G 的每一边 e ,赋以一个实数 w(e) —直通铁路的长度,称为 e 的权,得到赋权图 G 。G 的子图的权是指子图的各边的权和。问题就是求赋权图 G 中指定的两个顶点 u0 , v0间的具最小权的轨。这条轨叫做 u0 , v0 间的最短路,它的权叫做 u0 , v0 间的距离,亦记作 d (u0 , v0 ) 。

求最短路已有成熟的算法:迪克斯特拉(Dijkstra)算法,其基本思想是按距 u0 从近到远为顺序,依次求得 u0 到 G 的各顶点的最短路和距离,直至 v0 (或直至 G 的所有顶点),算法结束。为避免重复并保留每一步的计算信息,采用了标号算法。下面是该算法。

568dc7ed0237ebd09cd3641eb6103d1c.png

算法结束时,从 u0 到各顶点 v 的距离由 v 的最后一次的标号 l(v) 给出。在 v 进入 Si 之前的标号 l(v) 叫 T 标号, v 进入 Si 时的标号 l(v) 叫 P 标号。算法就是不断修改各顶点的 T 标号,直至获得 P 标号。若在算法运行过程中,将每一顶点获得 P 标号所由来的边在图上标明,则算法结束时, u0 至各项点的最短路也在图上标示出来了。

例 7

某公司在六个城市 c1, c2 ,L, c6 中有分公司,从 ci 到 cj 的直接航程票价记在下述矩阵的 (i, j) 位置上。( ∞ 表示无直接航路),请帮助该公司设计一张城市 c1 到其它城市间的票价最便宜的路线图。

8a5f3fccd944ed80610f5245106ea3f1.png

用矩阵 an×n( n 为顶点个数)存放各边权的邻接矩阵,行向量 pb 、index₁ 、index₂ 、

d 分别用来存放 P 标号信息、标号顶点顺序、标号顶点索引、最短通路的值。其中分量

06f6ef71ea5cf2be39ada6da2a1ab953.png

求第一个城市到其它城市的最短路径的 Matlab 程序如下:

clc,clear

a=zeros(6);

a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;

a(2,3)=15;a(2,4)=20;a(2,6)=25;

a(3,4)=10;a(3,5)=20;

a(4,5)=10;a(4,6)=25;

a(5,6)=55;

a=a+a';

a(find(a==0))=inf;

pb(1:length(a))=0;pb(1)=1;index1=1;index2=ones(1,length(a));

d(1:length(a))=inf;d(1)=0;temp=1;

while sum(pb)

tb=find(pb==0);

d(tb)=min(d(tb),d(temp)+a(temp,tb));

tmpb=find(d(tb)==min(d(tb)));

temp=tb(tmpb(1));

pb(temp)=1;

index1=[index1,temp];

temp2=find(d(index1)==d(temp)-a(temp,index1));

index2(temp)=index1(temp2(1));

end

d, index1, index2

 两个指定顶点之间最短路问题的数学表达式

假设有向图有 n 个顶点,现需要求从顶点 1 到顶点 n 的最短路。设

83402bd0d16e9a2c1a7b103a2691f12c.png

 为赋权邻接矩阵,其分量为

ab7c4fcc34ab1d0f0f69eeed7fef7d02.png d97aa262c7af5e5a1b5d8f92c5eb0e60.png

例 8

在图1 中,用点表示城市,现有 A, B1, B2 , C1 , C2 , C3 , D 共 7 个城市。点与点之间的连线表示城市间有道路相连。连线旁的数字表示道路的长度。现计划从城市 A 到城市 D 铺设一条天然气管道,请设计出最小价格管道铺设方案。

4515d1e26363032d1254a11a74f9e649.png

图1 七个城市间的连线图

编写 LINGO 程序如下

model:

sets:

cities/A,B1,B2,C1,C2,C3,D/;

roads(cities,cities)/A B1,A B2,B1 C1,B1 C2,B1 C3,B2 C1, B2 C2,B2 C3,C1 D,C2 D,C3 D/:w,x; endsets

data:

w=2 4 3 3 1 2 3 1 1 3 4;

enddata

n=@size(cities); !城市的个数;

min=@sum(roads:w*x);

@for(cities(i)|i #ne#1 #and# i #ne#n:

@sum(roads(i,j):x(i,j))=@sum(roads(j,i):x(j,i))); @sum(roads(i,j)|i #eq#1:x(i,j))=1; @sum(roads(i,j)|j #eq#n:x(i,j))=1;

end

例9

无向图的最短路问题

求图 2中v1到v11的最短路。分析例8处理的问题属于有向图的最短路问题,本例是处理无向图的最短路问题,在处理方式上与有向图的最短路问题有一些差别,这里选择赋权邻接矩阵的方法编写 LINGO 程序。

3a9d857a39fbbabb572e1a57c392ebc0.png

图2 无向图的最短路问题

编写 LINGO 程序如下

model:

sets:

cities/1..11/;

roads(cities,cities):w,x;

endsets

data:

w=0;

enddata

calc:

w(1,2)=2;w(1,3)=8;w(1,4)=1;

w(2,3)=6;w(2,5)=1;

w(3,4)=7;w(3,5)=5;w(3,6)=1;w(3,7)=2;

w(4,7)=9;

w(5,6)=3;w(5,8)=2;w(5,9)=9;

w(6,7)=4;w(6,9)=6;

w(7,9)=3;w(7,10)=1;

w(8,9)=7;w(8,11)=9;

w(9,10)=1;w(9,11)=2;w(10,11)=4; @for(roads(i,j):w(i,j)=w(i,j)+w(j,i)); @for(roads(i,j):w(i,j)=@if(w(i,j) #eq# 0, 1000,w(i,j))); 

endcalc

n=@size(cities); !城市的个数;

min=@sum(roads:w*x);

@for(cities(i)|i #ne#1 #and# i #ne#

n:@sum(cities(j):x(i,j))=@sum(cities(j):x(j,i)));

@sum(cities(j):x(1,j))=1;

@sum(cities(j):x(j,1))=0; !不能回到顶点1; 

@sum(cities(j):x(j,n))=1; 

@for(roads:@bin(x)); 

end

与有向图相比较,在程序中只增加了一个语句@sum(cities(j):x(j,1))=0,即从顶点 1 离开后,再不能回到该顶点。

求得的最短路径为1→2→5→6→3→7→10→9→11

最短路径长度为 13。

每对顶点之间的最短路径

计算赋权图中各对顶点之间最短路径,显然可以调用 Dijkstra 算法。具体方法是:每次以不同的顶点作为起点,用 Dijkstra 算法求出从该起点到其余顶点的最短路径,反复执行 n −1次这样的操作,就可得到从每一个顶点到其它顶点的最短路径。这种算法的时间复杂度为 O(n³) 。第二种解决这一问题的方法是由 Floyd R W 提出的算法,称之为 Floyd 算法。

6e948327fc865f5d64fda78a9ba1a530.png

假设图 G 权的邻接矩阵为de87600c9548054ccb2082d7667af9ff.png

b0c9065663cff5896d193dcde2086ac5.png

来存放各边长度,其中:

93e5f4d9c238d320c6b861757761ffcf.png

Floyd 算法的基本思想是:递推产生一个矩阵序列aeaff3bd7dc0ce2a59d11720d8351f75.png ,其中 edfea31b87a34b3e64e0a9b0269b4fad.png 表示从顶点 f616b748bd2f275b9b7e08297a6e4000.png 到顶点 76f61a6ed4de2c2ce691bd14b9f8de35.png 的路径上所经过的顶点序号不大于 k 的最短路径长度。

计算时用迭代公式:

400230cc732464b517fffecf40a5b568.png

k 是迭代次数, i, j, k = 1,2,......, n 。

最后,当 k = n 时, An 即是各顶点之间的最短通路值。

例10

用Floyd算法求解例7

矩阵path用来存放每对顶点之间最短路径上所经过的顶点的序号。Floyd算法的Matlab程序如下:

clear;clc;

n=6; a=zeros(n);

a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;

a(2,3)=15;a(2,4)=20;a(2,6)=25; a(3,4)=10;a(3,5)=20;

a(4,5)=10;a(4,6)=25; a(5,6)=55;

a=a+a'; M=max(max(a))*n^2; %M为充分大的正实数 a=a+((a==0)-eye(n))*M; path=zeros(n);

for k=1:n

for i=1:n

for j=1:n

if a(i,j)>a(i,k)+a(k,j)

a(i,j)=a(i,k)+a(k,j);

path(i,j)=k;

end

end

end

end

a, path

•  END  •

f59dcc4641feaa2deccfac9ff90a23f5.png 2b8aedbfc5391cd1eb51774476998b5e.png c8e16cba4a2c58f85886e95eac0136a6.png 2b8aedbfc5391cd1eb51774476998b5e.png

微信号 :smlyor

数模乐园

倡导和践行数学建模应用社会化

● 扫码关注我们 ●

8a53c9974be70f2e61f68cb1a8f3556d.gif

球分享

8a53c9974be70f2e61f68cb1a8f3556d.gif

球点赞

8a53c9974be70f2e61f68cb1a8f3556d.gif

球在看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值