图与网络的基本概念与数据结构

一.图与网络的基本概念

图论中图是由点和边构成的,可以反映一些对象之间的关系。

无向图

无向图(简称图):没有方向,由点和边构成的图,记做G =(V , E),点是V,边是E。
:图论的图与几何图、工程图不一样。
因为一般情况下的图中点的相对位置及点间连线长短,对于反映对象之间的关系并不是重要的。

联结vi1v_i{_1}vi​1​ 和vikv_{ik}vik​ 的链:在无向图G中,若存在一个点边的交错序列(vi1,ei1,vi2,ei2,...vik−1,eik−1,cikv_{i1},e_{i1},v_{i2},e_{i2},...v_{i_{k-1}},e_{i_{k-1}},c_{ik}vi1​,ei1​,vi2​,ei2​,...vik−1​​,eik−1​​,cik​)其中vikv_{ik}vik​属于V(G),eije_{ij}eij​属于E(G)

联结 v_{i1} 和 v_{ik} 的圈:在上述的链中,若 v_{i1} = v_{ik},也就是首尾相连。

连通图:对于一个无向图,若任何两个不同的点之间,至少存在一条链。

简单图:一个图如果它既没有环也没有平行边(两条边连接同一对顶点),称为简单图(simple graph)。

完全图:其中每对不同的顶点之间都恰连有一条边相连

赋权图:对无向图的每一条边(vi,vjv_i,v_jvi​,vj​) ,都有一个数(称为权重) wijw_{ij}wij​对应。

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图

顶点的度:与顶点v关联的边的个数称为顶点v 的
度(degree) (环计两度),记作 d(v) .
度为零的点称为弧立点,度为1的点称为悬挂点。悬挂点的关联边称为悬挂边。度为奇数的点称为奇点(odd point) ,度为偶数的点称为偶点(even point) 。

有向图

有向图:由点和弧构成的图,记做D =(V , A),其中V是图D的点集,A是图D的弧集。
:无向图是一种特殊的有向图,无向图的边实际上就是等 价于两条方向相反的弧。
联结vi1v_i{_1}vi​1​ 和vikv_{ik}vik​ 的路:在无向图G中,若存在一个点边的交错序列(vi1,ei1,vi2,ei2,...vik−1,eik−1,cikv_{i1},e_{i1},v_{i2},e_{i2},...v_{i_{k-1}},e_{i_{k-1}},c_{ik}vi1​,ei1​,vi2​,ei2​,...vik−1​​,eik−1​​,cik​)其中vikv_{ik}vik​属于V(D),eije_{ij}eij​属于V(D)
*联结 v_{i1} 和 v_{ik} 的回路:在上述的链中,若 v_{i1} = v_{ik},也就是首尾相连。
赋权图:对无向图的每一条弧(vi,vjv_i,v_jvi​,vj​) ,都有一个数(称为权重) cijc_{ij}cij​对应。
网络:在赋权的有向图D中指定一点为发点(记为 vsv_svs​ ),指定另一点为收点(记为vtv_tvt​),其余的点为中间点,并把 D 中的每一条弧的赋权数cijc_ijci​j 称为弧 (vi,vj)(v_i,v_j)(vi​,vj​) 的容量 ,这样的赋权有向图 D 就称为网络。

二.图与网络的数据结构

描述图与网络的3种常用表示方法:邻接矩阵表示法、关联矩阵表示法、弧表表示法

邻接矩阵表示法

邻接矩阵表示法是将图以邻接矩阵(adjacency matrix)的形式存储在计算机中。图 G=(V,A) 的邻接矩阵是如下定义的:C是一个n∗nn*nn∗n的0-1矩阵,即

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

例一:对于下图,可以用邻接矩阵表示为

解释:现在有五个图,邻接矩阵a就是5∗55*55∗5的方阵,∵ 1→2,∴a[1][2]=1;
∵1→3所以a[1][3]=1;∵ 4→3,∴a[4][3]=1,其他都是一样的,所有的都写出来就是:
同样,对于网络中的权,也可以用类似邻接矩阵的矩阵表示。只是此时一条弧所对应的元素不再是1,而是相应的权而已。如果网络中每条 弧赋有多种权,则可以用多个矩阵表示这些权。

关联矩阵表示法

关联矩阵表示法是将图以关联矩阵(incidence matrix)的形式存储在计算机中.
图 B=(bik)n∗m∈(−1,0,1)n∗mB=(b_{ik})_{n*m}\in({-1 ,0 ,1}) ^{n*m}B=(bik​)n∗m​∈(−1,0,1)n∗m 的关联矩阵B是如下定义的:B是一个n*m的矩阵,即

如果一个顶点是一条弧的起点,则关联矩阵中对应的元素为1;如果一个顶点是一条弧的终点,则关联矩阵中对应的元素为-1;如果一个顶点与一条弧不关联,则关联矩阵中对应的元素为0。

例2 对于例1所示的图,如果关联矩阵中每列对应弧的顺序为 (1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4),则关联矩阵表示为(列单位为弧)
这个图有4个节点,7条连线,所以是4∗74*74∗7的矩阵,每一列都是只有一个1,一个 -1。
看e1这条线,头是v1尾是v2,所以v1=1,v2=-1
e3,头是v3,尾是v4,所以v3是1,v4是-1;
)

弧表表示法

弧表表示法将图以弧表(arc list)的形式存储在计算机中。所谓图的弧表,也就是图的弧集合中的所有有序对。
假设例1中的弧(1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4)上的权分别为8,9,6,4,0,3,6和7,则弧表表示如下:

最短路问题 (Shortest Path Problem)

最短路问题:对一个赋权有向图中指定的两个点vsv_svs​和vtv_tvt​找到条从vsv_svs​到vtv_tvt​的路,使得这条路上所有弧的权数总和最小,这条路被称为从vsv_svs​ 到vtv_tvt​, 的最短路,这条路_上所有弧的权数的总和被称为从vsv_svs​到vtv_tvt​ 的距离。

Dijkstra算法

如上图,带权值的最短路径长度就是黄线标出来的 为7
求解最短路的迪克斯特拉Dijkstra算法(双标号法)
双标号即:对图中的点 vjv_jvj​ 赋予两个标号 (lj,kj)(l_j,k_j)(lj​,kj​) ,其中 l_j 表示从起点vsv_svs​ 到 vjv_jvj​ 的最短路的长度,kjk_jkj​ 表示在 vsv_svs​ 至vjv_jvj​ 的最短路上前面一个邻点的下标,从而找到所求的最短路及其距离。

下面给出Dijkstra算法的基本步骤:{\mathbb{\color{Red}下面给出Dijkstra算法的基本步骤:}}下面给出Dijkstra算法的基本步骤:

  1. 先给起点 vsv_svs​ 标号:(0,s),表示从 vsv_svs​ 到 vsv_svs​ 的距离为0, vsv_svs​ 为起点。
  2. 找出已标号的点集 I ,未标号的点集 J 以及从 I 到 J 的弧集。
  3. 若上述弧集是空集,则计算结束。此时,如果 vtv_tvt​ 已标号 (l_t,k_t) 则 vsv_svs​到 vtv_tvt​ 的距离为 ltl_tlt​ ,而从 vsv_svs​ 到vtv_tvt​ 的最短路,可以从 ktk_tkt​ 反向追踪到起点 vsv_svs​而得到。 如果 vtv_tvt​ 未标号,则不存在从 vsv_svs​ 到 vtv_tvt​ 的有向路。 若上述弧集不是空集,则转下一步。
  4. 对上述弧集中的每一条弧,计算sij=li+cijs_{ij}=l_i+c_{ij}sij​=li​+cij​ 在所有的sijs_{ij}sij​中,找值最小的弧,不妨设为(vc,va)(v_c,v_a)(vc​,va​)则给此弧的终点 vav_ava​ 标号(scd,c)(s_cd,c)(sc​d,c) ,返回步骤2.

标号(m,n)m是权重,n是前一个节点


同时,我们可以从各点的标号得到起点到该点的最短路径及距离。



用行向量pb表示P标号信息,index1表示标号顶点顺序, index2表示标号顶点索引,d表示最短路的值.

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(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; %最新的P标号的顶点
while sum(pb)<length(a)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

程序过程就不具体分析了,只看看输出吧。
d代表距离,在这个题里代表票价,代表c1分别到c1,c2,c3,c4,c5,c6的距离
index1代表标号顺序
index2代表该标号的前一个标号

d =0    35    45    35    25    10
index1 =1     6     5     2     4     3
index2 =1     6     5     6     1     1

第一个标号的是自身c1,不用管,从第二个开始c1→c6,可以看到c6的前一个节点是1,所以c1直接到了c6.距离d=10;
第三个是c5,也是c1直接到的,距离d=25;
第四个c2,可以看到c2的前一个节点是c6,c6的前一个节点是c1,所以c1到c2的最短距离为c1先到c6再从c6到c2,距离为40
其他的以此类推

Floyd算法

主要用来计算每对顶点之间的最短路径。
Dijkstra算法用来计算一对顶点之间的最短路径。

Floyd算法的基本思想是:递推产生一个矩阵序列 A0,A1...Ak...AnA_0,A_1...A_k...A_nA0​,A1​...Ak​...An​ ,其中 Ak(i,j)A_k(i,j)Ak​(i,j) 表示从顶点viv_ivi​到顶点 vjv_jvj​ 的路径上所经过的顶点序号不大于k的最
短路径度。迭代公式为:

k是迭代次数,i,j,k=1,2,3,...ni,j,k=1 ,2,3,...ni,j,k=1,2,3,...n最后,当k=n时, 即是各顶点之间的最短通路值。
这个算法要产生两个矩阵
这个算法就是找一个中间点,通过判断两个顶点的直接距离与通过中间点的简介距离的远近比较(近的为优) 来不断对两个矩阵进行更新。



A代表每两个点之间的距离,path是每两个点之间的最短路径经过的中间点,一开始没有中间点,所以设置为-1,代表没有中间点。

这个是找一个中间点,一般是从0开始,再找1 2 3,这样过一遍。

我们直接用1开始吧,因为我算了,0没有更新。
算自身和自身都是0没啥意思,两两连接就是这12对顶点。
{0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 2}, {1, 3),
{2, 0}, {2, 1}, {2, 3}, {3, 0}, {3, 1}, {3, 2}

  • {0,1}:因为要经过1,所以可以看成是A[0][1]=A[0][1]+A[1][1]A[0][1]=A[0][1]+A[1][1]A[0][1]=A[0][1]+A[1][1],左右相等,不更新
  • {0,2}:A[0][2]>A[0][1]+A[1][2]→∞>5+4A[0][2]>A[0][1]+A[1][2] \rightarrow \infin >5+4A[0][2]>A[0][1]+A[1][2]→∞>5+4所以更新,Path矩阵的A[0][2]更新为1(因为中间点是1)A矩阵中的A[0][2]更新为9
  • 这是经过中间点为1跟新后的两个新矩阵
  • {0,3}:A[0][3]>A[0][1]+A[1][3]→7=5+2A[0][3]>A[0][1]+A[1][3] \rightarrow 7 =5+2A[0][3]>A[0][1]+A[1][3]→7=5+2不更新
  • {1,2}{1,3}{1,0}都经过1,不更新,剩下的自己算吧,当然我算了,没有更新。

再以顶点2为中间点进行检测

  • {0,1}:A[0][1]<A[0][2]+A[2][1]→5<9+3A[0][1]<A[0][2]+A[2][1] \rightarrow 5<9+3A[0][1]<A[0][2]+A[2][1]→5<9+3不更新
  • {0,2}{2,0} {2,1}{2,3}有2不用算
  • {0,3}:A[0][3]<A[0][2]+A[2][3]→7<9+2A[0][3]<A[0][2]+A[2][3] \rightarrow 7<9+2A[0][3]<A[0][2]+A[2][3]→7<9+2不更新
  • {1,0}:A[1][0]=A[1][2]+A[2][0]→∞>4+3A[1][0]=A[1][2]+A[2][0] \rightarrow \infin >4+3A[1][0]=A[1][2]+A[2][0]→∞>4+3 更新
  • {3,0}A[3][0]>A[3][2]+A[2][0]→4=1+2A[3][0]>A[3][2]+A[2][0] \rightarrow 4 =1+2A[3][0]>A[3][2]+A[2][0]→4=1+2不更新
  • 两个矩阵都分别跟新为如下两个
  • 后面也都是一样,上次更新后直接以上次更新的那个矩阵为基础进行计算。这是以2为中间点进行更新的结果
  • 这是3为中间点进行更新的结果

    弗洛伊德算法就是利用矩阵的不断更新进行运算
    当然FLoyd算法也有MATLAB程序
    以Dijkstra算法那个例题为例,进行计算
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';
a(a==0)=inf; %把所有零元素替换成无穷
a([1:n+1:n^2])=0; %对角线元素替换成零,Matlab中数据是逐列存储的
path=zeros(n);
for k=1:nfor i=1:nfor j=1:nif a(i,j)>a(i,k)+a(k,j)a(i,j)=a(i,k)+a(k,j);path(i,j)=k;end endend
end
a, patha =0    35    45    35    25    1035     0    15    20    30    2545    15     0    10    20    3535    20    10     0    10    2525    30    20    10     0    3510    25    35    25    35     0path =0     6     5     5     0     06     0     0     0     4     05     0     0     0     0     45     0     0     0     0     00     4     0     0     0     10     0     4     0     1     0

可以看到输出a是一个对称矩阵,代表两个点之间的距离,path代表路径,如[1,2]的数值是6,也就是经过了6这个中间点。

是不是只有距离这种题才能用这个模型呢?


设备更新问题。某公司使用一台设备,在每年年初,公司就要决定是购买新的设备还是继续使用旧设备。如果购置新设备,就要支付一定的购置费,当然新设备的维修费用就低。如果继续使用旧设备,这样可以省去了购置费,但维修费用就高了。现在需要我们制定一个五年之内的更新设备的计划,使得五年内购置费和维修费总的支付费用最小。

这种设备每年年初的价格如下表

另外,还已知使用不同时间(年)的设备所需要的维修费如下图

用点vi 表示第 i 年年初购进一台新设备,i=1, 2, 3, 4, 5, 6.
用弧 (vi,vj) 表示在第 i 年年初购进的设备一直使用到第 j 年年初,其中i<j
化为最短路问题后,相应的图示如下:

相应地,把费用转化为图中弧的权数。

对于弧 (vi,vj) ,其权数为从第 i 年年初购进设备使用到第 j-1 年年底所花费的购置费及维修费的总和。如下:

下面把计算得到的权数赋到图上,得到赋权图,则求解五年
内购置费和维修费总费用最小的问题就转化为从赋权图中求解一
条从 v1 到v6 的最短路问题。

最短路径:
v1→v3→v6v1→v3→v6v1→v3→v6 即:第1年初购置的新设备使用到第3年初 (第2年底) ,第3年初再购置新设备使用到第6年初 (第5年底) 。
v1→v4→v6v1→v4→v6v1→v4→v6 即:第1年初购置的新设备使用到第4年初 (第3年底) ,第4年初再购置新设备使用到第6年初 (第5年底)
两个路径耗费的金钱是一样的
用MATLAB

clear;clc;
n=6; a=zeros(n);
a(1,2)=16;a(1,3)=22;a(1,4)=30;a(1,5)=41;a(1,6)=59;
a(2,3)=16;a(2,4)=22;a(2,5)=22;a(2,6)=41;
a(3,4)=17;a(3,5)=23;a(3,6)=31;
a(4,5)=17;a(4,6)=23;
a(5,6)=18;
a=a+a';
a(a==0)=inf; %把所有零元素替换成无穷
a([1:n+1:n^2])=0; %对角线元素替换成零,Matlab中数据是逐列存储的
path=zeros(n);
for k=1:nfor i=1:nfor j=1:nif a(i,j)>a(i,k)+a(k,j)a(i,j)=a(i,k)+a(k,j);path(i,j)=k;end endend
end
a, path

下一篇数学建模之图论——图与网络模型(二)(最小生成树问题、最大流问题) https://blog.csdn.net/weixin_45755332/article/details/106946149

数学建模之图论——图与网络模型(一)(基本概念和最短路问题,附MATLAB源码)相关推荐

  1. 数学建模之图论——图与网络模型(二)(最小生成树问题、最大流问题)

    建议先看上一篇基本概念篇 https://blog.csdn.net/weixin_45755332/article/details/106899147 最小生成树 基本概念和方法 树:没有圈的连通图 ...

  2. 数学建模-关于碎纸片的拼接复原的理解(2003年建模国赛B题 附Matlab源码)

    目录 赛题解析 题目 解题思路 算法细节 运行结果 Matlab源码 赛题解析 题目 2013年B题 碎纸片的拼接复原     破碎文件的拼接在司法物证复原.历史文献修复以及军事情报获取等领域都有着重 ...

  3. 2022年高教社杯全国大学生数学建模竞赛-A题:波浪能最大输出功率设计(附MATLAB代码)

    前言 最近发现一个关于数学建模比较好的专栏,需要的小伙伴可移步[数学建模应用]算法实战案例精讲300篇(持续更新ing) 赛题描述 随着经济和社会的发展,人类面临能源需求和环境污染的双重挑战,发展可再 ...

  4. MATLAB实战系列(十七)-大学生数学建模赛题解析-水塔中水流量估计(附MATLAB源码)

    题目 美国某洲的各用水管理机构要求各社区提供以每小时多少加仑计的用水率以及每天总 的用水量,但许多社区并没有测量水流入或流出当地水塔的水量的设备,他们只能代之以每小时测量水塔中的水位,精度在 0.5% ...

  5. 【数学建模】基于SIR模型实现新冠病毒COVID-19估计附matlab代码

    1 内容介绍 COVID-19是由严重急性呼吸综合症冠状病毒2型引发的传染病,它最初病毒携带者是一些动物,传染源主要是COVID-19患者,无症状患者.传播方式主要是呼吸道飞沫近距离传播,接触传播,还 ...

  6. 2019年第十六届中国研究生数学建模竞赛F题·一种快速找到最优解的算法(提供Matlab源码)

    2019年第十六届中国研究生数学建模竞赛F题·一种快速找到最优解的算法(提供Matlab源码) 目录 0. 源码+数据 1. 问题介绍 2. 贪心寻找较优解 2.1 算法步骤 2.2 源码 2.2.1 ...

  7. 澳洲森林火灾蔓延数学建模,基于元胞自动机模拟多模式下火灾蔓延(附部分源码)

    前言 本文篇幅较长,希望各位小伙伴能够耐心看完. 元胞自动机模型可以用来模拟交通流.火灾蔓延情况.高速收费站交通情况,有利于我们更好地改善交通状况,更好地控制火灾蔓延,合理地设置收费站的数量等. 关于 ...

  8. 【数学建模】基于matlab武汉地铁2号线路线地图动态模拟【含Matlab源码 1092期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[数学建模]基于matlab武汉地铁2号线路线地图动态模拟[含Matlab源码 1092期] 点击上面蓝色字体,直接付费下载,即可. 获取代 ...

  9. 【数学建模】基于matlab船舶三自由度MMG模型【含Matlab源码 1925期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[数学建模]基于matlab船舶三自由度MMG模型[含Matlab源码 1925期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式 ...

最新文章

  1. 西瓜书_学习任务_更新至9.5号
  2. 程序怎么启动vasp_构建可扩展的GPU加速应用程序(NVIDIA HPC)
  3. OpenCV在浏览器中运行深度网络
  4. Leet Code OJ 118. Pascal's Triangle [Difficulty: Easy]
  5. 通过border来实现各种三角符号
  6. VB讲课笔记13:二级公共基础
  7. easyexcel 导入指定_阿里巴巴EasyExcel使用(3)-导入
  8. iphone主屏幕动态壁纸_苹果11怎么设置动态壁纸?这个简单!只需这样操作
  9. vba实现粘贴复制功能
  10. SecureCRT安装及破解
  11. 富士通Fujitsu DPK2089K 打印机驱动
  12. opencv将16位灰度图片转化为8位
  13. 袁老走好,谢谢您!我辈也当自强。
  14. 一文读懂高频交易程序化交易和量化交易区别
  15. Fandis COSTECH A17M23SWB MT0再见,故宫
  16. 谈谈eve-ng仿真模器
  17. WIFI转串口无线传输模块,个人体会
  18. Conditional Positional Encodings for Vision Transformers(论文阅读笔记)
  19. Android面试题最全总结系列 (持续更新中...)
  20. TensorFlow Mnist数据集下载问题

热门文章

  1. python 拟牛顿法 求非线性方程_C语言实现迭代法求非线性方程的根
  2. python数据清洗csv_Pandas 数据处理,数据清洗详解
  3. int** 赋值_一篇文章搞明白Integer、new Integer() 和 int 的概念与区别
  4. js最小化浏览器_「译」解析、抽象语法树(ast) +如何最小化解析时间的5个技巧...
  5. python选课系统作业_Python 大作业4:选课系统
  6. android cm 老罗,Android之父打造了一款全面屏旗舰 罗永浩如此评价
  7. workbench提示工作负载高度不平衡_功率因数负载组
  8. 数据挖掘肿瘤预测_喜欢临床预测模型|SEER数据挖掘的期刊有哪些
  9. mysql查询特殊符号时_数据库查询中的特殊字符的问题_MySQL
  10. stm32——modbus例程网址收藏