【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)

文章目录

    • 图与网络
      • 1 概论
      • 2 图与网络的基本概念
        • 2.1 无向图
        • 2.2 有向图
        • 2.3 完全图、二分图
        • 2.4 子图
        • 2.5 顶点的度
        • 2.6 图与网络的数据结构
      • 3 应用—最短路问题
        • 3.1 两个指定顶点之间的最短路径
        • 3.2 两个指定顶点之间最短路问题的数学表达式
        • 3.3 每对顶点之间的最短路径
      • 4 树
        • 4.1 基本概念
        • 4.2 应用—连线问题
          • 4.2.1 prim 算法构造最小生成树
          • 4.2.2 Kruskal 算法构造最小生成树
      • 5 邮递员问题

图与网络

1 概论

图论起源于 18 世纪。第一篇图论论文是瑞士数学家欧拉于 1736 年发表的“哥尼斯堡的七座桥”。1847 年,克希霍夫为了给出电网络方程而引进了“树”的概念。1857年,凯莱在计数烷CnH2n+2 的同分异构物时,也发现了“树”。哈密尔顿于 1859 年提出“周游世界”游戏,用图论的术语,就是如何找出一个连通图中的生成圈、近几十年来,由于计算机技术和科学的飞速发展,大大地促进了图论研究和应用,图论的理论和方法已经渗透到物理、化学、通讯科学、建筑学、运筹学,生物遗传学、心理学、经济学、社会学等学科中。

图论中所谓的“图”是指某类具体事物和这些事物之间的联系。如果我们用点表示这些具体事物,用连接两点的线段(直的或曲的)表示两个事物的特定的联系,就得到了描述这个“图”的几何形象。图论为任何一个包含了一种二元关系的离散系统提供了一个数学模型,借助于图论的概念、理论和方法,可以对该模型求解。哥尼斯堡七桥问题就是一个典型的例子。在哥尼斯堡有七座桥将普莱格尔河中的两个岛及岛与河岸联结起来,问题是要从这四块陆地中的任何一块开始通过每一座桥正好一次,再回到起点。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第1张图片

当然可以通过试验去尝试解决这个问题,但该城居民的任何尝试均未成功。欧拉为了解决这个问题,采用了建立数学模型的方法。他将每一块陆地用一个点来代替,将每一座桥用连接相应两点的一条线来代替,从而得到一个有四个“点”,七条“线”的“图”。

问题成为从任一点出发一笔画出七条线再回到起点。欧拉考察了一般一笔画的结构特点,给出了一笔画的一个判定法则:这个图是连通的,且每个点都与偶数线相关联,将这个判定法则应用于七桥问题,得到了“不可能走通”的结果,不但彻底解决了这个问题,而且开创了图论研究的先河。

图与网络是运筹学(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)问题。所以上面例子中介绍的问题都是网络优化问题。由于多数网络优化问题是以网络上的流(flow)为研究的对象,因此网络优化又常常被称为网络流(network flows)或网络流规划等。

下面首先简要介绍图与网络的一些基本概念。

2 图与网络的基本概念

2.1 无向图

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第2张图片

边上赋权的无向图称为赋权无向图或无向网络(undirected network)。我们对图和网络不作严格区分,因为任何图总是可以赋权的。

2.2 有向图

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第3张图片

对应于每个有向图 D ,可以在相同顶点集上作一个图G ,使得对于 D 的每条弧,G 有一条有相同端点的边与之相对应。这个图称为 D 的基础图。反之,给定任意图G ,对于它的每个边,给其端点指定一个顺序,从而确定一条弧,由此得到一个有向图,这样的有向图称为G 的一个定向图。

2.3 完全图、二分图

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第4张图片

2.4 子图

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第5张图片

2.5 顶点的度

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第6张图片

2.6 图与网络的数据结构

网络优化研究的是网络上的各种优化模型与算法。为了在计算机上实现网络优化的算法,首先我们必须有一种方法(即数据结构)在计算机上来描述图与网络。一般来说,算法的好坏与网络的具体表示方法,以及中间结果的操作方案是有关系的。这里我们介绍计算机上用来描述图与网络的 5 种常用表示方法:邻接矩阵表示法、关联矩阵表示法、弧表表示法、邻接表表示法和星形表示法。

在下面数据结构的讨论中,我们首先假设

G = (V, A)是一个简单有向图,|V |= n,| A |= m ,并假设V 中的顶点用自然数1,2,L,n表示或编号, A 中的弧用自然数1,2,L,m 表示或编号。对于有多重边或无向网络的情况,我们只是在讨论完简单有向图的表示方法之后,给出一些说明。

(i)邻接矩阵表示法

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第7张图片

也就是说,如果两节点之间有一条弧,则邻接矩阵中对应的元素为 1;否则为 0。

可以看出,这种表示法非常简单、直接。但是,在邻接矩阵的所有n2 个元素中,只有m个为非零元。如果网络比较稀疏,这种表示法浪费大量的存储空间,从而增加了在网络中查找弧的时间。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第8张图片

同样,对于网络中的权,也可以用类似邻接矩阵的n × n 矩阵表示。只是此时一条弧所对应的元素不再是 1,而是相应的权而已。如果网络中每条弧赋有多种权,则可以用多个矩阵表示这些权。

(ii)关联矩阵表示法

关联矩阵表示法是将图以关联矩阵(incidence matrix)的形式存储在计算机中.

请添加图片描述

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第9张图片

也就是说,在关联矩阵中,每行对应于图的一个节点,每列对应于图的一条弧。如果一个节点是一条弧的起点,则关联矩阵中对应的元素为 1;如果一个节点是一条弧的终点,则关联矩阵中对应的元素为 −1;如果一个节点与一条弧不关联,则关联矩阵中对应的元素为 0。对于简单图,关联矩阵每列只含有两个非零元(一个 +1,一个 −1)。

可以看出,这种表示法也非常简单、直接。但是,在关联矩阵的所有nm 个元素中,只有2m 个为非零元。如果网络比较稀疏,这种表示法也会浪费大量的存储空间。但由于关联矩阵有许多特别重要的理论性质,因此它在网络优化中是非常重要的概念。

例 8 对于例 7 所示的图,如果关联矩阵中每列对应弧的顺序为(1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4),则关联矩阵表示为

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第10张图片

同样,对于网络中的权,也可以通过对关联矩阵的扩展来表示。例如,如果网络中每条弧有一个权,我们可以把关联矩阵增加一行,把每一条弧所对应的权存储在增加的行中。如果网络中每条弧赋有多个权,我们可以把关联矩阵增加相应的行数,把每一条弧所对应的权存储在增加的行中。

(iii)弧表表示法

弧表表示法将图以弧表(arc list)的形式存储在计算机中。所谓图的弧表,也就是图的弧集合中的所有有序对。弧表表示法直接列出所有弧的起点和终点,共需2m 个存储单元,因此当网络比较稀疏时比较方便。此外,对于网络图中每条弧上的权,也要对应地用额外的存储单元表示。

例如,例 7 所示的图,假设弧(1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4)上的权分别为 8,9,6,4,0,3,6 和 7,则弧表表示如表 1所示。

请添加图片描述

为了便于检索,一般按照起点、终点的字典序顺序存储弧表,如上面的弧表就是按照这样的顺序存储的。

(iv)邻接表表示法

邻接表表示法将图以邻接表(adjacency lists)的形式存储在计算机中。所谓图的邻接表,也就是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧。邻接表表示法就是对图的每个节点,用一个单向链表列出从该节点出发的所有弧,链表中每个单元对应于一条出弧。为了记录弧上的权,链表中每个单元除列出弧的另一个端点外,还可以包含弧上的权等作为数据域。图的整个邻接表可以用一个指针数组表示。

例如,例 7 所示的图,邻接表表示为

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第11张图片

这是一个 5 维指针数组,每一维(上面表示法中的每一行)对应于一个节点的邻接表,如第 1 行对应于第 1 个节点的邻接表(即第 1 个节点的所有出弧)。每个指针单元的第 1 个数据域表示弧的另一个端点(弧的头),后面的数据域表示对应弧上的权。

如第 1 行中的“2”表示弧的另一个端点为 2(即弧为(1,2)),“8”表示对应弧(1,2)上的权为 8;“3”表示弧的另一个端点为 3(即弧为(1,3)),“9”表示对应弧(1,3)上的权为 9。

又如,第 5 行说明节点 5 出发的弧有(5,3)、(5,4),他们对应的权分别为 6 和 7。对于有向图G = (V, A),一般用 A(i) 表示节点i 的邻接表,即节点i 的所有出弧构成的集合或链表(实际上只需要列出弧的另一个端点,即弧的头)。例如上面例子,A(1) = {2,3}, A(5) = {3,4}等。

(v)星形表示法

星形(star)表示法的思想与邻接表表示法的思想有一定的相似之处。对每个节点,它也是记录从该节点出发的所有弧,但它不是采用单向链表而是采用一个单一的数组表示。

也就是说,在该数组中首先存放从节点 1 出发的所有弧,然后接着存放从节点 2出发的所有孤,依此类推,最后存放从节点n 出发的所有孤。对每条弧,要依次存放其起点、终点、权的数值等有关信息。这实际上相当于对所有弧给出了一个顺序和编号,只是从同一节点出发的弧的顺序可以任意排列。

此外,为了能够快速检索从每个节点出发的所有弧,我们一般还用一个数组记录每个节点出发的弧的起始地址(即弧的编号)。

在这种表示法中,可以快速检索从每个节点出发的所有弧,这种星形表示法称为前向星形(forward star)表示法。

例如,在例 7 所示的图中,仍然假设弧(1,2),(l,3),(2,4),(3,2),(4,3),(4,5), (5,3)和(5,4)上的权分别为 8,9,6,4,0,3,6 和 7。此时该网络图可以用前向星形表示法表示为表 2 和表 3 。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第12张图片

对于网络图的表示法,我们作如下说明:

① 星形表示法和邻接表表示法在实际算法实现中都是经常采用的。星形表示法的优点是占用的存储空间较少,并且对那些不提供指针类型的语言(如 FORTRAN 语言等)也容易实现。邻接表表示法对那些提供指针类型的语言(如 C 语言等)是方便的,且增加或删除一条弧所需的计算工作量很少,而这一操作在星形表示法中所需的计算工作量较大(需要花费O(m) 的计算时间)。有关“计算时间”的观念是网络优化中需要考虑的一个关键因素。

② 当网络不是简单图,而是具有平行弧(即多重弧)时,显然此时邻接矩阵表示法是不能采用的。其他方法则可以很方便地推广到可以处理平行弧的情形。

③ 上述方法可以很方便地推广到可以处理无向图的情形,但由于无向图中边没有方向,因此可能需要做一些自然的修改。例如,可以在计算机中只存储邻接矩阵的一半信息(如上三角部分),因为此时邻接矩阵是对称矩阵。无向图的关联矩阵只含有元素0 和 +1,而不含有 −1,因为此时不区分边的起点和终点。又如,在邻接表和星形表示法中,每条边会被存储两次,而且反向星形表示显然是没有必要的,等等。

3 应用—最短路问题

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

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

以各城镇为图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 的所有顶点),算法结束。为避免重复并保留每一步的计算信息,采用了标号算法。下面是该算法。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第13张图片

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

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第14张图片

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第15张图片

求第一个城市到其它城市的最短路径的 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)

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

假设有向图有 n 个顶点,现需要求从顶点 1 到顶点 n 的最短路。设W = (w**ij)n×n 为赋权邻接矩阵,其分量为

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第16张图片

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第17张图片

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

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第18张图片

编写 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 

例 11(无向图的最短路问题)求图 4 中v1到v11的最短路。

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

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第19张图片

编写 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。

3.3 每对顶点之间的最短路径

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

假设图G 权的邻接矩阵为 A0 ,

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第20张图片

来存放各边长度,其中:

请添加图片描述

Floyd 算法的基本思想是:递推产生一个矩阵序列 A0 , A1,L, A**k ,L, A**n ,其中A**k (i, j) 表示从顶点 v**i 到顶点 v j 的路径上所经过的顶点序号不大于 k 的最短路径长度。

计算时用迭代公式:

请添加图片描述

例12 用Floyd算法求解例9。

矩阵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

我们使用LINGO9.0编写的FLOYD算法如下:

model: 
sets: 
nodes/c1..c6/; 
link(nodes,nodes):w,path; !path标志最短路径上走过的顶点;
endsets
data: 
path=0; 
w=0; 
@text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j): 
@format(w(i,j),' 10.0f')),@newline(1)); 
@text(mydata1.txt)=@write(@newline(1)); 
@text(mydata1.txt)=@writefor(nodes(i):@writefor(nodes(j): 
@format(path(i,j),' 10.0f')),@newline(1)); 
enddata
calc: 
w(1,2)=50;w(1,4)=40;w(1,5)=25;w(1,6)=10; 
w(2,3)=15;w(2,4)=20;w(2,6)=25; 
w(3,4)=10;w(3,5)=20; 
w(4,5)=10;w(4,6)=25;w(5,6)=55; 
@for(link(i,j):w(i,j)=w(i,j)+w(j,i)); 
@for(link(i,j) |i#ne#j:w(i,j)=@if(w(i,j)#eq#0,10000,w(i,j))); 
@for(nodes(k):@for(nodes(i):@for(nodes(j): 
tm=@smin(w(i,j),w(i,k)+w(k,j)); 
path(i,j)=@if(w(i,j)#gt# tm,k,path(i,j));w(i,j)=tm))); 
endcalc
end

4 树

4.1 基本概念

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第21张图片

4.2 应用—连线问题

欲修筑连接 n 个城市的铁路,已知i 城与 j 城之间的铁路造价为C**ij ,设计一个线路图,使总造价最低。

连线问题的数学模型是在连通赋权图上求权最小的生成树。赋权图的具最小权的生成树叫做最小生成树。

下面介绍构造最小生成树的两种常用算法。

4.2.1 prim 算法构造最小生成树

设置两个集合 PQ ,其中 P 用于存放G 的最小生成树中的顶点,集合Q 存放G的最小生成树中的边。令集合 P 的初值为 P = {v1}(假设构造最小生成树时,从顶点v1出发),集合Q 的初值为Q = Φ 。prim 算法的思想是,从所有 pPvVP 的边中,选取具有最小权值的边 pv ,将顶点 v 加入集合 P 中,将边 pv 加入集合Q 中,如此不断重复,直到 P =V 时,最小生成树构造完毕,这时集合Q 中包含了最小生成树的所有边。

prim 算法如下:

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第22张图片

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第23张图片

例 13 用 prim 算法求图 5 的最小生成树。

我们用 resultn 的第一、二、三行分别表示生成树边的起点、终点、权集合。Matlab程序如下:

clc;clear;
a=zeros(7);
a(1,2)=50; a(1,3)=60;
a(2,4)=65; a(2,5)=40;
a(3,4)=52;a(3,7)=45;
a(4,5)=50; a(4,6)=30;a(4,7)=42;
a(5,6)=70; 
a=a+a';a(find(a==0))=inf;
result=[];p=1;tb=2:length(a);
while length(result)~=length(a)-1
   temp=a(p,tb);temp=temp(:);
   d=min(temp);
   [jb,kb]=find(a(p,tb)==d);
   j=p(jb(1));k=tb(kb(1));
   result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[];
end
result
4.2.2 Kruskal 算法构造最小生成树

克鲁斯卡尔(Kruskal)算法是一个好算法。Kruskal 算法如下:

请添加图片描述

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第24张图片

例 14 用 Kruskal 算法构造例 3 的最小生成树。

我们用indexn 存放各边端点的信息,当选中某一边之后,就将此边对应的顶点序号中较大序号u 改记为此边的另一序号v ,同时把后面边中所有序号为u 的改记为v

此方法的几何意义是:将序号u 的这个顶点收缩到v 顶点,u 顶点不复存在。后面继续寻查时,发现某边的两个顶点序号相同时,认为已被收缩掉,失去了被选取的资格。

Matlab 程序如下:

clc;clear; 
a(1,2)=50; a(1,3)=60; a(2,4)=65; a(2,5)=40; 
a(3,4)=52;a(3,7)=45; a(4,5)=50; a(4,6)=30; 
a(4,7)=42; a(5,6)=70; 
[i,j,b]=find(a); 
data=[i';j';b'];index=data(1:2,:); 
loop=max(size(a))-1; 
result=[]; 
while length(result)

5 邮递员问题

中国邮递员问题

一位邮递员从邮局选好邮件去投递,然后返回邮局,当然他必须经过他负责投递的每条街道至少一次,为他设计一条投递路线,使得他行程最短。

上述中国邮递员问题的数学模型是:在一个赋权连通图上求一个含所有边的回路,且使此回路的权最小。

显然,若此连通赋权图是 Euler 图,则可用 Fleury 算法求 Euler 回路,此回路即为所求。

对于非 Euler 图,1973 年,Edmonds 和 Johnson 给出下面的解法:

G 是连通赋权图。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第25张图片

多邮递员问题:

邮局有 k(k ≥ 2) 位投递员,同时投递信件,全城街道都要投递,完成任务返回邮局,如何分配投递路线,使得完成投递任务的时间最早?我们把这一问题记成 kPP。

kPP 的数学模型如下:

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第26张图片

例 15 从北京(Pe)乘飞机到东京(T)、纽约(N)、墨西哥城(M)、伦敦(L)、巴黎(Pa)五城市做旅游,每城市恰去一次再回北京,应如何安排旅游线,使旅程最短?各城市之间的航线距离如表 7。

【数学建模】数学建模学习5---图与网络(例题+matlab代码实现)_第27张图片

解:编写程序如下:

function main 
clc,clear 
global a 
a=zeros(6); 
a(1,2)=56;a(1,3)=35;a(1,4)=21;a(1,5)=51;a(1,6)=60; 
a(2,3)=21;a(2,4)=57;a(2,5)=78;a(2,6)=70; 
a(3,4)=36;a(3,5)=68;a(3,6)=68; a(4,5)=51;a(4,6)=61; 
a(5,6)=13; a=a+a'; L=size(a,1); 
c1=[5 1:4 6]; 
[circle,long]=modifycircle(c1,L); 
c2=[5 6 1:4];%改变初始圈,该算法的最后一个顶点不动
[circle2,long2]=modifycircle(c2,L); 
if long20 
       flag=0; 
   for m=1:L-3 
       for n=m+2:L-1 
           if a(c1(m),c1(n))+a(c1(m+1),c1(n+1))<... 
               a(c1(m),c1(m+1))+a(c1(n),c1(n+1)) 
               flag=1; 
               c1(m+1:n)=c1(n:-1:m+1); 
           end 
       end 
   end 
end 
long=a(c1(1),c1(L)); 
for i=1:L-1 
   long=long+a(c1(i),c1(i+1)); 
end 
circle=c1; 
************************ 
%修改圈的子函数
%******************************************* 
function [circle,long]=modifycircle(c1,L); -87- 
global a 
flag=1; 
while flag>0 
       flag=0; 
   for m=1:L-3 
       for n=m+2:L-1 
           if a(c1(m),c1(n))+a(c1(m+1),c1(n+1))<... 
               a(c1(m),c1(m+1))+a(c1(n),c1(n+1)) 
               flag=1; 
               c1(m+1:n)=c1(n:-1:m+1); 
           end 
       end 
   end 
end 
long=a(c1(1),c1(L)); 
for i=1:L-1 
   long=long+a(c1(i),c1(i+1)); 
end 
circle=c1; 

你可能感兴趣的:(#,数学建模,数学建模,图,网络)